]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: take inode ref on first WRBUFFER cap ref in set_page_dirty
authorSage Weil <sage@newdream.net>
Thu, 3 Sep 2009 20:19:44 +0000 (13:19 -0700)
committerSage Weil <sage@newdream.net>
Thu, 3 Sep 2009 20:19:44 +0000 (13:19 -0700)
This only came up if the first dirty data on the inode was from
an mmap write; the aio_write would grab a ref via the
__take_cap_ref path first and grab the reference.

Fix the put_cap_refs() too for consistency, even though that path
isn't normally used (but theoretically could be?).

src/kernel/addr.c
src/kernel/caps.c

index 89273c93aa9e5ddb8ef67f5735184b0f0549c720..a5dd43abc374ff9c04e833be2e6e782b274238bd 100644 (file)
@@ -84,6 +84,8 @@ static int ceph_set_page_dirty(struct page *page)
        if (ci->i_wrbuffer_ref_head == 0)
                ci->i_head_snapc = ceph_get_snap_context(snapc);
        ++ci->i_wrbuffer_ref_head;
+       if (ci->i_wrbuffer_ref == 0)
+               igrab(inode);
        ++ci->i_wrbuffer_ref;
        dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d "
             "snapc %p seq %lld (%d snaps)\n",
index 2ce693430bb03e903a2efc8efc538e3f8f6c8c30..b883e83679fed12c65b5db8ae18f0acc91dcff7b 100644 (file)
@@ -1950,7 +1950,7 @@ void ceph_get_cap_refs(struct ceph_inode_info *ci, int caps)
 void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
 {
        struct inode *inode = &ci->vfs_inode;
-       int last = 0, flushsnaps = 0, wake = 0;
+       int last = 0, put = 0, flushsnaps = 0, wake = 0;
        struct ceph_cap_snap *capsnap;
 
        spin_lock(&inode->i_lock);
@@ -1963,8 +1963,10 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
                if (--ci->i_rdcache_ref == 0)
                        last++;
        if (had & CEPH_CAP_FILE_BUFFER) {
-               if (--ci->i_wrbuffer_ref == 0)
+               if (--ci->i_wrbuffer_ref == 0) {
                        last++;
+                       put++;
+               }
                dout("put_cap_refs %p wrbuffer %d -> %d (?)\n",
                     inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref);
        }
@@ -1995,6 +1997,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had)
                ceph_flush_snaps(ci);
        if (wake)
                wake_up(&ci->i_cap_wq);
+       if (put)
+               iput(inode);
 }
 
 /*