]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
fakestore: clone, using either btrfs clone or splice
authorSage Weil <sage@newdream.net>
Fri, 25 Apr 2008 20:34:52 +0000 (13:34 -0700)
committerSage Weil <sage@newdream.net>
Mon, 28 Apr 2008 03:57:20 +0000 (20:57 -0700)
src/osd/FakeStore.cc
src/osd/FakeStore.h
src/osd/ObjectStore.h

index 2096c19147ffa9202a064554ad9e760036e2a1ad..27afb9704cb97790c49598e806b74e03509d3e85 100644 (file)
@@ -49,6 +49,7 @@
 # define BTRFS_IOC_TRANS_START  _IO(BTRFS_IOCTL_MAGIC, 6)
 # define BTRFS_IOC_TRANS_END    _IO(BTRFS_IOCTL_MAGIC, 7)
 # define BTRFS_IOC_SYNC         _IO(BTRFS_IOCTL_MAGIC, 8)
+# define BTRFS_IOC_CLONE        _IOW(BTRFS_IOCTL_MAGIC, 9, int)
 #endif
 #endif
 
@@ -198,9 +199,8 @@ int FakeStore::mkfs()
   fsid = rand();
   char fn[100];
   sprintf(fn, "%s/fsid", basedir.c_str());
-  int fd = ::open(fn, O_CREAT|O_TRUNC|O_WRONLY);
+  int fd = ::open(fn, O_CREAT|O_TRUNC|O_WRONLY, 0644);
   ::write(fd, &fsid, sizeof(fsid));
-  ::fchmod(fd, 0644);
   ::close(fd);
   dout(10) << "mkfs fsid is " << fsid << dendl;
 
@@ -470,16 +470,12 @@ int FakeStore::write(pobject_t oid,
 
   dout(20) << "write " << fn << " len " << len << " off " << offset << dendl;
 
-  
-  ::mknod(fn, 0644, 0);  // in case it doesn't exist yet.
-
-  int flags = O_WRONLY;//|O_CREAT;
-  int fd = ::open(fn, flags);
+  int flags = O_WRONLY|O_CREAT;
+  int fd = ::open(fn, flags, 0644);
   if (fd < 0) {
     derr(0) << "write couldn't open " << fn << " flags " << flags << " errno " << errno << " " << strerror(errno) << dendl;
     return fd;
   }
-  ::fchmod(fd, 0644);
   ::flock(fd, LOCK_EX);    // lock for safety
   
   // seek
@@ -516,6 +512,38 @@ int FakeStore::write(pobject_t oid,
   return did;
 }
 
+int FakeStore::clone(pobject_t oldoid, pobject_t newoid)
+{
+  char ofn[200], nfn[200];
+  get_oname(oldoid, ofn);
+  get_oname(newoid, nfn);
+
+  dout(20) << "clone " << ofn << " -> " << nfn << dendl;
+
+  int o = ::open(ofn, O_RDONLY);
+  if (o < 0)
+      return -errno;
+  int n = ::open(nfn, O_CREAT|O_TRUNC|O_WRONLY, 0644);
+  if (n < 0)
+      return -errno;
+  int r = 0;
+  if (btrfs_fd >= 0)
+    r = ::ioctl(n, BTRFS_IOC_CLONE, o);
+  else {
+    struct stat st;
+    ::fstat(o, &st);
+    loff_t op = 0, np = 0;
+    while (op < st.st_size && r >= 0)
+      r = ::splice(o, &op, n, &np, st.st_size-op, 0);
+  }
+  if (r < 0)
+    return -errno;
+
+  ::close(n);
+  ::close(o);
+  return 0;
+}
+
 
 void FakeStore::sync_entry()
 {
index 6a90987a384318eb8e93824672c67b15d368d328..d930ef58dfbb5030b9f0d24fc770a9701556e827 100644 (file)
@@ -99,6 +99,7 @@ class FakeStore : public JournalingObjectStore {
   int truncate(pobject_t oid, off_t size, Context *onsafe);
   int read(pobject_t oid, off_t offset, size_t len, bufferlist& bl);
   int write(pobject_t oid, off_t offset, size_t len, const bufferlist& bl, Context *onsafe);
+  int clone(pobject_t oldoid, pobject_t newoid);
 
   void sync();
   void sync(Context *onsafe);
index 68fa306d1b35a16bd10365001762a07bb99f6732..7026e2f695fb5664b010be5c6f42e571cb08b14c 100644 (file)
@@ -599,7 +599,7 @@ public:
                      Context *onsafe=0) {return 0;}
 
   virtual int clone(pobject_t oid, pobject_t noid) {
-    return -1; 
+    return -1;
   }
   
   virtual int list_objects(list<pobject_t>& ls) = 0;//{ return -1; }