diff options
| author | Chris Mason <clm@fb.com> | 2014-09-08 16:08:51 -0400 |
|---|---|---|
| committer | Chris Mason <clm@fb.com> | 2014-09-08 16:56:45 -0400 |
| commit | b0d5d10f41a0f1cd839408dd94427f2db3553bca (patch) | |
| tree | 0245a9bf559bfab38f9a2812d3aebb252a81cebb | |
| parent | 49dae1bc1c665817e434d01eefaa11967f618243 (diff) | |
Btrfs: use insert_inode_locked4 for inode creation
Btrfs was inserting inodes into the hash table before we had fully
set the inode up on disk. This leaves us open to rare races that allow
two different inodes in memory for the same [root, inode] pair.
This patch fixes things by using insert_inode_locked4 to insert an I_NEW
inode and unlock_new_inode when we're ready for the rest of the kernel
to use the inode.
It also makes sure to init the operations pointers on the inode before
going into the error handling paths.
Signed-off-by: Chris Mason <clm@fb.com>
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/btrfs/inode.c | 176 |
1 files changed, 109 insertions, 67 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 88823f4ca451..214b936bdd3d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -5634,6 +5634,17 @@ int btrfs_set_inode_index(struct inode *dir, u64 *index) | |||
| 5634 | return ret; | 5634 | return ret; |
| 5635 | } | 5635 | } |
| 5636 | 5636 | ||
| 5637 | static int btrfs_insert_inode_locked(struct inode *inode) | ||
| 5638 | { | ||
| 5639 | struct btrfs_iget_args args; | ||
| 5640 | args.location = &BTRFS_I(inode)->location; | ||
| 5641 | args.root = BTRFS_I(inode)->root; | ||
| 5642 | |||
| 5643 | return insert_inode_locked4(inode, | ||
| 5644 | btrfs_inode_hash(inode->i_ino, BTRFS_I(inode)->root), | ||
| 5645 | btrfs_find_actor, &args); | ||
| 5646 | } | ||
| 5647 | |||
| 5637 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | 5648 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, |
| 5638 | struct btrfs_root *root, | 5649 | struct btrfs_root *root, |
| 5639 | struct inode *dir, | 5650 | struct inode *dir, |
| @@ -5726,10 +5737,19 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 5726 | sizes[1] = name_len + sizeof(*ref); | 5737 | sizes[1] = name_len + sizeof(*ref); |
| 5727 | } | 5738 | } |
| 5728 | 5739 | ||
| 5740 | location = &BTRFS_I(inode)->location; | ||
| 5741 | location->objectid = objectid; | ||
| 5742 | location->offset = 0; | ||
| 5743 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | ||
| 5744 | |||
| 5745 | ret = btrfs_insert_inode_locked(inode); | ||
| 5746 | if (ret < 0) | ||
| 5747 | goto fail; | ||
| 5748 | |||
| 5729 | path->leave_spinning = 1; | 5749 | path->leave_spinning = 1; |
| 5730 | ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems); | 5750 | ret = btrfs_insert_empty_items(trans, root, path, key, sizes, nitems); |
| 5731 | if (ret != 0) | 5751 | if (ret != 0) |
| 5732 | goto fail; | 5752 | goto fail_unlock; |
| 5733 | 5753 | ||
| 5734 | inode_init_owner(inode, dir, mode); | 5754 | inode_init_owner(inode, dir, mode); |
| 5735 | inode_set_bytes(inode, 0); | 5755 | inode_set_bytes(inode, 0); |
| @@ -5752,11 +5772,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 5752 | btrfs_mark_buffer_dirty(path->nodes[0]); | 5772 | btrfs_mark_buffer_dirty(path->nodes[0]); |
| 5753 | btrfs_free_path(path); | 5773 | btrfs_free_path(path); |
| 5754 | 5774 | ||
| 5755 | location = &BTRFS_I(inode)->location; | ||
| 5756 | location->objectid = objectid; | ||
| 5757 | location->offset = 0; | ||
| 5758 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | ||
| 5759 | |||
| 5760 | btrfs_inherit_iflags(inode, dir); | 5775 | btrfs_inherit_iflags(inode, dir); |
| 5761 | 5776 | ||
| 5762 | if (S_ISREG(mode)) { | 5777 | if (S_ISREG(mode)) { |
| @@ -5767,7 +5782,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 5767 | BTRFS_INODE_NODATASUM; | 5782 | BTRFS_INODE_NODATASUM; |
| 5768 | } | 5783 | } |
| 5769 | 5784 | ||
| 5770 | btrfs_insert_inode_hash(inode); | ||
| 5771 | inode_tree_add(inode); | 5785 | inode_tree_add(inode); |
| 5772 | 5786 | ||
| 5773 | trace_btrfs_inode_new(inode); | 5787 | trace_btrfs_inode_new(inode); |
| @@ -5782,6 +5796,9 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 5782 | btrfs_ino(inode), root->root_key.objectid, ret); | 5796 | btrfs_ino(inode), root->root_key.objectid, ret); |
| 5783 | 5797 | ||
| 5784 | return inode; | 5798 | return inode; |
| 5799 | |||
| 5800 | fail_unlock: | ||
| 5801 | unlock_new_inode(inode); | ||
| 5785 | fail: | 5802 | fail: |
| 5786 | if (dir && name) | 5803 | if (dir && name) |
| 5787 | BTRFS_I(dir)->index_cnt--; | 5804 | BTRFS_I(dir)->index_cnt--; |
| @@ -5916,28 +5933,28 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 5916 | goto out_unlock; | 5933 | goto out_unlock; |
| 5917 | } | 5934 | } |
| 5918 | 5935 | ||
| 5919 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | ||
| 5920 | if (err) { | ||
| 5921 | drop_inode = 1; | ||
| 5922 | goto out_unlock; | ||
| 5923 | } | ||
| 5924 | |||
| 5925 | /* | 5936 | /* |
| 5926 | * If the active LSM wants to access the inode during | 5937 | * If the active LSM wants to access the inode during |
| 5927 | * d_instantiate it needs these. Smack checks to see | 5938 | * d_instantiate it needs these. Smack checks to see |
| 5928 | * if the filesystem supports xattrs by looking at the | 5939 | * if the filesystem supports xattrs by looking at the |
| 5929 | * ops vector. | 5940 | * ops vector. |
| 5930 | */ | 5941 | */ |
| 5931 | |||
| 5932 | inode->i_op = &btrfs_special_inode_operations; | 5942 | inode->i_op = &btrfs_special_inode_operations; |
| 5933 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); | 5943 | init_special_inode(inode, inode->i_mode, rdev); |
| 5944 | |||
| 5945 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | ||
| 5934 | if (err) | 5946 | if (err) |
| 5935 | drop_inode = 1; | 5947 | goto out_unlock_inode; |
| 5936 | else { | 5948 | |
| 5937 | init_special_inode(inode, inode->i_mode, rdev); | 5949 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 5950 | if (err) { | ||
| 5951 | goto out_unlock_inode; | ||
| 5952 | } else { | ||
| 5938 | btrfs_update_inode(trans, root, inode); | 5953 | btrfs_update_inode(trans, root, inode); |
| 5954 | unlock_new_inode(inode); | ||
| 5939 | d_instantiate(dentry, inode); | 5955 | d_instantiate(dentry, inode); |
| 5940 | } | 5956 | } |
| 5957 | |||
| 5941 | out_unlock: | 5958 | out_unlock: |
| 5942 | btrfs_end_transaction(trans, root); | 5959 | btrfs_end_transaction(trans, root); |
| 5943 | btrfs_balance_delayed_items(root); | 5960 | btrfs_balance_delayed_items(root); |
| @@ -5947,6 +5964,12 @@ out_unlock: | |||
| 5947 | iput(inode); | 5964 | iput(inode); |
| 5948 | } | 5965 | } |
| 5949 | return err; | 5966 | return err; |
| 5967 | |||
| 5968 | out_unlock_inode: | ||
| 5969 | drop_inode = 1; | ||
| 5970 | unlock_new_inode(inode); | ||
| 5971 | goto out_unlock; | ||
| 5972 | |||
| 5950 | } | 5973 | } |
| 5951 | 5974 | ||
| 5952 | static int btrfs_create(struct inode *dir, struct dentry *dentry, | 5975 | static int btrfs_create(struct inode *dir, struct dentry *dentry, |
| @@ -5981,15 +6004,6 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 5981 | goto out_unlock; | 6004 | goto out_unlock; |
| 5982 | } | 6005 | } |
| 5983 | drop_inode_on_err = 1; | 6006 | drop_inode_on_err = 1; |
| 5984 | |||
| 5985 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | ||
| 5986 | if (err) | ||
| 5987 | goto out_unlock; | ||
| 5988 | |||
| 5989 | err = btrfs_update_inode(trans, root, inode); | ||
| 5990 | if (err) | ||
| 5991 | goto out_unlock; | ||
| 5992 | |||
| 5993 | /* | 6007 | /* |
| 5994 | * If the active LSM wants to access the inode during | 6008 | * If the active LSM wants to access the inode during |
| 5995 | * d_instantiate it needs these. Smack checks to see | 6009 | * d_instantiate it needs these. Smack checks to see |
| @@ -5998,14 +6012,23 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 5998 | */ | 6012 | */ |
| 5999 | inode->i_fop = &btrfs_file_operations; | 6013 | inode->i_fop = &btrfs_file_operations; |
| 6000 | inode->i_op = &btrfs_file_inode_operations; | 6014 | inode->i_op = &btrfs_file_inode_operations; |
| 6015 | inode->i_mapping->a_ops = &btrfs_aops; | ||
| 6016 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 6017 | |||
| 6018 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); | ||
| 6019 | if (err) | ||
| 6020 | goto out_unlock_inode; | ||
| 6021 | |||
| 6022 | err = btrfs_update_inode(trans, root, inode); | ||
| 6023 | if (err) | ||
| 6024 | goto out_unlock_inode; | ||
| 6001 | 6025 | ||
| 6002 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); | 6026 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 6003 | if (err) | 6027 | if (err) |
| 6004 | goto out_unlock; | 6028 | goto out_unlock_inode; |
| 6005 | 6029 | ||
| 6006 | inode->i_mapping->a_ops = &btrfs_aops; | ||
| 6007 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | ||
| 6008 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 6030 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
| 6031 | unlock_new_inode(inode); | ||
| 6009 | d_instantiate(dentry, inode); | 6032 | d_instantiate(dentry, inode); |
| 6010 | 6033 | ||
| 6011 | out_unlock: | 6034 | out_unlock: |
| @@ -6017,6 +6040,11 @@ out_unlock: | |||
| 6017 | btrfs_balance_delayed_items(root); | 6040 | btrfs_balance_delayed_items(root); |
| 6018 | btrfs_btree_balance_dirty(root); | 6041 | btrfs_btree_balance_dirty(root); |
| 6019 | return err; | 6042 | return err; |
