]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
filestore: allow clone_range to different offsets
authorSage Weil <sage@newdream.net>
Thu, 2 Jun 2011 16:19:39 +0000 (09:19 -0700)
committerSage Weil <sage@newdream.net>
Thu, 2 Jun 2011 16:19:39 +0000 (09:19 -0700)
The old OP_CLONERANGE would only clone a range of bytes at the same offset
in both objects.  Add an OP_CLONERANGE2 op code that adds a dst offset.
Continue to support the old op code so that we can decode old transactions.

Signed-off-by: Sage Weil <sage@newdream.net>
src/os/FileStore.cc
src/os/FileStore.h
src/os/ObjectStore.h
src/osd/ReplicatedPG.cc

index 8aa1bafd4cfb6bfe9e2cf7e92e77469a168bf18d..fde1187b43f050e5ce1440e842575a2105a2f225 100644 (file)
@@ -1308,7 +1308,7 @@ int FileStore::_detect_fs()
     // clone_range?
     if (g_conf.filestore_btrfs_clone_range) {
       btrfs_clone_range = true;
-      int r = _do_clone_range(fsid_fd, -1, 0, 1);
+      int r = _do_clone_range(fsid_fd, -1, 0, 1, 0);
       if (r == -EBADF) {
        dout(0) << "mount btrfs CLONE_RANGE ioctl is supported" << dendl;
       } else {
@@ -2442,7 +2442,19 @@ unsigned FileStore::_do_transaction(Transaction& t)
        sobject_t noid = t.get_oid();
        uint64_t off = t.get_length();
        uint64_t len = t.get_length();
-       r = _clone_range(cid, oid, noid, off, len);
+       r = _clone_range(cid, oid, noid, off, len, off);
+      }
+      break;
+
+    case Transaction::OP_CLONERANGE2:
+      {
+       coll_t cid = t.get_cid();
+       sobject_t oid = t.get_oid();
+       sobject_t noid = t.get_oid();
+       uint64_t srcoff = t.get_length();
+       uint64_t len = t.get_length();
+       uint64_t dstoff = t.get_length();
+       r = _clone_range(cid, oid, noid, srcoff, len, dstoff);
       }
       break;
 
@@ -2795,7 +2807,7 @@ int FileStore::_clone(coll_t cid, const sobject_t& oldoid, const sobject_t& newo
     struct stat st;
     ::fstat(o, &st);
     dout(10) << "clone " << cid << "/" << oldoid << " -> " << cid << "/" << newoid << " READ+WRITE" << dendl;
-    r = _do_clone_range(o, n, 0, st.st_size);
+    r = _do_clone_range(o, n, 0, st.st_size, 0);
   }
   if (r < 0)
     r = -errno;
@@ -2808,28 +2820,28 @@ int FileStore::_clone(coll_t cid, const sobject_t& oldoid, const sobject_t& newo
   return 0;
 }
 
-int FileStore::_do_clone_range(int from, int to, uint64_t off, uint64_t len)
+int FileStore::_do_clone_range(int from, int to, uint64_t srcoff, uint64_t len, uint64_t dstoff)
 {
-  dout(20) << "_do_clone_range " << off << "~" << len << dendl;
+  dout(20) << "_do_clone_range " << srcoff << "~" << len << " to " << dstoff << dendl;
   int r = 0;
   
   if (btrfs_clone_range) {
     btrfs_ioctl_clone_range_args a;
     a.src_fd = from;
-    a.src_offset = off;
+    a.src_offset = srcoff;
     a.src_length = len;
-    a.dest_offset = off;
+    a.dest_offset = dstoff;
     r = ::ioctl(to, BTRFS_IOC_CLONE_RANGE, &a);
     if (r >= 0)
       return r;
     return -errno;
   }
 
-  ::lseek64(from, off, SEEK_SET);
-  ::lseek64(to, off, SEEK_SET);
-
-  loff_t pos = off;
-  loff_t end = off + len;
+  ::lseek64(from, srcoff, SEEK_SET);
+  ::lseek64(to, dstoff, SEEK_SET);
+  
+  loff_t pos = srcoff;
+  loff_t end = srcoff + len;
   int buflen = 4096*32;
   char buf[buflen];
   while (pos < end) {
@@ -2865,13 +2877,14 @@ int FileStore::_do_clone_range(int from, int to, uint64_t off, uint64_t len)
       break;
     pos += r;
   }
-  dout(20) << "_do_clone_range " << off << "~" << len << " = " << r << dendl;
+  dout(20) << "_do_clone_range " << srcoff << "~" << len << " to " << dstoff << " = " << r << dendl;
   return r;
 }
 
-int FileStore::_clone_range(coll_t cid, const sobject_t& oldoid, const sobject_t& newoid, uint64_t off, uint64_t len)
+int FileStore::_clone_range(coll_t cid, const sobject_t& oldoid, const sobject_t& newoid,
+                           uint64_t srcoff, uint64_t len, uint64_t dstoff)
 {
-  dout(15) << "clone_range " << cid << "/" << oldoid << " -> " << cid << "/" << newoid << " " << off << "~" << len << dendl;
+  dout(15) << "clone_range " << cid << "/" << oldoid << " -> " << cid << "/" << newoid << " " << srcoff << "~" << len << " to " << dstoff << dendl;
 
   int r;
   int o, n;
@@ -2885,12 +2898,13 @@ int FileStore::_clone_range(coll_t cid, const sobject_t& oldoid, const sobject_t
     r = -errno;
     goto out;
   }
-  r = _do_clone_range(o, n, off, len);
+  r = _do_clone_range(o, n, srcoff, len, dstoff);
   ::close(n);
  out:
   ::close(o);
  out2:
-  dout(10) << "clone_range " << cid << "/" << oldoid << " -> " << cid << "/" << newoid << " " << off << "~" << len << " = " << r << dendl;
+  dout(10) << "clone_range " << cid << "/" << oldoid << " -> " << cid << "/" << newoid << " "
+          << srcoff << "~" << len << " to " << dstoff << " = " << r << dendl;
   return r;
 }
 
index 9f884bf28343353a476a4b9cf225bfdda6007975..eaf20a8ef679089e655f31d361bfd023adda1514 100644 (file)
@@ -293,8 +293,8 @@ public:
   int _zero(coll_t cid, const sobject_t& oid, uint64_t offset, size_t len);
   int _truncate(coll_t cid, const sobject_t& oid, uint64_t size);
   int _clone(coll_t cid, const sobject_t& oldoid, const sobject_t& newoid);
-  int _clone_range(coll_t cid, const sobject_t& oldoid, const sobject_t& newoid, uint64_t off, uint64_t len);
-  int _do_clone_range(int from, int to, uint64_t off, uint64_t len);
+  int _clone_range(coll_t cid, const sobject_t& oldoid, const sobject_t& newoid, uint64_t srcoff, uint64_t len, uint64_t dstoff);
+  int _do_clone_range(int from, int to, uint64_t srcoff, uint64_t len, uint64_t dstoff);
   int _remove(coll_t cid, const sobject_t& oid);
 
   void _start_sync();
index 22f563f1be923d9d53b6628d44d81c647e8a6527..2ab80ef9d89b32fba4f615e0fec808932b7effff 100644 (file)
@@ -135,6 +135,7 @@ public:
     static const int OP_RMATTR =       16;  // cid, oid, attrname
     static const int OP_CLONE =        17;  // cid, oid, newoid
     static const int OP_CLONERANGE =   18;  // cid, oid, newoid, offset, len
+    static const int OP_CLONERANGE2 =  30;  // cid, oid, newoid, srcoff, len, dstoff
 
     static const int OP_TRIMCACHE =    19;  // cid, oid, offset, len
 
@@ -390,14 +391,16 @@ public:
       ::encode(noid, tbl);
       ops++;
     }
