aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/dev-replace.c2
-rw-r--r--fs/btrfs/disk-io.c7
-rw-r--r--fs/btrfs/transaction.c5
-rw-r--r--fs/btrfs/transaction.h1
-rw-r--r--fs/btrfs/volumes.c87
-rw-r--r--fs/btrfs/volumes.h13
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,
4479void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, 4479void 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
336void btrfs_free_device(struct btrfs_device *device) 335void 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 */
7585void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info) 7590void 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 */
7605void 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
7629void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info) 7614void 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 {
45struct btrfs_device { 45struct 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
568const char *get_raid_name(enum btrfs_raid_types type); 562const char *get_raid_name(enum btrfs_raid_types type);
569 563
570void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info); 564void btrfs_commit_device_sizes(struct btrfs_transaction *trans);
571void btrfs_update_commit_device_bytes_used(struct btrfs_transaction *trans);
572 565
573struct list_head *btrfs_get_fs_uuids(void); 566struct list_head *btrfs_get_fs_uuids(void);
574void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info); 567void btrfs_set_fs_info_ptr(struct btrfs_fs_info *fs_info);