aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode_dotl.c
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-07-06 07:02:31 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2011-07-23 10:32:50 -0400
commited80fcfac2565fa866d93ba14f0e75de17a8223e (patch)
tree504a4efb5377bc5d8e9ff3a8eb45bb2b00303b93 /fs/9p/vfs_inode_dotl.c
parent4d63055fa9657aa402da25575045c23f37c3da05 (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_dotl.c')
-rw-r--r--fs/9p/vfs_inode_dotl.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index dc9e7de38202..276f4a69ecd4 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -108,6 +108,12 @@ static int v9fs_test_inode_dotl(struct inode *inode, void *data)
108 return 1; 108 return 1;
109} 109}
110 110
111/* Always get a new inode */
112static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
113{
114 return 0;
115}
116
111static int v9fs_set_inode_dotl(struct inode *inode, void *data) 117static int v9fs_set_inode_dotl(struct inode *inode, void *data)
112{ 118{
113 struct v9fs_inode *v9inode = V9FS_I(inode); 119 struct v9fs_inode *v9inode = V9FS_I(inode);
@@ -121,16 +127,22 @@ static int v9fs_set_inode_dotl(struct inode *inode, void *data)
121static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, 127static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
122 struct p9_qid *qid, 128 struct p9_qid *qid,
123 struct p9_fid *fid, 129 struct p9_fid *fid,
124 struct p9_stat_dotl *st) 130 struct p9_stat_dotl *st,
131 int new)
125{ 132{
126 int retval; 133 int retval;
127 unsigned long i_ino; 134 unsigned long i_ino;
128 struct inode *inode; 135 struct inode *inode;
129 struct v9fs_session_info *v9ses = sb->s_fs_info; 136 struct v9fs_session_info *v9ses = sb->s_fs_info;
137 int (*test)(struct inode *, void *);
138
139 if (new)
140 test = v9fs_test_new_inode_dotl;
141 else
142 test = v9fs_test_inode_dotl;
130 143
131 i_ino = v9fs_qid2ino(qid); 144 i_ino = v9fs_qid2ino(qid);
132 inode = iget5_locked(sb, i_ino, v9fs_test_inode_dotl, 145 inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
133 v9fs_set_inode_dotl, st);
134 if (!inode) 146 if (!inode)
135 return ERR_PTR(-ENOMEM); 147 return ERR_PTR(-ENOMEM);
136 if (!(inode->i_state & I_NEW)) 148 if (!(inode->i_state & I_NEW))
@@ -164,7 +176,7 @@ error:
164 176
165struct inode * 177struct inode *
166v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 178v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
167 struct super_block *sb) 179 struct super_block *sb, int new)
168{ 180{
169 struct p9_stat_dotl *st; 181 struct p9_stat_dotl *st;
170 struct inode *inode = NULL; 182 struct inode *inode = NULL;
@@ -173,7 +185,7 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
173 if (IS_ERR(st)) 185 if (IS_ERR(st))
174 return ERR_CAST(st); 186 return ERR_CAST(st);
175 187
176 inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st); 188 inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
177 kfree(st); 189 kfree(st);
178 return inode; 190 return inode;
179} 191}
@@ -263,7 +275,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
263 fid = NULL; 275 fid = NULL;
264 goto error; 276 goto error;
265 } 277 }
266 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 278 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
267 if (IS_ERR(inode)) { 279 if (IS_ERR(inode)) {
268 err = PTR_ERR(inode); 280 err = PTR_ERR(inode);
269 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 281 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -383,7 +395,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
383 goto error; 395 goto error;
384 } 396 }
385 397
386 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 398 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
387 if (IS_ERR(inode)) { 399 if (IS_ERR(inode)) {
388 err = PTR_ERR(inode); 400 err = PTR_ERR(inode);
389 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 401 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -636,7 +648,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
636 } 648 }
637 649
638 /* instantiate inode and assign the unopened fid to dentry */ 650 /* instantiate inode and assign the unopened fid to dentry */
639 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 651 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
640 if (IS_ERR(inode)) { 652 if (IS_ERR(inode)) {
641 err = PTR_ERR(inode); 653 err = PTR_ERR(inode);
642 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 654 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -789,7 +801,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
789 goto error; 801 goto error;
790 } 802 }
791 803
792 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 804 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
793 if (IS_ERR(inode)) { 805 if (IS_ERR(inode)) {
794 err = PTR_ERR(inode); 806 err = PTR_ERR(inode);
795 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", 807 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",