rbd: drop dev reference on error in rbd_open()

If a read-only rbd device is opened for writing in rbd_open(), it
returns without dropping the just-acquired device reference.

Fix this by moving the read-only check before getting the reference.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: handle locking inside __rbd_client_find()

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: Alex Elder <elder@inktank.com>
rbd: move rbd_opts to struct rbd_device

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.

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: add read_only rbd map option

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."

Signed-off-by: Alex Elder <elder@inktank.com>
rbd: kill notify_timeout option

The "notify_timeout" rbd device option is never used, so get rid of
it.

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

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:
    - defined 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: Alex Elder <elder@inktank.com>
rbd: drop needless test in rbd_rq_fn()

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: Alex Elder <elder@inktank.com>
rbd: check for overflow in rbd_get_num_segments()

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: Alex Elder <elder@inktank.com>
rbd: split up rbd_get_segment()

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_offset() 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: 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: 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: 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 name

Create a function that looks up the name of a snapshot.  At the
moment this 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: encapsulate code that gets snapshot size

Create a function that looks up the size of a snapshot.  This
and the others will have matching functions that support this
operation for version 2 rbd images.

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