Loic Dachary [Tue, 14 May 2013 08:52:40 +0000 (10:52 +0200)]
update op added to a waiting queue or discarded
The decision to discard an op happens either in OSD or in PG.
The operation queue goes to a single OpWQ object if waiting_map does not impose a delay op_queue.
The decision to add an op to a waiting queue regardless of its type is updated.
The decision to add a CEPH_MSG_OSD_OP to a waiting queue is described in full.
Josh Durgin [Sun, 12 May 2013 21:53:26 +0000 (14:53 -0700)]
librbd: add options to enable balanced or localized reads for snapshots
Since snapshots never change, it's safe to read from replicas for them.
A common use for this would be reading from a parent snapshot shared by
many clones.
Convert LibrbdWriteback and AioRead to use the ObjectOperation api
so we can set flags. Fortunately the external wrapper holds no data,
so its lifecycle doesn't need to be managed.
Include a simple workunit that sets the flags in various combinations
and looks for their presence in the logs from 'rbd export'.
Josh Durgin [Sun, 12 May 2013 21:43:13 +0000 (14:43 -0700)]
librados: add sparse_read() to the C++ bindings for an ObjectOperation
This will allow it to be used with general aio_operate() so we don't have
to add new versions of each operation when we want to add new per-op
arguments, like flags, namespaces, or explicit snapshot contexts/ids.
Josh Durgin [Sun, 12 May 2013 21:39:58 +0000 (14:39 -0700)]
Objecter, librados: use only ObjectOperation form of sparse_read internally
This will be used when exposing an ObjectOperation version of sparse_read()
to the librados user, and there's no reason to duplicate code for creating
and handling it. Add a wrapper Context for handling the lifecycle of the
::ObjectOperation.
This cleans up the synchronous version of sparse_read quite a bit by
using the general operate_read() instead of duplicating decoding and
a bunch of sync boilerplate.
Move handling the decoding of a sparse_read into the Objecter, with
the rest of the decoding of rados operations. librados shouldn't be
the only user of the Objecter that can understand sparse_reads.
Danny Al-Gaaf [Sat, 11 May 2013 17:51:02 +0000 (19:51 +0200)]
osd/OSD.h: fix try_stop_deletion
Fix try_stop_deletion(): The comment above the while loop says "If we are
in DELETING_DIR or DELETED_DIR", but the while loop checks for DELETING_DIR
twice. Change one check to DELETED_DIR otherwise on state get missed.
Signed-off-by: Danny Al-Gaaf <danny.al-gaaf@bisect.de>
Josh Durgin [Fri, 10 May 2013 22:59:10 +0000 (15:59 -0700)]
Throttle: move start_op() to C_SimpleThrottle constructor
This is done by all callers right before constructing this.
Since C_SimpleThrottle is already responsible for calling ->end_op(),
it makes sense to call start_op() there too.
Josh Durgin [Fri, 10 May 2013 22:54:51 +0000 (15:54 -0700)]
librbd: run copy in parallel
Instead of using read_iterate(), loop over each period of objects in
the source, read from them asynchronously, and then asynchronously
write to the destination.
The callbacks make this a bit more complex, but it can perform much
better.
Josh Durgin [Fri, 10 May 2013 22:45:57 +0000 (15:45 -0700)]
librbd: move completion release into rbd_ctx_cb()
All the users of rbd_ctx_cb() do this separately right now, but
there's no reason to keep the completion around after the nested
completion has been called. Also declare rbd_ctx_cb() in the header
so it can be used before its definition.
Josh Durgin [Fri, 10 May 2013 00:12:33 +0000 (17:12 -0700)]
librbd: parallelize and simplify flatten
Flattening reads the logical child object from the parent image, and
then does a copyup operation if the data is non-zero. This is
equivalent to doing a zero-length write to each object in the
child image. Do this instead, so that we can easily control how
many are in flight, and eliminate some code as well.
Since we no longer read from the parent within the flatten function,
the buffer is not needed. It would be leaked in some error conditions,
but since's it's unecessary we can just get rid of it.
Josh Durgin [Fri, 10 May 2013 00:05:20 +0000 (17:05 -0700)]
librbd: only send non-zero copyup data
If the parent image is logically zero for the range of a child object,
it's equivalent to the object not existing. Save some I/O and network
bandwidth and don't send the useless zeroes.
Danny Al-Gaaf [Fri, 10 May 2013 11:44:50 +0000 (13:44 +0200)]
rados_sync.cc: remove dead and not needed code
The first if handles all chars < 32, the last 2 if's check for
'\n' (10) and '\r' (13). This code will never be reached and
is already covered. Remove unneeded code.
Sage Weil [Fri, 10 May 2013 21:14:52 +0000 (14:14 -0700)]
mds: be more explicit about path_traverse completion
Coverity turned up
CID 717085 (#1 of 1): Resource leak (RESOURCE_LEAK)
10. leaked_storage: Variable "c" going out of scope leaks the storage it points to.
from _find_ino_dir(), but for all r > 0 cases fin is consumed. Make this
a bit more explicit by using the helper in the mdr-only case, and by
asserting it is zero in the return 2 path. Hopefully coverity will notice.
Josh Durgin [Mon, 6 May 2013 23:51:12 +0000 (16:51 -0700)]
Throttle: add a simpler throttle that just blocks above a threshold
This is convenient to use to turn synchronous calls into asynchronous
calls with a limited number of operations in flight concurrently.
It assumes the caller will wait for all operations to complete at the
end.
Samuel Just [Wed, 8 May 2013 23:19:34 +0000 (16:19 -0700)]
PG,OSD: delay ops for map prior to queueing in the OpWQ
Previously, we simply queued ops in the OpWQ without checking. The PG
would then check in do_request whether the message should wait for a new
map. Unfortunately, this has the side effect that any op requeued for
any reason must also requeue the waiting_for_map queue.
Now, we will check before queueing the op whether it must wait on a map.
To avoid contention, there is now a map_lock which must be held along
with the PG lock in order to update the osdmap_ref. The map_lock also
protects the waiting_for_map list and queueing PG ops at the back of
the OpWQ. A few details:
1) It is no longer necessary to requeue waiting_for_map in on_change()
since the other ops are queued at the front.
2) Once waiting_for_map is non-empty, all ops are delayed to simplify
ordering.
3) waiting_for_map may now be non-empty during split, so we must split
waiting_for_map along with waiting_for_active. This must be done
under the map_lock.
The bug which uncovered this involved an out of order op as follows:
client.4208.0:2378 (e252) arrives, object is degraded
client.4208.0:2379 (e253) arrives, waits for map
client.4208.0:2378 (e252) is requeued after recovery
client.4208.0:2379 (e253) is requeued on map arrival
client.4208.0:2379 is processed
client.4208.0:2378 is processed
Fixes: #4955 Signed-off-by: Samuel Just <sam.just@inktank.com>