]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: keep a pointer to the current snap context in the inode
authorYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 31 Oct 2008 18:07:23 +0000 (11:07 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Fri, 31 Oct 2008 18:07:23 +0000 (11:07 -0700)
src/kernel/addr.c
src/kernel/caps.c
src/kernel/inode.c
src/kernel/snap.c
src/kernel/super.h

index bf18332b266d0fa5c1030ee063959d6f3d557a18..32e9617361ac8c22d86ce9dd10996163afa65944 100644 (file)
@@ -88,6 +88,9 @@ static int ceph_set_page_dirty(struct page *page,
                /* dirty the head */
                ++ci->i_wrbuffer_ref_head;
                snapc = ceph_get_snap_context(ci->i_snap_realm->cached_context);
+               if (ci->i_wrbuffer_ref_head == 1) {
+                       ci->i_head_snapc = ceph_get_snap_context(snapc);
+               }
                dout(20, "%p set_page_dirty %p head %d/%d -> %d/%d "
                     "snapc %p seq %lld (%d snaps)\n",
                     mapping->host, page,
index 60a5d7097eb4f3858bc542780437d9d7e6bd354b..706416d0ea90a380258303b01212c12801a44229 100644 (file)
@@ -865,17 +865,27 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
        struct inode *inode = &ci->vfs_inode;
        int last = 0;
        int last_snap = 0;
-       int snapc_cached = 0;
        int found = 0;
+       struct list_head *p;
+       struct ceph_cap_snap *capsnap = NULL;
 
        spin_lock(&inode->i_lock);
        ci->i_wrbuffer_ref -= nr;
        last = !ci->i_wrbuffer_ref;
-       if (snapc == ci->i_snap_realm->cached_context) {
-               snapc_cached = 1;
+
+       if (ci->i_head_snapc == snapc) {
+               ci->i_wrbuffer_ref_head -= nr;
+               dout(30, "put_wrbuffer_cap_refs on %p head %d/%d -> %d/%d %s\n",
+                       inode,
+                       ci->i_wrbuffer_ref+nr, ci->i_wrbuffer_ref_head+nr,
+                       ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
+                       last ? " LAST":"");
+
+            if (!ci->i_wrbuffer_ref_head) {
+               ceph_put_snap_context(ci->i_head_snapc);
+               ci->i_head_snapc = NULL;
+            }
        } else {
-               struct list_head *p;
-               struct ceph_cap_snap *capsnap = NULL;
                list_for_each(p, &ci->i_cap_snaps) {
                        capsnap = list_entry(p, struct ceph_cap_snap, ci_item);
                        if (capsnap->context == snapc) {
@@ -885,24 +895,14 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr,
                                break;
                        }
                }
-               if (found) {
-                       dout(30, "put_wrbuffer_cap_refs on %p cap_snap %p "
-                            " snap %lld %d/%d -> %d/%d %s%s\n",
-                            inode, capsnap, capsnap->context->seq,
-                            ci->i_wrbuffer_ref+nr, capsnap->dirty + nr,
-                            ci->i_wrbuffer_ref, capsnap->dirty,
-                            last ? " (wrbuffer last)":"",
-                            last_snap ? " (capsnap last)":"");
-               }
-       }
-
-       if (snapc_cached || !found) {
-               ci->i_wrbuffer_ref_head -= nr;
-               dout(30, "put_wrbuffer_cap_refs on %p head %d/%d -> %d/%d %s\n",
-                    inode,
-                    ci->i_wrbuffer_ref+nr, ci->i_wrbuffer_ref_head+nr,
-                    ci->i_wrbuffer_ref, ci->i_wrbuffer_ref_head,
-                    last ? " LAST":"");
+               BUG_ON(!found);
+               dout(30, "put_wrbuffer_cap_refs on %p cap_snap %p "
+                    " snap %lld %d/%d -> %d/%d %s%s\n",
+                    inode, capsnap, capsnap->context->seq,
+                    ci->i_wrbuffer_ref+nr, capsnap->dirty + nr,
+                    ci->i_wrbuffer_ref, capsnap->dirty,
+                    last ? " (wrbuffer last)":"",
+                    last_snap ? " (capsnap last)":"");
        }
 
        spin_unlock(&inode->i_lock);
index fd16e5ab13eb07f72e7659e66b5af66bc90c3267..821d080c4c4036601cd5dd20f35a842c8a2c69f9 100644 (file)
@@ -269,6 +269,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
        init_waitqueue_head(&ci->i_cap_wq);
        INIT_LIST_HEAD(&ci->i_cap_snaps);
        ci->i_snap_caps = 0;
+       ci->i_head_snapc = 0;
 
        ci->i_wanted_max_size = 0;
        ci->i_requested_max_size = 0;
index dfbbbed84a1b3480bdf9ed3916801d2726f49f8b..79aa70167e0cb4f7b899e2e3b418c4408be486c4 100644 (file)
@@ -334,6 +334,8 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci,
                   snapshot. */
                capsnap->dirty = ci->i_wrbuffer_ref_head;
                ci->i_wrbuffer_ref_head = 0;
+               ceph_put_snap_context(ci->i_head_snapc);
+               ci->i_head_snapc = NULL;
                list_add_tail(&capsnap->ci_item, &ci->i_cap_snaps);
 
                if (used & CEPH_CAP_WR) {
index 1026ebab42b6d3bae44ed64e2c0c03a30d6937ad..3430827eef6d2f3cabf3429103af4b56593eae98 100644 (file)
@@ -220,6 +220,7 @@ struct ceph_inode_info {
        unsigned i_cap_exporting_mseq;   /*  mds's. */
        unsigned i_cap_exporting_issued;
        struct list_head i_cap_snaps;   /* snapped state pending flush to mds */
+       struct ceph_snap_context *i_head_snapc; /* defined if wr_buffer_head > 0 */
        unsigned i_snap_caps;           /* cap bits for snapped files */
 
        int i_nr_by_mode[CEPH_FILE_MODE_NUM];  /* open file counts */