fs/9p: Always ask new inode in lookup for cache mode disabled
commit 73f507171cfa407b19f254aef95cbb058c8180cf upstream. This make sure we don't end up reusing the unlinked inode object. The ideal way is to use inode i_generation. But i_generation is not available in userspace always. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8926487ad8
commit
8bdb14f9c3
@@ -799,6 +799,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||||||
struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
struct nameidata *nameidata)
|
struct nameidata *nameidata)
|
||||||
{
|
{
|
||||||
|
struct dentry *res;
|
||||||
struct super_block *sb;
|
struct super_block *sb;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *dfid, *fid;
|
struct p9_fid *dfid, *fid;
|
||||||
@@ -830,22 +831,35 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
|||||||
|
|
||||||
return ERR_PTR(result);
|
return ERR_PTR(result);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* Make sure we don't use a wrong inode due to parallel
|
||||||
|
* unlink. For cached mode create calls request for new
|
||||||
|
* inode. But with cache disabled, lookup should do this.
|
||||||
|
*/
|
||||||
|
if (v9ses->cache)
|
||||||
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||||
|
else
|
||||||
|
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
result = PTR_ERR(inode);
|
result = PTR_ERR(inode);
|
||||||
inode = NULL;
|
inode = NULL;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = v9fs_fid_add(dentry, fid);
|
result = v9fs_fid_add(dentry, fid);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto error_iput;
|
goto error_iput;
|
||||||
|
|
||||||
inst_out:
|
inst_out:
|
||||||
d_add(dentry, inode);
|
/*
|
||||||
return NULL;
|
* If we had a rename on the server and a parallel lookup
|
||||||
|
* for the new name, then make sure we instantiate with
|
||||||
|
* the new name. ie look up for a/b, while on server somebody
|
||||||
|
* moved b under k and client parallely did a lookup for
|
||||||
|
* k/b.
|
||||||
|
*/
|
||||||
|
res = d_materialise_unique(dentry, inode);
|
||||||
|
if (!IS_ERR(res))
|
||||||
|
return res;
|
||||||
|
result = PTR_ERR(res);
|
||||||
error_iput:
|
error_iput:
|
||||||
iput(inode);
|
iput(inode);
|
||||||
error:
|
error:
|
||||||
|
|||||||
Reference in New Issue
Block a user