From: Yan, Zheng Date: Mon, 20 Jul 2015 08:46:39 +0000 (+0800) Subject: client: fix directory fsync X-Git-Tag: v9.1.0~518^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F5294%2Fhead;p=ceph.git client: fix directory fsync 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 --- diff --git a/src/client/Client.cc b/src/client/Client.cc index abadc8bf296..d4fb5a8cb95 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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)); diff --git a/src/client/Client.h b/src/client/Client.h index b24a7829ddb..db015040c31 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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); diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index 72ac98d23f6..6e0589f920a 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -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(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,