瀏覽代碼

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>
Al Viro 13 年之前
父節點
當前提交
5e608671df
共有 1 個文件被更改,包括 17 次插入3 次删除
  1. 17 3
      fs/9p/fid.c

+ 17 - 3
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;