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 2936ca49b3b4..fadeba6a5db9 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, |
@@ -1823,6 +1904,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1823 | free_extent_buffer(info->extent_root->commit_root); | 1904 | free_extent_buffer(info->extent_root->commit_root); |
1824 | free_extent_buffer(info->csum_root->node); | 1905 | free_extent_buffer(info->csum_root->node); |
1825 | free_extent_buffer(info->csum_root->commit_root); | 1906 | free_extent_buffer(info->csum_root->commit_root); |
1907 | if (info->quota_root) { | ||
1908 | free_extent_buffer(info->quota_root->node); | ||
1909 | free_extent_buffer(info->quota_root->commit_root); | ||
1910 | } | ||
1826 | 1911 | ||
1827 | info->tree_root->node = NULL; | 1912 | info->tree_root->node = NULL; |
1828 | info->tree_root->commit_root = NULL; | 1913 | info->tree_root->commit_root = NULL; |
@@ -1832,6 +1917,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
1832 | info->extent_root->commit_root = NULL; | 1917 | info->extent_root->commit_root = NULL; |
1833 | info->csum_root->node = NULL; | 1918 | info->csum_root->node = NULL; |
1834 | info->csum_root->commit_root = NULL; | 1919 | info->csum_root->commit_root = NULL; |
1920 | if (info->quota_root) { | ||
1921 | info->quota_root->node = NULL; | ||
1922 | info->quota_root->commit_root = NULL; | ||
1923 | } | ||
1835 | 1924 | ||
1836 | if (chunk_root) { | 1925 | if (chunk_root) { |
1837 | free_extent_buffer(info->chunk_root->node); | 1926 | free_extent_buffer(info->chunk_root->node); |
@@ -1862,6 +1951,7 @@ int open_ctree(struct super_block *sb, | |||
1862 | struct btrfs_root *csum_root; | 1951 | struct btrfs_root *csum_root; |
1863 | struct btrfs_root *chunk_root; | 1952 | struct btrfs_root *chunk_root; |
1864 | struct btrfs_root *dev_root; | 1953 | struct btrfs_root *dev_root; |
1954 | struct btrfs_root *quota_root; | ||
1865 | struct btrfs_root *log_tree_root; | 1955 | struct btrfs_root *log_tree_root; |
1866 | int ret; | 1956 | int ret; |
1867 | int err = -EINVAL; | 1957 | int err = -EINVAL; |
@@ -1873,9 +1963,10 @@ int open_ctree(struct super_block *sb, | |||
1873 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); | 1963 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); |
1874 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); | 1964 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); |
1875 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); | 1965 | dev_root = fs_info->dev_root = btrfs_alloc_root(fs_info); |
1966 | quota_root = fs_info->quota_root = btrfs_alloc_root(fs_info); | ||
1876 | 1967 | ||
1877 | if (!tree_root || !extent_root || !csum_root || | 1968 | if (!tree_root || !extent_root || !csum_root || |
1878 | !chunk_root || !dev_root) { | 1969 | !chunk_root || !dev_root || !quota_root) { |
1879 | err = -ENOMEM; | 1970 | err = -ENOMEM; |
1880 | goto fail; | 1971 | goto fail; |
1881 | } | 1972 | } |
@@ -1944,6 +2035,8 @@ int open_ctree(struct super_block *sb, | |||
1944 | fs_info->free_chunk_space = 0; | 2035 | fs_info->free_chunk_space = 0; |
1945 | fs_info->tree_mod_log = RB_ROOT; | 2036 | fs_info->tree_mod_log = RB_ROOT; |
1946 | 2037 | ||
2038 | init_waitqueue_head(&fs_info->tree_mod_seq_wait); | ||
2039 | |||
1947 | /* readahead state */ | 2040 | /* readahead state */ |
1948 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); | 2041 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); |
1949 | spin_lock_init(&fs_info->reada_lock); | 2042 | spin_lock_init(&fs_info->reada_lock); |
@@ -2032,6 +2125,13 @@ int open_ctree(struct super_block *sb, | |||
2032 | init_rwsem(&fs_info->cleanup_work_sem); | 2125 | init_rwsem(&fs_info->cleanup_work_sem); |
2033 | init_rwsem(&fs_info->subvol_sem); | 2126 | init_rwsem(&fs_info->subvol_sem); |
2034 | 2127 | ||
2128 | spin_lock_init(&fs_info->qgroup_lock); | ||
2129 | fs_info->qgroup_tree = RB_ROOT; | ||
2130 | INIT_LIST_HEAD(&fs_info->dirty_qgroups); | ||
2131 | fs_info->qgroup_seq = 1; | ||
2132 | fs_info->quota_enabled = 0; | ||
2133 | fs_info->pending_quota_state = 0; | ||
2134 | |||
2035 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | 2135 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); |
2036 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | 2136 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); |
2037 | 2137 | ||
@@ -2244,7 +2344,7 @@ int open_ctree(struct super_block *sb, | |||
2244 | ret |= btrfs_start_workers(&fs_info->caching_workers); | 2344 | ret |= btrfs_start_workers(&fs_info->caching_workers); |
2245 | ret |= btrfs_start_workers(&fs_info->readahead_workers); | 2345 | ret |= btrfs_start_workers(&fs_info->readahead_workers); |
2246 | if (ret) { | 2346 | if (ret) { |
2247 | ret = -ENOMEM; | 2347 | err = -ENOMEM; |
2248 | goto fail_sb_buffer; | 2348 | goto fail_sb_buffer; |
2249 | } | 2349 | } |
2250 | 2350 | ||
@@ -2356,6 +2456,17 @@ retry_root_backup: | |||
2356 | goto recovery_tree_root; | 2456 | goto recovery_tree_root; |
2357 | csum_root->track_dirty = 1; | 2457 | csum_root->track_dirty = 1; |
2358 | 2458 | ||
2459 | ret = find_and_setup_root(tree_root, fs_info, | ||
2460 | BTRFS_QUOTA_TREE_OBJECTID, quota_root); | ||
2461 | if (ret) { | ||
2462 | kfree(quota_root); | ||
2463 | quota_root = fs_info->quota_root = NULL; | ||
2464 | } else { | ||
2465 | quota_root->track_dirty = 1; | ||
2466 | fs_info->quota_enabled = 1; | ||
2467 | fs_info->pending_quota_state = 1; | ||
2468 | } | ||
2469 | |||
2359 | fs_info->generation = generation; | 2470 | fs_info->generation = generation; |
2360 | fs_info->last_trans_committed = generation; | 2471 | fs_info->last_trans_committed = generation; |
2361 | 2472 | ||
@@ -2415,6 +2526,9 @@ retry_root_backup: | |||
2415 | " integrity check module %s\n", sb->s_id); | 2526 | " integrity check module %s\n", sb->s_id); |
2416 | } | 2527 | } |
2417 | #endif | 2528 | #endif |
2529 | ret = btrfs_read_qgroup_config(fs_info); | ||
2530 | if (ret) | ||
2531 | goto fail_trans_kthread; | ||
2418 | 2532 | ||
2419 | /* do not make disk changes in broken FS */ | 2533 | /* do not make disk changes in broken FS */ |
2420 | if (btrfs_super_log_root(disk_super) != 0 && | 2534 | if (btrfs_super_log_root(disk_super) != 0 && |
@@ -2425,7 +2539,7 @@ retry_root_backup: | |||
2425 | printk(KERN_WARNING "Btrfs log replay required " | 2539 | printk(KERN_WARNING "Btrfs log replay required " |
2426 | "on RO media\n"); | 2540 | "on RO media\n"); |
2427 | err = -EIO; | 2541 | err = -EIO; |
2428 | goto fail_trans_kthread; | 2542 | goto fail_qgroup; |
2429 | } | 2543 | } |
2430 | blocksize = | 2544 | blocksize = |
2431 | btrfs_level_size(tree_root, | 2545 | btrfs_level_size(tree_root, |
@@ -2434,7 +2548,7 @@ retry_root_backup: | |||
2434 | log_tree_root = btrfs_alloc_root(fs_info); | 2548 | log_tree_root = btrfs_alloc_root(fs_info); |
2435 | if (!log_tree_root) { | 2549 | if (!log_tree_root) { |
2436 | err = -ENOMEM; | 2550 | err = -ENOMEM; |
2437 | goto fail_trans_kthread; | 2551 | goto fail_qgroup; |
2438 | } | 2552 | } |
2439 | 2553 | ||
2440 | __setup_root(nodesize, leafsize, sectorsize, stripesize, | 2554 | __setup_root(nodesize, leafsize, sectorsize, stripesize, |
@@ -2466,15 +2580,15 @@ retry_root_backup: | |||
2466 | 2580 | ||
2467 | if (!(sb->s_flags & MS_RDONLY)) { | 2581 | if (!(sb->s_flags & MS_RDONLY)) { |
2468 | ret = btrfs_cleanup_fs_roots(fs_info); | 2582 | ret = btrfs_cleanup_fs_roots(fs_info); |
2469 | if (ret) { | 2583 | if (ret) |
2470 | } | 2584 | goto fail_trans_kthread; |
2471 | 2585 | ||
2472 | ret = btrfs_recover_relocation(tree_root); | 2586 | ret = btrfs_recover_relocation(tree_root); |
2473 | if (ret < 0) { | 2587 | if (ret < 0) { |
2474 | printk(KERN_WARNING | 2588 | printk(KERN_WARNING |
2475 | "btrfs: failed to recover relocation\n"); | 2589 | "btrfs: failed to recover relocation\n"); |
2476 | err = -EINVAL; | 2590 | err = -EINVAL; |
2477 | goto fail_trans_kthread; | 2591 | goto fail_qgroup; |
2478 | } | 2592 | } |
2479 | } | 2593 | } |
2480 | 2594 | ||
@@ -2484,10 +2598,10 @@ retry_root_backup: | |||
2484 | 2598 | ||
2485 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); | 2599 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); |
2486 | if (!fs_info->fs_root) | 2600 | if (!fs_info->fs_root) |
2487 | goto fail_trans_kthread; | 2601 | goto fail_qgroup; |
2488 | if (IS_ERR(fs_info->fs_root)) { | 2602 | if (IS_ERR(fs_info->fs_root)) { |
2489 | err = PTR_ERR(fs_info->fs_root); | 2603 | err = PTR_ERR(fs_info->fs_root); |
2490 | goto fail_trans_kthread; | 2604 | goto fail_qgroup; |
2491 | } | 2605 | } |
2492 | 2606 | ||
2493 | if (sb->s_flags & MS_RDONLY) | 2607 | if (sb->s_flags & MS_RDONLY) |
@@ -2511,6 +2625,8 @@ retry_root_backup: | |||
2511 | 2625 | ||
2512 | return 0; | 2626 | return 0; |
2513 | 2627 | ||
2628 | fail_qgroup: | ||
2629 | btrfs_free_qgroup_config(fs_info); | ||
2514 | fail_trans_kthread: | 2630 | fail_trans_kthread: |
2515 | kthread_stop(fs_info->transaction_kthread); | 2631 | kthread_stop(fs_info->transaction_kthread); |
2516 | fail_cleaner: | 2632 | fail_cleaner: |
@@ -3109,6 +3225,8 @@ int close_ctree(struct btrfs_root *root) | |||
3109 | fs_info->closing = 2; | 3225 | fs_info->closing = 2; |
3110 | smp_mb(); | 3226 | smp_mb(); |
3111 | 3227 | ||
3228 | btrfs_free_qgroup_config(root->fs_info); | ||
3229 | |||
3112 | if (fs_info->delalloc_bytes) { | 3230 | if (fs_info->delalloc_bytes) { |
3113 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", | 3231 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", |
3114 | (unsigned long long)fs_info->delalloc_bytes); | 3232 | (unsigned long long)fs_info->delalloc_bytes); |
@@ -3128,6 +3246,10 @@ int close_ctree(struct btrfs_root *root) | |||
3128 | free_extent_buffer(fs_info->dev_root->commit_root); | 3246 | free_extent_buffer(fs_info->dev_root->commit_root); |
3129 | free_extent_buffer(fs_info->csum_root->node); | 3247 | free_extent_buffer(fs_info->csum_root->node); |
3130 | free_extent_buffer(fs_info->csum_root->commit_root); | 3248 | free_extent_buffer(fs_info->csum_root->commit_root); |
3249 | if (fs_info->quota_root) { | ||
3250 | free_extent_buffer(fs_info->quota_root->node); | ||
3251 | free_extent_buffer(fs_info->quota_root->commit_root); | ||
3252 | } | ||
3131 | 3253 | ||
3132 | btrfs_free_block_groups(fs_info); | 3254 | btrfs_free_block_groups(fs_info); |
3133 | 3255 | ||
@@ -3258,7 +3380,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
3258 | return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 3380 | return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
3259 | } | 3381 | } |
3260 | 3382 | ||
3261 | static int btree_lock_page_hook(struct page *page, void *data, | 3383 | int btree_lock_page_hook(struct page *page, void *data, |
3262 | void (*flush_fn)(void *)) | 3384 | void (*flush_fn)(void *)) |
3263 | { | 3385 | { |
3264 | struct inode *inode = page->mapping->host; | 3386 | struct inode *inode = page->mapping->host; |