]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: add versions of a couple functions taking explicit snap args
authorJosh Durgin <josh.durgin@inktank.com>
Wed, 27 Mar 2013 22:32:29 +0000 (15:32 -0700)
committerJosh Durgin <josh.durgin@inktank.com>
Tue, 23 Apr 2013 18:33:18 +0000 (11:33 -0700)
Usually the snapid to read from or the snapcontext to send with a write
are determined implicitly by the IoCtx the operations are done on.

This makes it difficult to have multiple ops in flight to the same
IoCtx using different snapcontexts or reading from different snapshots,
particularly when more than one operation may be needed past the initial
scheduling.

Add versions of aio_read, aio_sparse_read, and aio_operate
that don't depend on the snap id or snapcontext stored in the IoCtx,
but get them from the caller. Specifying this information for each
operation can be a more useful interface in general, but for now just
add it for the methods used by librbd.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
(cherry picked from commit f06debef6c293750539501ec4e6103e5ae078392)

src/include/rados/librados.hpp
src/librados/IoCtxImpl.cc
src/librados/IoCtxImpl.h
src/librados/librados.cc

index 37e0eb75f5941b089fd83c51180a134da3348cb6..ea001bffbe3a2e8f0b84edf0506033500636b9e6 100644 (file)
@@ -454,9 +454,54 @@ namespace librados
 
     int aio_read(const std::string& oid, AioCompletion *c,
                 bufferlist *pbl, size_t len, uint64_t off);
+    /**
+     * Asynchronously read from an object at a particular snapshot
+     *
+     * This is the same as normal aio_read, except that it chooses
+     * the snapshot to read from from its arguments instead of the
+     * internal IoCtx state.
+     *
+     * The return value of the completion will be number of bytes read on
+     * success, negative error code on failure.
+     *
+     * @param oid the name of the object to read from
+     * @param c what to do when the read is complete
+     * @param pbl where to store the results
+     * @param len the number of bytes to read
+     * @param off the offset to start reading from in the object
+     * @param snapid the id of the snapshot to read from
+     * @returns 0 on success, negative error code on failure
+     */
+    int aio_read(const std::string& oid, AioCompletion *c,
+                bufferlist *pbl, size_t len, uint64_t off, uint64_t snapid);
     int aio_sparse_read(const std::string& oid, AioCompletion *c,
                        std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
                        size_t len, uint64_t off);
