aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c71
1 files changed, 53 insertions, 18 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 790f4b61a3d7..a4f531047c4a 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -41,6 +41,7 @@
41 41
42static struct extent_io_ops btree_extent_io_ops; 42static struct extent_io_ops btree_extent_io_ops;
43static void end_workqueue_fn(struct btrfs_work *work); 43static void end_workqueue_fn(struct btrfs_work *work);
44static void free_fs_root(struct btrfs_root *root);
44 45
45static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); 46static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
46 47
@@ -951,14 +952,16 @@ static int find_and_setup_root(struct btrfs_root *tree_root,
951 root, fs_info, objectid); 952 root, fs_info, objectid);
952 ret = btrfs_find_last_root(tree_root, objectid, 953 ret = btrfs_find_last_root(tree_root, objectid,
953 &root->root_item, &root->root_key); 954 &root->root_item, &root->root_key);
955 if (ret > 0)
956 return -ENOENT;
954 BUG_ON(ret); 957 BUG_ON(ret);
955 958
956 generation = btrfs_root_generation(&root->root_item); 959 generation = btrfs_root_generation(&root->root_item);
957 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); 960 blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
958 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), 961 root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
959 blocksize, generation); 962 blocksize, generation);
960 root->commit_root = btrfs_root_node(root);
961 BUG_ON(!root->node); 963 BUG_ON(!root->node);
964 root->commit_root = btrfs_root_node(root);
962 return 0; 965 return 0;
963} 966}
964 967
@@ -1176,39 +1179,66 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
1176 return fs_info->dev_root; 1179 return fs_info->dev_root;
1177 if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) 1180 if (location->objectid == BTRFS_CSUM_TREE_OBJECTID)
1178 return fs_info->csum_root; 1181 return fs_info->csum_root;
1179 1182again:
1183 spin_lock(&fs_info->fs_roots_radix_lock);
1180 root = radix_tree_lookup(&fs_info->fs_roots_radix, 1184 root = radix_tree_lookup(&fs_info->fs_roots_radix,
1181 (unsigned long)location->objectid); 1185 (unsigned long)location->objectid);
1186 spin_unlock(&fs_info->fs_roots_radix_lock);
1182 if (root) 1187 if (root)
1183 return root; 1188 return root;
1184 1189
1190 ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid);
1191 if (ret == 0)
1192 ret = -ENOENT;
1193 if (ret < 0)
1194 return ERR_PTR(ret);
1195
1185 root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); 1196 root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location);
1186 if (IS_ERR(root)) 1197 if (IS_ERR(root))
1187 return root; 1198 return root;
1188 1199
1200 WARN_ON(btrfs_root_refs(&root->root_item) == 0);
1189 set_anon_super(&root->anon_super, NULL); 1201 set_anon_super(&root->anon_super, NULL);
1190 1202
1203 ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
1204 if (ret)
1205 goto fail;
1206
1207 spin_lock(&fs_info->fs_roots_radix_lock);
1191 ret = radix_tree_insert(&fs_info->fs_roots_radix, 1208 ret = radix_tree_insert(&fs_info->fs_roots_radix,
1192 (unsigned long)root->root_key.objectid, 1209 (unsigned long)root->root_key.objectid,
1193 root); 1210 root);
1211 if (ret == 0)
1212 root->in_radix = 1;
1213 spin_unlock(&fs_info->fs_roots_radix_lock);
1214 radix_tree_preload_end();
1194 if (ret) { 1215 if (ret) {
1195 free_extent_buffer(root->node); 1216 if (ret == -EEXIST) {
1196 kfree(root); 1217 free_fs_root(root);
1197 return ERR_PTR(ret); 1218 goto again;
1219 }
1220 goto fail;
1198 } 1221 }
1199 if (!(fs_info->sb->s_flags & MS_RDONLY)) { 1222
1200 ret = btrfs_find_dead_roots(fs_info->tree_root, 1223 ret = btrfs_find_dead_roots(fs_info->tree_root,
1201 root->root_key.objectid); 1224 root->root_key.objectid);
1202 BUG_ON(ret); 1225 WARN_ON(ret);
1226
1227 if (!(fs_info->sb->s_flags & MS_RDONLY))
1203 btrfs_orphan_cleanup(root); 1228 btrfs_orphan_cleanup(root);
1204 } 1229
1205 return root; 1230 return root;
1231fail:
1232 free_fs_root(root);
1233 return ERR_PTR(ret);
1206} 1234}
1207 1235
1208struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, 1236struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
1209 struct btrfs_key *location, 1237 struct btrfs_key *location,
1210 const char *name, int namelen) 1238 const char *name, int namelen)
1211{ 1239{
1240 return btrfs_read_fs_root_no_name(fs_info, location);
1241#if 0
1212 struct btrfs_root *root; 1242 struct btrfs_root *root;
1213 int ret; 1243 int ret;
1214 1244
@@ -1225,7 +1255,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
1225 kfree(root); 1255 kfree(root);
1226 return ERR_PTR(ret); 1256 return ERR_PTR(ret);
1227 } 1257 }
1228#if 0 1258
1229 ret = btrfs_sysfs_add_root(root); 1259 ret = btrfs_sysfs_add_root(root);
1230 if (ret) { 1260 if (ret) {
1231 free_extent_buffer(root->node); 1261 free_extent_buffer(root->node);
@@ -1233,9 +1263,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
1233 kfree(root); 1263 kfree(root);
1234 return ERR_PTR(ret); 1264 return ERR_PTR(ret);
1235 } 1265 }
1236#endif
1237 root->in_sysfs = 1; 1266 root->in_sysfs = 1;
1238 return root; 1267 return root;
1268#endif
1239} 1269}
1240 1270
1241static int btrfs_congested_fn(void *congested_data, int bdi_bits) 1271static int btrfs_congested_fn(void *congested_data, int bdi_bits)
@@ -2229,20 +2259,25 @@ int write_ctree_super(struct btrfs_trans_handle *trans,
2229 2259
2230int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) 2260int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
2231{ 2261{
2232 WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); 2262 spin_lock(&fs_info->fs_roots_radix_lock);
2233 radix_tree_delete(&fs_info->fs_roots_radix, 2263 radix_tree_delete(&fs_info->fs_roots_radix,
2234 (unsigned long)root->root_key.objectid); 2264 (unsigned long)root->root_key.objectid);
2265 spin_unlock(&fs_info->fs_roots_radix_lock);
2266 free_fs_root(root);
2267 return 0;
2268}
2269
2270static void free_fs_root(struct btrfs_root *root)
2271{
2272 WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree));
2235 if (root->anon_super.s_dev) { 2273 if (root->anon_super.s_dev) {
2236 down_write(&root->anon_super.s_umount); 2274 down_write(&root->anon_super.s_umount);
2237 kill_anon_super(&root->anon_super); 2275 kill_anon_super(&root->anon_super);
2238 } 2276 }
2239 if (root->node) 2277 free_extent_buffer(root->node);
2240 free_extent_buffer(root->node); 2278 free_extent_buffer(root->commit_root);
2241 if (root->commit_root)
2242 free_extent_buffer(root->commit_root);
2243 kfree(root->name); 2279 kfree(root->name);
2244 kfree(root); 2280 kfree(root);
2245 return 0;
2246} 2281}
2247 2282
2248static int del_fs_roots(struct btrfs_fs_info *fs_info) 2283static int del_fs_roots(struct btrfs_fs_info *fs_info)