1. 01 Oct, 2012 40 commits
    • Alex Elder's avatar
      rbd: read the header before registering device · 05fd6f6f
      Alex Elder authored
      Read the rbd header information and call rbd_dev_set_mapping()
      earlier--before registering the block device or setting up the sysfs
      entries for the image.  The sysfs entries provide users access to
      some information that's only available after doing the rbd header
      initialization, so this will make sure it's valid right away.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      05fd6f6f
    • Alex Elder's avatar
      rbd: call set_snap() before snap_devs_update() · 5ed16177
      Alex Elder authored
      rbd_header_set_snap() is a simple initialization routine for an rbd
      device's mapping.  It has to be called after the snapshot context
      for the rbd_dev has been updated, but can be done before snapshot
      devices have been registered.
      
      Change the name to rbd_dev_set_mapping() to better reflect its
      purpose, and call it a little sooner, before registering snapshot
      devices.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      5ed16177
    • Alex Elder's avatar
      rbd: defer registering snapshot devices · 304f6808
      Alex Elder authored
      When a new snapshot is found in an rbd device's updated snapshot
      context, __rbd_add_snap_dev() is called to create and insert an
      entry in the rbd devices list of snapshots.  In addition, a Linux
      device is registered to represent the snapshot.
      
      For version 2 rbd images, it will be undesirable to initialize the
      device right away.  So in anticipation of that, this patch separates
      the insertion of a snapshot entry in the snaps list from the
      creation of devices for those snapshots.
      
      To do this, create a new function rbd_dev_snaps_register() which
      traverses the list of snapshots and calls rbd_register_snap_dev()
      on any that have not yet been registered.
      
      Rename rbd_dev_snap_devs_update() to be rbd_dev_snaps_update()
      to better reflect that only the entry in the snaps list and not
      the snapshot's device is affected by the function.
      
      For now, call rbd_dev_snaps_register() immediately after each
      call to rbd_dev_snaps_update().
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      304f6808
    • Alex Elder's avatar
      rbd: assign header name later · 3fcf2581
      Alex Elder authored
      Move the assignment of the header name for an rbd image a bit later,
      outside rbd_add_parse_args() and into its caller.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      3fcf2581
    • Alex Elder's avatar
      rbd: use snaps list in rbd_snap_by_name() · e86924a8
      Alex Elder authored
      An rbd_dev structure maintains a list of current snapshots that have
      already been fully initialized.  The entries on the list have type
      struct rbd_snap, and each entry contains a copy of information
      that's found in the rbd_dev's snapshot context and header.
      
      The only caller of snap_by_name() is rbd_header_set_snap().  In that
      call site any positive return value (the index in the snapshot
      array) is ignored, so there's no need to return the index in
      the snapshot context's id array when it's found.
      
      rbd_header_set_snap() also has only one caller--rbd_add()--and that
      call is made after a call to rbd_dev_snap_devs_update().  Because
      the rbd_snap structures are initialized in that function, the
      current snapshot list can be used instead of the snapshot context to
      look up a snapshot's information by name.
      
      Change snap_by_name() so it uses the snapshot list rather than the
      rbd_dev's snapshot context in looking up snapshot information.
      Return 0 if it's found rather than the snapshot id.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      e86924a8
    • Alex Elder's avatar
      rbd: don't register snapshots in bus_add_dev() · cd789ab9
      Alex Elder authored
      When rbd_bus_add_dev() is called (one spot--in rbd_add()), the rbd
      image header has not even been read yet.  This means that the list
      of snapshots will be empty at the time of the call.  As a result,
      there is no need for the code that calls rbd_register_snap_dev()
      for each entry in that list--so get rid of it.
      
      Once the header has been read (just after returning), a call will
      be made to rbd_dev_snap_devs_update(), which will then find every
      snapshot in the context to be new and will therefore call
      rbd_register_snap_dev() via __rbd_add_snap_dev() accomplishing
      the same thing.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      cd789ab9
    • Alex Elder's avatar
      rbd: move locking out of rbd_header_set_snap() · 4bb1f1ed
      Alex Elder authored
      Move the calls to get the header semaphore out of
      rbd_header_set_snap() and into its caller.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      4bb1f1ed
    • Alex Elder's avatar
      rbd: simplify rbd_init_disk() a bit · 1fcdb8aa
      Alex Elder authored
      This just simplifies a few things in rbd_init_disk(), now that the
      previous patch has moved a bunch of initialization code out if it.
      Done separately to facilitate review.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      1fcdb8aa
    • Alex Elder's avatar
      rbd: do some header initialization earlier · 2ac4e75d
      Alex Elder authored
      Move some of the code that initializes an rbd header out of
      rbd_init_disk() and into its caller.
      
      Move the code at the end of rbd_init_disk() that sets the device
      capacity and activates the Linux device out of that function and
      into the caller, ensuring we still have the disk size available
      where we need it.
      
      Update rbd_free_disk() so it still aligns well as an inverse of
      rbd_init_disk(), moving the rbd_header_free() call out to its
      caller.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      2ac4e75d
    • Alex Elder's avatar
      rbd: simplify snap_by_name() interface · 8836b995
      Alex Elder authored
      There is only one caller of snap_by_name(), and it passes two values
      to be assigned, both of which are found within an rbd device
      structure.
      
      Change the interface so it just passes the address of the rbd_dev,
      and make the assignments to its fields directly.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      8836b995
    • Alex Elder's avatar
      rbd: set mapping name with the rest · 4e1105a2
      Alex Elder authored
      With the exception of the snapshot name, all of the mapping-specific
      fields in an rbd device structure are set in rbd_header_set_snap().
      
      Pass the snapshot name to be assigned into rbd_header_set_snap()
      to keep all of the mapping assignments together.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      4e1105a2
    • Alex Elder's avatar
      rbd: return snap name from rbd_add_parse_args() · 3feeb894
      Alex Elder authored
      This is the first of two patches aimed at isolating the code that
      sets the mapping information into a single spot.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      3feeb894
    • Alex Elder's avatar
      rbd: record mapped size · 99c1f08f
      Alex Elder authored
      Add the size of the mapped image to the set of mapping-specific
      fields in an rbd_device, and use it when setting the capacity of the
      disk.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      99c1f08f
    • Alex Elder's avatar
      rbd: separate mapping info in rbd_dev · f84344f3
      Alex Elder authored
      Several fields in a struct rbd_dev are related to what is mapped, as
      opposed to the actual base rbd image.  If the base image is mapped
      these are almost unneeded, but if a snapshot is mapped they describe
      information about that snapshot.
      
      In some contexts this can be a little bit confusing.  So group these
      mapping-related field into a structure to make it clear what they
      are describing.
      
      This also includes a minor change that rearranges the fields in the
      in-core image header structure so that invariant fields are at the
      top, followed by those that change.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      f84344f3
    • Alex Elder's avatar
      rbd: kill rbd_image_header->total_snaps · c9aadfe7
      Alex Elder authored
      The "total_snaps" field in an rbd header structure is never any
      different from the value of "num_snaps" stored within a snapshot
      context.  Avoid any confusion by just using the value held within
      the snapshot context, and get rid of the "total_snaps" field.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      c9aadfe7
    • Alex Elder's avatar
      rbd: kill rbd_dev->q · 98cec111
      Alex Elder authored
      A copy of rbd_dev->disk->queue is held in rbd_dev->q, but it's
      never actually used.  So get just get rid of the field.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      98cec111
    • Alex Elder's avatar
      rbd: rename __rbd_init_snaps_header() · 9fcbb800
      Alex Elder authored
      The name __rbd_init_snaps_header() doesn't really convey what that
      function does very well.  Its purpose is to scan a new snapshot
      context and either create or destroy snapshot device entries so
      that local host's view is consistent with the reality maintained
      on the OSDs.  This patch just changes the name of this function,
      to be rbd_dev_snap_devs_update().  Still not perfect, but I think
      better.
      
      Also add some dynamic debug statements to this function.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      9fcbb800
    • Alex Elder's avatar
      rbd: rename rbd_id_get() · e2839308
      Alex Elder authored
      This should have been done as part of this commit:
      
          commit de71a297
          Author: Alex Elder <elder@inktank.com>
          Date:   Tue Jul 3 16:01:19 2012 -0500
          rbd: rename rbd_device->id
      
      rbd_id_get() is assigning the rbd_dev->dev_id field.  Change the
      name of that function as well as rbd_id_put() and rbd_id_max
      to reflect what they are affecting.
      
      Add some dynamic debug statements related to rbd device id activity.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      e2839308
    • Alex Elder's avatar
      rbd: define rbd_assert() · aafb230e
      Alex Elder authored
      Define rbd_assert() and use it in place of various BUG_ON() calls
      now present in the code.  By default assertion checking is enabled;
      we want to do this differently at some point.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      aafb230e
    • Alex Elder's avatar
      rbd: split up rbd_get_segment() · 65ccfe21
      Alex Elder authored
      There are two places where rbd_get_segment() is called.  One, in
      rbd_rq_fn(), only needs to know the length within a segment that an
      I/O request should be.  The other, in rbd_do_op(), also needs the
      name of the object and the offset within it for the I/O request.
      
      Split out rbd_segment_name() into three dedicated functions:
          - rbd_segment_name() allocates and formats the name of the
            object for a segment containing a given rbd image offset
          - rbd_segment_offset() computes the offset within a segment for
            a given rbd image offset
          - rbd_segment_length() computes the length to use for I/O within
            a segment for a request, not to exceed the end of a segment
            object.
      
      In the new functions be a bit more careful, checking for possible
      error conditions:
          - watch for errors or overflows returned by snprintf()
          - catch (using BUG_ON()) potential overflow conditions
            when computing segment length
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      65ccfe21
    • Alex Elder's avatar
      rbd: check for overflow in rbd_get_num_segments() · df111be6
      Alex Elder authored
      It is possible in rbd_get_num_segments() for an overflow to occur
      when adding the offset and length.  This is easily avoided.
      
      Since the function returns an int and the one caller is already
      prepared to handle errors, have it return -ERANGE if overflow would
      occur.
      
      The overflow check would not work if a zero-length request was
      being tested, so short-circuit that case, returning 0 for the
      number of segments required.  (This condition might be avoided
      elsewhere already, I don't know.)
      
      Have the caller end the request if either an error or 0 is returned.
      The returned value is passed to __blk_end_request_all(), meaning
      a 0 length request is not treated an error.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      df111be6
    • Alex Elder's avatar
      rbd: drop needless test in rbd_rq_fn() · 38f5f65e
      Alex Elder authored
      There's a test for null rq pointer inside the while loop in
      rbd_rq_fn() that's not needed.  That same test already occurred
      in the immediatly preceding loop condition test.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      38f5f65e
    • Alex Elder's avatar
      rbd: bio_chain_clone() cleanups · 542582fc
      Alex Elder authored
      In bio_chain_clone(), at the end of the function the bi_next field
      of the tail of the new bio chain is nulled.  This isn't necessary,
      because if "tail" is non-null, its value will be the last bio
      structure allocated at the top of the while loop in that function.
      And before that structure is added to the end of the new chain, its
      bi_next pointer is always made null.
      
      While touching that function, clean a few other things:
          - define each local variable on its own line
          - move the definition of "tmp" to an inner scope
          - move the modification of gfpmask closer to where it's used
          - rearrange the logic that sets the chain's tail pointer
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      542582fc
    • Alex Elder's avatar
      rbd: kill notify_timeout option · 84d34dcc
      Alex Elder authored
      The "notify_timeout" rbd device option is never used, so get rid of
      it.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      84d34dcc
    • Alex Elder's avatar
      rbd: add read_only rbd map option · cc0538b6
      Alex Elder authored
      Add the ability to map an rbd image read-only, by specifying either
      "read_only" or "ro" as an option on the rbd "command line."  Also
      allow the inverse to be explicitly specified using "read_write" or
      "rw".
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      cc0538b6
    • Alex Elder's avatar
      rbd: move rbd_opts to struct rbd_device · f8c38929
      Alex Elder authored
      The rbd options don't really apply to the ceph client.  So don't
      store a pointer to it in the ceph_client structure, and put them
      (a struct, not a pointer) into the rbd_dev structure proper.
      
      Pass the rbd device structure to rbd_client_create() so it can
      assign rbd_dev->rbdc if successful, and have it return an error code
      instead of the rbd client pointer.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      f8c38929
    • Alex Elder's avatar
      rbd: more cleanup in rbd_header_from_disk() · 621901d6
      Alex Elder authored
      This just rearranges things a bit more in rbd_header_from_disk()
      so that the snapshot sizes are initialized right after the buffer
      to hold them is allocated and doing a little further consolidation
      that follows from that.  Also adds a few simple comments.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      621901d6
    • Alex Elder's avatar
      rbd: kill incore snap_names_len · f785cc1d
      Alex Elder authored
      The only thing the on-disk snap_names_len field is needed is to
      size the buffer allocated to hold a copy of the snapshot names
      for an rbd image.
      
      So don't bother saving it in the in-core rbd_image_header structure.
      Just use a local variable to hold the required buffer size while
      it's needed.
      
      Move the code that actually copies the snapshot names up closer
      to where the required length is saved.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      f785cc1d
    • Alex Elder's avatar
      rbd: don't over-allocate space for object prefix · 58c17b0e
      Alex Elder authored
      In rbd_header_from_disk() the object prefix buffer is sized based on
      the maximum size it's block_name equivalent on disk could be.
      
      Instead, only allocate enough to hold null-terminated string from
      the on-disk header--or the maximum size of no NUL is found.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      58c17b0e
    • Alex Elder's avatar
      rbd: handle locking inside __rbd_client_find() · 1f7ba331
      Alex Elder authored
      There is only caller of __rbd_client_find(), and it somewhat
      clumsily gets the appropriate lock and gets a reference to the
      existing ceph_client structure if it's found.
      
      Instead, have that function handle its own locking, and acquire the
      reference if found while it holds the lock.  Drop the underscores
      from the name because there's no need to signify anything special
      about this function.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarYehuda Sadeh <yehuda@inktank.com>
      1f7ba331
    • Wei Yongjun's avatar
      ceph: use list_move_tail instead of list_del/list_add_tail · cc4829e5
      Wei Yongjun authored
      Using list_move_tail() instead of list_del() + list_add_tail().
      Signed-off-by: default avatarWei Yongjun <yongjun_wei@trendmicro.com.cn>
      Signed-off-by: default avatarSage Weil <sage@inktank.com>
      cc4829e5
    • Alex Elder's avatar
      rbd: add new snapshots at the tail · 523f3258
      Alex Elder authored
      This fixes a bug that went in with this commit:
      
          commit f6e0c99092cca7be00fca4080cfc7081739ca544
          Author: Alex Elder <elder@inktank.com>
          Date:   Thu Aug 2 11:29:46 2012 -0500
          rbd: simplify __rbd_init_snaps_header()
      
      The problem is that a new rbd snapshot needs to go either after an
      existing snapshot entry, or at the *end* of an rbd device's snapshot
      list.  As originally coded, it is placed at the beginning.  This was
      based on the assumption the list would be empty (so it wouldn't
      matter), but in fact if multiple new snapshots are added to an empty
      list in one shot the list will be non-empty after the first one is
      added.
      
      This addresses http://tracker.newdream.net/issues/3063Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      523f3258
    • Alex Elder's avatar
      rbd: rename block_name -> object_prefix · 843a0d08
      Alex Elder authored
      In the on-disk image header structure there is a field "block_name"
      which represents what we now call the "object prefix" for an rbd
      image.  Rename this field "object_prefix" to be consistent with
      modern usage.
      
      This appears to be the only remaining vestige of the use of "block"
      in symbols that represent objects in the rbd code.
      
      This addresses http://tracker.newdream.net/issues/1761Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      Reviewed-by: default avatarDan Mick <dan.mick@inktank.com>
      843a0d08
    • Iulius Curt's avatar
      libceph: Fix sparse warning · 7698f2f5
      Iulius Curt authored
      Make ceph_monc_do_poolop() static to remove the following sparse warning:
       * net/ceph/mon_client.c:616:5: warning: symbol 'ceph_monc_do_poolop' was not
         declared. Should it be static?
      Also drops the 'ceph_monc_' prefix, now being a private function.
      Signed-off-by: default avatarIulius Curt <icurt@ixiacom.com>
      Signed-off-by: default avatarSage Weil <sage@inktank.com>
      7698f2f5
    • Sage Weil's avatar
      libceph: remove unused monc->have_fsid · 290e3359
      Sage Weil authored
      This is unused; use monc->client->have_fsid.
      Signed-off-by: default avatarSage Weil <sage@inktank.com>
      290e3359
    • Alex Elder's avatar
      ceph: let path portion of mount "device" be optional · c98f533c
      Alex Elder authored
      A recent change to /sbin/mountall causes any trailing '/' character
      in the "device" (or fs_spec) field in /etc/fstab to be stripped.  As
      a result, an entry for a ceph mount that intends to mount the root
      of the name space ends up with now path portion, and the ceph mount
      option processing code rejects this.
      
      That is, an entry in /etc/fstab like:
          cephserver:port:/ /mnt ceph defaults 0 0
      provides to the ceph code just "cephserver:port:" as the "device,"
      and that gets rejected.
      
      Although this is a bug in /sbin/mountall, we can have the ceph mount
      code support an empty/nonexistent path, interpreting it to mean the
      root of the name space.
      
      RFC 5952 offers recommendations for how to express IPv6 addresses,
      and recommends the usage found in RFC 3986 (which specifies the
      format for URI's) for representing both IPv4 and IPv6 addresses that
      include port numbers.  (See in particular the definition of
      "authority" found in the Appendix of RFC 3986.)
      
      According to those standards, no host specification will ever
      contain a '/' character.  As a result, it is sufficient to scan a
      provided "device" from an /etc/fstab entry for the first '/'
      character, and if it's found, treat that as the beginning of the
      path.  If no '/' character is present, we can treat the entire
      string as the monitor host specification(s), and assume the path
      to be the root of the name space.  We'll still require a ':' to
      separate the host portion from the (possibly empty) path portion.
      
      This means that we can more formally define how ceph will interpret
      the "device" it's provided when processing a mount request:
      
          "device" will look like:
              <server_spec>[,<server_spec>...]:[<path>]
          where
              <server_spec> is <ip>[:<port>]
              <path> is optional, but if present must begin with '/'
      
      This addresses http://tracker.newdream.net/issues/2919Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarDan Mick <dan.mick@inktank.com>
      c98f533c
    • Alex Elder's avatar
      rbd: separate reading header from decoding it · 4156d998
      Alex Elder authored
      Right now rbd_read_header() both reads the header object for an rbd
      image and decodes its contents.  It does this repeatedly if needed,
      in order to ensure a complete and intact header is obtained.
      
      Separate this process into two steps--reading of the raw header
      data (in new function, rbd_dev_v1_header_read()) and separately
      decoding its contents (in rbd_header_from_disk()).  As a result,
      the latter function no longer requires its allocated_snaps argument.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      4156d998
    • Alex Elder's avatar
      rbd: expand rbd_dev_ondisk_valid() checks · 103a150f
      Alex Elder authored
      Add checks on the validity of the snap_count and snap_names_len
      field values in rbd_dev_ondisk_valid().  This eliminates the
      need to do them in rbd_header_from_disk().
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      103a150f
    • Alex Elder's avatar
      rbd: return earlier in rbd_header_from_disk() · 28cb775d
      Alex Elder authored
      The only caller of rbd_header_from_disk() is rbd_read_header().
      It passes as allocated_snaps the number of snapshots it will
      have received from the server for the snapshot context that
      rbd_header_from_disk() is to interpret.  The first time through
      it provides 0--mainly to extract the number of snapshots from
      the snapshot context header--so that it can allocate an
      appropriately-sized buffer to receive the entire snapshot
      context from the server in a second request.
      
      rbd_header_from_disk() will not fill in the array of snapshot ids
      unless the number in the snapshot matches the number the caller
      had allocated.
      
      This patch adjusts that logic a little further to be more efficient.
      rbd_read_header() doesn't even examine the snapshot context unless
      the snapshot count (stored in header->total_snaps) matches the
      number of snapshots allocated.  So rbd_header_from_disk() doesn't
      need to allocate or fill in the snapshot context field at all in
      that case.
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      28cb775d
    • Alex Elder's avatar
      rbd: rearrange rbd_header_from_disk() · 6a52325f
      Alex Elder authored
      This just moves code around for the most part.  It was pulled out as
      a separate patch to avoid cluttering up some upcoming patches which
      are more substantive.  The point is basically to group everything
      related to initializing the snapshot context together.
      
      The only functional change is that rbd_header_from_disk() now
      ensures the (in-core) header it is passed is zero-filled.  This
      allows a simpler error handling path in rbd_header_from_disk().
      Signed-off-by: default avatarAlex Elder <elder@inktank.com>
      Reviewed-by: default avatarJosh Durgin <josh.durgin@inktank.com>
      6a52325f