-    void clone_range(coll_t cid, const sobject_t& oid, sobject_t noid, uint64_t off, uint64_t len) {
-      __u32 op = OP_CLONERANGE;
+    void clone_range(coll_t cid, const sobject_t& oid, sobject_t noid,
+                    uint64_t srcoff, uint64_t srclen, uint64_t dstoff) {
+      __u32 op = OP_CLONERANGE2;
       ::encode(op, tbl);
       ::encode(cid, tbl);
       ::encode(oid, tbl);
       ::encode(noid, tbl);
-      ::encode(off, tbl);
-      ::encode(len, tbl);
+      ::encode(srcoff, tbl);
+      ::encode(srclen, tbl);
+      ::encode(dstoff, tbl);
       ops++;
     }
     void create_collection(coll_t cid) {
index ac071bd7b9f9bf38c45fb75cca36a1c68ca11df0..4aba1de52c044c3b91fa0a111c0d3f0f5197055f 100644 (file)
@@ -3985,7 +3985,7 @@ void ReplicatedPG::sub_op_push(MOSDSubOp *op)
        dout(15) << " clone_range " << p->first << " "
                 << q.get_start() << "~" << q.get_len() << dendl;
        t->clone_range(coll, p->first, soid,
-                      q.get_start(), q.get_len());
+                      q.get_start(), q.get_len(), q.get_start());
       }
     }