diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 155 |
1 files changed, 137 insertions, 18 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2936ca49b3b4..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, |
| @@ -1533,8 +1614,6 @@ static int cleaner_kthread(void *arg) | |||
| 1533 | struct btrfs_root *root = arg; | 1614 | struct btrfs_root *root = arg; |
| 1534 | 1615 | ||
| 1535 | do { | 1616 | do { |
| 1536 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | ||
| 1537 | |||
| 1538 | if (!(root->fs_info->sb->s_flags & MS_RDONLY) && | 1617 | if (!(root->fs_info->sb->s_flags & MS_RDONLY) && |
| 1539 | mutex_trylock(&root->fs_info->cleaner_mutex)) { | 1618 | mutex_trylock(&root->fs_info->cleaner_mutex)) { |
| 1540 | btrfs_run_delayed_iputs(root); | 1619 | btrfs_run_delayed_iputs(root); |
| @@ -1566,7 +1645,6 @@ static int transaction_kthread(void *arg) | |||
| 1566 | do { | 1645 | do { |
| 1567 | cannot_commit = false; | 1646 | cannot_commit = false; |
| 1568 | delay = HZ * 30; | 1647 | delay = HZ * 30; |
| 1569 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | ||
| 1570 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 1648 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
| 1571 | 1649 | ||
| 1572 | spin_lock(&root->fs_info->trans_lock); | 1650 | spin_lock(&root->fs_info->trans_lock); |
| @@ -1823,6 +1901,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
| 1823 | free_extent_buffer(info->extent_root->commit_root); | 1901 | free_extent_buffer(info->extent_root->commit_root); |
| 1824 | free_extent_buffer(info->csum_root->node); | 1902 | free_extent_buffer(info->csum_root->node); |
| 1825 | 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 | } | ||
| 1826 | 1908 | ||
| 1827 | info->tree_root->node = NULL; | 1909 | info->tree_root->node = NULL; |
| 1828 | info->tree_root->commit_root = NULL; | 1910 | info->tree_root->commit_root = NULL; |
| @@ -1832,6 +1914,10 @@ static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root) | |||
| 1832 | info->extent_root->commit_root = NULL; | 1914 | info->extent_root->commit_root = NULL; |
| 1833 | info->csum_root->node = NULL; | 1915 | info->csum_root->node = NULL; |
| 1834 | 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 | } | ||
| 1835 | 1921 | ||
| 1836 | if (chunk_root) { | 1922 | if (chunk_root) { |
| 1837 | free_extent_buffer(info->chunk_root->node); | 1923 | free_extent_buffer(info->chunk_root->node); |
| @@ -1862,6 +1948,7 @@ int open_ctree(struct super_block *sb, | |||
| 1862 | struct btrfs_root *csum_root; | 1948 | struct btrfs_root *csum_root; |
| 1863 | struct btrfs_root *chunk_root; | 1949 | struct btrfs_root *chunk_root; |
| 1864 | struct btrfs_root *dev_root; | 1950 | struct btrfs_root *dev_root; |
| 1951 | struct btrfs_root *quota_root; | ||
| 1865 | struct btrfs_root *log_tree_root; | 1952 | struct btrfs_root *log_tree_root; |
| 1866 | int ret; | 1953 | int ret; |
| 1867 | int err = -EINVAL; | 1954 | int err = -EINVAL; |
| @@ -1873,9 +1960,10 @@ int open_ctree(struct super_block *sb, | |||
| 1873 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); | 1960 | csum_root = fs_info->csum_root = btrfs_alloc_root(fs_info); |
| 1874 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); | 1961 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); |
| 1875 | 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); | ||
| 1876 | 1964 | ||
| 1877 | if (!tree_root || !extent_root || !csum_root || | 1965 | if (!tree_root || !extent_root || !csum_root || |
| 1878 | !chunk_root || !dev_root) { | 1966 | !chunk_root || !dev_root || !quota_root) { |
| 1879 | err = -ENOMEM; | 1967 | err = -ENOMEM; |
| 1880 | goto fail; | 1968 | goto fail; |
| 1881 | } | 1969 | } |
| @@ -1944,6 +2032,8 @@ int open_ctree(struct super_block *sb, | |||
| 1944 | fs_info->free_chunk_space = 0; | 2032 | fs_info->free_chunk_space = 0; |
| 1945 | fs_info->tree_mod_log = RB_ROOT; | 2033 | fs_info->tree_mod_log = RB_ROOT; |
| 1946 | 2034 | ||
| 2035 | init_waitqueue_head(&fs_info->tree_mod_seq_wait); | ||
| 2036 | |||
| 1947 | /* readahead state */ | 2037 | /* readahead state */ |
| 1948 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); | 2038 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); |
| 1949 | spin_lock_init(&fs_info->reada_lock); | 2039 | spin_lock_init(&fs_info->reada_lock); |
| @@ -2032,6 +2122,13 @@ int open_ctree(struct super_block *sb, | |||
| 2032 | init_rwsem(&fs_info->cleanup_work_sem); | 2122 | init_rwsem(&fs_info->cleanup_work_sem); |
| 2033 | init_rwsem(&fs_info->subvol_sem); | 2123 | init_rwsem(&fs_info->subvol_sem); |
| 2034 | 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 | |||
| 2035 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | 2132 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); |
| 2036 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | 2133 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); |
| 2037 | 2134 | ||
| @@ -2244,7 +2341,7 @@ int open_ctree(struct super_block *sb, | |||
| 2244 | ret |= btrfs_start_workers(&fs_info->caching_workers); | 2341 | ret |= btrfs_start_workers(&fs_info->caching_workers); |
| 2245 | ret |= btrfs_start_workers(&fs_info->readahead_workers); | 2342 | ret |= btrfs_start_workers(&fs_info->readahead_workers); |
| 2246 | if (ret) { | 2343 | if (ret) { |
| 2247 | ret = -ENOMEM; | 2344 | err = -ENOMEM; |
| 2248 | goto fail_sb_buffer; | 2345 | goto fail_sb_buffer; |
| 2249 | } | 2346 | } |
| 2250 | 2347 | ||
| @@ -2356,6 +2453,17 @@ retry_root_backup: | |||
| 2356 | goto recovery_tree_root; | 2453 | goto recovery_tree_root; |
| 2357 | csum_root->track_dirty = 1; | 2454 | csum_root->track_dirty = 1; |
| 2358 | 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 | |||
| 2359 | fs_info->generation = generation; | 2467 | fs_info->generation = generation; |
| 2360 | fs_info->last_trans_committed = generation; | 2468 | fs_info->last_trans_committed = generation; |
| 2361 | 2469 | ||
| @@ -2415,6 +2523,9 @@ retry_root_backup: | |||
| 2415 | " integrity check module %s\n", sb->s_id); | 2523 | " integrity check module %s\n", sb->s_id); |
| 2416 | } | 2524 | } |
| 2417 | #endif | 2525 | #endif |
| 2526 | ret = btrfs_read_qgroup_config(fs_info); | ||
| 2527 | if (ret) | ||
| 2528 | goto fail_trans_kthread; | ||
| 2418 | 2529 | ||
| 2419 | /* do not make disk changes in broken FS */ | 2530 | /* do not make disk changes in broken FS */ |
| 2420 | if (btrfs_super_log_root(disk_super) != 0 && | 2531 | if (btrfs_super_log_root(disk_super) != 0 && |
| @@ -2425,7 +2536,7 @@ retry_root_backup: | |||
| 2425 | printk(KERN_WARNING "Btrfs log replay required " | 2536 | printk(KERN_WARNING "Btrfs log replay required " |
| 2426 | "on RO media\n"); | 2537 | "on RO media\n"); |
| 2427 | err = -EIO; | 2538 | err = -EIO; |
| 2428 | goto fail_trans_kthread; | 2539 | goto fail_qgroup; |
| 2429 | } | 2540 | } |
| 2430 | blocksize = | 2541 | blocksize = |
| 2431 | btrfs_level_size(tree_root, | 2542 | btrfs_level_size(tree_root, |
| @@ -2434,7 +2545,7 @@ retry_root_backup: | |||
| 2434 | log_tree_root = btrfs_alloc_root(fs_info); | 2545 | log_tree_root = btrfs_alloc_root(fs_info); |
| 2435 | if (!log_tree_root) { | 2546 | if (!log_tree_root) { |
| 2436 | err = -ENOMEM; | 2547 | err = -ENOMEM; |
| 2437 | goto fail_trans_kthread; | 2548 | goto fail_qgroup; |
| 2438 | } | 2549 | } |
| 2439 | 2550 | ||
| 2440 | __setup_root(nodesize, leafsize, sectorsize, stripesize, | 2551 | __setup_root(nodesize, leafsize, sectorsize, stripesize, |
| @@ -2466,15 +2577,15 @@ retry_root_backup: | |||
| 2466 | 2577 | ||
| 2467 | if (!(sb->s_flags & MS_RDONLY)) { | 2578 | if (!(sb->s_flags & MS_RDONLY)) { |
| 2468 | ret = btrfs_cleanup_fs_roots(fs_info); | 2579 | ret = btrfs_cleanup_fs_roots(fs_info); |
| 2469 | if (ret) { | 2580 | if (ret) |
| 2470 | } | 2581 | goto fail_trans_kthread; |
| 2471 | 2582 | ||
| 2472 | ret = btrfs_recover_relocation(tree_root); | 2583 | ret = btrfs_recover_relocation(tree_root); |
| 2473 | if (ret < 0) { | 2584 | if (ret < 0) { |
| 2474 | printk(KERN_WARNING | 2585 | printk(KERN_WARNING |
| 2475 | "btrfs: failed to recover relocation\n"); | 2586 | "btrfs: failed to recover relocation\n"); |
| 2476 | err = -EINVAL; | 2587 | err = -EINVAL; |
| 2477 | goto fail_trans_kthread; | 2588 | goto fail_qgroup; |
| 2478 | } | 2589 | } |
| 2479 | } | 2590 | } |
| 2480 | 2591 | ||
| @@ -2484,10 +2595,10 @@ retry_root_backup: | |||
| 2484 | 2595 | ||
| 2485 | 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); |
| 2486 | if (!fs_info->fs_root) | 2597 | if (!fs_info->fs_root) |
| 2487 | goto fail_trans_kthread; | 2598 | goto fail_qgroup; |
| 2488 | if (IS_ERR(fs_info->fs_root)) { | 2599 | if (IS_ERR(fs_info->fs_root)) { |
| 2489 | err = PTR_ERR(fs_info->fs_root); | 2600 | err = PTR_ERR(fs_info->fs_root); |
| 2490 | goto fail_trans_kthread; | 2601 | goto fail_qgroup; |
| 2491 | } | 2602 | } |
| 2492 | 2603 | ||
| 2493 | if (sb->s_flags & MS_RDONLY) | 2604 | if (sb->s_flags & MS_RDONLY) |
| @@ -2511,6 +2622,8 @@ retry_root_backup: | |||
| 2511 | 2622 | ||
| 2512 | return 0; | 2623 | return 0; |
| 2513 | 2624 | ||
| 2625 | fail_qgroup: | ||
| 2626 | btrfs_free_qgroup_config(fs_info); | ||
| 2514 | fail_trans_kthread: | 2627 | fail_trans_kthread: |
| 2515 | kthread_stop(fs_info->transaction_kthread); | 2628 | kthread_stop(fs_info->transaction_kthread); |
| 2516 | fail_cleaner: | 2629 | fail_cleaner: |
| @@ -3109,6 +3222,8 @@ int close_ctree(struct btrfs_root *root) | |||
| 3109 | fs_info->closing = 2; | 3222 | fs_info->closing = 2; |
| 3110 | smp_mb(); | 3223 | smp_mb(); |
| 3111 | 3224 | ||
| 3225 | btrfs_free_qgroup_config(root->fs_info); | ||
| 3226 | |||
| 3112 | if (fs_info->delalloc_bytes) { | 3227 | if (fs_info->delalloc_bytes) { |
| 3113 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", | 3228 | printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n", |
| 3114 | (unsigned long long)fs_info->delalloc_bytes); | 3229 | (unsigned long long)fs_info->delalloc_bytes); |
| @@ -3128,6 +3243,10 @@ int close_ctree(struct btrfs_root *root) | |||
| 3128 | free_extent_buffer(fs_info->dev_root->commit_root); | 3243 | free_extent_buffer(fs_info->dev_root->commit_root); |
| 3129 | free_extent_buffer(fs_info->csum_root->node); | 3244 | free_extent_buffer(fs_info->csum_root->node); |
| 3130 | 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 | } | ||
| 3131 | 3250 | ||
| 3132 | btrfs_free_block_groups(fs_info); | 3251 | btrfs_free_block_groups(fs_info); |
| 3133 | 3252 | ||
| @@ -3258,7 +3377,7 @@ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid) | |||
| 3258 | return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 3377 | return btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
| 3259 | } | 3378 | } |
| 3260 | 3379 | ||
| 3261 | static int btree_lock_page_hook(struct page *page, void *data, | 3380 | int btree_lock_page_hook(struct page *page, void *data, |
| 3262 | void (*flush_fn)(void *)) | 3381 | void (*flush_fn)(void *)) |
| 3263 | { | 3382 | { |
| 3264 | struct inode *inode = page->mapping->host; | 3383 | struct inode *inode = page->mapping->host; |
