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 works) for
write requests.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: set r_num_pages in rbd_do_request()

XXX I need to investigate this one a bit more XXX

For an osd request with incoming data, we need to indicate in the
request's r_num_pages field how many pages are present in the
request.  The r_page_alignment field should also be set.

    --> Is this even used?  Where?

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: ensure invalid pointers are made null

Fix a number of spots where a pointer value that is known to
have become invalid but was not reset to null.

Signed-off-by: Alex Elder <elder@inktank.com>
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: 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: rearrange rbd_header_from_disk()

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: Alex Elder <elder@inktank.com>
rbd: blah

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 iterpret.  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: Alex Elder <elder@inktank.com>
rbd: define struct snapshot

Currently a ceph snapshot context stores an array of ceph snapshot
ids.  This is consistent with how they're stored in the rbd image
header.  But there's no reason the in-core representation of a
snapshot has to match what's on disk.

Define a new struct type to hold the snapshot id, and eventually
hold other information we know about the snapshot.  This is
motivated by upcoming changes to support rbd image format 2.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: incorporate snapshot sizes in snap context

Rather than allocating a separate array of sizes to record each
snapshot's size, just include each snapshot's size in its
snapshot structure that's incorporated in the snapshot context.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: incorporate snapshot names in snap context

Allocate an individual name string for each snapshot and include it
in its snapshot structure that's incorporated in the snapshot
context.

For now, this will be *in addition* to the block allocated to
hold a copy of the on-disk names.  We'll switch over completely
to using the per-snapshot allocated names in the next patch.

One intentional design note:  The snapshot context num_snaps field
will now be used to define the number of valid snapshot entries in
its snaps[] array; this may be less than the size of the array
(which is held in header->total_snaps).  This is a transient
condition, only existing during initialization.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: use per-snap names in snap_by_name()

The function snap_by_name() looks up searches the set of snapshots
for an image to see if it has one having a given name.  Previously
it used the in-memory copy of contiguously names block as stored
on disk.  But now that the snap context's snaps array has these
names available in an indexed form, do the search using those
names instead.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: use per-snap names in __rbd_init_snaps_header()

Like snap_by_name(), __rbd_init_snaps_header() used the in-memory
copy of contiguously names block as stored on disk in order to
determine what changes had occurred between an old and new snapshot
context.

Use the names found in the snapshot context snaps[] array instead.

As a result, there is no longer any need for rbd_prev_snap_name(),
so get rid of it.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: get rid of snap_names buffer

When a snapshot context is read from disk, the id, size, and name of
each snapshot is recorded in its in-memory representation.  A copy
of the on-disk names is maintained in core, but there is no longer
any code that makes use of it.

So get rid of that buffer.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: get rid of in-core snap_names_len

The only reason we need to know the length of the on-disk space that
holds the names of the snapshots for an rbd image is so that we can
allocate a buffer large enough to read it in.  Thereafter, knowledge
of its size serves no purpose.

The size is determined in rbd_header_from_disk(), and the size is
needed in rbd_read_header().   (The latter is the sole caller of
the former.)

Change rbd_header_from_disk() so its return value is the size of
the contiguous block of on-disk snapshot names, and use that value
in rbd_read_header() for allocating the buffer.  That way we can
get rid of the snap_names_len field of struct rbd_image_header.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: add an rbd features field

Record the snapshot features value for each rbd image.

This is close but not well tested.

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>