diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 169 |
1 files changed, 78 insertions, 91 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index feca04197d02..f3b287c22caf 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -74,6 +74,11 @@ struct async_submit_bio { | |||
74 | int rw; | 74 | int rw; |
75 | int mirror_num; | 75 | int mirror_num; |
76 | unsigned long bio_flags; | 76 | unsigned long bio_flags; |
77 | /* | ||
78 | * bio_offset is optional, can be used if the pages in the bio | ||
79 | * can't tell us where in the file the bio should go | ||
80 | */ | ||
81 | u64 bio_offset; | ||
77 | struct btrfs_work work; | 82 | struct btrfs_work work; |
78 | }; | 83 | }; |
79 | 84 | ||
@@ -534,7 +539,8 @@ static void run_one_async_start(struct btrfs_work *work) | |||
534 | async = container_of(work, struct async_submit_bio, work); | 539 | async = container_of(work, struct async_submit_bio, work); |
535 | fs_info = BTRFS_I(async->inode)->root->fs_info; | 540 | fs_info = BTRFS_I(async->inode)->root->fs_info; |
536 | async->submit_bio_start(async->inode, async->rw, async->bio, | 541 | async->submit_bio_start(async->inode, async->rw, async->bio, |
537 | async->mirror_num, async->bio_flags); | 542 | async->mirror_num, async->bio_flags, |
543 | async->bio_offset); | ||
538 | } | 544 | } |
539 | 545 | ||
540 | static void run_one_async_done(struct btrfs_work *work) | 546 | static void run_one_async_done(struct btrfs_work *work) |
@@ -556,7 +562,8 @@ static void run_one_async_done(struct btrfs_work *work) | |||
556 | wake_up(&fs_info->async_submit_wait); | 562 | wake_up(&fs_info->async_submit_wait); |
557 | 563 | ||
558 | async->submit_bio_done(async->inode, async->rw, async->bio, | 564 | async->submit_bio_done(async->inode, async->rw, async->bio, |
559 | async->mirror_num, async->bio_flags); | 565 | async->mirror_num, async->bio_flags, |
566 | async->bio_offset); | ||
560 | } | 567 | } |
561 | 568 | ||
562 | static void run_one_async_free(struct btrfs_work *work) | 569 | static void run_one_async_free(struct btrfs_work *work) |
@@ -570,6 +577,7 @@ static void run_one_async_free(struct btrfs_work *work) | |||
570 | int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | 577 | int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, |
571 | int rw, struct bio *bio, int mirror_num, | 578 | int rw, struct bio *bio, int mirror_num, |
572 | unsigned long bio_flags, | 579 | unsigned long bio_flags, |
580 | u64 bio_offset, | ||
573 | extent_submit_bio_hook_t *submit_bio_start, | 581 | extent_submit_bio_hook_t *submit_bio_start, |
574 | extent_submit_bio_hook_t *submit_bio_done) | 582 | extent_submit_bio_hook_t *submit_bio_done) |
575 | { | 583 | { |
@@ -592,6 +600,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
592 | 600 | ||
593 | async->work.flags = 0; | 601 | async->work.flags = 0; |
594 | async->bio_flags = bio_flags; | 602 | async->bio_flags = bio_flags; |
603 | async->bio_offset = bio_offset; | ||
595 | 604 | ||
596 | atomic_inc(&fs_info->nr_async_submits); | 605 | atomic_inc(&fs_info->nr_async_submits); |
597 | 606 | ||
@@ -627,7 +636,8 @@ static int btree_csum_one_bio(struct bio *bio) | |||
627 | 636 | ||
628 | static int __btree_submit_bio_start(struct inode *inode, int rw, | 637 | static int __btree_submit_bio_start(struct inode *inode, int rw, |
629 | struct bio *bio, int mirror_num, | 638 | struct bio *bio, int mirror_num, |
630 | unsigned long bio_flags) | 639 | unsigned long bio_flags, |
640 | u64 bio_offset) | ||
631 | { | 641 | { |
632 | /* | 642 | /* |
633 | * when we're called for a write, we're already in the async | 643 | * when we're called for a write, we're already in the async |
@@ -638,7 +648,8 @@ static int __btree_submit_bio_start(struct inode *inode, int rw, | |||
638 | } | 648 | } |
639 | 649 | ||
640 | static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | 650 | static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio, |
641 | int mirror_num, unsigned long bio_flags) | 651 | int mirror_num, unsigned long bio_flags, |
652 | u64 bio_offset) | ||
642 | { | 653 | { |
643 | /* | 654 | /* |
644 | * when we're called for a write, we're already in the async | 655 | * when we're called for a write, we're already in the async |
@@ -648,7 +659,8 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio, | |||
648 | } | 659 | } |
649 | 660 | ||
650 | static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | 661 | static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, |
651 | int mirror_num, unsigned long bio_flags) | 662 | int mirror_num, unsigned long bio_flags, |
663 | u64 bio_offset) | ||
652 | { | 664 | { |
653 | int ret; | 665 | int ret; |
654 | 666 | ||
@@ -671,6 +683,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
671 | */ | 683 | */ |
672 | return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | 684 | return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, |
673 | inode, rw, bio, mirror_num, 0, | 685 | inode, rw, bio, mirror_num, 0, |
686 | bio_offset, | ||
674 | __btree_submit_bio_start, | 687 | __btree_submit_bio_start, |
675 | __btree_submit_bio_done); | 688 | __btree_submit_bio_done); |
676 | } | 689 | } |
@@ -894,7 +907,8 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
894 | root->ref_cows = 0; | 907 | root->ref_cows = 0; |
895 | root->track_dirty = 0; | 908 | root->track_dirty = 0; |
896 | root->in_radix = 0; | 909 | root->in_radix = 0; |
897 | root->clean_orphans = 0; | 910 | root->orphan_item_inserted = 0; |
911 | root->orphan_cleanup_state = 0; | ||
898 | 912 | ||
899 | root->fs_info = fs_info; | 913 | root->fs_info = fs_info; |
900 | root->objectid = objectid; | 914 | root->objectid = objectid; |
@@ -903,13 +917,16 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
903 | root->name = NULL; | 917 | root->name = NULL; |
904 | root->in_sysfs = 0; | 918 | root->in_sysfs = 0; |
905 | root->inode_tree = RB_ROOT; | 919 | root->inode_tree = RB_ROOT; |
920 | root->block_rsv = NULL; | ||
921 | root->orphan_block_rsv = NULL; | ||
906 | 922 | ||
907 | INIT_LIST_HEAD(&root->dirty_list); | 923 | INIT_LIST_HEAD(&root->dirty_list); |
908 | INIT_LIST_HEAD(&root->orphan_list); | 924 | INIT_LIST_HEAD(&root->orphan_list); |
909 | INIT_LIST_HEAD(&root->root_list); | 925 | INIT_LIST_HEAD(&root->root_list); |
910 | spin_lock_init(&root->node_lock); | 926 | spin_lock_init(&root->node_lock); |
911 | spin_lock_init(&root->list_lock); | 927 | spin_lock_init(&root->orphan_lock); |
912 | spin_lock_init(&root->inode_lock); | 928 | spin_lock_init(&root->inode_lock); |
929 | spin_lock_init(&root->accounting_lock); | ||
913 | mutex_init(&root->objectid_mutex); | 930 | mutex_init(&root->objectid_mutex); |
914 | mutex_init(&root->log_mutex); | 931 | mutex_init(&root->log_mutex); |
915 | init_waitqueue_head(&root->log_writer_wait); | 932 | init_waitqueue_head(&root->log_writer_wait); |
@@ -968,42 +985,6 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
968 | return 0; | 985 | return 0; |
969 | } | 986 | } |
970 | 987 | ||
971 | int btrfs_free_log_root_tree(struct btrfs_trans_handle *trans, | ||
972 | struct btrfs_fs_info *fs_info) | ||
973 | { | ||
974 | struct extent_buffer *eb; | ||
975 | struct btrfs_root *log_root_tree = fs_info->log_root_tree; | ||
976 | u64 start = 0; | ||
977 | u64 end = 0; | ||
978 | int ret; | ||
979 | |||
980 | if (!log_root_tree) | ||
981 | return 0; | ||
982 | |||
983 | while (1) { | ||
984 | ret = find_first_extent_bit(&log_root_tree->dirty_log_pages, | ||
985 | 0, &start, &end, EXTENT_DIRTY | EXTENT_NEW); | ||
986 | if (ret) | ||
987 | break; | ||
988 | |||
989 | clear_extent_bits(&log_root_tree->dirty_log_pages, start, end, | ||
990 | EXTENT_DIRTY | EXTENT_NEW, GFP_NOFS); | ||
991 | } | ||
992 | eb = fs_info->log_root_tree->node; | ||
993 | |||
994 | WARN_ON(btrfs_header_level(eb) != 0); | ||
995 | WARN_ON(btrfs_header_nritems(eb) != 0); | ||
996 | |||
997 | ret = btrfs_free_reserved_extent(fs_info->tree_root, | ||
998 | eb->start, eb->len); | ||
999 | BUG_ON(ret); | ||
1000 | |||
1001 | free_extent_buffer(eb); | ||
1002 | kfree(fs_info->log_root_tree); | ||
1003 | fs_info->log_root_tree = NULL; | ||
1004 | return 0; | ||
1005 | } | ||
1006 | |||
1007 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | 988 | static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, |
1008 | struct btrfs_fs_info *fs_info) | 989 | struct btrfs_fs_info *fs_info) |
1009 | { | 990 | { |
@@ -1191,19 +1172,23 @@ again: | |||
1191 | if (root) | 1172 | if (root) |
1192 | return root; | 1173 | return root; |
1193 | 1174 | ||
1194 | ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid); | ||
1195 | if (ret == 0) | ||
1196 | ret = -ENOENT; | ||
1197 | if (ret < 0) | ||
1198 | return ERR_PTR(ret); | ||
1199 | |||
1200 | root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); | 1175 | root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); |
1201 | if (IS_ERR(root)) | 1176 | if (IS_ERR(root)) |
1202 | return root; | 1177 | return root; |
1203 | 1178 | ||
1204 | WARN_ON(btrfs_root_refs(&root->root_item) == 0); | ||
1205 | set_anon_super(&root->anon_super, NULL); | 1179 | set_anon_super(&root->anon_super, NULL); |
1206 | 1180 | ||
1181 | if (btrfs_root_refs(&root->root_item) == 0) { | ||
1182 | ret = -ENOENT; | ||
1183 | goto fail; | ||
1184 | } | ||
1185 | |||
1186 | ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid); | ||
1187 | if (ret < 0) | ||
1188 | goto fail; | ||
1189 | if (ret == 0) | ||
1190 | root->orphan_item_inserted = 1; | ||
1191 | |||
1207 | ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); | 1192 | ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); |
1208 | if (ret) | 1193 | if (ret) |
1209 | goto fail; | 1194 | goto fail; |
@@ -1212,10 +1197,9 @@ again: | |||
1212 | ret = radix_tree_insert(&fs_info->fs_roots_radix, | 1197 | ret = radix_tree_insert(&fs_info->fs_roots_radix, |
1213 | (unsigned long)root->root_key.objectid, | 1198 | (unsigned long)root->root_key.objectid, |
1214 | root); | 1199 | root); |
1215 | if (ret == 0) { | 1200 | if (ret == 0) |
1216 | root->in_radix = 1; | 1201 | root->in_radix = 1; |
1217 | root->clean_orphans = 1; | 1202 | |
1218 | } | ||
1219 | spin_unlock(&fs_info->fs_roots_radix_lock); | 1203 | spin_unlock(&fs_info->fs_roots_radix_lock); |
1220 | radix_tree_preload_end(); | 1204 | radix_tree_preload_end(); |
1221 | if (ret) { | 1205 | if (ret) { |
@@ -1461,10 +1445,6 @@ static int cleaner_kthread(void *arg) | |||
1461 | struct btrfs_root *root = arg; | 1445 | struct btrfs_root *root = arg; |
1462 | 1446 | ||
1463 | do { | 1447 | do { |
1464 | smp_mb(); | ||
1465 | if (root->fs_info->closing) | ||
1466 | break; | ||
1467 | |||
1468 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | 1448 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); |
1469 | 1449 | ||
1470 | if (!(root->fs_info->sb->s_flags & MS_RDONLY) && | 1450 | if (!(root->fs_info->sb->s_flags & MS_RDONLY) && |
@@ -1477,11 +1457,9 @@ static int cleaner_kthread(void *arg) | |||
1477 | if (freezing(current)) { | 1457 | if (freezing(current)) { |
1478 | refrigerator(); | 1458 | refrigerator(); |
1479 | } else { | 1459 | } else { |
1480 | smp_mb(); | ||
1481 | if (root->fs_info->closing) | ||
1482 | break; | ||
1483 | set_current_state(TASK_INTERRUPTIBLE); | 1460 | set_current_state(TASK_INTERRUPTIBLE); |
1484 | schedule(); | 1461 | if (!kthread_should_stop()) |
1462 | schedule(); | ||
1485 | __set_current_state(TASK_RUNNING); | 1463 | __set_current_state(TASK_RUNNING); |
1486 | } | 1464 | } |
1487 | } while (!kthread_should_stop()); | 1465 | } while (!kthread_should_stop()); |
@@ -1493,36 +1471,40 @@ static int transaction_kthread(void *arg) | |||
1493 | struct btrfs_root *root = arg; | 1471 | struct btrfs_root *root = arg; |
1494 | struct btrfs_trans_handle *trans; | 1472 | struct btrfs_trans_handle *trans; |
1495 | struct btrfs_transaction *cur; | 1473 | struct btrfs_transaction *cur; |
1474 | u64 transid; | ||
1496 | unsigned long now; | 1475 | unsigned long now; |
1497 | unsigned long delay; | 1476 | unsigned long delay; |
1498 | int ret; | 1477 | int ret; |
1499 | 1478 | ||
1500 | do { | 1479 | do { |
1501 | smp_mb(); | ||
1502 | if (root->fs_info->closing) | ||
1503 | break; | ||
1504 | |||
1505 | delay = HZ * 30; | 1480 | delay = HZ * 30; |
1506 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | 1481 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); |
1507 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 1482 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
1508 | 1483 | ||
1509 | mutex_lock(&root->fs_info->trans_mutex); | 1484 | spin_lock(&root->fs_info->new_trans_lock); |
1510 | cur = root->fs_info->running_transaction; | 1485 | cur = root->fs_info->running_transaction; |
1511 | if (!cur) { | 1486 | if (!cur) { |
1512 | mutex_unlock(&root->fs_info->trans_mutex); | 1487 | spin_unlock(&root->fs_info->new_trans_lock); |
1513 | goto sleep; | 1488 | goto sleep; |
1514 | } | 1489 | } |
1515 | 1490 | ||
1516 | now = get_seconds(); | 1491 | now = get_seconds(); |
1517 | if (now < cur->start_time || now - cur->start_time < 30) { | 1492 | if (!cur->blocked && |
1518 | mutex_unlock(&root->fs_info->trans_mutex); | 1493 | (now < cur->start_time || now - cur->start_time < 30)) { |
1494 | spin_unlock(&root->fs_info->new_trans_lock); | ||
1519 | delay = HZ * 5; | 1495 | delay = HZ * 5; |
1520 | goto sleep; | 1496 | goto sleep; |
1521 | } | 1497 | } |
1522 | mutex_unlock(&root->fs_info->trans_mutex); | 1498 | transid = cur->transid; |
1523 | trans = btrfs_start_transaction(root, 1); | 1499 | spin_unlock(&root->fs_info->new_trans_lock); |
1524 | ret = btrfs_commit_transaction(trans, root); | ||
1525 | 1500 | ||
1501 | trans = btrfs_join_transaction(root, 1); | ||
1502 | if (transid == trans->transid) { | ||
1503 | ret = btrfs_commit_transaction(trans, root); | ||
1504 | BUG_ON(ret); | ||
1505 | } else { | ||
1506 | btrfs_end_transaction(trans, root); | ||
1507 | } | ||
1526 | sleep: | 1508 | sleep: |
1527 | wake_up_process(root->fs_info->cleaner_kthread); | 1509 | wake_up_process(root->fs_info->cleaner_kthread); |
1528 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 1510 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
@@ -1530,10 +1512,10 @@ sleep: | |||
1530 | if (freezing(current)) { | 1512 | if (freezing(current)) { |
1531 | refrigerator(); | 1513 | refrigerator(); |
1532 | } else { | 1514 | } else { |
1533 | if (root->fs_info->closing) | ||
1534 | break; | ||
1535 | set_current_state(TASK_INTERRUPTIBLE); | 1515 | set_current_state(TASK_INTERRUPTIBLE); |
1536 | schedule_timeout(delay); | 1516 | if (!kthread_should_stop() && |
1517 | !btrfs_transaction_blocked(root->fs_info)) | ||
1518 | schedule_timeout(delay); | ||
1537 | __set_current_state(TASK_RUNNING); | 1519 | __set_current_state(TASK_RUNNING); |
1538 | } | 1520 | } |
1539 | } while (!kthread_should_stop()); | 1521 | } while (!kthread_should_stop()); |
@@ -1620,6 +1602,13 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1620 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); | 1602 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); |
1621 | INIT_LIST_HEAD(&fs_info->space_info); | 1603 | INIT_LIST_HEAD(&fs_info->space_info); |
1622 | btrfs_mapping_init(&fs_info->mapping_tree); | 1604 | btrfs_mapping_init(&fs_info->mapping_tree); |
1605 | btrfs_init_block_rsv(&fs_info->global_block_rsv); | ||
1606 | btrfs_init_block_rsv(&fs_info->delalloc_block_rsv); | ||
1607 | btrfs_init_block_rsv(&fs_info->trans_block_rsv); | ||
1608 | btrfs_init_block_rsv(&fs_info->chunk_block_rsv); | ||
1609 | btrfs_init_block_rsv(&fs_info->empty_block_rsv); | ||
1610 | INIT_LIST_HEAD(&fs_info->durable_block_rsv_list); | ||
1611 | mutex_init(&fs_info->durable_block_rsv_mutex); | ||
1623 | atomic_set(&fs_info->nr_async_submits, 0); | 1612 | atomic_set(&fs_info->nr_async_submits, 0); |
1624 | atomic_set(&fs_info->async_delalloc_pages, 0); | 1613 | atomic_set(&fs_info->async_delalloc_pages, 0); |
1625 | atomic_set(&fs_info->async_submit_draining, 0); | 1614 | atomic_set(&fs_info->async_submit_draining, 0); |
@@ -1759,9 +1748,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1759 | min_t(u64, fs_devices->num_devices, | 1748 | min_t(u64, fs_devices->num_devices, |
1760 | fs_info->thread_pool_size), | 1749 | fs_info->thread_pool_size), |
1761 | &fs_info->generic_worker); | 1750 | &fs_info->generic_worker); |
1762 | btrfs_init_workers(&fs_info->enospc_workers, "enospc", | ||
1763 | fs_info->thread_pool_size, | ||
1764 | &fs_info->generic_worker); | ||
1765 | 1751 | ||
1766 | /* a higher idle thresh on the submit workers makes it much more | 1752 | /* a higher idle thresh on the submit workers makes it much more |
1767 | * likely that bios will be send down in a sane order to the | 1753 | * likely that bios will be send down in a sane order to the |
@@ -1809,7 +1795,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1809 | btrfs_start_workers(&fs_info->endio_meta_workers, 1); | 1795 | btrfs_start_workers(&fs_info->endio_meta_workers, 1); |
1810 | btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); | 1796 | btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); |
1811 | btrfs_start_workers(&fs_info->endio_write_workers, 1); | 1797 | btrfs_start_workers(&fs_info->endio_write_workers, 1); |
1812 | btrfs_start_workers(&fs_info->enospc_workers, 1); | ||
1813 | 1798 | ||
1814 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); | 1799 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); |
1815 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, | 1800 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, |
@@ -1912,17 +1897,18 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1912 | 1897 | ||
1913 | csum_root->track_dirty = 1; | 1898 | csum_root->track_dirty = 1; |
1914 | 1899 | ||
1900 | fs_info->generation = generation; | ||
1901 | fs_info->last_trans_committed = generation; | ||
1902 | fs_info->data_alloc_profile = (u64)-1; | ||
1903 | fs_info->metadata_alloc_profile = (u64)-1; | ||
1904 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | ||
1905 | |||
1915 | ret = btrfs_read_block_groups(extent_root); | 1906 | ret = btrfs_read_block_groups(extent_root); |
1916 | if (ret) { | 1907 | if (ret) { |
1917 | printk(KERN_ERR "Failed to read block groups: %d\n", ret); | 1908 | printk(KERN_ERR "Failed to read block groups: %d\n", ret); |
1918 | goto fail_block_groups; | 1909 | goto fail_block_groups; |
1919 | } | 1910 | } |
1920 | 1911 | ||
1921 | fs_info->generation = generation; | ||
1922 | fs_info->last_trans_committed = generation; | ||
1923 | fs_info->data_alloc_profile = (u64)-1; | ||
1924 | fs_info->metadata_alloc_profile = (u64)-1; | ||
1925 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | ||
1926 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 1912 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
1927 | "btrfs-cleaner"); | 1913 | "btrfs-cleaner"); |
1928 | if (IS_ERR(fs_info->cleaner_kthread)) | 1914 | if (IS_ERR(fs_info->cleaner_kthread)) |
@@ -1977,6 +1963,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1977 | BUG_ON(ret); | 1963 | BUG_ON(ret); |
1978 | 1964 | ||
1979 | if (!(sb->s_flags & MS_RDONLY)) { | 1965 | if (!(sb->s_flags & MS_RDONLY)) { |
1966 | ret = btrfs_cleanup_fs_roots(fs_info); | ||
1967 | BUG_ON(ret); | ||
1968 | |||
1980 | ret = btrfs_recover_relocation(tree_root); | 1969 | ret = btrfs_recover_relocation(tree_root); |
1981 | if (ret < 0) { | 1970 | if (ret < 0) { |
1982 | printk(KERN_WARNING | 1971 | printk(KERN_WARNING |
@@ -2040,7 +2029,6 @@ fail_sb_buffer: | |||
2040 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); | 2029 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); |
2041 | btrfs_stop_workers(&fs_info->endio_write_workers); | 2030 | btrfs_stop_workers(&fs_info->endio_write_workers); |
2042 | btrfs_stop_workers(&fs_info->submit_workers); | 2031 | btrfs_stop_workers(&fs_info->submit_workers); |
2043 | btrfs_stop_workers(&fs_info->enospc_workers); | ||
2044 | fail_iput: | 2032 | fail_iput: |
2045 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | 2033 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); |
2046 | iput(fs_info->btree_inode); | 2034 | iput(fs_info->btree_inode); |
@@ -2405,11 +2393,11 @@ int btrfs_commit_super(struct btrfs_root *root) | |||
2405 | down_write(&root->fs_info->cleanup_work_sem); | 2393 | down_write(&root->fs_info->cleanup_work_sem); |
2406 | up_write(&root->fs_info->cleanup_work_sem); | 2394 | up_write(&root->fs_info->cleanup_work_sem); |
2407 | 2395 | ||
2408 | trans = btrfs_start_transaction(root, 1); | 2396 | trans = btrfs_join_transaction(root, 1); |
2409 | ret = btrfs_commit_transaction(trans, root); | 2397 | ret = btrfs_commit_transaction(trans, root); |
2410 | BUG_ON(ret); | 2398 | BUG_ON(ret); |
2411 | /* run commit again to drop the original snapshot */ | 2399 | /* run commit again to drop the original snapshot */ |
2412 | trans = btrfs_start_transaction(root, 1); | 2400 | trans = btrfs_join_transaction(root, 1); |
2413 | btrfs_commit_transaction(trans, root); | 2401 | btrfs_commit_transaction(trans, root); |
2414 | ret = btrfs_write_and_wait_transaction(NULL, root); | 2402 | ret = btrfs_write_and_wait_transaction(NULL, root); |
2415 | BUG_ON(ret); | 2403 | BUG_ON(ret); |
@@ -2426,15 +2414,15 @@ int close_ctree(struct btrfs_root *root) | |||
2426 | fs_info->closing = 1; | 2414 | fs_info->closing = 1; |
2427 | smp_mb(); | 2415 | smp_mb(); |
2428 | 2416 | ||
2429 | kthread_stop(root->fs_info->transaction_kthread); | ||
2430 | kthread_stop(root->fs_info->cleaner_kthread); | ||
2431 | |||
2432 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { | 2417 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { |
2433 | ret = btrfs_commit_super(root); | 2418 | ret = btrfs_commit_super(root); |
2434 | if (ret) | 2419 | if (ret) |
2435 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); | 2420 | printk(KERN_ERR "btrfs: commit super ret %d\n", ret); |
2436 | } | 2421 | } |
2437 | 2422 | ||
2423 | kthread_stop(root->fs_info->transaction_kthread); | ||
2424 | kthread_stop(root->fs_info->cleaner_kthread); | ||
2425 | |||
2438 | fs_info->closing = 2; | 2426 | fs_info->closing = 2; |
2439 | smp_mb(); | 2427 | smp_mb(); |
2440 | 2428 | ||
@@ -2473,7 +2461,6 @@ int close_ctree(struct btrfs_root *root) | |||
2473 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); | 2461 | btrfs_stop_workers(&fs_info->endio_meta_write_workers); |
2474 | btrfs_stop_workers(&fs_info->endio_write_workers); | 2462 | btrfs_stop_workers(&fs_info->endio_write_workers); |
2475 | btrfs_stop_workers(&fs_info->submit_workers); | 2463 | btrfs_stop_workers(&fs_info->submit_workers); |
2476 | btrfs_stop_workers(&fs_info->enospc_workers); | ||
2477 | 2464 | ||
2478 | btrfs_close_devices(fs_info->fs_devices); | 2465 | btrfs_close_devices(fs_info->fs_devices); |
2479 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 2466 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |