diff options
-rw-r--r-- | fs/btrfs/dev-replace.c | 2 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 7 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 5 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 1 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 87 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 13 |
6 files changed, 51 insertions, 64 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index ee193c5222b2..dba43ada41d1 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -662,7 +662,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
662 | btrfs_device_set_disk_total_bytes(tgt_device, | 662 | btrfs_device_set_disk_total_bytes(tgt_device, |
663 | src_device->disk_total_bytes); | 663 | src_device->disk_total_bytes); |
664 | btrfs_device_set_bytes_used(tgt_device, src_device->bytes_used); | 664 | btrfs_device_set_bytes_used(tgt_device, src_device->bytes_used); |
665 | ASSERT(list_empty(&src_device->resized_list)); | 665 | ASSERT(list_empty(&src_device->post_commit_list)); |
666 | tgt_device->commit_total_bytes = src_device->commit_total_bytes; | 666 | tgt_device->commit_total_bytes = src_device->commit_total_bytes; |
667 | tgt_device->commit_bytes_used = src_device->bytes_used; | 667 | tgt_device->commit_bytes_used = src_device->bytes_used; |
668 | 668 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 0fa65aca56a3..de1dcccc7c9d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -4479,10 +4479,17 @@ void btrfs_cleanup_dirty_bgs(struct btrfs_transaction *cur_trans, | |||
4479 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | 4479 | void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, |
4480 | struct btrfs_fs_info *fs_info) | 4480 | struct btrfs_fs_info *fs_info) |
4481 | { | 4481 | { |
4482 | struct btrfs_device *dev, *tmp; | ||
4483 | |||
4482 | btrfs_cleanup_dirty_bgs(cur_trans, fs_info); | 4484 | btrfs_cleanup_dirty_bgs(cur_trans, fs_info); |
4483 | ASSERT(list_empty(&cur_trans->dirty_bgs)); | 4485 | ASSERT(list_empty(&cur_trans->dirty_bgs)); |
4484 | ASSERT(list_empty(&cur_trans->io_bgs)); | 4486 | ASSERT(list_empty(&cur_trans->io_bgs)); |
4485 | 4487 | ||
4488 | list_for_each_entry_safe(dev, tmp, &cur_trans->dev_update_list, | ||
4489 | post_commit_list) { | ||
4490 | list_del_init(&dev->post_commit_list); | ||
4491 | } | ||
4492 | |||
4486 | btrfs_destroy_delayed_refs(cur_trans, fs_info); | 4493 | btrfs_destroy_delayed_refs(cur_trans, fs_info); |
4487 | 4494 | ||
4488 | cur_trans->state = TRANS_STATE_COMMIT_START; | 4495 | cur_trans->state = TRANS_STATE_COMMIT_START; |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f1732b77a379..4aa827a2e951 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -75,6 +75,7 @@ void btrfs_put_transaction(struct btrfs_transaction *transaction) | |||
75 | btrfs_put_block_group_trimming(cache); | 75 | btrfs_put_block_group_trimming(cache); |
76 | btrfs_put_block_group(cache); | 76 | btrfs_put_block_group(cache); |
77 | } | 77 | } |
78 | WARN_ON(!list_empty(&transaction->dev_update_list)); | ||
78 | kfree(transaction); | 79 | kfree(transaction); |
79 | } | 80 | } |
80 | } | 81 | } |
@@ -264,6 +265,7 @@ loop: | |||
264 | 265 | ||
265 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 266 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
266 | INIT_LIST_HEAD(&cur_trans->pending_chunks); | 267 | INIT_LIST_HEAD(&cur_trans->pending_chunks); |
268 | INIT_LIST_HEAD(&cur_trans->dev_update_list); | ||
267 | INIT_LIST_HEAD(&cur_trans->switch_commits); | 269 | INIT_LIST_HEAD(&cur_trans->switch_commits); |
268 | INIT_LIST_HEAD(&cur_trans->dirty_bgs); | 270 | INIT_LIST_HEAD(&cur_trans->dirty_bgs); |
269 | INIT_LIST_HEAD(&cur_trans->io_bgs); | 271 | INIT_LIST_HEAD(&cur_trans->io_bgs); |
@@ -2241,8 +2243,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans) | |||
2241 | memcpy(fs_info->super_for_commit, fs_info->super_copy, | 2243 | memcpy(fs_info->super_for_commit, fs_info->super_copy, |
2242 | sizeof(*fs_info->super_copy)); | 2244 | sizeof(*fs_info->super_copy)); |
2243 | 2245 | ||
2244 | btrfs_update_commit_device_size(fs_info); | 2246 | btrfs_commit_device_sizes(cur_trans); |
2245 | btrfs_update_commit_device_bytes_used(cur_trans); | ||
2246 | 2247 | ||
2247 | clear_bit(BTRFS_FS_LOG1_ERR, &fs_info->flags); | 2248 | clear_bit(BTRFS_FS_LOG1_ERR, &fs_info->flags); |
2248 | clear_bit(BTRFS_FS_LOG2_ERR, &fs_info->flags); | 2249 | clear_bit(BTRFS_FS_LOG2_ERR, &fs_info->flags); |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index b34678e7968e..2bd76f681520 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -52,6 +52,7 @@ struct btrfs_transaction { | |||
52 | wait_queue_head_t commit_wait; | 52 | wait_queue_head_t commit_wait; |
53 | struct list_head pending_snapshots; | 53 | struct list_head pending_snapshots; |
54 | struct list_head pending_chunks; | 54 | struct list_head pending_chunks; |
55 | struct list_head dev_update_list; | ||
55 | struct list_head switch_commits; | 56 | struct list_head switch_commits; |
56 | struct list_head dirty_bgs; | 57 | struct list_head dirty_bgs; |
57 | 58 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 77bca3a61e26..72e069c227ab 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -319,7 +319,6 @@ static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid, | |||
319 | mutex_init(&fs_devs->device_list_mutex); | 319 | mutex_init(&fs_devs->device_list_mutex); |
320 | 320 | ||
321 | INIT_LIST_HEAD(&fs_devs->devices); | 321 | INIT_LIST_HEAD(&fs_devs->devices); |
322 | INIT_LIST_HEAD(&fs_devs->resized_devices); | ||
323 | INIT_LIST_HEAD(&fs_devs->alloc_list); | 322 | INIT_LIST_HEAD(&fs_devs->alloc_list); |
324 | INIT_LIST_HEAD(&fs_devs->fs_list); | 323 | INIT_LIST_HEAD(&fs_devs->fs_list); |
325 | if (fsid) | 324 | if (fsid) |
@@ -335,6 +334,7 @@ static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid, | |||
335 | 334 | ||
336 | void btrfs_free_device(struct btrfs_device *device) | 335 | void btrfs_free_device(struct btrfs_device *device) |
337 | { | 336 | { |
337 | WARN_ON(!list_empty(&device->post_commit_list)); | ||
338 | rcu_string_free(device->name); | 338 | rcu_string_free(device->name); |
339 | bio_put(device->flush_bio); | 339 | bio_put(device->flush_bio); |
340 | kfree(device); | 340 | kfree(device); |
@@ -403,7 +403,7 @@ static struct btrfs_device *__alloc_device(void) | |||
403 | 403 | ||
404 | INIT_LIST_HEAD(&dev->dev_list); | 404 | INIT_LIST_HEAD(&dev->dev_list); |
405 | INIT_LIST_HEAD(&dev->dev_alloc_list); | 405 | INIT_LIST_HEAD(&dev->dev_alloc_list); |
406 | INIT_LIST_HEAD(&dev->resized_list); | 406 | INIT_LIST_HEAD(&dev->post_commit_list); |
407 | 407 | ||
408 | spin_lock_init(&dev->io_lock); | 408 | spin_lock_init(&dev->io_lock); |
409 | 409 | ||
@@ -2853,7 +2853,6 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans, | |||
2853 | { | 2853 | { |
2854 | struct btrfs_fs_info *fs_info = device->fs_info; | 2854 | struct btrfs_fs_info *fs_info = device->fs_info; |
2855 | struct btrfs_super_block *super_copy = fs_info->super_copy; | 2855 | struct btrfs_super_block *super_copy = fs_info->super_copy; |
2856 | struct btrfs_fs_devices *fs_devices; | ||
2857 | u64 old_total; | 2856 | u64 old_total; |
2858 | u64 diff; | 2857 | u64 diff; |
2859 | 2858 | ||
@@ -2872,8 +2871,6 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans, | |||
2872 | return -EINVAL; | 2871 | return -EINVAL; |
2873 | } | 2872 | } |
2874 | 2873 | ||
2875 | fs_devices = fs_info->fs_devices; | ||
2876 | |||
2877 | btrfs_set_super_total_bytes(super_copy, | 2874 | btrfs_set_super_total_bytes(super_copy, |
2878 | round_down(old_total + diff, fs_info->sectorsize)); | 2875 | round_down(old_total + diff, fs_info->sectorsize)); |
2879 | device->fs_devices->total_rw_bytes += diff; | 2876 | device->fs_devices->total_rw_bytes += diff; |
@@ -2881,9 +2878,9 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans, | |||
2881 | btrfs_device_set_total_bytes(device, new_size); | 2878 | btrfs_device_set_total_bytes(device, new_size); |
2882 | btrfs_device_set_disk_total_bytes(device, new_size); | 2879 | btrfs_device_set_disk_total_bytes(device, new_size); |
2883 | btrfs_clear_space_info_full(device->fs_info); | 2880 | btrfs_clear_space_info_full(device->fs_info); |
2884 | if (list_empty(&device->resized_list)) | 2881 | if (list_empty(&device->post_commit_list)) |
2885 | list_add_tail(&device->resized_list, | 2882 | list_add_tail(&device->post_commit_list, |
2886 | &fs_devices->resized_devices); | 2883 | &trans->transaction->dev_update_list); |
2887 | mutex_unlock(&fs_info->chunk_mutex); | 2884 | mutex_unlock(&fs_info->chunk_mutex); |
2888 | 2885 | ||
2889 | return btrfs_update_device(trans, device); | 2886 | return btrfs_update_device(trans, device); |
@@ -4872,9 +4869,9 @@ again: | |||
4872 | } | 4869 | } |
4873 | 4870 | ||
4874 | btrfs_device_set_disk_total_bytes(device, new_size); | 4871 | btrfs_device_set_disk_total_bytes(device, new_size); |
4875 | if (list_empty(&device->resized_list)) | 4872 | if (list_empty(&device->post_commit_list)) |
4876 | list_add_tail(&device->resized_list, | 4873 | list_add_tail(&device->post_commit_list, |
4877 | &fs_info->fs_devices->resized_devices); | 4874 | &trans->transaction->dev_update_list); |
4878 | 4875 | ||
4879 | WARN_ON(diff > old_total); | 4876 | WARN_ON(diff > old_total); |
4880 | btrfs_set_super_total_bytes(super_copy, | 4877 | btrfs_set_super_total_bytes(super_copy, |
@@ -5214,9 +5211,14 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
5214 | if (ret) | 5211 | if (ret) |
5215 | goto error_del_extent; | 5212 | goto error_del_extent; |
5216 | 5213 | ||
5217 | for (i = 0; i < map->num_stripes; i++) | 5214 | for (i = 0; i < map->num_stripes; i++) { |
5218 | btrfs_device_set_bytes_used(map->stripes[i].dev, | 5215 | struct btrfs_device *dev = map->stripes[i].dev; |
5219 | map->stripes[i].dev->bytes_used + stripe_size); | 5216 | |
5217 | btrfs_device_set_bytes_used(dev, dev->bytes_used + stripe_size); | ||
5218 | if (list_empty(&dev->post_commit_list)) | ||
5219 | list_add_tail(&dev->post_commit_list, | ||
5220 | &trans->transaction->dev_update_list); | ||
5221 | } | ||
5220 | 5222 | ||
5221 | atomic64_sub(stripe_size * map->num_stripes, &info->free_chunk_space); | 5223 | atomic64_sub(stripe_size * map->num_stripes, &info->free_chunk_space); |
5222 | 5224 | ||
@@ -7579,51 +7581,34 @@ void btrfs_scratch_superblocks(struct block_device *bdev, const char *device_pat | |||
7579 | } | 7581 | } |
7580 | 7582 | ||
7581 | /* | 7583 | /* |
7582 | * Update the size of all devices, which is used for writing out the | 7584 | * Update the size and bytes used for each device where it changed. This is |
7583 | * super blocks. | 7585 | * delayed since we would otherwise get errors while writing out the |
7586 | * superblocks. | ||
7587 | * | ||
7588 | * Must be invoked during transaction commit. | ||
7584 | */ | 7589 | */ |
7585 | void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info) | 7590 | void btrfs_commit_device_sizes(struct btrfs_transaction *trans) |
7586 | { | 7591 | { |
7587 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; | ||
7588 | struct btrfs_device *curr, *next; | 7592 | struct btrfs_device *curr, *next; |
7589 | 7593 | ||
7590 | if (list_empty(&fs_devices->resized_devices)) | 7594 | ASSERT(trans->state == TRANS_STATE_COMMIT_DOING); |
7591 | return; | ||
7592 | |||
7593 | mutex_lock(&fs_devices->device_list_mutex); | ||
7594 | mutex_lock(&fs_info->chunk_mutex); | ||
7595 | list_for_each_entry_safe(curr, next, &fs_devices->resized_devices, | ||
7596 | resized_list) { | ||
7597 | list_del_init(&curr->resized_list); | ||
7598 | curr->commit_total_bytes = curr->disk_total_bytes; | ||
7599 | } | ||
7600 | mutex_unlock(&fs_info->chunk_mutex); | ||
7601 | mutex_unlock(&fs_devices->device_list_mutex); | ||
7602 | } | ||
7603 | |||
7604 | /* Must be invoked during the transaction commit */ | ||
7605 | void btrfs_update_commit_device_bytes_used(struct btrfs_transaction *trans) | ||
7606 | { | ||
7607 | struct btrfs_fs_info *fs_info = trans->fs_info; | ||
7608 | struct extent_map *em; | ||
7609 | struct map_lookup *map; | ||
7610 | struct btrfs_device *dev; | ||
7611 | int i; | ||
7612 | 7595 | ||
7613 | if (list_empty(&trans->pending_chunks)) | 7596 | if (list_empty(&trans->dev_update_list)) |
7614 | return; | 7597 | return; |
7615 | 7598 | ||
7616 | /* In order to kick the device replace finish process */ | 7599 | /* |
7617 | mutex_lock(&fs_info->chunk_mutex); | 7600 | * We don't need the device_list_mutex here. This list is owned by the |
7618 | list_for_each_entry(em, &trans->pending_chunks, list) { | 7601 | * transaction and the transaction must complete before the device is |
7619 | map = em->map_lookup; | 7602 | * released. |
7620 | 7603 | */ | |
7621 | for (i = 0; i < map->num_stripes; i++) { | 7604 | mutex_lock(&trans->fs_info->chunk_mutex); |
7622 | dev = map->stripes[i].dev; | 7605 | list_for_each_entry_safe(curr, next, &trans->dev_update_list, |
7623 | dev->commit_bytes_used = dev->bytes_used; | 7606 | post_commit_list) { |
7624 | } | 7607 | list_del_init(&curr->post_commit_list); |
7608 | curr->commit_total_bytes = curr->disk_total_bytes; | ||
7609 | curr->commit_bytes_used = curr->bytes_used; | ||
7625 | } | 7610 | } |
7626 | mutex_unlock(&fs_info->chunk_mutex); | 7611 | mutex_unlock(&trans->fs_info->chunk_mutex); |
7627 | } | 7612 | } |
7628 | 7613 | ||
7629 | void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info) | 7614 | void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info) |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 38ed94b77202..b9912b910d6d 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -45,6 +45,7 @@ struct btrfs_pending_bios { | |||
45 | struct btrfs_device { | 45 | struct btrfs_device { |
46 | struct list_head dev_list; | 46 | struct list_head dev_list; |
47 | struct list_head dev_alloc_list; | 47 | struct list_head dev_alloc_list; |
48 | struct list_head post_commit_list; /* chunk mutex */ | ||
48 | struct btrfs_fs_devices *fs_devices; | 49 | struct btrfs_fs_devices *fs_devices; |
49 | struct btrfs_fs_info *fs_info; | 50 | struct btrfs_fs_info *fs_info; |
50 | 51 | ||
@@ -102,18 +103,12 @@ struct btrfs_device { | |||
102 | * size of the device on the current transaction | 103 | * size of the device on the current transaction |
103 | * | 104 | * |
104 | * This variant is update when committing the transaction, | 105 | * This variant is update when committing the transaction, |
105 | * and protected by device_list_mutex | 106 | * and protected by chunk mutex |
106 | */ | 107 | */ |
107 | u64 commit_total_bytes; | 108 | u64 commit_total_bytes; |
108 | 109 | ||
109 | /* bytes used on the current transaction */ | 110 | /* bytes used on the current transaction */ |
110 | u64 commit_bytes_used; | 111 | u64 commit_bytes_used; |
111 | /* | ||
112 | * used to manage the device which is resized | ||
113 | * | ||
114 | * It is protected by chunk_lock. | ||
115 | */ | ||
116 | struct list_head resized_list; | ||
117 | 112 | ||
118 | /* for sending down flush barriers */ | 113 | /* for sending down flush barriers */ |
119 | struct bio *flush_bio; | 114 | struct bio *flush_bio; |
@@ -235,7 +230,6 @@ struct btrfs_fs_devices { | |||
235 | struct mutex device_list_mutex; | 230 | struct mutex device_list_mutex; |
236 | struct list_head devices; | 231 | struct list_head devices; |
237 | 232 | ||
238 | struct list_head resized_devices; | ||
239 | /* devices not currently being allocated */ | 233 | /* devices not currently being allocated */ |
240 | struct list_head alloc_list; | 234 | struct list_head alloc_list; |
241 | 235 | ||
@@ -567,8 +561,7 @@ static inline enum btrfs_raid_types btrfs_bg_flags_to_raid_index(u64 flags) | |||
567 | 561 | ||
568 | const char *get_raid_name(enum btrfs_raid_types type); | 562 | const char *get_raid_name(enum btrfs_raid_types type); |
569 | 563 | ||
570 | void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info); | 564 | void btrfs_commit_device_sizes(struct btrfs_transaction *trans); |
571 | void btrfs_update_commit_device_bytes_used(struct btrfs_transaction *trans); | ||
572 | 565 | ||
573 | struct list_head *btrfs_get_fs_uuids(void); | 566 | struct list_head *btrfs_get_fs_uuids(void); |
574 | void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info); | 567 | void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info); |