aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2014-09-03 09:35:34 -0400
committerChris Mason <clm@fb.com>2014-09-17 16:38:34 -0400
commitce7213c70c37e3a66bc0b50c45edcbfea505f62f (patch)
tree3b458f3f28ae3d69f508b4bd9194a264f74f6f34 /fs/btrfs
parent935e5cc935bcbf9b3d0dd59fed7dbc0f2ebca6bc (diff)
Btrfs: fix wrong device bytes_used in the super block
device->bytes_used will be changed when allocating a new chunk, and disk_total_size will be changed if resizing is successful. Meanwhile, the on-disk super blocks of the previous transaction might not be updated. Considering the consistency of the metadata in the previous transaction, We should use the size in the previous transaction to check if the super block is beyond the boundary of the device. Though it is not big problem because we don't use it now, but anyway it is better that we make it be consistent with the common metadata, maybe we will use it in the future. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/dev-replace.c3
-rw-r--r--fs/btrfs/disk-io.c3
-rw-r--r--fs/btrfs/transaction.c1
-rw-r--r--fs/btrfs/volumes.c27
-rw-r--r--fs/btrfs/volumes.h4
5 files changed, 37 insertions, 1 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 7877b0fc6a8d..1be03d85d267 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -172,6 +172,8 @@ no_valid_dev_replace_entry_found:
172 dev_replace->srcdev->commit_total_bytes; 172 dev_replace->srcdev->commit_total_bytes;
173 dev_replace->tgtdev->bytes_used = 173 dev_replace->tgtdev->bytes_used =
174 dev_replace->srcdev->bytes_used; 174 dev_replace->srcdev->bytes_used;
175 dev_replace->tgtdev->commit_bytes_used =
176 dev_replace->srcdev->commit_bytes_used;
175 } 177 }
176 dev_replace->tgtdev->is_tgtdev_for_dev_replace = 1; 178 dev_replace->tgtdev->is_tgtdev_for_dev_replace = 1;
177 btrfs_init_dev_replace_tgtdev_for_resume(fs_info, 179 btrfs_init_dev_replace_tgtdev_for_resume(fs_info,
@@ -558,6 +560,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
558 ASSERT(list_empty(&src_device->resized_list)); 560 ASSERT(list_empty(&src_device->resized_list));
559 tgt_device->commit_total_bytes = src_device->commit_total_bytes; 561 tgt_device->commit_total_bytes = src_device->commit_total_bytes;
560 tgt_device->bytes_used = src_device->bytes_used; 562 tgt_device->bytes_used = src_device->bytes_used;
563 tgt_device->commit_bytes_used = src_device->bytes_used;
561 if (fs_info->sb->s_bdev == src_device->bdev) 564 if (fs_info->sb->s_bdev == src_device->bdev)
562 fs_info->sb->s_bdev = tgt_device->bdev; 565 fs_info->sb->s_bdev = tgt_device->bdev;
563 if (fs_info->fs_devices->latest_bdev == src_device->bdev) 566 if (fs_info->fs_devices->latest_bdev == src_device->bdev)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 0cd18b725554..a224fb9b34a3 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3446,7 +3446,8 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
3446 btrfs_set_stack_device_id(dev_item, dev->devid); 3446 btrfs_set_stack_device_id(dev_item, dev->devid);
3447 btrfs_set_stack_device_total_bytes(dev_item, 3447 btrfs_set_stack_device_total_bytes(dev_item,
3448 dev->commit_total_bytes); 3448 dev->commit_total_bytes);
3449 btrfs_set_stack_device_bytes_used(dev_item, dev->bytes_used); 3449 btrfs_set_stack_device_bytes_used(dev_item,
3450 dev->commit_bytes_used);
3450 btrfs_set_stack_device_io_align(dev_item, dev->io_align); 3451 btrfs_set_stack_device_io_align(dev_item, dev->io_align);
3451 btrfs_set_stack_device_io_width(dev_item, dev->io_width); 3452 btrfs_set_stack_device_io_width(dev_item, dev->io_width);
3452 btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); 3453 btrfs_set_stack_device_sector_size(dev_item, dev->sector_size);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 2f7c0bef4043..16d0c1b62b3e 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1869,6 +1869,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1869 sizeof(*root->fs_info->super_copy)); 1869 sizeof(*root->fs_info->super_copy));
1870 1870
1871 btrfs_update_commit_device_size(root->fs_info); 1871 btrfs_update_commit_device_size(root->fs_info);
1872 btrfs_update_commit_device_bytes_used(root, cur_trans);
1872 1873
1873 spin_lock(&root->fs_info->trans_lock); 1874 spin_lock(&root->fs_info->trans_lock);
1874 cur_trans->state = TRANS_STATE_UNBLOCKED; 1875 cur_trans->state = TRANS_STATE_UNBLOCKED;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7b5c04259a6e..f8273bb53b3f 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2370,6 +2370,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
2370 ASSERT(list_empty(&srcdev->resized_list)); 2370 ASSERT(list_empty(&srcdev->resized_list));
2371 device->commit_total_bytes = srcdev->commit_total_bytes; 2371 device->commit_total_bytes = srcdev->commit_total_bytes;
2372 device->bytes_used = srcdev->bytes_used; 2372 device->bytes_used = srcdev->bytes_used;
2373 device->commit_bytes_used = device->bytes_used;
2373 device->dev_root = fs_info->dev_root; 2374 device->dev_root = fs_info->dev_root;
2374 device->bdev = bdev; 2375 device->bdev = bdev;
2375 device->in_fs_metadata = 1; 2376 device->in_fs_metadata = 1;
@@ -6009,6 +6010,7 @@ static void fill_device_from_item(struct extent_buffer *leaf,
6009 device->total_bytes = device->disk_total_bytes; 6010 device->total_bytes = device->disk_total_bytes;
6010 device->commit_total_bytes = device->disk_total_bytes; 6011 device->commit_total_bytes = device->disk_total_bytes;
6011 device->bytes_used = btrfs_device_bytes_used(leaf, dev_item); 6012 device->bytes_used = btrfs_device_bytes_used(leaf, dev_item);
6013 device->commit_bytes_used = device->bytes_used;
6012 device->type = btrfs_device_type(leaf, dev_item); 6014 device->type = btrfs_device_type(leaf, dev_item);
6013 device->io_align = btrfs_device_io_align(leaf, dev_item); 6015 device->io_align = btrfs_device_io_align(leaf, dev_item);
6014 device->io_width = btrfs_device_io_width(leaf, dev_item); 6016 device->io_width = btrfs_device_io_width(leaf, dev_item);
@@ -6558,3 +6560,28 @@ void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info)
6558 unlock_chunks(fs_info->dev_root); 6560 unlock_chunks(fs_info->dev_root);
6559 mutex_unlock(&fs_devices->device_list_mutex); 6561 mutex_unlock(&fs_devices->device_list_mutex);
6560} 6562}
6563
6564/* Must be invoked during the transaction commit */
6565void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
6566 struct btrfs_transaction *transaction)
6567{
6568 struct extent_map *em;
6569 struct map_lookup *map;
6570 struct btrfs_device *dev;
6571 int i;
6572
6573 if (list_empty(&transaction->pending_chunks))
6574 return;
6575
6576 /* In order to kick the device replace finish process */
6577 lock_chunks(root);
6578 list_for_each_entry(em, &transaction->pending_chunks, list) {
6579 map = (struct map_lookup *)em->bdev;
6580
6581 for (i = 0; i < map->num_stripes; i++) {
6582 dev = map->stripes[i].dev;
6583 dev->commit_bytes_used = dev->bytes_used;
6584 }
6585 }
6586 unlock_chunks(root);
6587}
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index b30d018fa359..f79d532fedb0 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -95,6 +95,8 @@ struct btrfs_device {
95 */ 95 */
96 u64 commit_total_bytes; 96 u64 commit_total_bytes;
97 97
98 /* bytes used on the current transaction */
99 u64 commit_bytes_used;
98 /* 100 /*
99 * used to manage the device which is resized 101 * used to manage the device which is resized
100 * 102 *
@@ -420,4 +422,6 @@ static inline void btrfs_dev_stat_reset(struct btrfs_device *dev,
420} 422}
421 423
422void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info); 424void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info);
425void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
426 struct btrfs_transaction *transaction);
423#endif 427#endif