]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: rename listener -> unsafe; fix fsync; simplify dir_fsync
authorSage Weil <sage@newdream.net>
Mon, 16 Mar 2009 22:29:29 +0000 (15:29 -0700)
committerSage Weil <sage@newdream.net>
Mon, 16 Mar 2009 22:51:36 +0000 (15:51 -0700)
src/kernel/dir.c
src/kernel/file.c
src/kernel/inode.c
src/kernel/mds_client.c
src/kernel/mds_client.h
src/kernel/super.h

index 7540f5a80c736bd365f6e6cf86f4ff62d7745112..e31e3a756a21e10e38d313bcea6b1c963c56600b 100644 (file)
@@ -800,52 +800,50 @@ 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)
+static int ceph_dir_fsync(struct file *file, struct dentry *dentry,
+                         int datasync)
 {
        struct inode *inode = dentry->d_inode;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       int ret, err;
-       struct list_head *p, *n, *head;
+       struct list_head *head = &ci->i_unsafe_dirops;
        struct ceph_mds_request *req;
        u64 last_tid;
+       int ret = 0;
 
-       ret = 0;
-       dout(10, "sync on directory\n");
-
-       head = &ci->i_listener_list;
-
-       spin_lock(&ci->i_listener_lock);
-
+       dout(10, "dir_fsync %p\n", inode);
+       spin_lock(&ci->i_unsafe_lock);
        if (list_empty(head))
                goto out;
 
        req = list_entry(head->prev,
-                        struct ceph_mds_request, r_listener_item);
+                        struct ceph_mds_request, r_unsafe_dir_item);
        last_tid = req->r_tid;
 
-       list_for_each_safe(p, n, head) {
-               req = list_entry(p, struct ceph_mds_request, r_listener_item);
-
-               /* avoid starvation */
-               if (req->r_tid > last_tid)
-                       goto out;
-
+       do {
                ceph_mdsc_get_request(req);
-               spin_unlock(&ci->i_listener_lock);
+               spin_unlock(&ci->i_unsafe_lock);
+               dout(10, "dir_fsync %p wait on tid %llu (until %llu)\n",
+                    inode, req->r_tid, last_tid);
                if (req->r_timeout) {
-                       err = wait_for_completion_timeout(&req->r_safe_completion,
-                                                       req->r_timeout);
-                       if (err == 0)
+                       ret = wait_for_completion_timeout(&req->r_safe_completion,
+                                                         req->r_timeout);
+                       if (ret > 0)
+                               ret = 0;
+                       else if (ret == 0)
                                ret = -EIO;  /* timed out */
                } else {
                        wait_for_completion(&req->r_safe_completion);
                }
-               spin_lock(&ci->i_listener_lock);
-
+               spin_lock(&ci->i_unsafe_lock);
                ceph_mdsc_put_request(req);
-       }
+
+               if (ret || list_empty(head))
+                       break;
+               req = list_entry(head->next,
+                                struct ceph_mds_request, r_unsafe_dir_item);
+       } while (req->r_tid < last_tid);
 out:
-       spin_unlock(&ci->i_listener_lock);
+       spin_unlock(&ci->i_unsafe_lock);
        return ret;
 }
 
index d027d71fa9d90fc3a569a7c55d89f4e79e22f717..0c379bd18871dbb7531f4770e9393c46612d45a4 100644 (file)
@@ -412,9 +412,9 @@ static void sync_write_commit(struct ceph_osd_request *req)
        struct ceph_inode_info *ci = ceph_inode(req->r_inode);
 
        dout(10, "sync_write_commit %p tid %llu\n", req, req->r_tid);
-       spin_lock(&ci->i_listener_lock);
+       spin_lock(&ci->i_unsafe_lock);
        list_del_init(&req->r_unsafe_item);
-       spin_unlock(&ci->i_listener_lock);
+       spin_unlock(&ci->i_unsafe_lock);
        ceph_put_cap_refs(ci, CEPH_CAP_FILE_WR);
 }
 
@@ -431,7 +431,7 @@ static void sync_write_wait(struct inode *inode)
        struct ceph_osd_request *req;
        u64 last_tid;
 
-       spin_lock(&ci->i_listener_lock);
+       spin_lock(&ci->i_unsafe_lock);
        if (list_empty(head))
               goto out;
 
@@ -442,22 +442,24 @@ static void sync_write_wait(struct inode *inode)
 
        do {
               ceph_osdc_get_request(req);
-              spin_unlock(&ci->i_listener_lock);
+              spin_unlock(&ci->i_unsafe_lock);
               dout(10, "sync_write_wait on tid %llu (until %llu)\n",
                    req->r_tid, last_tid);
               wait_for_completion(&req->r_safe_completion);
-              spin_lock(&ci->i_listener_lock);
+              spin_lock(&ci->i_unsafe_lock);
               ceph_osdc_put_request(req);
 
               /*
                * from here on look at first entry in chain, since we
                * only want to wait for anything older than last_tid
                */
+              if (list_empty(head))
+                      break;
               req = list_entry(head->next, struct ceph_osd_request,
                                r_unsafe_item);
-       } while (req->r_tid <= last_tid);
+       } while (req->r_tid < last_tid);
 out:
-       spin_unlock(&ci->i_listener_lock);
+       spin_unlock(&ci->i_unsafe_lock);
 }
 
 /*
@@ -560,9 +562,9 @@ more:
                         * Add to inode unsafe list only after we
                         * start_request so that a tid has been assigned.
                         */
-                       spin_lock(&ci->i_listener_lock);
+                       spin_lock(&ci->i_unsafe_lock);
                        list_add(&ci->i_unsafe_writes, &req->r_unsafe_item);
-                       spin_unlock(&ci->i_listener_lock);
+                       spin_unlock(&ci->i_unsafe_lock);
                        ceph_get_more_cap_refs(ci, CEPH_CAP_FILE_WR);
                }
                ret = ceph_osdc_wait_request(&client->osdc, req);
@@ -733,7 +735,7 @@ static int ceph_fsync(struct file *file, struct dentry *dentry, int datasync)
        struct inode *inode = dentry->d_inode;
        int ret;
 
-       dout(10, "fsync on inode %p\n", inode);
+       dout(10, "fsync %p\n", inode);
        sync_write_wait(inode);
 
        ret = filemap_write_and_wait(inode->i_mapping);
index bedf122a0d21902117a48d1f128a11fbe03ae6b2..0754f274e87f99ea7d87208154c267e552378b85 100644 (file)
@@ -288,7 +288,10 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
        ci->i_wrbuffer_ref_head = 0;
        ci->i_rdcache_gen = 0;
        ci->i_rdcache_revoking = 0;
+
        INIT_LIST_HEAD(&ci->i_unsafe_writes);
+       INIT_LIST_HEAD(&ci->i_unsafe_dirops);
+       spin_lock_init(&ci->i_unsafe_lock);
 
        ci->i_snap_realm = NULL;
        INIT_LIST_HEAD(&ci->i_snap_realm_item);
@@ -299,9 +302,6 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
 
        INIT_WORK(&ci->i_vmtruncate_work, ceph_vmtruncate_work);
 
-       INIT_LIST_HEAD(&ci->i_listener_list);
-       spin_lock_init(&ci->i_listener_lock);
-
        return &ci->vfs_inode;
 }
 
index 1eb0210b2f13f95734aaa153220a41e6986d1c6e..6959d461bab77b418930a3a9b6bc5fc202d547f0 100644 (file)
@@ -441,10 +441,10 @@ static void __register_request(struct ceph_mds_client *mdsc,
        if (listener) {
                struct ceph_inode_info *ci = ceph_inode(listener);
                
-               spin_lock(&ci->i_listener_lock);
-               req->r_listener = listener;
-               list_add_tail(&req->r_listener_item, &ci->i_listener_list);
-               spin_unlock(&ci->i_listener_lock);
+               spin_lock(&ci->i_unsafe_lock);
+               req->r_unsafe_dir = listener;
+               list_add_tail(&req->r_unsafe_dir_item, &ci->i_unsafe_dirops);
+               spin_unlock(&ci->i_unsafe_lock);
        }
 
        ceph_sysfs_mds_req_init(mdsc, req);
@@ -457,12 +457,12 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
        radix_tree_delete(&mdsc->request_tree, req->r_tid);
        ceph_mdsc_put_request(req);
 
-       if (req->r_listener) {
-               struct ceph_inode_info *ci = ceph_inode(req->r_listener);
+       if (req->r_unsafe_dir) {
+               struct ceph_inode_info *ci = ceph_inode(req->r_unsafe_dir);
 
-               spin_lock(&ci->i_listener_lock);
-               list_del_init(&req->r_listener_item);
-               spin_unlock(&ci->i_listener_lock);
+               spin_lock(&ci->i_unsafe_lock);
+               list_del_init(&req->r_unsafe_dir_item);
+               spin_unlock(&ci->i_unsafe_lock);
        }
 
        ceph_sysfs_mds_req_cleanup(req);
@@ -836,7 +836,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op,
                return ERR_PTR(-ENOMEM);
        req->r_started = jiffies;
        req->r_resend_mds = -1;
-       INIT_LIST_HEAD(&req->r_listener_item);
+       INIT_LIST_HEAD(&req->r_unsafe_dir_item);
        req->r_fmode = -1;
        atomic_set(&req->r_ref, 1);  /* one for request_tree, one for caller */
        INIT_LIST_HEAD(&req->r_wait);
index 9d25a9d004dec254d6d8329b6227d26fb413b4ea..0af5851231f02657bb761d3da98cd715b8f171a7 100644 (file)
@@ -179,8 +179,8 @@ struct ceph_mds_request {
        u32 r_direct_hash;      /* choose dir frag based on this dentry hash */
        bool r_direct_is_hash;  /* true if r_direct_hash is valid */
 
-       struct inode    *r_listener;
-       struct list_head r_listener_item;
+       struct inode    *r_unsafe_dir;
+       struct list_head r_unsafe_dir_item;
 
        /* references to the trailing dentry and inode from parsing the
         * mds response.  also used to feed a VFS-provided dentry into
index 5caeae807d931a04326142c9bc6894301d8436d4..403f83a65545bc53e11f39cbeb66621a68871646 100644 (file)
@@ -281,7 +281,10 @@ struct ceph_inode_info {
                                   If it's non-zero, we _may_ have cached
                                   pages. */
        u32 i_rdcache_revoking; /* RDCACHE gen to async invalidate, if any */
+
        struct list_head i_unsafe_writes; /* uncommitted sync writes */
+       struct list_head i_unsafe_dirops; /* uncommitted mds dir ops */
+       spinlock_t i_unsafe_lock;
 
        struct ceph_snap_realm *i_snap_realm; /* snap realm (if caps) */
        struct list_head i_snap_realm_item;
@@ -292,9 +295,6 @@ struct ceph_inode_info {
 
        struct work_struct i_vmtruncate_work;
 
-       struct list_head i_listener_list; /* requests we pend on */
-       spinlock_t i_listener_lock;
-
        struct inode vfs_inode; /* at end */
 };