aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2014-09-08 16:08:51 -0400
committerChris Mason <clm@fb.com>2014-09-08 16:56:45 -0400
commitb0d5d10f41a0f1cd839408dd94427f2db3553bca (patch)
tree0245a9bf559bfab38f9a2812d3aebb252a81cebb
parent49dae1bc1c665817e434d01eefaa11967f618243 (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.c176
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
5637static 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
5637static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, 5648static 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
5800fail_unlock:
5801 unlock_new_inode(inode);
5785fail: 5802fail:
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
5941out_unlock: 5958out_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
5968out_unlock_inode:
5969 drop_inode = 1;
5970 unlock_new_inode(inode);
5971 goto out_unlock;
5972
5950} 5973}
5951 5974
5952static int btrfs_create(struct inode *dir, struct dentry *dentry, 5975static 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
6011out_unlock: 6034out_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;