]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
filestore: use new async btrfs ioctls
authorSage Weil <sage@newdream.net>
Tue, 23 Feb 2010 00:03:09 +0000 (16:03 -0800)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 22 Oct 2010 17:16:13 +0000 (10:16 -0700)
src/os/FileStore.cc
src/os/FileStore.h
src/os/btrfs_ioctl.h

index 7257d8f7a9e50c0a8916d14fe043e4bc1ee7b592..78033b9afe1a4f9e8bb1642e1405bcc7ba041c92 100644 (file)
@@ -512,6 +512,49 @@ int FileStore::_detect_fs()
           << "           Linux 2.6.32).\n"
           << TEXT_NORMAL;
       return -ENOTTY;
+
+    // start_sync?
+    __u64 transid = 0;
+    r = ::ioctl(fd, BTRFS_IOC_START_SYNC, &transid);
+    dout(0) << "mount btrfs START_SYNC got " << r << " " << strerror_r(-r, buf, sizeof(buf)) << dendl;
+    if (r == 0 && transid > 0) {
+      dout(0) << "mount btrfs START_SYNC is supported (transid " << transid << ")" << dendl;
+
+      // do we have wait_sync too?
+      r = ::ioctl(fd, BTRFS_IOC_WAIT_SYNC, &transid);
+      if (r == 0 || r == -ERANGE) {
+       dout(0) << "mount btrfs WAIT_SYNC is supported" << dendl;
+       btrfs_wait_sync = true;
+      } else {
+       dout(0) << "mount btrfs WAIT_SYNC is NOT supported: " << strerror_r(-r, buf, sizeof(buf)) << dendl;
+      }
+    } else {
+      dout(0) << "mount btrfs START_SYNC is NOT supported: " << strerror_r(-r, buf, sizeof(buf)) << dendl;
+    }
+
+    if (btrfs_wait_sync) {
+      // async snap creation?
+      struct btrfs_ioctl_vol_args volargs;
+      volargs.fd = fd;
+      strcpy(volargs.name, "async_snap_test");
+      volargs.transid = 0;
+      volargs.reserved = 0;
+      r = ::ioctl(fd, BTRFS_IOC_SNAP_CREATE_ASYNC, &volargs);
+      dout(0) << "mount btrfs SNAP_CREATE_ASYNC got " << r << " " << strerror_r(-r, buf, sizeof(buf)) << dendl;
+      if (r == 0 || errno == EEXIST) {
+       dout(0) << "mount btrfs SNAP_CREATE_ASYNC is supported" << dendl;
+       btrfs_snap_create_async = true;
+      
+       // clean up
+       volargs.fd = 0;
+       r = ::ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &volargs);
+       if (r != 0) {
+         dout(0) << "mount btrfs SNAP_DESTROY failed: " << strerror_r(-r, buf, sizeof(buf)) << dendl;
+       }
+      } else {
+       dout(0) << "mount btrfs SNAP_CREATE_ASYNC is NOT supported: "
+               << strerror_r(-r, buf, sizeof(buf)) << dendl;
+      }
     }
   } else {
     dout(0) << "mount did NOT detect btrfs" << dendl;
@@ -1740,22 +1783,42 @@ void FileStore::sync_entry()
        btrfs_ioctl_vol_args snapargs;
        snapargs.fd = current_fd;
        snprintf(snapargs.name, sizeof(snapargs.name), COMMIT_SNAP_ITEM, (long long unsigned)cp);
-       dout(10) << "taking snap '" << snapargs.name << "'" << dendl;
-       int r = ::ioctl(basedir_fd, BTRFS_IOC_SNAP_CREATE, &snapargs);
-       if (r) {
+
+       if (btrfs_snap_create_async) {
+         // be smart!
+         dout(10) << "taking async snap '" << snapargs.name << "'" << dendl;
+         int r = ::ioctl(basedir_fd, BTRFS_IOC_SNAP_CREATE_ASYNC, &snapargs);
          char buf[100];
-         dout(0) << "snap create '" << snapargs.name << "' got " << r
-                 << " " << strerror_r(r < 0 ? errno : 0, buf, sizeof(buf)) << dendl;
+         dout(20) << "async snap create '" << snapargs.name
+                  << "' transid " << snapargs.transid
+                  << " got " << r << " " << strerror_r(r < 0 ? errno : 0, buf, sizeof(buf)) << dendl;
          assert(r == 0);
-       }
-       snaps.push_back(cp);
-      }
+         snaps.push_back(cp);
+
+         commit_started();
+
+         // wait for commit
+         dout(20) << " waiting for transid " << snapargs.transid << " to complete" << dendl;
+         ::ioctl(op_fd, BTRFS_IOC_WAIT_SYNC, &snapargs.transid);
+         dout(20) << " done waiting for transid " << snapargs.transid << " to complete" << dendl;
 
-      commit_started();
+       } else {
+         // the synchronous snap create does a sync.
+         dout(10) << "taking snap '" << snapargs.name << "'" << dendl;
+         int r = ::ioctl(basedir_fd, BTRFS_IOC_SNAP_CREATE, &snapargs);
+         char buf[100];
+         dout(20) << "snap create '" << snapargs.name << "' got " << r
+                  << " " << strerror_r(r < 0 ? errno : 0, buf, sizeof(buf)) << dendl;
+         assert(r == 0);
+         snaps.push_back(cp);
+         
+         commit_started();
+       }
+      } else {
+       commit_started();
 
-      if (!do_snap) {
        if (btrfs) {
-         dout(15) << "sync_entry doing btrfs sync" << dendl;
+         dout(15) << "sync_entry doing btrfs SYNC" << dendl;
          // do a full btrfs commit
          ::ioctl(op_fd, BTRFS_IOC_SYNC);
        } else if (g_conf.filestore_fsync_flushes_journal_data) {
index 72d7794b621ffef512ef0f669e6b4914016671a2..dc26e15a34ba33db49d8422547b41ff8f0f38cf3 100644 (file)
@@ -48,6 +48,8 @@ class FileStore : public JournalingObjectStore {
   bool btrfs_clone_range;
   bool btrfs_snap_create;
   bool btrfs_snap_destroy;
+  bool btrfs_snap_create_async;
+  bool btrfs_wait_sync;
   int fsid_fd, op_fd;
 
   int basedir_fd, current_fd;
@@ -175,6 +177,8 @@ class FileStore : public JournalingObjectStore {
     btrfs(false), btrfs_trans_start_end(false), btrfs_clone_range(false),
     btrfs_snap_create(false),
     btrfs_snap_destroy(false),
+    btrfs_snap_create_async(false),
+    btrfs_wait_sync(false),
     fsid_fd(-1), op_fd(-1),
     attrs(this), fake_attrs(false), 
     collections(this), fake_collections(false),
index 0eb2c4912721ed2670aa68b002bd70ac52b4cb47..21ff3c1d3537751b9561f61125e8da1ae5b75230 100644 (file)
 
 #define BTRFS_IOCTL_MAGIC 0x94
 #define BTRFS_VOL_NAME_MAX 255
-#define BTRFS_PATH_NAME_MAX 4087
+#define BTRFS_PATH_NAME_MAX 4071
 
 /* this should be 4k */
 struct btrfs_ioctl_vol_args {
        __s64 fd;
        char name[BTRFS_PATH_NAME_MAX + 1];
+       __u64 transid;
+       __u64 reserved;
 };
 
 #define BTRFS_INO_LOOKUP_PATH_MAX 4080
@@ -178,4 +180,8 @@ struct btrfs_ioctl_space_args {
 #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64)
 #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \
                                    struct btrfs_ioctl_space_args)
+#define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 21, __u64)
+#define BTRFS_IOC_WAIT_SYNC  _IOW(BTRFS_IOCTL_MAGIC, 22, __u64)
+#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \
+                                  struct btrfs_ioctl_vol_args)
 #endif