]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
ceph: only release clean, unused caps with mds requests
authorSage Weil <sage@newdream.net>
Thu, 24 Jun 2010 22:12:37 +0000 (15:12 -0700)
committerSage Weil <sage@newdream.net>
Tue, 29 Jun 2010 16:31:55 +0000 (09:31 -0700)
We can drop caps with an mds request.  Ensure we only drop unused AND
clean caps, since the MDS doesn't support cap writeback in that context,
nor do we track it.  If caps are dirty, and the MDS needs them back, we
it will revoke and we will flush in the normal fashion.

This fixes a possibly loss of metadata.

Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/caps.c

index 619b61655ee5dd4496ca4ec6374849c09f892817..d4fcdda7676c6399bd67567b0e631c36a3df52ab 100644 (file)
@@ -2886,18 +2886,19 @@ int ceph_encode_inode_release(void **p, struct inode *inode,
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_cap *cap;
        struct ceph_mds_request_release *rel = *p;
+       int used, dirty;
        int ret = 0;
-       int used = 0;
 
        spin_lock(&inode->i_lock);
        used = __ceph_caps_used(ci);
+       dirty = __ceph_caps_dirty(ci);
 
-       dout("encode_inode_release %p mds%d used %s drop %s unless %s\n", inode,
-            mds, ceph_cap_string(used), ceph_cap_string(drop),
+       dout("encode_inode_release %p mds%d used|dirty %s drop %s unless %s\n",
+            inode, mds, ceph_cap_string(used|dirty), ceph_cap_string(drop),
             ceph_cap_string(unless));
 
-       /* only drop unused caps */
-       drop &= ~used;
+       /* only drop unused, clean caps */
+       drop &= ~(used | dirty);
 
        cap = __get_cap_for_mds(ci, mds);
        if (cap && __cap_is_valid(cap)) {