ceph: only release unused caps with mds requests
We were releasing used caps (e.g. FILE_CACHE) from encode_inode_release with MDS requests (e.g. setattr). We don't carry refs on most caps, so this code worked most of the time, but for setattr (utimes) we try to drop Fscr. This causes cap state to get slightly out of sync with reality, and may result in subsequent mds revoke messages getting ignored. Fix by only releasing unused caps. Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
parent
15637c8b12
commit
916623da10
@ -2836,11 +2836,18 @@ int ceph_encode_inode_release(void **p, struct inode *inode,
|
||||
struct ceph_cap *cap;
|
||||
struct ceph_mds_request_release *rel = *p;
|
||||
int ret = 0;
|
||||
|
||||
dout("encode_inode_release %p mds%d drop %s unless %s\n", inode,
|
||||
mds, ceph_cap_string(drop), ceph_cap_string(unless));
|
||||
int used = 0;
|
||||
|
||||
spin_lock(&inode->i_lock);
|
||||
used = __ceph_caps_used(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),
|
||||
ceph_cap_string(unless));
|
||||
|
||||
/* only drop unused caps */
|
||||
drop &= ~used;
|
||||
|
||||
cap = __get_cap_for_mds(ci, mds);
|
||||
if (cap && __cap_is_valid(cap)) {
|
||||
if (force ||
|
||||
|
Loading…
Reference in New Issue
Block a user