]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: fix directory fsync 5294/head
authorYan, Zheng <zyan@redhat.com>
Mon, 20 Jul 2015 08:46:39 +0000 (16:46 +0800)
committerYan, Zheng <zyan@redhat.com>
Tue, 21 Jul 2015 02:23:29 +0000 (10:23 +0800)
When opening a regular file, fuse assigns a 'struct Fh' pointer to
fuse_file_info::fh. but when openning a directory, fuse assigns a
'struct dir_result_t' to fuse_file_info::fh. So we need a seperate
function for fsyncdir (cast fuse_file_info::fh to a struct
dir_result_t pointer)

Fixes: #12354
Signed-off-by: Yan, Zheng <zyan@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/fuse_ll.cc

index abadc8bf296c8ab0697829b4e256967d8b1e04ce..d4fb5a8cb95e0be8526c4b4ec7926011220db3d7 100644 (file)
@@ -7806,11 +7806,9 @@ int Client::fsync(int fd, bool syncdataonly)
   return r;
 }
 
-int Client::_fsync(Fh *f, bool syncdataonly)
+int Client::_fsync(Inode *in, bool syncdataonly)
 {
   int r = 0;
-
-  Inode *in = f->inode;
   uint16_t wait_on_flush[CEPH_CAP_BITS];
   bool flushed_metadata = false;
   Mutex lock("Client::_fsync::lock");
@@ -7818,7 +7816,7 @@ int Client::_fsync(Fh *f, bool syncdataonly)
   bool done = false;
   C_SafeCond *object_cacher_completion = NULL;
 
-  ldout(cct, 3) << "_fsync(" << f << ", " << (syncdataonly ? "dataonly)":"data+metadata)") << dendl;
+  ldout(cct, 3) << "_fsync on " << *in << " " << (syncdataonly ? "(dataonly)":"(data+metadata)") << dendl;
   
   if (cct->_conf->client_oc) {
     object_cacher_completion = new C_SafeCond(&lock, &cond, &done, &r);
@@ -7888,6 +7886,12 @@ int Client::_fsync(Fh *f, bool syncdataonly)
   return r;
 }
 
+int Client::_fsync(Fh *f, bool syncdataonly)
+{
+  ldout(cct, 3) << "_fsync(" << f << ", " << (syncdataonly ? "dataonly)":"data+metadata)") << dendl;
+  return _fsync(f->inode, syncdataonly);
+}
+
 int Client::fstat(int fd, struct stat *stbuf) 
 {
   Mutex::Locker lock(client_lock);
@@ -10012,6 +10016,16 @@ int Client::ll_releasedir(dir_result_t *dirp)
   return 0;
 }
 
+int Client::ll_fsyncdir(dir_result_t *dirp)
+{
+  Mutex::Locker lock(client_lock);
+  ldout(cct, 3) << "ll_fsyncdir " << dirp << dendl;
+  tout(cct) << "ll_fsyncdir" << std::endl;
+  tout(cct) << (unsigned long)dirp << std::endl;
+
+  return _fsync(dirp->inode, false);
+}
+
 int Client::ll_open(Inode *in, int flags, Fh **fhp, int uid, int gid)
 {
   assert(!(flags & O_CREAT));
index b24a7829ddbe3fbb8010ca3cf6fdbdb4dfb54e78..db015040c310d42134756f6091bc546c84a72a76 100644 (file)
@@ -682,6 +682,7 @@ private:
   int _preadv_pwritev(int fd, const struct iovec *iov, unsigned iovcnt, int64_t offset, bool write);
   int _flush(Fh *fh);
   int _fsync(Fh *fh, bool syncdataonly);
+  int _fsync(Inode *in, bool syncdataonly);
   int _sync_fs();
   int _fallocate(Fh *fh, int mode, int64_t offset, int64_t length);
   int _getlk(Fh *fh, struct flock *fl, uint64_t owner);
@@ -927,6 +928,7 @@ public:
   int ll_listxattr(Inode *in, char *list, size_t size, int uid=-1, int gid=-1);
   int ll_opendir(Inode *in, dir_result_t **dirpp, int uid = -1, int gid = -1);
   int ll_releasedir(dir_result_t* dirp);
+  int ll_fsyncdir(dir_result_t* dirp);
   int ll_readlink(Inode *in, char *buf, size_t bufsize, int uid = -1, int gid = -1);
   int ll_mknod(Inode *in, const char *name, mode_t mode, dev_t rdev,
               struct stat *attr, Inode **out, int uid = -1, int gid = -1);
index 72ac98d23f6acda0a6dd0532300123058864e261..6e0589f920a82f1a255f6bf723f9ff992ce01fa7 100644 (file)
@@ -596,6 +596,15 @@ static void fuse_ll_releasedir(fuse_req_t req, fuse_ino_t ino,
   fuse_reply_err(req, 0);
 }
 
+static void fuse_ll_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
+                            struct fuse_file_info *fi)
+{
+  CephFuse::Handle *cfuse = (CephFuse::Handle *)fuse_req_userdata(req);
+  dir_result_t *dirp = reinterpret_cast<dir_result_t*>(fi->fh);
+  int r = cfuse->client->ll_fsyncdir(dirp);
+  fuse_reply_err(req, -r);
+}
+
 static void fuse_ll_access(fuse_req_t req, fuse_ino_t ino, int mask)
 {
   fuse_reply_err(req, 0);
@@ -817,7 +826,7 @@ const static struct fuse_lowlevel_ops fuse_ll_oper = {
  opendir: fuse_ll_opendir,
  readdir: fuse_ll_readdir,
  releasedir: fuse_ll_releasedir,
- fsyncdir: fuse_ll_fsync,
+ fsyncdir: fuse_ll_fsyncdir,
  statfs: fuse_ll_statfs,
  setxattr: fuse_ll_setxattr,
  getxattr: fuse_ll_getxattr,