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