ceph: fix RCU case handling in ceph_d_revalidate()
For RCU case ->d_revalidate() is called with rcu_read_lock() and without pinning the dentry passed to it. Which means that it can't rely upon ->d_inode remaining stable; that's the reason for d_inode_rcu(), actually. Make sure we don't reload ->d_inode there. Cc: stable@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
ea60ed6fcf
commit
aa8dd81673
|
@ -1553,36 +1553,37 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
{
|
||||
int valid = 0;
|
||||
struct dentry *parent;
|
||||
struct inode *dir;
|
||||
struct inode *dir, *inode;
|
||||
|
||||
if (flags & LOOKUP_RCU) {
|
||||
parent = READ_ONCE(dentry->d_parent);
|
||||
dir = d_inode_rcu(parent);
|
||||
if (!dir)
|
||||
return -ECHILD;
|
||||
inode = d_inode_rcu(dentry);
|
||||
} else {
|
||||
parent = dget_parent(dentry);
|
||||
dir = d_inode(parent);
|
||||
inode = d_inode(dentry);
|
||||
}
|
||||
|
||||
dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry,
|
||||
dentry, d_inode(dentry), ceph_dentry(dentry)->offset);
|
||||
dentry, inode, ceph_dentry(dentry)->offset);
|
||||
|
||||
/* always trust cached snapped dentries, snapdir dentry */
|
||||
if (ceph_snap(dir) != CEPH_NOSNAP) {
|
||||
dout("d_revalidate %p '%pd' inode %p is SNAPPED\n", dentry,
|
||||
dentry, d_inode(dentry));
|
||||
dentry, inode);
|
||||
valid = 1;
|
||||
} else if (d_really_is_positive(dentry) &&
|
||||
ceph_snap(d_inode(dentry)) == CEPH_SNAPDIR) {
|
||||
} else if (inode && ceph_snap(inode) == CEPH_SNAPDIR) {
|
||||
valid = 1;
|
||||
} else {
|
||||
valid = dentry_lease_is_valid(dentry, flags);
|
||||
if (valid == -ECHILD)
|
||||
return valid;
|
||||
if (valid || dir_lease_is_valid(dir, dentry)) {
|
||||
if (d_really_is_positive(dentry))
|
||||
valid = ceph_is_any_caps(d_inode(dentry));
|
||||
if (inode)
|
||||
valid = ceph_is_any_caps(inode);
|
||||
else
|
||||
valid = 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue