aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2009-09-21 15:56:00 -0400
committerChris Mason <chris.mason@oracle.com>2009-09-21 15:56:00 -0400
commit13a8a7c8c47e542b3cdb45bec3f431f96af79361 (patch)
tree473f3cc94b4a93a0a5f6f19b1832ef2e6b7ecf62 /fs/btrfs
parent1c4850e21df8b441164d910bc611ef46a01d5d75 (diff)
Btrfs: do not reuse objectid of deleted snapshot/subvol
The new back reference format does not allow reusing objectid of deleted snapshot/subvol. So we use ++highest_objectid to allocate objectid for new snapshot/subvol. Now we use ++highest_objectid to allocate objectid for both new inode and new snapshot/subvolume, so this patch removes 'find hole' code in btrfs_find_free_objectid. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/disk-io.c39
-rw-r--r--fs/btrfs/inode-item.c2
-rw-r--r--fs/btrfs/inode-map.c93
-rw-r--r--fs/btrfs/inode.c3
-rw-r--r--fs/btrfs/tree-log.c6
6 files changed, 31 insertions, 116 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 3b6df7140575..746a9acd2189 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1007,8 +1007,8 @@ struct btrfs_root {
1007 u32 stripesize; 1007 u32 stripesize;
1008 1008
1009 u32 type; 1009 u32 type;
1010 u64 highest_inode; 1010
1011 u64 last_inode_alloc; 1011 u64 highest_objectid;
1012 int ref_cows; 1012 int ref_cows;
1013 int track_dirty; 1013 int track_dirty;
1014 u64 defrag_trans_start; 1014 u64 defrag_trans_start;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 16dae122dda4..790f4b61a3d7 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -895,8 +895,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
895 root->fs_info = fs_info; 895 root->fs_info = fs_info;
896 root->objectid = objectid; 896 root->objectid = objectid;
897 root->last_trans = 0; 897 root->last_trans = 0;
898 root->highest_inode = 0; 898 root->highest_objectid = 0;
899 root->last_inode_alloc = 0;
900 root->name = NULL; 899 root->name = NULL;
901 root->in_sysfs = 0; 900 root->in_sysfs = 0;
902 root->inode_tree.rb_node = NULL; 901 root->inode_tree.rb_node = NULL;
@@ -1095,7 +1094,6 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
1095 struct btrfs_fs_info *fs_info = tree_root->fs_info; 1094 struct btrfs_fs_info *fs_info = tree_root->fs_info;
1096 struct btrfs_path *path; 1095 struct btrfs_path *path;
1097 struct extent_buffer *l; 1096 struct extent_buffer *l;
1098 u64 highest_inode;
1099 u64 generation; 1097 u64 generation;
1100 u32 blocksize; 1098 u32 blocksize;
1101 int ret = 0; 1099 int ret = 0;
@@ -1110,7 +1108,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
1110 kfree(root); 1108 kfree(root);
1111 return ERR_PTR(ret); 1109 return ERR_PTR(ret);
1112 } 1110 }
1113 goto insert; 1111 goto out;
1114 } 1112 }
1115 1113
1116 __setup_root(tree_root->nodesize, tree_root->leafsize, 1114 __setup_root(tree_root->nodesize, tree_root->leafsize,
@@ -1120,39 +1118,30 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
1120 path = btrfs_alloc_path(); 1118 path = btrfs_alloc_path();
1121 BUG_ON(!path); 1119 BUG_ON(!path);
1122 ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); 1120 ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0);
1123 if (ret != 0) { 1121 if (ret == 0) {
1124 if (ret > 0) 1122 l = path->nodes[0];
1125 ret = -ENOENT; 1123 read_extent_buffer(l, &root->root_item,
1126 goto out; 1124 btrfs_item_ptr_offset(l, path->slots[0]),
1125 sizeof(root->root_item));
1126 memcpy(&root->root_key, location, sizeof(*location));
1127 } 1127 }
1128 l = path->nodes[0];
1129 read_extent_buffer(l, &root->root_item,
1130 btrfs_item_ptr_offset(l, path->slots[0]),
1131 sizeof(root->root_item));
1132 memcpy(&root->root_key, location, sizeof(*location));
1133 ret = 0;
1134out:
1135 btrfs_release_path(root, path);
1136 btrfs_free_path(path); 1128 btrfs_free_path(path);
1137 if (ret) { 1129 if (ret) {
1138 kfree(root); 1130 if (ret > 0)
1131 ret = -ENOENT;
1139 return ERR_PTR(ret); 1132 return ERR_PTR(ret);
1140 } 1133 }
1134
1141 generation = btrfs_root_generation(&root->root_item); 1135 generation = btrfs_root_generation(&root->root_item);
1142 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 1136 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
1143 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 1137 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
1144 blocksize, generation); 1138 blocksize, generation);
1145 root->commit_root = btrfs_root_node(root); 1139 root->commit_root = btrfs_root_node(root);
1146 BUG_ON(!root->node); 1140 BUG_ON(!root->node);
1147insert: 1141out:
1148 if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { 1142 if (location->objectid != BTRFS_TREE_LOG_OBJECTID)
1149 root->ref_cows = 1; 1143 root->ref_cows = 1;
1150 ret = btrfs_find_highest_inode(root, &highest_inode); 1144
1151 if (ret == 0) {
1152 root->highest_inode = highest_inode;
1153 root->last_inode_alloc = highest_inode;
1154 }
1155 }
1156 return root; 1145 return root;
1157} 1146}
1158 1147
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c
index 6b627c611808..fc6f4a7f6405 100644
--- a/fs/btrfs/inode-item.c
+++ b/fs/btrfs/inode-item.c
@@ -177,8 +177,6 @@ int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
177 177
178 ret = btrfs_insert_empty_item(trans, root, path, &key, 178 ret = btrfs_insert_empty_item(trans, root, path, &key,
179 sizeof(struct btrfs_inode_item)); 179 sizeof(struct btrfs_inode_item));
180 if (ret == 0 && objectid > root->highest_inode)
181 root->highest_inode = objectid;
182 return ret; 180 return ret;
183} 181}
184 182
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 9abbced1123d..c56eb5909172 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -43,9 +43,10 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid)
43 slot = path->slots[0] - 1; 43 slot = path->slots[0] - 1;
44 l = path->nodes[0]; 44 l = path->nodes[0];
45 btrfs_item_key_to_cpu(l, &found_key, slot); 45 btrfs_item_key_to_cpu(l, &found_key, slot);
46 *objectid = found_key.objectid; 46 *objectid = max_t(u64, found_key.objectid,
47 BTRFS_FIRST_FREE_OBJECTID - 1);
47 } else { 48 } else {
48 *objectid = BTRFS_FIRST_FREE_OBJECTID; 49 *objectid = BTRFS_FIRST_FREE_OBJECTID - 1;
49 } 50 }
50 ret = 0; 51 ret = 0;
51error: 52error:
@@ -53,91 +54,27 @@ error:
53 return ret; 54 return ret;
54} 55}
55 56
56/*
57 * walks the btree of allocated inodes and find a hole.
58 */
59int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, 57int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
60 struct btrfs_root *root, 58 struct btrfs_root *root,
61 u64 dirid, u64 *objectid) 59 u64 dirid, u64 *objectid)
62{ 60{
63 struct btrfs_path *path;
64 struct btrfs_key key;
65 int ret; 61 int ret;
66 int slot = 0;
67 u64 last_ino = 0;
68 int start_found;
69 struct extent_buffer *l;
70 struct btrfs_key search_key;
71 u64 search_start = dirid;
72
73 mutex_lock(&root->objectid_mutex); 62 mutex_lock(&root->objectid_mutex);
74 if (root->last_inode_alloc >= BTRFS_FIRST_FREE_OBJECTID &&
75 root->last_inode_alloc < BTRFS_LAST_FREE_OBJECTID) {
76 *objectid = ++root->last_inode_alloc;
77 mutex_unlock(&root->objectid_mutex);
78 return 0;
79 }
80 path = btrfs_alloc_path();
81 BUG_ON(!path);
82 search_start = max(search_start, (u64)BTRFS_FIRST_FREE_OBJECTID);
83 search_key.objectid = search_start;
84 search_key.type = 0;
85 search_key.offset = 0;
86
87 start_found = 0;
88 ret = btrfs_search_slot(trans, root, &search_key, path, 0, 0);
89 if (ret < 0)
90 goto error;
91 63
92 while (1) { 64 if (unlikely(root->highest_objectid < BTRFS_FIRST_FREE_OBJECTID)) {
93 l = path->nodes[0]; 65 ret = btrfs_find_highest_inode(root, &root->highest_objectid);
94 slot = path->slots[0]; 66 if (ret)
95 if (slot >= btrfs_header_nritems(l)) { 67 goto out;
96 ret = btrfs_next_leaf(root, path); 68 }
97 if (ret == 0)
98 continue;
99 if (ret < 0)
100 goto error;
101 if (!start_found) {
102 *objectid = search_start;
103 start_found = 1;
104 goto found;
105 }
106 *objectid = last_ino > search_start ?
107 last_ino : search_start;
108 goto found;
109 }
110 btrfs_item_key_to_cpu(l, &key, slot);
111 if (key.objectid >= search_start) {
112 if (start_found) {
113 if (last_ino < search_start)
114 last_ino = search_start;
115 if (key.objectid > last_ino) {
116 *objectid = last_ino;
117 goto found;
118 }
119 } else if (key.objectid > search_start) {
120 *objectid = search_start;
121 goto found;
122 }
123 }
124 if (key.objectid >= BTRFS_LAST_FREE_OBJECTID)
125 break;
126 69
127 start_found = 1; 70 if (unlikely(root->highest_objectid >= BTRFS_LAST_FREE_OBJECTID)) {
128 last_ino = key.objectid + 1; 71 ret = -ENOSPC;
129 path->slots[0]++; 72 goto out;
130 } 73 }
131 BUG_ON(1); 74
132found: 75 *objectid = ++root->highest_objectid;
133 btrfs_release_path(root, path); 76 ret = 0;
134 btrfs_free_path(path); 77out:
135 BUG_ON(*objectid < search_start);
136 mutex_unlock(&root->objectid_mutex);
137 return 0;
138error:
139 btrfs_release_path(root, path);
140 btrfs_free_path(path);
141 mutex_unlock(&root->objectid_mutex); 78 mutex_unlock(&root->objectid_mutex);
142 return ret; 79 return ret;
143} 80}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 81ba6654c332..9e81f3184f24 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3624,9 +3624,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
3624 if (ret != 0) 3624 if (ret != 0)
3625 goto fail; 3625 goto fail;
3626 3626
3627 if (objectid > root->highest_inode)
3628 root->highest_inode = objectid;
3629
3630 inode->i_uid = current_fsuid(); 3627 inode->i_uid = current_fsuid();
3631 3628
3632 if (dir && (dir->i_mode & S_ISGID)) { 3629 if (dir && (dir->i_mode & S_ISGID)) {
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f4a7b62f9bea..6e674d76186d 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2951,7 +2951,6 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
2951 struct btrfs_key tmp_key; 2951 struct btrfs_key tmp_key;
2952 struct btrfs_root *log; 2952 struct btrfs_root *log;
2953 struct btrfs_fs_info *fs_info = log_root_tree->fs_info; 2953 struct btrfs_fs_info *fs_info = log_root_tree->fs_info;
2954 u64 highest_inode;
2955 struct walk_control wc = { 2954 struct walk_control wc = {
2956 .process_func = process_one_buffer, 2955 .process_func = process_one_buffer,
2957 .stage = 0, 2956 .stage = 0,
@@ -3010,11 +3009,6 @@ again:
3010 path); 3009 path);
3011 BUG_ON(ret); 3010 BUG_ON(ret);
3012 } 3011 }
3013 ret = btrfs_find_highest_inode(wc.replay_dest, &highest_inode);
3014 if (ret == 0) {
3015 wc.replay_dest->highest_inode = highest_inode;
3016 wc.replay_dest->last_inode_alloc = highest_inode;
3017 }
3018 3012
3019 key.offset = found_key.offset - 1; 3013 key.offset = found_key.offset - 1;
3020 wc.replay_dest->log_root = NULL; 3014 wc.replay_dest->log_root = NULL;