Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Aneesh Kumar K.V and committed by
Eric Van Hensbergen
ed80fcfa 4d63055f

+61 -18
+23 -4
fs/9p/v9fs.h
··· 153 153 void *p); 154 154 extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, 155 155 struct p9_fid *fid, 156 - struct super_block *sb); 156 + struct super_block *sb, int new); 157 157 extern const struct inode_operations v9fs_dir_inode_operations_dotl; 158 158 extern const struct inode_operations v9fs_file_inode_operations_dotl; 159 159 extern const struct inode_operations v9fs_symlink_inode_operations_dotl; 160 160 extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, 161 161 struct p9_fid *fid, 162 - struct super_block *sb); 162 + struct super_block *sb, int new); 163 163 164 164 /* other default globals */ 165 165 #define V9FS_PORT 564 ··· 201 201 struct super_block *sb) 202 202 { 203 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 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 227 #endif
+17 -5
fs/9p/vfs_inode.c
··· 454 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 462 static int v9fs_set_inode(struct inode *inode, void *data) 458 463 { 459 464 struct v9fs_inode *v9inode = V9FS_I(inode); ··· 470 465 471 466 static struct inode *v9fs_qid_iget(struct super_block *sb, 472 467 struct p9_qid *qid, 473 - struct p9_wstat *st) 468 + struct p9_wstat *st, 469 + int new) 474 470 { 475 471 int retval, umode; 476 472 unsigned long i_ino; 477 473 struct inode *inode; 478 474 struct v9fs_session_info *v9ses = sb->s_fs_info; 475 + int (*test)(struct inode *, void *); 476 + 477 + if (new) 478 + test = v9fs_test_new_inode; 479 + else 480 + test = v9fs_test_inode; 479 481 480 482 i_ino = v9fs_qid2ino(qid); 481 - inode = iget5_locked(sb, i_ino, v9fs_test_inode, v9fs_set_inode, st); 483 + inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st); 482 484 if (!inode) 483 485 return ERR_PTR(-ENOMEM); 484 486 if (!(inode->i_state & I_NEW)) ··· 516 504 517 505 struct inode * 518 506 v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, 519 - struct super_block *sb) 507 + struct super_block *sb, int new) 520 508 { 521 509 struct p9_wstat *st; 522 510 struct inode *inode = NULL; ··· 525 513 if (IS_ERR(st)) 526 514 return ERR_CAST(st); 527 515 528 - inode = v9fs_qid_iget(sb, &st->qid, st); 516 + inode = v9fs_qid_iget(sb, &st->qid, st, new); 529 517 p9stat_free(st); 530 518 kfree(st); 531 519 return inode; ··· 627 615 } 628 616 629 617 /* instantiate inode and assign the unopened fid to the dentry */ 630 - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 618 + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 631 619 if (IS_ERR(inode)) { 632 620 err = PTR_ERR(inode); 633 621 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
+21 -9
fs/9p/vfs_inode_dotl.c
··· 108 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 117 static int v9fs_set_inode_dotl(struct inode *inode, void *data) 112 118 { 113 119 struct v9fs_inode *v9inode = V9FS_I(inode); ··· 127 121 static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, 128 122 struct p9_qid *qid, 129 123 struct p9_fid *fid, 130 - struct p9_stat_dotl *st) 124 + struct p9_stat_dotl *st, 125 + int new) 131 126 { 132 127 int retval; 133 128 unsigned long i_ino; 134 129 struct inode *inode; 135 130 struct v9fs_session_info *v9ses = sb->s_fs_info; 131 + int (*test)(struct inode *, void *); 132 + 133 + if (new) 134 + test = v9fs_test_new_inode_dotl; 135 + else 136 + test = v9fs_test_inode_dotl; 136 137 137 138 i_ino = v9fs_qid2ino(qid); 138 - inode = iget5_locked(sb, i_ino, v9fs_test_inode_dotl, 139 - v9fs_set_inode_dotl, st); 139 + inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st); 140 140 if (!inode) 141 141 return ERR_PTR(-ENOMEM); 142 142 if (!(inode->i_state & I_NEW)) ··· 176 164 177 165 struct inode * 178 166 v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 179 - struct super_block *sb) 167 + struct super_block *sb, int new) 180 168 { 181 169 struct p9_stat_dotl *st; 182 170 struct inode *inode = NULL; ··· 185 173 if (IS_ERR(st)) 186 174 return ERR_CAST(st); 187 175 188 - inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st); 176 + inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new); 189 177 kfree(st); 190 178 return inode; 191 179 } ··· 275 263 fid = NULL; 276 264 goto error; 277 265 } 278 - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 266 + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 279 267 if (IS_ERR(inode)) { 280 268 err = PTR_ERR(inode); 281 269 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err); ··· 395 383 goto error; 396 384 } 397 385 398 - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 386 + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 399 387 if (IS_ERR(inode)) { 400 388 err = PTR_ERR(inode); 401 389 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", ··· 648 636 } 649 637 650 638 /* instantiate inode and assign the unopened fid to dentry */ 651 - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 639 + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 652 640 if (IS_ERR(inode)) { 653 641 err = PTR_ERR(inode); 654 642 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", ··· 801 789 goto error; 802 790 } 803 791 804 - inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); 792 + inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 805 793 if (IS_ERR(inode)) { 806 794 err = PTR_ERR(inode); 807 795 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",