]> git.apps.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>
Thu, 28 Mar 2013 17:46:59 +0000 (10:46 -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>
src/include/rados/librados.hpp
src/librados/IoCtxImpl.cc
src/librados/IoCtxImpl.h
src/librados/librados.cc

index cf3b33d5328aad7c0170c0610821f8cacc96d1c6..f77cc48a7eced23b72f57ba6cd7932878b68ac77 100644 (file)
@@ -457,9 +457,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,
@@ -503,6 +548,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 76daec9c6edfc44fae89bd03a6d2bc3de2dfdf23..8b7bf9d47fb0a1d323f60708f5d44e8a9e4ab63d 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 a87a87250254d775486e2ee3116c018df27fb773..263fd104167e1344981926785a9647f495feaf68 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 {
@@ -172,12 +173,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 43e377097c2a1deef52660bc32ce4a39ad893b95..d6df4762a1f716cc7ceb76cc00c816500487c6d5 100644 (file)
@@ -855,10 +855,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)
@@ -956,7 +972,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,
@@ -973,7 +997,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,
@@ -2189,7 +2222,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,