diff options
| author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2011-07-25 14:06:32 -0400 |
|---|---|---|
| committer | Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com> | 2011-10-17 13:32:45 -0400 |
| commit | d62ddbc280aec00a08c3069f90302920c8ad3cea (patch) | |
| tree | 9929b92f4df57dbeb2225aa7ed504df9b3b93f26 /fs/9p | |
| parent | e1015aecefa7b7526be26a10806f1b233090ca6b (diff) | |
fs/9p: Add fid before dentry instantiation
BugLink: http://bugs.launchpad.net/bugs/868628
commit 5441ae5eb3614d3c28f77073370738a2820c88e4 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/9p')
| -rw-r--r-- | fs/9p/vfs_inode.c | 4 | ||||
| -rw-r--r-- | fs/9p/vfs_inode_dotl.c | 8 |
2 files changed, 5 insertions, 7 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 35d412187d0..ad7aae4b03d 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -633,13 +633,11 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
| 633 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | 633 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); |
| 634 | goto error; | 634 | goto error; |
| 635 | } | 635 | } |
| 636 | d_instantiate(dentry, inode); | ||
| 637 | err = v9fs_fid_add(dentry, fid); | 636 | err = v9fs_fid_add(dentry, fid); |
| 638 | if (err < 0) | 637 | if (err < 0) |
| 639 | goto error; | 638 | goto error; |
| 640 | 639 | d_instantiate(dentry, inode); | |
| 641 | return ofid; | 640 | return ofid; |
| 642 | |||
| 643 | error: | 641 | error: |
| 644 | if (ofid) | 642 | if (ofid) |
| 645 | p9_client_clunk(ofid); | 643 | p9_client_clunk(ofid); |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 185ce37ee3f..0a1723587fa 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
| @@ -281,10 +281,10 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, | |||
| 281 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); | 281 | P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); |
| 282 | goto error; | 282 | goto error; |
| 283 | } | 283 | } |
| 284 | d_instantiate(dentry, inode); | ||
| 285 | err = v9fs_fid_add(dentry, fid); | 284 | err = v9fs_fid_add(dentry, fid); |
| 286 | if (err < 0) | 285 | if (err < 0) |
| 287 | goto error; | 286 | goto error; |
| 287 | d_instantiate(dentry, inode); | ||
| 288 | 288 | ||
| 289 | /* Now set the ACL based on the default value */ | 289 | /* Now set the ACL based on the default value */ |
| 290 | v9fs_set_create_acl(dentry, &dacl, &pacl); | 290 | v9fs_set_create_acl(dentry, &dacl, &pacl); |
| @@ -403,10 +403,10 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir, | |||
| 403 | err); | 403 | err); |
| 404 | goto error; | 404 | goto error; |
| 405 | } | 405 | } |
| 406 | d_instantiate(dentry, inode); | ||
| 407 | err = v9fs_fid_add(dentry, fid); | 406 | err = v9fs_fid_add(dentry, fid); |
| 408 | if (err < 0) | 407 | if (err < 0) |
| 409 | goto error; | 408 | goto error; |
| 409 | d_instantiate(dentry, inode); | ||
| 410 | fid = NULL; | 410 | fid = NULL; |
| 411 | } else { | 411 | } else { |
| 412 | /* | 412 | /* |
| @@ -657,10 +657,10 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, | |||
| 657 | err); | 657 | err); |
| 658 | goto error; | 658 | goto error; |
| 659 | } | 659 | } |
| 660 | d_instantiate(dentry, inode); | ||
| 661 | err = v9fs_fid_add(dentry, fid); | 660 | err = v9fs_fid_add(dentry, fid); |
| 662 | if (err < 0) | 661 | if (err < 0) |
| 663 | goto error; | 662 | goto error; |
| 663 | d_instantiate(dentry, inode); | ||
| 664 | fid = NULL; | 664 | fid = NULL; |
| 665 | } else { | 665 | } else { |
| 666 | /* Not in cached mode. No need to populate inode with stat */ | 666 | /* 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, | |||
| 810 | err); | 810 | err); |
| 811 | goto error; | 811 | goto error; |
| 812 | } | 812 | } |
| 813 | d_instantiate(dentry, inode); | ||
| 814 | err = v9fs_fid_add(dentry, fid); | 813 | err = v9fs_fid_add(dentry, fid); |
| 815 | if (err < 0) | 814 | if (err < 0) |
| 816 | goto error; | 815 | goto error; |
| 816 | d_instantiate(dentry, inode); | ||
| 817 | fid = NULL; | 817 | fid = NULL; |
| 818 | } else { | 818 | } else { |
| 819 | /* | 819 | /* |
