Browse Source

fs/9p: Add fid before dentry instantiation

d_instantiate marks the dentry positive. So a parallel lookup and mkdir of
the directory can find dentry that doesn't have fid attached. This can result
in both the code path doing v9fs_fid_add which results in v9fs_dentry leak.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Aneesh Kumar K.V 14 years ago
parent
commit
5441ae5eb3
2 changed files with 5 additions and 7 deletions
  1. 1 3
      fs/9p/vfs_inode.c
  2. 4 4
      fs/9p/vfs_inode_dotl.c

+ 1 - 3
fs/9p/vfs_inode.c

@@ -645,13 +645,11 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
 		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 		goto error;
 		goto error;
 	}
 	}
-	d_instantiate(dentry, inode);
 	err = v9fs_fid_add(dentry, fid);
 	err = v9fs_fid_add(dentry, fid);
 	if (err < 0)
 	if (err < 0)
 		goto error;
 		goto error;
-
+	d_instantiate(dentry, inode);
 	return ofid;
 	return ofid;
-
 error:
 error:
 	if (ofid)
 	if (ofid)
 		p9_client_clunk(ofid);
 		p9_client_clunk(ofid);

+ 4 - 4
fs/9p/vfs_inode_dotl.c

@@ -281,10 +281,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
 		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 		goto error;
 		goto error;
 	}
 	}
-	d_instantiate(dentry, inode);
 	err = v9fs_fid_add(dentry, fid);
 	err = v9fs_fid_add(dentry, fid);
 	if (err < 0)
 	if (err < 0)
 		goto error;
 		goto error;
+	d_instantiate(dentry, inode);
 
 
 	/* Now set the ACL based on the default value */
 	/* Now set the ACL based on the default value */
 	v9fs_set_create_acl(dentry, &dacl, &pacl);
 	v9fs_set_create_acl(dentry, &dacl, &pacl);
@@ -403,10 +403,10 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
 				err);
 				err);
 			goto error;
 			goto error;
 		}
 		}
-		d_instantiate(dentry, inode);
 		err = v9fs_fid_add(dentry, fid);
 		err = v9fs_fid_add(dentry, fid);
 		if (err < 0)
 		if (err < 0)
 			goto error;
 			goto error;
+		d_instantiate(dentry, inode);
 		fid = NULL;
 		fid = NULL;
 	} else {
 	} else {
 		/*
 		/*
@@ -657,10 +657,10 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
 					err);
 					err);
 			goto error;
 			goto error;
 		}
 		}
-		d_instantiate(dentry, inode);
 		err = v9fs_fid_add(dentry, fid);
 		err = v9fs_fid_add(dentry, fid);
 		if (err < 0)
 		if (err < 0)
 			goto error;
 			goto error;
+		d_instantiate(dentry, inode);
 		fid = NULL;
 		fid = NULL;
 	} else {
 	} else {
 		/* Not in cached mode. No need to populate inode with stat */
 		/* Not in cached mode. No need to populate inode with stat */
@@ -810,10 +810,10 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
 				err);
 				err);
 			goto error;
 			goto error;
 		}
 		}
-		d_instantiate(dentry, inode);
 		err = v9fs_fid_add(dentry, fid);
 		err = v9fs_fid_add(dentry, fid);
 		if (err < 0)
 		if (err < 0)
 			goto error;
 			goto error;
+		d_instantiate(dentry, inode);
 		fid = NULL;
 		fid = NULL;
 	} else {
 	} else {
 		/*
 		/*