+    /**
+     * Asynchronously read existing extents from an object at a
+     * particular snapshot
+     *
+     * This is the same as normal aio_sparse_read, except that it chooses
+     * the snapshot to read from from its arguments instead of the
+     * internal IoCtx state.
+     *
+     * m will be filled in with a map of extents in the object,
+     * mapping offsets to lengths (in bytes) within the range
+     * requested. The data for all of the extents are stored
+     * back-to-back in offset order in data_bl.
+     *
+     * @param oid the name of the object to read from
+     * @param c what to do when the read is complete
+     * @param m where to store the map of extents
+     * @param data_bl where to store the data
+     * @param len the number of bytes to read
+     * @param off the offset to start reading from in the object
+     * @param snapid the id of the snapshot to read from
+     * @returns 0 on success, negative error code on failure
+     */
+    int aio_sparse_read(const std::string& oid, AioCompletion *c,
+                       std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
+                       size_t len, uint64_t off, uint64_t snapid);
     int aio_write(const std::string& oid, AioCompletion *c, const bufferlist& bl,
                  size_t len, uint64_t off);
     int aio_append(const std::string& oid, AioCompletion *c, const bufferlist& bl,
@@ -498,6 +543,23 @@ namespace librados
     int operate(const std::string& oid, ObjectWriteOperation *op);
     int operate(const std::string& oid, ObjectReadOperation *op, bufferlist *pbl);
     int aio_operate(const std::string& oid, AioCompletion *c, ObjectWriteOperation *op);
+    /**
+     * Schedule an async write operation with explicit snapshot parameters
+     *
+     * This is the same as the first aio_operate(), except that it
+     * gets the snapshot context from its arguments instead of the
+     * IoCtx internal state.
+     *
+     * @param oid the object to operate on
+     * @param c what to do when the operation is complete and safe
+     * @param op which operations to perform
+     * @param seq latest selfmanaged snapshot sequence number for this object
+     * @param snaps currently existing selfmanaged snapshot ids for this object
+     * @returns 0 on success, negative error code on failure
+     */
+    int aio_operate(const std::string& oid, AioCompletion *c,
+                   ObjectWriteOperation *op, snap_t seq,
+                   std::vector<snap_t>& snaps);
     int aio_operate(const std::string& oid, AioCompletion *c, ObjectReadOperation *op,
                    bufferlist *pbl);
 
index 0c339caedc501575d0343c2acb86ac0ac77314a8..b7c5594ba50f8f25469335bd1a166e42583cb003 100644 (file)
@@ -711,7 +711,8 @@ int librados::IoCtxImpl::aio_operate_read(const object_t &oid,
 }
 
 int librados::IoCtxImpl::aio_operate(const object_t& oid,
-                                    ::ObjectOperation *o, AioCompletionImpl *c)
+                                    ::ObjectOperation *o, AioCompletionImpl *c,
+                                    snap_t seq, vector<snapid_t>& snaps)
 {
   utime_t ut = ceph_clock_now(client->cct);
   /* can't write to a snapshot */
@@ -724,14 +725,17 @@ int librados::IoCtxImpl::aio_operate(const object_t& oid,
   c->io = this;
   queue_aio_write(c);
 
+  ::SnapContext local_snapc(seq, snaps);
   Mutex::Locker l(*lock);
-  objecter->mutate(oid, oloc, *o, snapc, ut, 0, onack, oncommit, &c->objver);
+  objecter->mutate(oid, oloc, *o, local_snapc, ut, 0, onack, oncommit,
+                  &c->objver);
 
   return 0;
 }
 
 int librados::IoCtxImpl::aio_read(const object_t oid, AioCompletionImpl *c,
-                                 bufferlist *pbl, size_t len, uint64_t off)
+                                 bufferlist *pbl, size_t len, uint64_t off,
+                                 uint64_t snapid)
 {
   if (len > (size_t) INT_MAX)
     return -EDOM;
@@ -745,13 +749,14 @@ int librados::IoCtxImpl::aio_read(const object_t oid, AioCompletionImpl *c,
 
   Mutex::Locker l(*lock);
   objecter->read(oid, oloc,
-                off, len, snap_seq, &c->bl, 0,
+                off, len, snapid, &c->bl, 0,
                 onack, &c->objver);
   return 0;
 }
 
 int librados::IoCtxImpl::aio_read(const object_t oid, AioCompletionImpl *c,
-                                 char *buf, size_t len, uint64_t off)
+                                 char *buf, size_t len, uint64_t off,
+                                 uint64_t snapid)
 {
   if (len > (size_t) INT_MAX)
     return -EDOM;
@@ -765,7 +770,7 @@ int librados::IoCtxImpl::aio_read(const object_t oid, AioCompletionImpl *c,
 
   Mutex::Locker l(*lock);
   objecter->read(oid, oloc,
-                off, len, snap_seq, &c->bl, 0,
+                off, len, snapid, &c->bl, 0,
                 onack, &c->objver);
 
   return 0;
@@ -775,7 +780,7 @@ int librados::IoCtxImpl::aio_sparse_read(const object_t oid,
                                         AioCompletionImpl *c,
                                         std::map<uint64_t,uint64_t> *m,
                                         bufferlist *data_bl, size_t len,
-                                        uint64_t off)
+                                        uint64_t off, uint64_t snapid)
 {
   if (len > (size_t) INT_MAX)
     return -EDOM;
@@ -788,7 +793,7 @@ int librados::IoCtxImpl::aio_sparse_read(const object_t oid,
 
   Mutex::Locker l(*lock);
   objecter->sparse_read(oid, oloc,
-                off, len, snap_seq, &c->bl, 0,
+                off, len, snapid, &c->bl, 0,
                 onack);
   return 0;
 }
index b7c385d3cbd680580dd5a00c5d1348d25b980261..a1f16ccb50aec9f4d0606e4dbedccc96bb485ac5 100644 (file)
@@ -138,7 +138,8 @@ struct librados::IoCtxImpl {
 
   int operate(const object_t& oid, ::ObjectOperation *o, time_t *pmtime);
   int operate_read(const object_t& oid, ::ObjectOperation *o, bufferlist *pbl);
-  int aio_operate(const object_t& oid, ::ObjectOperation *o, AioCompletionImpl *c);
+  int aio_operate(const object_t& oid, ::ObjectOperation *o,
+                 AioCompletionImpl *c, snap_t seq, vector<snapid_t>& snaps);
   int aio_operate_read(const object_t& oid, ::ObjectOperation *o, AioCompletionImpl *c, bufferlist *pbl);
 
   struct C_aio_Ack : public Context {
@@ -164,12 +165,12 @@ struct librados::IoCtxImpl {
   };
 
   int aio_read(const object_t oid, AioCompletionImpl *c,
-                         bufferlist *pbl, size_t len, uint64_t off);
+              bufferlist *pbl, size_t len, uint64_t off, uint64_t snapid);
   int aio_read(object_t oid, AioCompletionImpl *c,
-              char *buf, size_t len, uint64_t off);
+              char *buf, size_t len, uint64_t off, uint64_t snapid);
   int aio_sparse_read(const object_t oid, AioCompletionImpl *c,
                      std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
-                     size_t len, uint64_t off);
+                     size_t len, uint64_t off, uint64_t snapid);
   int aio_write(const object_t &oid, AioCompletionImpl *c,
                const bufferlist& bl, size_t len, uint64_t off);
   int aio_append(const object_t &oid, AioCompletionImpl *c,
index fa8d8e2b2be160e494e8bd628ceec45eaa07b1f9..8fc65eb12e1d9f6895d7941281d596dd10ea4317 100644 (file)
@@ -827,10 +827,26 @@ int librados::IoCtx::operate(const std::string& oid, librados::ObjectReadOperati
   return io_ctx_impl->operate_read(obj, (::ObjectOperation*)o->impl, pbl);
 }
 
-int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c, librados::ObjectWriteOperation *o)
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+                                librados::ObjectWriteOperation *o)
 {
   object_t obj(oid);
-  return io_ctx_impl->aio_operate(obj, (::ObjectOperation*)o->impl, c->pc);
+  return io_ctx_impl->aio_operate(obj, (::ObjectOperation*)o->impl, c->pc,
+                                 io_ctx_impl->snapc.seq,
+                                 io_ctx_impl->snapc.snaps);
+}
+
+int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c,
+                                librados::ObjectWriteOperation *o,
+                                snap_t snap_seq, std::vector<snap_t>& snaps)
+{
+  object_t obj(oid);
+  vector<snapid_t> snv;
+  snv.resize(snaps.size());
+  for (size_t i = 0; i < snaps.size(); ++i)
+    snv[i] = snaps[i];
+  return io_ctx_impl->aio_operate(obj, (::ObjectOperation*)o->impl, c->pc,
+                                 snap_seq, snv);
 }
 
 int librados::IoCtx::aio_operate(const std::string& oid, AioCompletion *c, librados::ObjectReadOperation *o, bufferlist *pbl)
