1. 02 10月, 2012 40 次提交
    • A
      rbd: get image features for a v2 image · b1b5402a
      Alex Elder 提交于
      The features values for an rbd format 2 image are fetched from the
      server using a "get_features" method.  The same method is used for
      getting the features for a snapshot, so structure this addition with
      a generic helper routine that can get this information for either.
      
      The server will provide two 64-bit feature masks, one representing
      the features potentially in use for this image (or its snapshot),
      and one representing features that must be supported by the client
      in order to work with the image.
      
      For the time being, neither of these is really used so we keep
      things simple and just record the first feature vector.  Once we
      start using these feature masks, what we record and what we expose
      to the user will most likely change.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      b1b5402a
    • A
      rbd: get the object prefix for a v2 rbd image · 1e130199
      Alex Elder 提交于
      The object prefix of an rbd format 2 image is fetched from the
      server using a "get_object_prefix" method.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      1e130199
    • A
      rbd: add code to get the size of a v2 rbd image · 9d475de5
      Alex Elder 提交于
      The size of an rbd format 2 image is fetched from the server using a
      "get_size" method.  The same method is used for getting the size of
      a snapshot, so structure this addition with a generic helper routine
      that we can get this information for either.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      9d475de5
    • A
      rbd: lay out header probe infrastructure · a30b71b9
      Alex Elder 提交于
      This defines a new function rbd_dev_probe() as a top-level
      function for populating detailed information about an rbd device.
      
      It first checks for the existence of a format 2 rbd image id object.
      If it exists, the image is assumed to be a format 2 rbd image, and
      another function rbd_dev_v2() is called to finish populating
      header data for that image.  If it does not exist, it is assumed to
      be an old (format 1) rbd image, and calls a similar function
      rbd_dev_v1() to populate its header information.
      
      A new field, rbd_dev->format, is defined to record which version
      of the rbd image format the device represents.  For a valid mapped
      rbd device it will have one of two values, 1 or 2.
      
      So far, the format 2 images are not really supported; this is
      laying out the infrastructure for fleshing out that support.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      a30b71b9
    • A
      rbd: encapsulate code that gets snapshot info · cd892126
      Alex Elder 提交于
      Create a function that encapsulates looking up the name, size and
      features related to a given snapshot, which is indicated by its
      index in an rbd device's snapshot context array of snapshot ids.
      
      This interface will be used to hide differences between the format 1
      and format 2 images.
      
      At the moment this (looking up the name anyway) is slightly less
      efficient than what's done currently, but we may be able to optimize
      this a bit later on by cacheing the last lookup if it proves to be a
      problem.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      cd892126
    • A
      rbd: add an rbd features field · 34b13184
      Alex Elder 提交于
      Record the features values for each rbd image and each of its
      snapshots.  This is really something that only becomes meaningful
      for version 2 images, so this is just putting in place code
      that will form common infrastructure.
      
      It may be useful to expand the sysfs entries--and therefore the
      information we maintain--for the image and for each snapshot.
      But I'm going to hold off doing that until we start making
      active use of the feature bits.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      34b13184
    • A
      rbd: don't use index in __rbd_add_snap_dev() · c8d18425
      Alex Elder 提交于
      Pass the snapshot id and snapshot size rather than an index
      to __rbd_add_snap_dev() to specify values for a new snapshot.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      c8d18425
    • A
      rbd: kill create_snap sysfs entry · 02cdb02c
      Alex Elder 提交于
      Josh proposed the following change, and I don't think I could
      explain it any better than he did:
      
          From: Josh Durgin <josh.durgin@inktank.com>
          Date: Tue, 24 Jul 2012 14:22:11 -0700
          To: ceph-devel <ceph-devel@vger.kernel.org>
          Message-ID: <500F1203.9050605@inktank.com>
      
          Right now the kernel still has one piece of rbd management
          duplicated from the rbd command line tool: snapshot creation.
          There's nothing special about snapshot creation that makes it
          advantageous to do from the kernel, so I'd like to remove the
          create_snap sysfs interface.  That is,
      	/sys/bus/rbd/devices/<id>/create_snap
          would be removed.
      
          Does anyone rely on the sysfs interface for creating rbd
          snapshots?  If so, how hard would it be to replace with:
      
      	rbd snap create pool/image@snap
      
          Is there any benefit to the sysfs interface that I'm missing?
      
          Josh
      
      This patch implements this proposal, removing the code that
      implements the "snap_create" sysfs interface for rbd images.
      As a result, quite a lot of other supporting code goes away.
      Suggested-by: NJosh Durgin <josh.durgin@inktank.com>
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      02cdb02c
    • A
      rbd: define rbd_dev_image_id() · 589d30e0
      Alex Elder 提交于
      New format 2 rbd images are permanently identified by a unique image
      id.  Each rbd image also has a name, but the name can be changed.
      A format 2 rbd image will have an object--whose name is based on the
      image name--which maps an image's name to its image id.
      
      Create a new function rbd_dev_image_id() that checks for the
      existence of the image id object, and if it's found, records the
      image id in the rbd_device structure.
      
      Create a new rbd device attribute (/sys/bus/rbd/<num>/image_id) that
      makes this information available.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      589d30e0
    • A
      rbd: define some new format constants · 3bb59ad5
      Alex Elder 提交于
      Define constant symbols related to the rbd format 2 object names.
      This begins to bring this version of the "rbd_types.h" header
      more in line with the current user-space version of that file.
      Complete reconciliation of differences will be done at some
      point later, as a separate task.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3bb59ad5
    • A
      rbd: support data returned from OSD methods · f8d4de6e
      Alex Elder 提交于
      An OSD object method call can be made using rbd_req_sync_exec().
      Until now this has only been used for creating a new RBD snapshot,
      and that has only required sending data out, not receiving anything
      back from the OSD.
      
      We will now need to get data back from an OSD on a method call, so
      add parameters to rbd_req_sync_exec() that allow a buffer into which
      returned data should be placed to be specified, along with its size.
      
      Previously, rbd_req_sync_exec() passed a null pointer and zero
      size to rbd_req_sync_op(); change this so the new inbound buffer
      information is provided instead.
      
      Rename the "buf" and "len" parameters in rbd_req_sync_op() to
      make it more obvious they are describing inbound data.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      f8d4de6e
    • A
      rbd: pass flags to rbd_req_sync_exec() · 3cb4a687
      Alex Elder 提交于
      In order to allow both read requests and write requests to be
      initiated using rbd_req_sync_exec(), add an OSD flags value
      which can be passed down to rbd_req_sync_op().  Rename the "data"
      and "len" parameters to be more clear that they represent data
      that is outbound.
      
      At this point, this function is still only used (and only works) for
      write requests.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3cb4a687
    • A
      rbd: set up watch before announcing disk · 3ee4001e
      Alex Elder 提交于
      We're ready to handle header object (refresh) events at the point we
      call rbd_bus_add_dev().  Set up the watch request on the rbd image
      header just after that, and after we've registered the devices for
      the snapshots for the initial snapshot context.  Do this before
      announce the disk as available for use.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3ee4001e
    • A
      rbd: set initial capacity in rbd_init_disk() · 12f02944
      Alex Elder 提交于
      Move the setting of the initial capacity for an rbd image mapping
      into rb_init_disk().
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      12f02944
    • A
      rbd: drop dev registration check for new snap · 86ff77bb
      Alex Elder 提交于
      By the time rbd_dev_snaps_register() gets called during rbd device
      initialization, the main device will have already been registered.
      Similarly, a header refresh will only occur for an rbd device whose
      Linux device is registered.  There is therefore no need to verify
      the main device is registered when registering a snapshot device.
      
      For the time being, turn the check into a WARN_ON(), but it can
      eventually just go away.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      86ff77bb
    • A
      rbd: call rbd_init_disk() sooner · 0f308a31
      Alex Elder 提交于
      Call rbd_init_disk() from rbd_add() as soon as we have the major
      device number for the mapping.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      0f308a31
    • A
      rbd: defer setting device id · 85ae8926
      Alex Elder 提交于
      Hold off setting the device id and formatting the device name
      in rbd_add() until just before it's needed.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      85ae8926
    • A
      rbd: read the header before registering device · 05fd6f6f
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      05fd6f6f
    • A
      rbd: call set_snap() before snap_devs_update() · 5ed16177
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      5ed16177
    • A
      rbd: defer registering snapshot devices · 304f6808
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      304f6808
    • A
      rbd: assign header name later · 3fcf2581
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3fcf2581
    • A
      rbd: use snaps list in rbd_snap_by_name() · e86924a8
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      e86924a8
    • A
      rbd: don't register snapshots in bus_add_dev() · cd789ab9
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      cd789ab9
    • A
      rbd: move locking out of rbd_header_set_snap() · 4bb1f1ed
      Alex Elder 提交于
      Move the calls to get the header semaphore out of
      rbd_header_set_snap() and into its caller.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      4bb1f1ed
    • A
      rbd: simplify rbd_init_disk() a bit · 1fcdb8aa
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      1fcdb8aa
    • A
      rbd: do some header initialization earlier · 2ac4e75d
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      2ac4e75d
    • A
      rbd: simplify snap_by_name() interface · 8836b995
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      8836b995
    • A
      rbd: set mapping name with the rest · 4e1105a2
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      4e1105a2
    • A
      rbd: return snap name from rbd_add_parse_args() · 3feeb894
      Alex Elder 提交于
      This is the first of two patches aimed at isolating the code that
      sets the mapping information into a single spot.
      Signed-off-by: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      3feeb894
    • A
      rbd: record mapped size · 99c1f08f
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      99c1f08f
    • A
      rbd: separate mapping info in rbd_dev · f84344f3
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      f84344f3
    • A
      rbd: kill rbd_image_header->total_snaps · c9aadfe7
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      c9aadfe7
    • A
      rbd: kill rbd_dev->q · 98cec111
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      98cec111
    • A
      rbd: rename __rbd_init_snaps_header() · 9fcbb800
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      9fcbb800
    • A
      rbd: rename rbd_id_get() · e2839308
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      e2839308
    • A
      rbd: define rbd_assert() · aafb230e
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NJosh Durgin <josh.durgin@inktank.com>
      aafb230e
    • A
      rbd: split up rbd_get_segment() · 65ccfe21
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NYehuda Sadeh <yehuda@inktank.com>
      65ccfe21
    • A
      rbd: check for overflow in rbd_get_num_segments() · df111be6
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NYehuda Sadeh <yehuda@inktank.com>
      df111be6
    • A
      rbd: drop needless test in rbd_rq_fn() · 38f5f65e
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NYehuda Sadeh <yehuda@inktank.com>
      38f5f65e
    • A
      rbd: bio_chain_clone() cleanups · 542582fc
      Alex Elder 提交于
      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: NAlex Elder <elder@inktank.com>
      Reviewed-by: NYehuda Sadeh <yehuda@inktank.com>
      542582fc