summaryrefslogtreecommitdiff
path: root/fs/9p
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-02-28 06:50:20 (GMT)
committerAl Viro <viro@zeniv.linux.org.uk>2013-02-28 06:50:20 (GMT)
commit5e608671dfbfd6a9556c31df65a4f147439eed59 (patch)
treebb708c0bec27822d68defc54d8c79289b29d21fb /fs/9p
parenta3b2157e72e321fa313389ac744bbf6d6cb6986d (diff)
downloadlinux-fsl-qoriq-5e608671dfbfd6a9556c31df65a4f147439eed59.tar.xz
9p: if v9fs_fid_lookup() gets to asking server, it'd better have hashed dentry
... otherwise the path we'd built isn't worth much. Don't accept such fids obtained from paths unless dentry is still alived by the end of the work. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/fid.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 73ca550..616abaf 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -41,10 +41,15 @@
*
*/
+static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
+{
+ hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
+}
+
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
{
spin_lock(&dentry->d_lock);
- hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
+ __add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}
@@ -198,8 +203,17 @@ static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
}
kfree(wnames);
fid_out:
- if (!IS_ERR(fid))
- v9fs_fid_add(dentry, fid);
+ if (!IS_ERR(fid)) {
+ spin_lock(&dentry->d_lock);
+ if (d_unhashed(dentry)) {
+ spin_unlock(&dentry->d_lock);
+ p9_client_clunk(fid);
+ fid = ERR_PTR(-ENOENT);
+ } else {
+ __add_fid(dentry, fid);
+ spin_unlock(&dentry->d_lock);
+ }
+ }
err_out:
up_read(&v9ses->rename_sem);
return fid;