aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.de>2012-08-08 14:32:27 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-09 09:14:45 -0400
commitf186373fef005cee948a4a39e6a14c2e5f517298 (patch)
tree5683c66a7112e56147149f379658517ab18e7689 /fs/btrfs/inode.c
parent5a1d7843ca4b3a9009bea87f85ad33854b910aea (diff)
btrfs: extended inode refs
This patch adds basic support for extended inode refs. This includes support for link and unlink of the refs, which basically gets us support for rename as well. Inode creation does not need changing - extended refs are only added after the ref array is full. Signed-off-by: Mark Fasheh <mfasheh@suse.de>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1c50f7c4f5ac..596305e4d75b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2903,7 +2903,6 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
2903 struct btrfs_trans_handle *trans; 2903 struct btrfs_trans_handle *trans;
2904 struct btrfs_root *root = BTRFS_I(dir)->root; 2904 struct btrfs_root *root = BTRFS_I(dir)->root;
2905 struct btrfs_path *path; 2905 struct btrfs_path *path;
2906 struct btrfs_inode_ref *ref;
2907 struct btrfs_dir_item *di; 2906 struct btrfs_dir_item *di;
2908 struct inode *inode = dentry->d_inode; 2907 struct inode *inode = dentry->d_inode;
2909 u64 index; 2908 u64 index;
@@ -3017,17 +3016,17 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
3017 } 3016 }
3018 btrfs_release_path(path); 3017 btrfs_release_path(path);
3019 3018
3020 ref = btrfs_lookup_inode_ref(trans, root, path, 3019 ret = btrfs_get_inode_ref_index(trans, root, path, dentry->d_name.name,
3021 dentry->d_name.name, dentry->d_name.len, 3020 dentry->d_name.len, ino, dir_ino, 0,
3022 ino, dir_ino, 0); 3021 &index);
3023 if (IS_ERR(ref)) { 3022 if (ret) {
3024 err = PTR_ERR(ref); 3023 err = ret;
3025 goto out; 3024 goto out;
3026 } 3025 }
3027 BUG_ON(!ref); /* Logic error */ 3026
3028 if (check_path_shared(root, path)) 3027 if (check_path_shared(root, path))
3029 goto out; 3028 goto out;
3030 index = btrfs_inode_ref_index(path->nodes[0], ref); 3029
3031 btrfs_release_path(path); 3030 btrfs_release_path(path);
3032 3031
3033 /* 3032 /*
@@ -4743,6 +4742,12 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
4743 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); 4742 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
4744 key[0].offset = 0; 4743 key[0].offset = 0;
4745 4744
4745 /*
4746 * Start new inodes with an inode_ref. This is slightly more
4747 * efficient for small numbers of hard links since they will
4748 * be packed into one item. Extended refs will kick in if we
4749 * add more hard links than can fit in the ref item.
4750 */
4746 key[1].objectid = objectid; 4751 key[1].objectid = objectid;
4747 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY); 4752 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
4748 key[1].offset = ref_objectid; 4753 key[1].offset = ref_objectid;
@@ -5049,7 +5054,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
5049 if (root->objectid != BTRFS_I(inode)->root->objectid) 5054 if (root->objectid != BTRFS_I(inode)->root->objectid)
5050 return -EXDEV; 5055 return -EXDEV;
5051 5056
5052 if (inode->i_nlink == ~0U) 5057 if (inode->i_nlink >= BTRFS_LINK_MAX)
5053 return -EMLINK; 5058 return -EMLINK;
5054 5059
5055 err = btrfs_set_inode_index(dir, &index); 5060 err = btrfs_set_inode_index(dir, &index);