]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix fsync for directories
authorYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 8 Jan 2009 18:37:56 +0000 (10:37 -0800)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 9 Jan 2009 19:06:13 +0000 (11:06 -0800)
src/kernel/dir.c
src/kernel/file.c
src/kernel/mds_client.c
src/kernel/super.h

index 960e96ed47412aba4ac76c9673a04a33de424e45..666d3bc548b2be7ba07f3c50db1c1c449b7154db 100644 (file)
@@ -857,6 +857,37 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size,
        return size - left;
 }
 
+static int ceph_dir_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+       struct inode *inode = dentry->d_inode;
+       int ret, err;
+       struct ceph_mds_request *req;
+       u64 nexttid = 0;
+
+       ret = 0;
+       dout(0, "sync on directory\n");
+
+       do {
+               req = ceph_mdsc_get_listener_req(inode, nexttid);
+
+               if (!req)
+                       break;
+               nexttid = req->r_tid + 1;
+
+               if (req->r_timeout) {
+                       err = wait_for_completion_timeout(&req->r_safe_completion,
+                                                       req->r_timeout);
+                       if (err == 0)
+                               ret = -EIO;  /* timed out */
+               } else {
+                       wait_for_completion(&req->r_safe_completion);
+               }
+               ceph_mdsc_put_request(req);
+       } while (req);
+
+       return ret;
+}
+
 const struct file_operations ceph_dir_fops = {
        .read = ceph_read_dir,
        .readdir = ceph_readdir,
@@ -864,6 +895,7 @@ const struct file_operations ceph_dir_fops = {
        .open = ceph_open,
        .release = ceph_release,
        .unlocked_ioctl = ceph_ioctl,
+       .fsync = ceph_dir_fsync,
 };
 
 const struct inode_operations ceph_dir_iops = {
index cb701878142f30ef2cec955cd9dfa09cb26129a7..d7fd0c71085c8e1c5d6a01e19ed27cc348edf555 100644 (file)
@@ -167,7 +167,7 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
        struct ceph_client *client = ceph_sb_to_client(dir->i_sb);
        struct ceph_mds_client *mdsc = &client->mdsc;
        struct file *file = nd->intent.open.file;
-       struct inode *parent_inode = file->f_dentry->d_parent->d_inode;
+       struct inode *parent_inode = get_dentry_parent_inode(file->f_dentry);
        struct ceph_mds_request *req;
        int err;
        int flags = nd->intent.open.flags - 1;  /* silly vfs! */
@@ -421,38 +421,12 @@ out:
 static int ceph_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
        struct inode *inode = dentry->d_inode;
-       int ret, err;
-       struct ceph_mds_request *req;
-       u64 nexttid = 0;
+       int ret;
 
        dout(10, "fsync on inode %p\n", inode);
        ret = write_inode_now(inode, 1);
        if (ret < 0)
                return ret;
-
-       ret = 0;
-       if ((inode->i_mode & S_IFMT) == S_IFDIR) {
-               dout(0, "sync on directory\n");
-
-               do {
-                       req = ceph_mdsc_get_listener_req(inode, nexttid);
-
-                       if (!req)
-                               break;
-                       nexttid = req->r_tid + 1;
-
-                       if (req->r_timeout) {
-                               err = wait_for_completion_timeout(&req->r_safe_completion,
-                                                               req->r_timeout);
-                               if (err == 0)
-                                       ret = -EIO;  /* timed out */
-                       } else {
-                               wait_for_completion(&req->r_safe_completion);
-                       }
-                       ceph_mdsc_put_request(req);
-               } while (req);
-       }
-
        /*
         * HMM: should we also ensure that caps are flushed to mds?
         * It's not strictly necessary, since with the data on the
index aa3fb5c763e97a8a810668e66e427ff9b260760f..c56afd010b5398f998fd20722c1d2e1356d18220 100644 (file)
@@ -491,11 +491,11 @@ struct ceph_mds_request *ceph_mdsc_get_listener_req(struct inode *inode,
 
        spin_lock(&ci->i_listener_lock);
        got = radix_tree_gang_lookup(&ci->i_listener_tree,
-                                       (void **)&req, 0, 1);
+                                       (void **)&req, tid, 1);
 
-       if (got >= 0) {
+       if (got > 0)
                get_request(req);
-       }
+
        spin_unlock(&ci->i_listener_lock);
 
        return req;
@@ -1299,7 +1299,7 @@ void ceph_mdsc_handle_reply(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
        dout(10, "handle_reply %p expected_cap=%p\n", req, req->r_expected_cap);
        mds = le32_to_cpu(msg->hdr.src.name.num);
        if (req->r_got_reply) {
-               if (req->r_reply_info.head->safe) {
+               if (head->safe) {
                        /* 
                           We already handled the unsafe response, now do the cleanup.
                           Shouldn't we check the safe response to see if it matches
@@ -1307,11 +1307,12 @@ void ceph_mdsc_handle_reply(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
                        */
                        complete(&req->r_safe_completion);
                        __unregister_request(mdsc, req);
-                       dout(10, "got another reply %llu, mds%d\n",
+                       dout(10, "got safe reply %llu, mds%d\n",
                                tid, mds);
                        ceph_msg_put(req->r_request);
                        req->r_request = NULL;
                } else {
+                       mutex_unlock(&mdsc->mutex);
                        dout(0, "got another _unsafe_ reply %llu, mds%d\n",
                                tid, mds);
                }
index 43fa69253c81a01057a8284b104294c5e7660fdb..d047b2fa1e139febd584f68f2acf7e74b4f8f219 100644 (file)
@@ -738,4 +738,12 @@ extern const struct export_operations ceph_export_ops;
 extern int ceph_proc_init(void);
 extern void ceph_proc_cleanup(void);
 
+static inline struct inode *get_dentry_parent_inode(struct dentry *dentry)
+{
+       if (dentry && dentry->d_parent)
+               return dentry->d_parent->d_inode;
+
+       return NULL;
+}
+
 #endif /* _FS_CEPH_SUPER_H */