rbd: defer setting device id

Hold off setting the device id and formatting the device name
in rbd_add() until just before it's needed.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: assign header name later

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: Alex Elder <elder@inktank.com>
rbd: do some header initialization earlier

Move some of the code that initializes an rbd header out of
rbd_init_disk() and into its caller.  In order to do this we
need to supply the disk size (either the size of the base
image or the size of the snapshot) to rbd_init_disk().

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: rename __rbd_init_snaps_header()

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().

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: register device after header init

Now move down registration of the device with the system, so it
occurs after doing all of the rbd header initialization.

This was done in steps in hopes it would make reviewing the change a
little easier.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: pass flags to rbd_req_sync_exec()

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: Alex Elder <elder@inktank.com>
rbd: support data returned from OSD methods

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: Alex Elder <elder@inktank.com>
rbd: define some new format constants

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.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: define rbd_dev_image_id()

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: Alex Elder <elder@inktank.com>
rbd: kill create_snap sysfs entry

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: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Alex Elder <elder@inktank.com>
rbd: use snaps list in rbd_snap_by_name()

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 the information
that's found in the rbd_dev's snapshot context.

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.

rbd_header_set_snap() also has only one caller--rbd_add()--and that
call is made after a call to rbd_read_header().  Because the
rbd_snap structures are initialized in rbd_read_header(), 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.  To do this,
change rbd_snap_by_name() to take an rbd_dev rather than
rbd_image_header structure pointer as its first argument.

No caller ever passes a null pointer to snap_by_name() for the
snapshot id or the size, so just assign using those pointers
unconditionally.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: don't use index in __rbd_add_snap_dev()

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: Alex Elder <elder@inktank.com>
rbd: add an rbd features field

Record the features value for each rbd image and each of its
snapshots.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: encapsulate code that gets snapshot info

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.

At the moment this (looking up the name anyway) is less efficient
than what's done currently, but we may be able to optimize this a
bit later on by cacheing the last lookup.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: combine header_from_disk in read_header

This won't work yet, but it's my current state of combining the work
done in __rbd_refresh_header() into rbd_header_from_disk().  One
benefit is that we don't load in one header and then just copy the
whole thing over to the one stored in the rbd_dev.  But them main
thing is this is going to allow a more unified way of loading header
information--both at initialization time and at snapshot update
time.  And this will fit the version 2 images much more naturally.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: lay out header probe infrastructure

This defines a new function rbd_dev_header_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: Alex Elder <elder@inktank.com>
rbd: add code to get the size of a v2 rbd image

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: Alex Elder <elder@inktank.com>
rbd: get the object prefix for a v2 rbd image

The object prefix of an rbd format 2 image is fetched from the
server using a "get_object_prefix" method.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: get image features for a v2 image

The features value for an rbd format 2 image is 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.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: get the snapshot context for a v2 image

Fetch the snapshot context for an rbd format 2 image by calling
the "get_snapcontext" method on its header object.

Signed-off-by: Alex Elder <elder@inktank.com>