aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-08-16 12:49:28 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2011-09-06 09:17:15 -0400
commit73f507171cfa407b19f254aef95cbb058c8180cf (patch)
tree18456029c1b723669232e1ed45895f9d65853927 /fs/9p
parentf88657ce3f9713a0c62101dffb0e972a979e77b9 (diff)
fs/9p: Always ask new inode in lookup for cache mode disabled
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>
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/vfs_inode.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 9e3ea6ce695..e3c03db3c78 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -825,6 +825,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
825struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, 825struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
826 struct nameidata *nameidata) 826 struct nameidata *nameidata)
827{ 827{
828 struct dentry *res;
828 struct super_block *sb; 829 struct super_block *sb;
829 struct v9fs_session_info *v9ses; 830 struct v9fs_session_info *v9ses;
830 struct p9_fid *dfid, *fid; 831 struct p9_fid *dfid, *fid;
@@ -856,22 +857,35 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
856 857
857 return ERR_PTR(result); 858 return ERR_PTR(result);
858 } 859 }
859 860 /*
860 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 861 * Make sure we don't use a wrong inode due to parallel
862 * unlink. For cached mode create calls request for new
863 * inode. But with cache disabled, lookup should do this.
864 */
865 if (v9ses->cache)
866 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
867 else
868 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
861 if (IS_ERR(inode)) { 869 if (IS_ERR(inode)) {
862 result = PTR_ERR(inode); 870 result = PTR_ERR(inode);
863 inode = NULL; 871 inode = NULL;
864 goto error; 872 goto error;
865 } 873 }
866
867 result = v9fs_fid_add(dentry, fid); 874 result = v9fs_fid_add(dentry, fid);
868 if (result < 0) 875 if (result < 0)
869 goto error_iput; 876 goto error_iput;
870
871inst_out: 877inst_out:
872 d_add(dentry, inode); 878 /*
873 return NULL; 879 * If we had a rename on the server and a parallel lookup
874 880 * for the new name, then make sure we instantiate with
881 * the new name. ie look up for a/b, while on server somebody
882 * moved b under k and client parallely did a lookup for
883 * k/b.
884 */
885 res = d_materialise_unique(dentry, inode);
886 if (!IS_ERR(res))
887 return res;
888 result = PTR_ERR(res);
875error_iput: 889error_iput:
876 iput(inode); 890 iput(inode);
877error: 891error: