aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-06-24 15:12:37 -0700
committerSage Weil <sage@newdream.net>2010-06-29 09:31:55 -0700
commitec97f88ba6d4256927fde516033ee76d5d85b54a (patch)
tree0df9cb10364afdb9092a089ba0da4a15f3c25a06 /fs
parenta1a31e734241aefcb2b30fb0cc0376977b6d2ba8 (diff)
downloadkernel_samsung_tuna-ec97f88ba6d4256927fde516033ee76d5d85b54a.zip
kernel_samsung_tuna-ec97f88ba6d4256927fde516033ee76d5d85b54a.tar.gz
kernel_samsung_tuna-ec97f88ba6d4256927fde516033ee76d5d85b54a.tar.bz2
ceph: only release clean, unused caps with mds requests
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/caps.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 619b616..d4fcdda 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -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)) {