1. 02 5月, 2013 30 次提交
    • A
      libceph: be explicit in masking bottom 16 bits · 0baa1bd9
      Alex Elder 提交于
      In ceph_osdc_build_request() there is a call to cpu_to_le16() which
      provides a 64-bit value as its argument.  Because of the implied
      byte swapping going on it looked pretty suspect to me.
      
      At the moment it turns out the behavior is well defined, but masking
      off those bottom bits explicitly eliminates this distraction, and is
      in fact more directly related to the purpose of the message header's
      data_off field.
      
      This resolves:
          http://tracker.ceph.com/issues/4125Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      0baa1bd9
    • A
      libceph: send queued requests when starting new one · 7e2766a1
      Alex Elder 提交于
      An osd expects the transaction ids of arriving request messages from
      a given client to a given osd to increase monotonically.  So the osd
      client needs to send its requests in ascending tid order.
      
      The transaction id for a request is set at the time it is
      registered, in __register_request().  This is also where the request
      gets placed at the end of the osd client's unsent messages list.
      
      At the end of ceph_osdc_start_request(), the request message for a
      newly-mapped osd request is supplied to the messenger to be sent
      (via __send_request()).  If any other messages were present in the
      osd client's unsent list at that point they would be sent *after*
      this new request message.
      
      Because those unsent messages have already been registered, their
      tids would be lower than the newly-mapped request message, and
      sending that message first can violate the tid ordering rule.
      
      Rather than sending the new request only, send all queued requests
      (including the new one) at that point in ceph_osdc_start_request().
      This ensures the tid ordering property is preserved.
      
      With this in place, all messages should now be sent in tid order
      regardless of whether they're being sent for the first time or
      re-sent as a result of a call to osd_reset().
      
      This resolves:
          http://tracker.ceph.com/issues/4392Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-off-by: NSage Weil <sage@inktank.com>
      7e2766a1
    • A
      libceph: keep request lists in tid order · ad885927
      Alex Elder 提交于
      In __map_request(), when adding a request to an osd client's unsent
      list, add it to the tail rather than the head.  That way the newest
      entries (with the highest tid value) will be last.
      
      Maintain an osd's request list in order of increasing tid also.
      
      Finally--to be consistent--maintain an osd client's "notarget" list
      in that order as well.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4392Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-off-by: NSage Weil <sage@inktank.com>
      ad885927
    • A
      libceph: requeue only sent requests when kicking · e02493c0
      Alex Elder 提交于
      The osd expects incoming requests for a given object from a given
      client to arrive in order, with the tid for each request being
      greater than the tid for requests that have already arrived.  This
      patch fixes two places the osd client might not maintain that
      ordering.
      
      For the osd client, the connection fault method is osd_reset().
      That function calls __reset_osd() to close and re-open the
      connection, then calls __kick_osd_requests() to cause all
      outstanding requests for the affected osd to be re-sent after
      the connection has been re-established.
      
      When an osd is reset, any in-flight messages will need to be
      re-sent.  An osd client maintains distinct lists for unsent and
      in-flight messages.  Meanwhile, an osd maintains a single list of
      all its requests (both sent and un-sent).  (Each message is linked
      into two lists--one for the osd client and one list for the osd.)
      
      To process an osd "kick" operation, the request list for the *osd*
      is traversed, and each request is moved off whichever osd *client*
      list it was on (unsent or sent) and placed onto the osd client's
      unsent list.  (It remains where it is on the osd's request list.)
      
      When that is done, osd_reset() calls __send_queued() to cause each
      of the osd client's unsent messages to be sent.
      
      OK, with that background...
      
      As the osd request list is traversed each request is prepended to
      the osd client's unsent list in the order they're seen.  The effect
      of this is to reverse the order of these requests as they are put
      (back) onto the unsent list.
      
      Instead, build up a list of only the requests for an osd that have
      already been sent (by checking their r_sent flag values).  Once an
      unsent request is found, stop examining requests and prepend the
      requests that need re-sending to the osd client's unsent list.
      
      Preserve the original order of requests in the process (previously
      re-queued requests were reversed in this process).  Because they
      have already been sent, they will have lower tids than any request
      already present on the unsent list.
      
      Just below that, traverse the linger list in forward order as
      before, but add them to the *tail* of the list rather than the head.
      These requests get re-registered, and in the process are give a new
      (higher) tid, so the should go at the end.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4392Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-off-by: NSage Weil <sage@inktank.com>
      e02493c0
    • A
      libceph: no more kick_requests() race · 92451b49
      Alex Elder 提交于
      Since we no longer drop the request mutex between registering and
      mapping an osd request in ceph_osdc_start_request(), there is no
      chance of a race with kick_requests().
      
      We can now therefore map and send the new request unconditionally
      (but we'll issue a warning should it ever occur).
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-off-by: NSage Weil <sage@inktank.com>
      92451b49
    • A
      libceph: slightly defer registering osd request · dc4b870c
      Alex Elder 提交于
      One of the first things ceph_osdc_start_request() does is register
      the request.  It then acquires the osd client's map semaphore and
      request mutex and proceeds to map and send the request.
      
      There is no reason the request has to be registered before acquiring
      the map semaphore.  So hold off doing so until after the map
      semaphore is held.
      
      Since register_request() is nothing more than a wrapper around
      __register_request(), call the latter function instead, after
      acquiring the request mutex.
      
      That leaves register_request() unused, so get rid of it.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4392Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-off-by: NSage Weil <sage@inktank.com>
      dc4b870c
    • S
      libceph: wrap auth ops in wrapper functions · 27859f97
      Sage Weil 提交于
      Use wrapper functions that check whether the auth op exists so that callers
      do not need a bunch of conditional checks.  Simplifies the external
      interface.
      Signed-off-by: NSage Weil <sage@inktank.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      27859f97
    • S
      libceph: add update_authorizer auth method · 0bed9b5c
      Sage Weil 提交于
      Currently the messenger calls out to a get_authorizer con op, which will
      create a new authorizer if it doesn't yet have one.  In the meantime, when
      we rotate our service keys, the authorizer doesn't get updated.  Eventually
      it will be rejected by the server on a new connection attempt and get
      invalidated, and we will then rebuild a new authorizer, but this is not
      ideal.
      
      Instead, if we do have an authorizer, call a new update_authorizer op that
      will verify that the current authorizer is using the latest secret.  If it
      is not, we will build a new one that does.  This avoids the transient
      failure.
      
      This fixes one of the sorry sequence of events for bug
      
      	http://tracker.ceph.com/issues/4282Signed-off-by: NSage Weil <sage@inktank.com>
      Reviewed-by: NAlex Elder <elder@inktank.com>
      0bed9b5c
    • A
      libceph: kill osd request r_trail · 95e072eb
      Alex Elder 提交于
      The osd trail is a pagelist, used only for a CALL osd operation
      to hold the class and method names, along with any input data for
      the call.
      
      It is only currently used by the rbd client, and when it's used it
      is the only bit of outbound data in the osd request.  Since we
      already support (non-trail) pagelist data in a message, we can
      just save this outbound CALL data in the "normal" pagelist rather
      than the trail, and get rid of the trail entirely.
      
      The existing pagelist support depends on the pagelist being
      dynamically allocated, and ownership of it is passed to the
      messenger once it's been attached to a message.  (That is to say,
      the messenger releases and frees the pagelist when it's done with
      it).  That means we need to dynamically allocate the pagelist also.
      
      Note that we simply assert that the allocation of a pagelist
      structure succeeds.  Appending to a pagelist might require a dynamic
      allocation, so we're already assuming we won't run into trouble
      doing so (we're just ignore any failures--and that should be fixed
      at some point).
      
      This resolves:
          http://tracker.ceph.com/issues/4407Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      95e072eb
    • A
      libceph: have osd requests support pagelist data · 9a5e6d09
      Alex Elder 提交于
      Add support for recording a ceph pagelist as data associated with an
      osd request.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      9a5e6d09
    • A
      libceph: let osd ops determine request data length · 175face2
      Alex Elder 提交于
      The length of outgoing data in an osd request is dependent on the
      osd ops that are embedded in that request.  Each op is encoded into
      a request message using osd_req_encode_op(), so that should be used
      to determine the amount of outgoing data implied by the op as it
      is encoded.
      
      Have osd_req_encode_op() return the number of bytes of outgoing data
      implied by the op being encoded, and accumulate and use that in
      ceph_osdc_build_request().
      
      As a result, ceph_osdc_build_request() no longer requires its "len"
      parameter, so get rid of it.
      
      Using the sum of the op lengths rather than the length provided is
      a valid change because:
          - The only callers of osd ceph_osdc_build_request() are
            rbd and the osd client (in ceph_osdc_new_request() on
            behalf of the file system).
          - When rbd calls it, the length provided is only non-zero for
            write requests, and in that case the single op has the
            same length value as what was passed here.
          - When called from ceph_osdc_new_request(), (it's not all that
            easy to see, but) the length passed is also always the same
            as the extent length encoded in its (single) write op if
            present.
      
      This resolves:
          http://tracker.ceph.com/issues/4406Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      175face2
    • A
      libceph: set response data fields earlier · 70636773
      Alex Elder 提交于
      When an incoming message is destined for the osd client, the
      messenger calls the osd client's alloc_msg method.  That function
      looks up which request has the tid matching the incoming message,
      and returns the request message that was preallocated to receive the
      response.  The response message is therefore known before the
      request is even started.
      
      Between the start of the request and the receipt of the response,
      the request and its data fields will not change, so there's no
      reason we need to hold off setting them.  In fact it's preferable
      to set them just once because it's more obvious that they're
      unchanging.
      
      So set up the fields describing where incoming data is to land in a
      response message at the beginning of ceph_osdc_start_request().
      Define a helper function that sets these fields, and use it to
      set the fields for both outgoing data in the request message and
      incoming data in the response.
      
      This resolves:
          http://tracker.ceph.com/issues/4284Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      70636773
    • A
      ceph: only set message data pointers if non-empty · ebf18f47
      Alex Elder 提交于
      Change it so we only assign outgoing data information for messages
      if there is outgoing data to send.
      
      This then allows us to add a few more (currently commented-out)
      assertions.
      
      This is related to:
          http://tracker.ceph.com/issues/4284Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NGreg Farnum <greg@inktank.com>
      ebf18f47
    • A
      libceph: isolate other message data fields · 27fa8385
      Alex Elder 提交于
      Define ceph_msg_data_set_pagelist(), ceph_msg_data_set_bio(), and
      ceph_msg_data_set_trail() to clearly abstract the assignment of the
      remaining data-related fields in a ceph message structure.  Use the
      new functions in the osd client and mds client.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4263Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      27fa8385
    • A
      libceph: set page info with byte length · f1baeb2b
      Alex Elder 提交于
      When setting page array information for message data, provide the
      byte length rather than the page count ceph_msg_data_set_pages().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      f1baeb2b
    • A
      libceph: isolate message page field manipulation · 02afca6c
      Alex Elder 提交于
      Define a function ceph_msg_data_set_pages(), which more clearly
      abstracts the assignment page-related fields for data in a ceph
      message structure.  Use this new function in the osd client and mds
      client.
      
      Ideally, these fields would never be set more than once (with
      BUG_ON() calls to guarantee that).  At the moment though the osd
      client sets these every time it receives a message, and in the event
      of a communication problem this can happen more than once.  (This
      will be resolved shortly, but setting up these helpers first makes
      it all a bit easier to work with.)
      
      Rearrange the field order in a ceph_msg structure to group those
      that are used to define the possible data payloads.
      
      This partially resolves:
          http://tracker.ceph.com/issues/4263Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      02afca6c
    • A
      libceph: record byte count not page count · e0c59487
      Alex Elder 提交于
      Record the byte count for an osd request rather than the page count.
      The number of pages can always be derived from the byte count (and
      alignment/offset) but the reverse is not true.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      e0c59487
    • A
      libceph: separate read and write data · 0fff87ec
      Alex Elder 提交于
      An osd request defines information about where data to be read
      should be placed as well as where data to write comes from.
      Currently these are represented by common fields.
      
      Keep information about data for writing separate from data to be
      read by splitting these into data_in and data_out fields.
      
      This is the key patch in this whole series, in that it actually
      identifies which osd requests generate outgoing data and which
      generate incoming data.  It's less obvious (currently) that an osd
      CALL op generates both outgoing and incoming data; that's the focus
      of some upcoming work.
      
      This resolves:
          http://tracker.ceph.com/issues/4127Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      0fff87ec
    • A
      libceph: distinguish page and bio requests · 2ac2b7a6
      Alex Elder 提交于
      An osd request uses either pages or a bio list for its data.  Use a
      union to record information about the two, and add a data type
      tag to select between them.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      2ac2b7a6
    • A
      libceph: separate osd request data info · 2794a82a
      Alex Elder 提交于
      Pull the fields in an osd request structure that define the data for
      the request out into a separate structure.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      2794a82a
    • A
      libceph: don't assign page info in ceph_osdc_new_request() · 153e5167
      Alex Elder 提交于
      Currently ceph_osdc_new_request() assigns an osd request's
      r_num_pages and r_alignment fields.  The only thing it does
      after that is call ceph_osdc_build_request(), and that doesn't
      need those fields to be assigned.
      
      Move the assignment of those fields out of ceph_osdc_new_request()
      and into its caller.  As a result, the page_align parameter is no
      longer used, so get rid of it.
      
      Note that in ceph_sync_write(), the value for req->r_num_pages had
      already been calculated earlier (as num_pages, and fortunately
      it was computed the same way).  So don't bother recomputing it,
      but because it's not needed earlier, move that calculation after the
      call to ceph_osdc_new_request().  Hold off making the assignment to
      r_alignment, doing it instead r_pages and r_num_pages are
      getting set.
      
      Similarly, in start_read(), nr_pages already holds the number of
      pages in the array (and is calculated the same way), so there's no
      need to recompute it.  Move the assignment of the page alignment
      down with the others there as well.
      
      This and the next few patches are preparation work for:
          http://tracker.ceph.com/issues/4127Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      153e5167
    • A
      libceph: rename ceph_calc_object_layout() · 41766f87
      Alex Elder 提交于
      The purpose of ceph_calc_object_layout() is to fill in the pool
      number and seed for a ceph_pg structure provided, based on a given
      osd map and target object id.
      
      Currently that function takes a file layout parameter, but the only
      thing used out of that is its pool number.
      
      Change the function so it takes a pool number rather than the full
      file layout structure.  Only update the ceph_pg if the pool is found
      in the osd map.  Get rid of few useless lines of code from the
      function while there.
      
      Since the function now very clearly just fills in the ceph_pg
      structure it's provided, rename it ceph_calc_ceph_pg().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      41766f87
    • A
      libceph: fix wrong opcode use in osd_req_encode_op() · 8f63ca2d
      Alex Elder 提交于
      The new cases added to osd_req_encode_op() caused a new sparse
      error, which highlighted an existing problem that had been
      overlooked since it was originally checked in.  When an unsupported
      opcode is found the destination rather than the source opcode was
      being used in the error message.  The two differ in their byte
      order, and we want to be using the one in the source.
      
      Fix the problem in both spots.
      Reported-by: NFengguang Wu <fengguang.wu@intel.com>
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      8f63ca2d
    • A
      libceph: complete lingering requests only once · 0d5af164
      Alex Elder 提交于
      An osd request marked to linger will be re-submitted in the event
      a connection to the target osd gets dropped.  Currently, if there
      is a callback function associated with a request it will be called
      each time a request is submitted--which for lingering requests can
      be more than once.
      
      Change it so a request--including lingering ones--will get completed
      (from the perspective of the user of the osd client) exactly once.
      
      This resolves:
          http://tracker.ceph.com/issues/3967Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      0d5af164
    • A
      libceph: set page alignment in start_request() · f51a822c
      Alex Elder 提交于
      The page alignment field for a request is currently set in
      ceph_osdc_build_request().  It's not needed at that point
      nor do either of its callers need that value assigned at
      any point before they call ceph_osdc_start_request().
      
      So move that assignment into ceph_osdc_start_request().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      f51a822c
    • A
      libceph: distinguish page array and pagelist count · d4b515fa
      Alex Elder 提交于
      Use distinct fields for tracking the number of pages in a message's
      page array and in a message's page list.  Currently only one or the
      other is used at a time, but that will be changing soon.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      d4b515fa
    • A
      libceph: don't pass request to calc_layout() · 60cf5992
      Alex Elder 提交于
      The only remaining reason to pass the osd request to calc_layout()
      is to fill in its r_num_pages and r_page_alignment fields.  Once it
      fills those in, it doesn't do anything more with them.
      
      We can therefore move those assignments into the caller, and get rid
      of the "req" parameter entirely.
      
      Note, however, that the only caller is ceph_osdc_new_request(),
      and that immediately overwrites those fields with values based on
      its passed-in page offset.  So the assignment inside calc_layout()
      was redundant anyway.
      
      This resolves:
          http://tracker.ceph.com/issues/4262Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      60cf5992
    • A
      libceph: format target object name in caller · dbe0fc41
      Alex Elder 提交于
      Move the formatting of the object name (oid) to use for an object
      request into the caller of calc_layout().  This makes the "vino"
      parameter no longer necessary, so get rid of it.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      dbe0fc41
    • A
      libceph: pass object number back to calc_layout() caller · 47a05811
      Alex Elder 提交于
      Have calc_layout() pass the computed object number back to its
      caller.  (This is a small step to simplify review.)
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      47a05811
    • A
      libceph: fix a osd request memory leak · 3ff5f385
      Alex Elder 提交于
      If an invalid layout is provided to ceph_osdc_new_request(), its
      call to calc_layout() might return an error.  At that point in the
      function we've already allocated an osd request structure, so we
      need to free it (drop a reference) in the event such an error
      occurs.
      
      The only other value calc_layout() will return is 0, so make that
      explicit in the successful case.
      
      This resolves:
          http://tracker.ceph.com/issues/4240Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3ff5f385
  2. 27 2月, 2013 4 次提交
  3. 20 2月, 2013 2 次提交
  4. 19 2月, 2013 4 次提交