aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/9p/v9fs.h27
-rw-r--r--fs/9p/vfs_inode.c22
-rw-r--r--fs/9p/vfs_inode_dotl.c30
3 files changed, 61 insertions, 18 deletions
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index 5d7392ead24b..e78956cbd702 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -153,13 +153,13 @@ extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
153 void *p); 153 void *p);
154extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, 154extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
155 struct p9_fid *fid, 155 struct p9_fid *fid,
156 struct super_block *sb); 156 struct super_block *sb, int new);
157extern const struct inode_operations v9fs_dir_inode_operations_dotl; 157extern const struct inode_operations v9fs_dir_inode_operations_dotl;
158extern const struct inode_operations v9fs_file_inode_operations_dotl; 158extern const struct inode_operations v9fs_file_inode_operations_dotl;
159extern const struct inode_operations v9fs_symlink_inode_operations_dotl; 159extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
160extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, 160extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
161 struct p9_fid *fid, 161 struct p9_fid *fid,
162 struct super_block *sb); 162 struct super_block *sb, int new);
163 163
164/* other default globals */ 164/* other default globals */
165#define V9FS_PORT 564 165#define V9FS_PORT 564
@@ -201,8 +201,27 @@ v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
201 struct super_block *sb) 201 struct super_block *sb)
202{ 202{
203 if (v9fs_proto_dotl(v9ses)) 203 if (v9fs_proto_dotl(v9ses))
204 return v9fs_inode_from_fid_dotl(v9ses, fid, sb); 204 return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
205 else 205 else
206 return v9fs_inode_from_fid(v9ses, fid, sb); 206 return v9fs_inode_from_fid(v9ses, fid, sb, 0);
207} 207}
208
209/**
210 * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
211 * issuing a attribute request
212 * @v9ses: session information
213 * @fid: fid to issue attribute request for
214 * @sb: superblock on which to create inode
215 *
216 */
217static inline struct inode *
218v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
219 struct super_block *sb)
220{
221 if (v9fs_proto_dotl(v9ses))
222 return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
223 else
224 return v9fs_inode_from_fid(v9ses, fid, sb, 1);
225}
226
208#endif 227#endif
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 3d8a18ee78e6..3bbf705634b2 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)
454 return 1; 454 return 1;
455} 455}
456 456
457static int v9fs_test_new_inode(struct inode *inode, void *data)
458{
459 return 0;
460}
461
457static int v9fs_set_inode(struct inode *inode, void *data) 462static int v9fs_set_inode(struct inode *inode, void *data)
458{ 463{
459 struct v9fs_inode *v9inode = V9FS_I(inode); 464 struct v9fs_inode *v9inode = V9FS_I(inode);
@@ -465,15 +470,22 @@ static int v9fs_set_inode(struct inode *inode, void *data)
465 470
466static struct inode *v9fs_qid_iget(struct super_block *sb, 471static struct inode *v9fs_qid_iget(struct super_block *sb,
467 struct p9_qid *qid, 472 struct p9_qid *qid,
468 struct p9_wstat *st) 473 struct p9_wstat *st,
474 int new)
469{ 475{
470 int retval, umode; 476 int retval, umode;
471 unsigned long i_ino; 477 unsigned long i_ino;
472 struct inode *inode; 478 struct inode *inode;
473 struct v9fs_session_info *v9ses = sb->s_fs_info; 479 struct v9fs_session_info *v9ses = sb->s_fs_info;
480 int (*test)(struct inode *, void *);
481
482 if (new)
483 test = v9fs_test_new_inode;
484 else
485 test = v9fs_test_inode;
474 486
475 i_ino = v9fs_qid2ino(qid); 487 i_ino = v9fs_qid2ino(qid);
476 inode = iget5_locked(sb, i_ino, v9fs_test_inode, v9fs_set_inode, st); 488 inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
477 if (!inode) 489 if (!inode)
478 return ERR_PTR(-ENOMEM); 490 return ERR_PTR(-ENOMEM);
479 if (!(inode->i_state & I_NEW)) 491 if (!(inode->i_state & I_NEW))
@@ -504,7 +516,7 @@ error:
504 516
505struct inode * 517struct inode *
506v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 518v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
507 struct super_block *sb) 519 struct super_block *sb, int new)
508{ 520{
509 struct p9_wstat *st; 521 struct p9_wstat *st;
510 struct inode *inode = NULL; 522 struct inode *inode = NULL;
@@ -513,7 +525,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
513 if (IS_ERR(st)) 525 if (IS_ERR(st))
514 return ERR_CAST(st); 526 return ERR_CAST(st);
515 527
516 inode = v9fs_qid_iget(sb, &st->qid, st); 528 inode = v9fs_qid_iget(sb, &st->qid, st, new);
517 p9stat_free(st); 529 p9stat_free(st);
518 kfree(st); 530 kfree(st);
519 return inode; 531 return inode;
@@ -615,7 +627,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
615 } 627 }
616 628
617 /* instantiate inode and assign the unopened fid to the dentry */ 629 /* instantiate inode and assign the unopened fid to the dentry */
618 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 630 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
619 if (IS_ERR(inode)) { 631 if (IS_ERR(inode)) {
620 err = PTR_ERR(inode); 632 err = PTR_ERR(inode);
621 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); 633 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
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",