ceph: check inode caps in ceph_d_revalidate

Some inodes in readdir reply may have no caps. Getattr mds request
for these inodes can return -ESTALE. The fix is consider dentry that
links to inode with no caps as invalid. Invalid dentry causes a
lookup request to send to the mds, the MDS will send caps back.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
This commit is contained in:
Yan, Zheng 2013-11-30 12:47:41 +08:00
parent ca18bede04
commit 9215aeea62
3 changed files with 21 additions and 3 deletions

View File

@ -891,6 +891,18 @@ static int __ceph_is_any_caps(struct ceph_inode_info *ci)
return !RB_EMPTY_ROOT(&ci->i_caps) || ci->i_cap_exporting_mds >= 0;
}
int ceph_is_any_caps(struct inode *inode)
{
struct ceph_inode_info *ci = ceph_inode(inode);
int ret;
spin_lock(&ci->i_ceph_lock);
ret = __ceph_is_any_caps(ci);
spin_unlock(&ci->i_ceph_lock);
return ret;
}
/*
* Remove a cap. Take steps to deal with a racing iterate_session_caps.
*

View File

@ -1041,14 +1041,19 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
valid = 1;
} else if (dentry_lease_is_valid(dentry) ||
dir_lease_is_valid(dir, dentry)) {
valid = 1;
if (dentry->d_inode)
valid = ceph_is_any_caps(dentry->d_inode);
else
valid = 1;
}
dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid");
if (valid)
if (valid) {
ceph_dentry_lru_touch(dentry);
else
} else {
ceph_dir_clear_complete(dir);
d_drop(dentry);
}
iput(dir);
return valid;
}

View File

@ -782,6 +782,7 @@ extern int ceph_add_cap(struct inode *inode,
extern void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release);
extern void ceph_put_cap(struct ceph_mds_client *mdsc,
struct ceph_cap *cap);
extern int ceph_is_any_caps(struct inode *inode);
extern void __queue_cap_release(struct ceph_mds_session *session, u64 ino,
u64 cap_id, u32 migrate_seq, u32 issue_seq);