diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 152 |
1 files changed, 137 insertions, 15 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 20c49b16b759..62e0cafd6e25 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -407,7 +407,7 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, | |||
407 | break; | 407 | break; |
408 | } | 408 | } |
409 | 409 | ||
410 | if (failed && !ret) | 410 | if (failed && !ret && failed_mirror) |
411 | repair_eb_io_failure(root, eb, failed_mirror); | 411 | repair_eb_io_failure(root, eb, failed_mirror); |
412 | 412 | ||
413 | return ret; | 413 | return ret; |
@@ -1114,7 +1114,7 @@ void clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
1114 | spin_unlock(&root->fs_info->delalloc_lock); | 1114 | spin_unlock(&root->fs_info->delalloc_lock); |
1115 | btrfs_panic(root->fs_info, -EOVERFLOW, | 1115 | btrfs_panic(root->fs_info, -EOVERFLOW, |
1116 | "Can't clear %lu bytes from " | 1116 | "Can't clear %lu bytes from " |
1117 | " dirty_mdatadata_bytes (%lu)", | 1117 | " dirty_mdatadata_bytes (%llu)", |
1118 | buf->len, | 1118 | buf->len, |
1119 | root->fs_info->dirty_metadata_bytes); | 1119 | root->fs_info->dirty_metadata_bytes); |
1120 | } | 1120 | } |
@@ -1182,6 +1182,8 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
1182 | root->defrag_running = 0; | 1182 | root->defrag_running = 0; |
1183 | root->root_key.objectid = objectid; | 1183 | root->root_key.objectid = objectid; |
1184 | root->anon_dev = 0; | 1184 | root->anon_dev = 0; |
1185 | |||
1186 | spin_lock_init(&root->root_times_lock); | ||
1185 | } | 1187 | } |
1186 | 1188 | ||
1187 | static int __must_check find_and_setup_root(struct btrfs_root *tree_root, | 1189 | static int __must_check find_and_setup_root(struct btrfs_root *tree_root, |
@@ -1225,6 +1227,82 @@ static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info) | |||
1225 | return root; | 1227 | return root; |
1226 | } | 1228 | } |
1227 | 1229 | ||
1230 | struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans, | ||
1231 | struct btrfs_fs_info *fs_info, | ||
1232 | u64 objectid) | ||
1233 | { | ||
1234 | struct extent_buffer *leaf; | ||
1235 | struct btrfs_root *tree_root = fs_info->tree_root; | ||
1236 | struct btrfs_root *root; | ||
1237 | struct btrfs_key key; | ||
1238 | int ret = 0; | ||
1239 | u64 bytenr; | ||
1240 | |||
1241 | root = btrfs_alloc_root(fs_info); | ||
1242 | if (!root) | ||
1243 | return ERR_PTR(-ENOMEM); | ||
1244 | |||
1245 | __setup_root(tree_root->nodesize, tree_root->leafsize, | ||
1246 | tree_root->sectorsize, tree_root->stripesize, | ||
1247 | root, fs_info, objectid); | ||
1248 | root->root_key.objectid = objectid; | ||
1249 | root->root_key.type = BTRFS_ROOT_ITEM_KEY; | ||
1250 | root->root_key.offset = 0; | ||
1251 | |||
1252 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | ||
1253 | 0, objectid, NULL, 0, 0, 0); | ||
1254 | if (IS_ERR(leaf)) { | ||
1255 | ret = PTR_ERR(leaf); | ||
1256 | goto fail; | ||
1257 | } | ||
1258 | |||
1259 | bytenr = leaf->start; | ||
1260 | memset_extent_buffer(leaf, 0, 0, sizeof(struct btrfs_header)); | ||
1261 | btrfs_set_header_bytenr(leaf, leaf->start); | ||
1262 | btrfs_set_header_generation(leaf, trans->transid); | ||
1263 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); | ||
1264 | btrfs_set_header_owner(leaf, objectid); | ||
1265 | root->node = leaf; | ||
1266 | |||
1267 | write_extent_buffer(leaf, fs_info->fsid, | ||
1268 | (unsigned long)btrfs_header_fsid(leaf), | ||
1269 | BTRFS_FSID_SIZE); | ||
1270 | write_extent_buffer(leaf, fs_info->chunk_tree_uuid, | ||
1271 | (unsigned long)btrfs_header_chunk_tree_uuid(leaf), | ||
1272 | BTRFS_UUID_SIZE); | ||
1273 | btrfs_mark_buffer_dirty(leaf); | ||
1274 | |||
1275 | root->commit_root = btrfs_root_node(root); | ||
1276 | root->track_dirty = 1; | ||
1277 | |||
1278 | |||
1279 | root->root_item.flags = 0; | ||
1280 | root->root_item.byte_limit = 0; | ||
1281 | btrfs_set_root_bytenr(&root->root_item, leaf->start); | ||
1282 | btrfs_set_root_generation(&root->root_item, trans->transid); | ||
1283 | btrfs_set_root_level(&root->root_item, 0); | ||
1284 | btrfs_set_root_refs(&root->root_item, 1); | ||
1285 | btrfs_set_root_used(&root->root_item, leaf->len); | ||
1286 | btrfs_set_root_last_snapshot(&root->root_item, 0); | ||
1287 | btrfs_set_root_dirid(&root->root_item, 0); | ||
1288 | root->root_item.drop_level = 0; | ||
1289 | |||
1290 | key.objectid = objectid; | ||
1291 | key.type = BTRFS_ROOT_ITEM_KEY; | ||
1292 | key.offset = 0; | ||
1293 | ret = btrfs_insert_root(trans, tree_root, &key, &root->root_item); | ||
1294 | if (ret) | ||
1295 | goto fail; | ||
1296 | |||
1297 | btrfs_tree_unlock(leaf); | ||
1298 | |||
1299 | fail: | ||
1300 | if (ret) | ||
1301 | return ERR_PTR(ret); | ||
1302 | |||
1303 | return root; | ||
1304 | } | ||
1305 | |||
1228 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | 1306 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
1229 | struct btrfs_fs_info *fs_info) | 1307 | struct btrfs_fs_info *fs_info) |
1230 | { | 1308 | { |
@@ -1326,6 +1404,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
1326 | u64 generation; | 1404 | u64 generation; |
1327 | u32 blocksize; | 1405 | u32 blocksize; |
1328 | int ret = 0; | 1406 | int ret = 0; |
1407 | int slot; | ||
1329 | 1408 | ||
1330 | root = btrfs_alloc_root(fs_info); | 1409 | root = btrfs_alloc_root(fs_info); |
1331 | if (!root) | 1410 | if (!root) |
@@ -1352,9 +1431,8 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
1352 | ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); | 1431 | ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); |
1353 | if (ret == 0) { | 1432 | if (ret == 0) { |
1354 | l = path->nodes[0]; | 1433 | l = path->nodes[0]; |
1355 | read_extent_buffer(l, &root->root_item, | 1434 | slot = path->slots[0]; |
1356 | btrfs_item_ptr_offset(l, path->slots[0]), | 1435 | btrfs_read_root_item(tree_root, l, slot, &root->root_item); |
1357 | sizeof(root->root_item)); | ||
1358 | memcpy(&root->root_key, location, sizeof(*location)); | 1436 | memcpy(&root->root_key, location, sizeof(*location)); |
1359 | } | 1437 | } |
1360 | btrfs_free_path(path); | 1438 | btrfs_free_path(path); |
@@ -1396,6 +1474,9 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, | |||
1396 | return fs_info->dev_root; | 1474 | return fs_info->dev_root; |
1397 | if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) | 1475 | if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) |
1398 | return fs_info->csum_root; | 1476 | return fs_info->csum_root; |
1477 | if (location->objectid == BTRFS_QUOTA_TREE_OBJECTID) | ||
1478 | return fs_info->quota_root ? fs_info->quota_root : | ||
1479 | ERR_PTR(-ENOENT); | ||
1399 | again: | 1480 | again: |
1400 | spin_lock(&fs_info->fs_roots_radix_lock); | 1481 | spin_lock(&fs_info->fs_roots_radix_lock); |
1401 | root = radix_tree_lookup(&fs_info->fs_roots_radix, | 1482 | root = radix_tree_lookup(&fs_info->fs_roots_radix, |
@@ -1820,6 +1901,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1820 | free_extent_buffer(info->extent_root->commit_root); | 1901 | free_extent_buffer(info->extent_root->commit_root); |
1821 | free_extent_buffer(info->csum_root->node); | 1902 | free_extent_buffer(info->csum_root->node); |
1822 | free_extent_buffer(info->csum_root->commit_root); | 1903 | free_extent_buffer(info->csum_root->commit_root); |
1904 | if (info->quota_root) { | ||
1905 | free_extent_buffer(info->quota_root->node); | ||
1906 | free_extent_buffer(info->quota_root->commit_root); | ||
1907 | } | ||
1823 | 1908 | ||
1824 | info->tree_root->node = NULL; | 1909 | info->tree_root->node = NULL; |
1825 | info->tree_root->commit_root = NULL; | 1910 | info->tree_root->commit_root = NULL; |
@@ -1829,6 +1914,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1829 | info->extent_root->commit_root = NULL; | 1914 | info->extent_root->commit_root = NULL; |
1830 | info->csum_root->node = NULL; | 1915 | info->csum_root->node = NULL; |
1831 | info->csum_root->commit_root = NULL; | 1916 | info->csum_root->commit_root = NULL; |
1917 | if (info->quota_root) { | ||
1918 | info->quota_root->node = NULL; | ||
1919 | info->quota_root->commit_root = NULL; | ||
1920 | } | ||
1832 | 1921 | ||
1833 | if (chunk_root) { | 1922 | if (chunk_root) { |
1834 | free_extent_buffer(info->chunk_root->node); | 1923 | free_extent_buffer(info->chunk_root->node); |
@@ -1859,6 +1948,7 @@ int open_ctree(struct super_block *sb, | |||
1859 | struct btrfs_root *csum_root; | 1948 | struct btrfs_root *csum_root; |
1860 | struct btrfs_root *chunk_root; | 1949 | struct btrfs_root *chunk_root; |
1861 | struct btrfs_root *dev_root; | 1950 | struct btrfs_root *dev_root; |
1951 | struct btrfs_root *quota_root; | ||
1862 | struct btrfs_root *log_tree_root; | 1952 | struct btrfs_root *log_tree_root; |
1863 | int ret; | 1953 | int ret; |
1864 | int err = -EINVAL; | 1954 | int err = -EINVAL; |
@@ -1870,9 +1960,10 @@ int open_ctree(struct super_block *sb, | |||
1870 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); | 1960 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); |
1871 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); | 1961 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); |
1872 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); | 1962 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); |
1963 | quota_root = fs_info->quota_root = btrfs_alloc_root(fs_info); | ||
1873 | 1964 | ||
1874 | if (!tree_root || !extent_root || !csum_root || | 1965 | if (!tree_root || !extent_root || !csum_root || |
1875 | !chunk_root || !dev_root) { | 1966 | !chunk_root || !dev_root || !quota_root) { |
1876 | err = -ENOMEM; | 1967 | err = -ENOMEM; |
1877 | goto fail; | 1968 | goto fail; |
1878 | } | 1969 | } |
@@ -1941,6 +2032,8 @@ int open_ctree(struct super_block *sb, | |||
1941 | fs_info->free_chunk_space = 0; | 2032 | fs_info->free_chunk_space = 0; |
1942 | fs_info->tree_mod_log = RB_ROOT; | 2033 | fs_info->tree_mod_log = RB_ROOT; |
1943 | 2034 | ||
2035 | init_waitqueue_head(&fs_info->tree_mod_seq_wait); | ||
2036 | |||
1944 | /* readahead state */ | 2037 | /* readahead state */ |
1945 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); | 2038 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); |
1946 | spin_lock_init(&fs_info->reada_lock); | 2039 | spin_lock_init(&fs_info->reada_lock); |
@@ -2029,6 +2122,13 @@ int open_ctree(struct super_block *sb, | |||
2029 | init_rwsem(&fs_info->cleanup_work_sem); | 2122 | init_rwsem(&fs_info->cleanup_work_sem); |
2030 | init_rwsem(&fs_info->subvol_sem); | 2123 | init_rwsem(&fs_info->subvol_sem); |
2031 | 2124 | ||
2125 | spin_lock_init(&fs_info->qgroup_lock); | ||
2126 | fs_info->qgroup_tree = RB_ROOT; | ||
2127 | INIT_LIST_HEAD(&fs_info->dirty_qgroups); | ||
2128 | fs_info->qgroup_seq = 1; | ||
2129 | fs_info->quota_enabled = 0; | ||
2130 | fs_info->pending_quota_state = 0; | ||
2131 | |||
2032 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | 2132 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); |
2033 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | 2133 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); |
2034 | 2134 | ||
@@ -2241,7 +2341,7 @@ int open_ctree(struct super_block *sb, | |||
2241 | ret |= btrfs_start_workers(&fs_info->caching_workers); | 2341 | ret |= btrfs_start_workers(&fs_info->caching_workers); |
2242 | ret |= btrfs_start_workers(&fs_info->readahead_workers); | 2342 | ret |= btrfs_start_workers(&fs_info->readahead_workers); |
2243 | if (ret) { | 2343 | if (ret) { |
2244 | ret = -ENOMEM; | 2344 | err = -ENOMEM; |
2245 | goto fail_sb_buffer; | 2345 | goto fail_sb_buffer; |
2246 | } | 2346 | } |
2247 | 2347 | ||
@@ -2353,6 +2453,17 @@ retry_root_backup: | |||
2353 | goto recovery_tree_root; | 2453 | goto recovery_tree_root; |
2354 | csum_root->track_dirty = 1; | 2454 | csum_root->track_dirty = 1; |
2355 | 2455 | ||
2456 | ret = find_and_setup_root(tree_root, fs_info, | ||
2457 | BTRFS_QUOTA_TREE_OBJECTID, quota_root); | ||
2458 | if (ret) { | ||
2459 | kfree(quota_root); | ||
2460 | quota_root = fs_info->quota_root = NULL; | ||
2461 | } else { | ||
2462 | quota_root->track_dirty = 1; | ||
2463 | fs_info->quota_enabled = 1; | ||
2464 | fs_info->pending_quota_state = 1; | ||
2465 | } | ||
2466 | |||
2356 | fs_info->generation = generation; | 2467 | fs_info->generation = generation; |
2357 | fs_info->last_trans_committed = generation; | 2468 | fs_info->last_trans_committed = generation; |
2358 | 2469 | ||
@@ -2412,6 +2523,9 @@ retry_root_backup: | |||
2412 | " integrity check module %s\n", sb->s_id); | 2523 | " integrity check module %s\n", sb->s_id); |
2413 | } | 2524 | } |
2414 | #endif | 2525 | #endif |
2526 | ret = btrfs_read_qgroup_config(fs_info); | ||
2527 | if (ret) | ||
2528 | goto fail_trans_kthread; | ||
2415 | 2529 | ||
2416 | /* do not make disk changes in broken FS */ | 2530 | /* do not make disk changes in broken FS */ |
2417 | if (btrfs_super_log_root(disk_super) != 0 && | 2531 | if (btrfs_super_log_root(disk_super) != 0 && |
@@ -2422,7 +2536,7 @@ retry_root_backup: | |||
2422 | printk(KERN_WARNING "Btrfs log replay required " | 2536 | printk(KERN_WARNING "Btrfs log replay required " |
2423 | "on RO media\n"); | 2537 | "on RO media\n"); |
2424 | err = -EIO; | 2538 | err = -EIO; |
2425 | goto fail_trans_kthread; | 2539 | goto fail_qgroup; |
2426 | } | 2540 | } |
2427 | blocksize = | 2541 | blocksize = |
2428 | btrfs_level_size(tree_root, | 2542 | btrfs_level_size(tree_root, |
@@ -2431,7 +2545,7 @@ retry_root_backup: | |||
2431 | log_tree_root = btrfs_alloc_root(fs_info); | 2545 | log_tree_root = btrfs_alloc_root(fs_info); |
2432 | if (!log_tree_root) { | 2546 | if (!log_tree_root) { |
2433 | err = -ENOMEM; | 2547 | err = -ENOMEM; |
2434 | goto fail_trans_kthread; | 2548 | goto fail_qgroup; |
2435 | } | 2549 | } |
2436 | 2550 | ||
2437 | __setup_root(nodesize, leafsize, sectorsize, stripesize, | 2551 | __setup_root(nodesize, leafsize, sectorsize, stripesize, |
@@ -2463,15 +2577,15 @@ retry_root_backup: | |||
2463 | 2577 | ||
2464 | if (!(sb->s_flags & MS_RDONLY)) { | 2578 | if (!(sb->s_flags & MS_RDONLY)) { |
2465 | ret = btrfs_cleanup_fs_roots(fs_info); | 2579 | ret = btrfs_cleanup_fs_roots(fs_info); |
2466 | if (ret) { | 2580 | if (ret) |
2467 | } | 2581 | goto fail_trans_kthread; |
2468 | 2582 | ||
2469 | ret = btrfs_recover_relocation(tree_root); | 2583 | ret = btrfs_recover_relocation(tree_root); |
2470 | if (ret < 0) { | 2584 | if (ret < 0) { |
2471 | printk(KERN_WARNING | 2585 | printk(KERN_WARNING |
2472 | "btrfs: failed to recover relocation\n"); | 2586 | "btrfs: failed to recover relocation\n"); |
2473 | err = -EINVAL; | 2587 | err = -EINVAL; |
2474 | goto fail_trans_kthread; | 2588 | goto fail_qgroup; |
2475 | } | 2589 | } |
2476 | } | 2590 | } |
2477 | 2591 | ||
@@ -2481,10 +2595,10 @@ retry_root_backup: | |||
2481 | 2595 | ||
2482 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); | 2596 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); |
2483 | if (!fs_info->fs_root) | 2597 | if (!fs_info->fs_root) |
2484 | goto fail_trans_kthread; | 2598 | goto fail_qgroup; |
2485 | if (IS_ERR(fs_info->fs_root)) { | 2599 | if (IS_ERR(fs_info->fs_root)) { |
2486 | err = PTR_ERR(fs_info->fs_root); | 2600 | err = PTR_ERR(fs_info->fs_root); |
2487 | goto fail_trans_kthread; | 2601 | goto fail_qgroup; |
2488 | } | 2602 | } |
2489 | 2603 | ||
2490 | if (sb->s_flags & MS_RDONLY) | 2604 | if (sb->s_flags & MS_RDONLY) |
@@ -2508,6 +2622,8 @@ retry_root_backup: | |||
2508 | 2622 | ||
2509 | return 0; | 2623 | return 0; |
2510 | 2624 | ||
2625 | fail_qgroup: | ||
2626 | btrfs_free_qgroup_config(fs_info); | ||
2511 | fail_trans_kthread: | 2627 | fail_trans_kthread: |
2512 | kthread_stop(fs_info->transaction_kthread); | 2628 | kthread_stop(fs_info->transaction_kthread); |
2513 | fail_cleaner: | 2629 | fail_cleaner: |
@@ -3106,6 +3222,8 @@ int close_ctree(struct btrfs_root *root) | |||
3106 | fs_info->closing = 2; | 3222 | fs_info->closing = 2; |
3107 | smp_mb(); | 3223 | smp_mb(); |
3108 | 3224 | ||
3225 | btrfs_free_qgroup_config(root->fs_info); | ||
3226 | |||
3109 | if (fs_info->delalloc_bytes) { | 3227 | if (fs_info->delalloc_bytes) { |
3110 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", | 3228 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", |
3111 | (unsigned long long)fs_info->delalloc_bytes); | 3229 | (unsigned long long)fs_info->delalloc_bytes); |
@@ -3125,6 +3243,10 @@ int close_ctree(struct btrfs_root *root) | |||
3125 | free_extent_buffer(fs_info->dev_root->commit_root); | 3243 | free_extent_buffer(fs_info->dev_root->commit_root); |
3126 | free_extent_buffer(fs_info->csum_root->node); | 3244 | free_extent_buffer(fs_info->csum_root->node); |
3127 | free_extent_buffer(fs_info->csum_root->commit_root); | 3245 | free_extent_buffer(fs_info->csum_root->commit_root); |
3246 | if (fs_info->quota_root) { | ||
3247 | free_extent_buffer(fs_info->quota_root->node); | ||
3248 | free_extent_buffer(fs_info->quota_root->commit_root); | ||
3249 | } | ||
3128 | 3250 | ||
3129 | btrfs_free_block_groups(fs_info); | 3251 | btrfs_free_block_groups(fs_info); |
3130 | 3252 | ||
@@ -3255,7 +3377,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
3255 | return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 3377 | return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
3256 | } | 3378 | } |
3257 | 3379 | ||
3258 | static int btree_lock_page_hook(struct page *page, void *data, | 3380 | int btree_lock_page_hook(struct page *page, void *data, |
3259 | void (*flush_fn)(void *)) | 3381 | void (*flush_fn)(void *)) |
3260 | { | 3382 | { |
3261 | struct inode *inode = page->mapping->host; | 3383 | struct inode *inode = page->mapping->host; |