diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2011-07-06 16:32:31 +0530 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2011-07-23 09:32:50 -0500 |
commit | ed80fcfac2565fa866d93ba14f0e75de17a8223e (patch) | |
tree | 504a4efb5377bc5d8e9ff3a8eb45bb2b00303b93 /fs/9p/vfs_inode.c | |
parent | 4d63055fa9657aa402da25575045c23f37c3da05 (diff) |
fs/9p: Always ask new inode in create
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>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r-- | fs/9p/vfs_inode.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 3d8a18ee78e..3bbf705634b 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -454,6 +454,11 @@ static int v9fs_test_inode(struct inode *inode, void *data) return 1; } +static int v9fs_test_new_inode(struct inode *inode, void *data) +{ + return 0; +} + static int v9fs_set_inode(struct inode *inode, void *data) { struct v9fs_inode *v9inode = V9FS_I(inode); @@ -465,15 +470,22 @@ static int v9fs_set_inode(struct inode *inode, void *data) static struct inode *v9fs_qid_iget(struct super_block *sb, struct p9_qid *qid, - struct p9_wstat *st) + struct p9_wstat *st, + int new) { int retval, umode; unsigned long i_ino; struct inode *inode; struct v9fs_session_info *v9ses = sb->s_fs_info; + int (*test)(struct inode *, void *); + + if (new) + test = v9fs_test_new_inode; + else + test = v9fs_test_inode; i_ino = v9fs_qid2ino(qid); - inode = iget5_locked(sb, i_ino, v9fs_test_inode, v9fs_set_inode, st); + inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st); if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) @@ -504,7 +516,7 @@ error: struct inode * v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, - struct super_block *sb) + struct super_block *sb, int new) { struct p9_wstat *st; struct inode *inode = NULL; @@ -513,7 +525,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, if (IS_ERR(st)) return ERR_CAST(st); - inode = v9fs_qid_iget(sb, &st->qid, st); + inode = v9fs_qid_iget(sb, &st->qid, st, new); p9stat_free(st); kfree(st); return inode; @@ -615,7 +627,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, } /* instantiate inode and assign the unopened fid to the dentry */ - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); if (IS_ERR(inode)) { err = PTR_ERR(inode); P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); |