@@ -928,7 +944,15 @@ uint64_t librados::IoCtx::get_last_version()
 int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
                              bufferlist *pbl, size_t len, uint64_t off)
 {
-  return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off);
+  return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off,
+                              io_ctx_impl->snap_seq);
+}
+
+int librados::IoCtx::aio_read(const std::string& oid, librados::AioCompletion *c,
+                             bufferlist *pbl, size_t len, uint64_t off,
+                             uint64_t snapid)
+{
+  return io_ctx_impl->aio_read(oid, c->pc, pbl, len, off, snapid);
 }
 
 int librados::IoCtx::aio_exec(const std::string& oid,
@@ -945,7 +969,16 @@ int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioComple
                                     size_t len, uint64_t off)
 {
   return io_ctx_impl->aio_sparse_read(oid, c->pc,
-                                     m, data_bl, len, off);
+                                     m, data_bl, len, off,
+                                     io_ctx_impl->snap_seq);
+}
+
+int librados::IoCtx::aio_sparse_read(const std::string& oid, librados::AioCompletion *c,
+                                    std::map<uint64_t,uint64_t> *m, bufferlist *data_bl,
+                                    size_t len, uint64_t off, uint64_t snapid)
+{
+  return io_ctx_impl->aio_sparse_read(oid, c->pc,
+                                     m, data_bl, len, off, snapid);
 }
 
 int librados::IoCtx::aio_write(const std::string& oid, librados::AioCompletion *c,
@@ -2126,7 +2159,7 @@ extern "C" int rados_aio_read(rados_ioctx_t io, const char *o,
   librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io;
   object_t oid(o);
   return ctx->aio_read(oid, (librados::AioCompletionImpl*)completion,
-                      buf, len, off);
+                      buf, len, off, ctx->snap_seq);
 }
 
 extern "C" int rados_aio_write(rados_ioctx_t io, const char *o,