diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2011-07-06 07:02:31 -0400 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2011-07-23 10:32:50 -0400 |
commit | ed80fcfac2565fa866d93ba14f0e75de17a8223e (patch) | |
tree | 504a4efb5377bc5d8e9ff3a8eb45bb2b00303b93 /fs | |
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')
-rw-r--r-- | fs/9p/v9fs.h | 27 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 22 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 30 |
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); |
154 | extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, | 154 | extern 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); |
157 | extern const struct inode_operations v9fs_dir_inode_operations_dotl; | 157 | extern const struct inode_operations v9fs_dir_inode_operations_dotl; |
158 | extern const struct inode_operations v9fs_file_inode_operations_dotl; | 158 | extern const struct inode_operations v9fs_file_inode_operations_dotl; |
159 | extern const struct inode_operations v9fs_symlink_inode_operations_dotl; | 159 | extern const struct inode_operations v9fs_symlink_inode_operations_dotl; |
160 | extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, | 160 | extern 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 | */ | ||
217 | static inline struct inode * | ||
218 | v9fs_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 | ||
457 | static int v9fs_test_new_inode(struct inode *inode, void *data) | ||
458 | { | ||
459 | return 0; | ||
460 | } | ||
461 | |||
457 | static int v9fs_set_inode(struct inode *inode, void *data) | 462 | static 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 | ||
466 | static struct inode *v9fs_qid_iget(struct super_block *sb, | 471 | static 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 | ||
505 | struct inode * | 517 | struct inode * |
506 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 518 | v9fs_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 */ | ||
112 | static int v9fs_test_new_inode_dotl(struct inode *inode, void *data) | ||
113 | { | ||
114 | return 0; | ||
115 | } | ||
116 | |||
111 | static int v9fs_set_inode_dotl(struct inode *inode, void *data) | 117 | static 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) | |||
121 | static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, | 127 | static 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 | ||
165 | struct inode * | 177 | struct inode * |
166 | v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, | 178 | v9fs_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", |