]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: flush kernel pagecache before creating snapshot
authorYan, Zheng <zyan@redhat.com>
Mon, 15 Feb 2016 07:29:28 +0000 (15:29 +0800)
committerYan, Zheng <zyan@redhat.com>
Wed, 9 Mar 2016 14:06:12 +0000 (22:06 +0800)
Fixes: #10436
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/fuse_ll.cc
src/common/config_opts.h

index 793cc4d1ab990e551ade3537f3f933cf0c399722..edbd1d6bd92e1e4d690709701ef916086ea33e1e 100644 (file)
@@ -328,11 +328,33 @@ static void fuse_ll_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
 {
   CephFuse::Handle *cfuse = fuse_ll_req_prepare(req);
   const struct fuse_ctx *ctx = fuse_req_ctx(req);
-  Inode *i2, *i1 = cfuse->iget(parent);
+  Inode *i2, *i1;
   struct fuse_entry_param fe;
 
   memset(&fe, 0, sizeof(fe));
 
+#ifdef HAVE_SYS_SYNCFS
+  if (cfuse->fino_snap(parent) == CEPH_SNAPDIR &&
+      cfuse->client->cct->_conf->fuse_multithreaded &&
+      cfuse->client->cct->_conf->fuse_syncfs_on_mksnap) {
+    int err = 0;
+    int fd = ::open(cfuse->mountpoint, O_RDONLY | O_DIRECTORY);
+    if (fd < 0) {
+      err = -errno;
+    } else {
+      int r = ::syncfs(fd);
+      if (r < 0)
+       err = -errno;
+      ::close(fd);
+    }
+    if (err) {
+      fuse_reply_err(req, err);
+      return;
+    }
+  }
+#endif
+
+  i1 = cfuse->iget(parent);
   int r = cfuse->client->ll_mkdir(i1, name, mode, &fe.attr, &i2, ctx->uid,
                                  ctx->gid);
   if (r == 0) {
index a0ae4955ebc7c742b26aced5cd946eb84bfec58a..f0a4512466587f520b6dcf260b84f5d835a064a5 100644 (file)
@@ -399,6 +399,7 @@ OPTION(fuse_atomic_o_trunc, OPT_BOOL, true)
 OPTION(fuse_debug, OPT_BOOL, false)
 OPTION(fuse_multithreaded, OPT_BOOL, true)
 OPTION(fuse_require_active_mds, OPT_BOOL, true) // if ceph_fuse requires active mds server
+OPTION(fuse_syncfs_on_mksnap, OPT_BOOL, true)
 
 OPTION(client_try_dentry_invalidate, OPT_BOOL, true) // the client should try to use dentry invaldation instead of remounting, on kernels it believes that will work for
 OPTION(client_die_on_failed_remount, OPT_BOOL, true)