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

btrfs: switch to discard_new_inode()

Make sure that no partially set up inodes can be returned by
open-by-handle.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 32955c54 c2b6d621

+39 -67
+39 -67
fs/btrfs/inode.c
··· 6335 6335 location->type = BTRFS_INODE_ITEM_KEY; 6336 6336 6337 6337 ret = btrfs_insert_inode_locked(inode); 6338 - if (ret < 0) 6338 + if (ret < 0) { 6339 + iput(inode); 6339 6340 goto fail; 6341 + } 6340 6342 6341 6343 path->leave_spinning = 1; 6342 6344 ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems); ··· 6397 6395 return inode; 6398 6396 6399 6397 fail_unlock: 6400 - unlock_new_inode(inode); 6398 + discard_new_inode(inode); 6401 6399 fail: 6402 6400 if (dir && name) 6403 6401 BTRFS_I(dir)->index_cnt--; 6404 6402 btrfs_free_path(path); 6405 - iput(inode); 6406 6403 return ERR_PTR(ret); 6407 6404 } 6408 6405 ··· 6506 6505 struct btrfs_root *root = BTRFS_I(dir)->root; 6507 6506 struct inode *inode = NULL; 6508 6507 int err; 6509 - int drop_inode = 0; 6510 6508 u64 objectid; 6511 6509 u64 index = 0; 6512 6510 ··· 6527 6527 mode, &index); 6528 6528 if (IS_ERR(inode)) { 6529 6529 err = PTR_ERR(inode); 6530 + inode = NULL; 6530 6531 goto out_unlock; 6531 6532 } 6532 6533 ··· 6542 6541 6543 6542 err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); 6544 6543 if (err) 6545 - goto out_unlock_inode; 6544 + goto out_unlock; 6546 6545 6547 6546 err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), 6548 6547 0, index); 6549 - if (err) { 6550 - goto out_unlock_inode; 6551 - } else { 6552 - btrfs_update_inode(trans, root, inode); 6553 - d_instantiate_new(dentry, inode); 6554 - } 6548 + if (err) 6549 + goto out_unlock; 6550 + 6551 + btrfs_update_inode(trans, root, inode); 6552 + d_instantiate_new(dentry, inode); 6555 6553 6556 6554 out_unlock: 6557 6555 btrfs_end_transaction(trans); 6558 6556 btrfs_btree_balance_dirty(fs_info); 6559 - if (drop_inode) { 6557 + if (err && inode) { 6560 6558 inode_dec_link_count(inode); 6561 - iput(inode); 6559 + discard_new_inode(inode); 6562 6560 } 6563 6561 return err; 6564 - 6565 - out_unlock_inode: 6566 - drop_inode = 1; 6567 - unlock_new_inode(inode); 6568 - goto out_unlock; 6569 - 6570 6562 } 6571 6563 6572 6564 static int btrfs_create(struct inode *dir, struct dentry *dentry, ··· 6569 6575 struct btrfs_trans_handle *trans; 6570 6576 struct btrfs_root *root = BTRFS_I(dir)->root; 6571 6577 struct inode *inode = NULL; 6572 - int drop_inode_on_err = 0; 6573 6578 int err; 6574 6579 u64 objectid; 6575 6580 u64 index = 0; ··· 6591 6598 mode, &index); 6592 6599 if (IS_ERR(inode)) { 6593 6600 err = PTR_ERR(inode); 6601 + inode = NULL; 6594 6602 goto out_unlock; 6595 6603 } 6596 - drop_inode_on_err = 1; 6597 6604 /* 6598 6605 * If the active LSM wants to access the inode during 6599 6606 * d_instantiate it needs these. Smack checks to see ··· 6606 6613 6607 6614 err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); 6608 6615 if (err) 6609 - goto out_unlock_inode; 6616 + goto out_unlock; 6610 6617 6611 6618 err = btrfs_update_inode(trans, root, inode); 6612 6619 if (err) 6613 - goto out_unlock_inode; 6620 + goto out_unlock; 6614 6621 6615 6622 err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), 6616 6623 0, index); 6617 6624 if (err) 6618 - goto out_unlock_inode; 6625 + goto out_unlock; 6619 6626 6620 6627 BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; 6621 6628 d_instantiate_new(dentry, inode); 6622 6629 6623 6630 out_unlock: 6624 6631 btrfs_end_transaction(trans); 6625 - if (err && drop_inode_on_err) { 6632 + if (err && inode) { 6626 6633 inode_dec_link_count(inode); 6627 - iput(inode); 6634 + discard_new_inode(inode); 6628 6635 } 6629 6636 btrfs_btree_balance_dirty(fs_info); 6630 6637 return err; 6631 - 6632 - out_unlock_inode: 6633 - unlock_new_inode(inode); 6634 - goto out_unlock; 6635 - 6636 6638 } 6637 6639 6638 6640 static int btrfs_link(struct dentry *old_dentry, struct inode *dir, ··· 6736 6748 S_IFDIR | mode, &index); 6737 6749 if (IS_ERR(inode)) { 6738 6750 err = PTR_ERR(inode); 6751 + inode = NULL; 6739 6752 goto out_fail; 6740 6753 } 6741 6754 ··· 6747 6758 6748 6759 err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); 6749 6760 if (err) 6750 - goto out_fail_inode; 6761 + goto out_fail; 6751 6762 6752 6763 btrfs_i_size_write(BTRFS_I(inode), 0); 6753 6764 err = btrfs_update_inode(trans, root, inode); 6754 6765 if (err) 6755 - goto out_fail_inode; 6766 + goto out_fail; 6756 6767 6757 6768 err = btrfs_add_link(trans, BTRFS_I(dir), BTRFS_I(inode), 6758 6769 dentry->d_name.name, 6759 6770 dentry->d_name.len, 0, index); 6760 6771 if (err) 6761 - goto out_fail_inode; 6772 + goto out_fail; 6762 6773 6763 6774 d_instantiate_new(dentry, inode); 6764 6775 drop_on_err = 0; 6765 6776 6766 6777 out_fail: 6767 6778 btrfs_end_transaction(trans); 6768 - if (drop_on_err) { 6779 + if (err && inode) { 6769 6780 inode_dec_link_count(inode); 6770 - iput(inode); 6781 + discard_new_inode(inode); 6771 6782 } 6772 6783 btrfs_btree_balance_dirty(fs_info); 6773 6784 return err; 6774 - 6775 - out_fail_inode: 6776 - unlock_new_inode(inode); 6777 - goto out_fail; 6778 6785 } 6779 6786 6780 6787 static noinline int uncompress_inline(struct btrfs_path *path, ··· 10097 10112 struct btrfs_key key; 10098 10113 struct inode *inode = NULL; 10099 10114 int err; 10100 - int drop_inode = 0; 10101 10115 u64 objectid; 10102 10116 u64 index = 0; 10103 10117 int name_len; ··· 10129 10145 objectid, S_IFLNK|S_IRWXUGO, &index); 10130 10146 if (IS_ERR(inode)) { 10131 10147 err = PTR_ERR(inode); 10148 + inode = NULL; 10132 10149 goto out_unlock; 10133 10150 } 10134 10151 ··· 10146 10161 10147 10162 err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); 10148 10163 if (err) 10149 - goto out_unlock_inode; 10164 + goto out_unlock; 10150 10165 10151 10166 path = btrfs_alloc_path(); 10152 10167 if (!path) { 10153 10168 err = -ENOMEM; 10154 - goto out_unlock_inode; 10169 + goto out_unlock; 10155 10170 } 10156 10171 key.objectid = btrfs_ino(BTRFS_I(inode)); 10157 10172 key.offset = 0; ··· 10161 10176 datasize); 10162 10177 if (err) { 10163 10178 btrfs_free_path(path); 10164 - goto out_unlock_inode; 10179 + goto out_unlock; 10165 10180 } 10166 10181 leaf = path->nodes[0]; 10167 10182 ei = btrfs_item_ptr(leaf, path->slots[0], ··· 10193 10208 if (!err) 10194 10209 err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, 10195 10210 BTRFS_I(inode), 0, index); 10196 - if (err) { 10197 - drop_inode = 1; 10198 - goto out_unlock_inode; 10199 - } 10211 + if (err) 10212 + goto out_unlock; 10200 10213 10201 10214 d_instantiate_new(dentry, inode); 10202 10215 10203 10216 out_unlock: 10204 10217 btrfs_end_transaction(trans); 10205 - if (drop_inode) { 10218 + if (err && inode) { 10206 10219 inode_dec_link_count(inode); 10207 - iput(inode); 10220 + discard_new_inode(inode); 10208 10221 } 10209 10222 btrfs_btree_balance_dirty(fs_info); 10210 10223 return err; 10211 - 10212 - out_unlock_inode: 10213 - drop_inode = 1; 10214 - unlock_new_inode(inode); 10215 - goto out_unlock; 10216 10224 } 10217 10225 10218 10226 static int __btrfs_prealloc_file_range(struct inode *inode, int mode, ··· 10414 10436 10415 10437 ret = btrfs_init_inode_security(trans, inode, dir, NULL); 10416 10438 if (ret) 10417 - goto out_inode; 10439 + goto out; 10418 10440 10419 10441 ret = btrfs_update_inode(trans, root, inode); 10420 10442 if (ret) 10421 - goto out_inode; 10443 + goto out; 10422 10444 ret = btrfs_orphan_add(trans, BTRFS_I(inode)); 10423 10445 if (ret) 10424 - goto out_inode; 10446 + goto out; 10425 10447 10426 10448 /* 10427 10449 * We set number of links to 0 in btrfs_new_inode(), and here we set ··· 10431 10453 * d_tmpfile() -> inode_dec_link_count() -> drop_nlink() 10432 10454 */ 10433 10455 set_nlink(inode, 1); 10434 - unlock_new_inode(inode); 10435 10456 d_tmpfile(dentry, inode); 10457 + unlock_new_inode(inode); 10436 10458 mark_inode_dirty(inode); 10437 - 10438 10459 out: 10439 10460 btrfs_end_transaction(trans); 10440 - if (ret) 10441 - iput(inode); 10461 + if (ret && inode) 10462 + discard_new_inode(inode); 10442 10463 btrfs_btree_balance_dirty(fs_info); 10443 10464 return ret; 10444 - 10445 - out_inode: 10446 - unlock_new_inode(inode); 10447 - goto out; 10448 - 10449 10465 } 10450 10466 10451 10467 __attribute__((const))