提交 ce7213c7 编写于 作者: M Miao Xie 提交者: Chris Mason

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: NMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: NChris Mason <clm@fb.com>
上级 935e5cc9
...@@ -172,6 +172,8 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info) ...@@ -172,6 +172,8 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)
dev_replace->srcdev->commit_total_bytes; dev_replace->srcdev->commit_total_bytes;
dev_replace->tgtdev->bytes_used = dev_replace->tgtdev->bytes_used =
dev_replace->srcdev->bytes_used; dev_replace->srcdev->bytes_used;
dev_replace->tgtdev->commit_bytes_used =
dev_replace->srcdev->commit_bytes_used;
} }
dev_replace->tgtdev->is_tgtdev_for_dev_replace = 1; dev_replace->tgtdev->is_tgtdev_for_dev_replace = 1;
btrfs_init_dev_replace_tgtdev_for_resume(fs_info, 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,6 +560,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
ASSERT(list_empty(&src_device->resized_list)); ASSERT(list_empty(&src_device->resized_list));
tgt_device->commit_total_bytes = src_device->commit_total_bytes; tgt_device->commit_total_bytes = src_device->commit_total_bytes;
tgt_device->bytes_used = src_device->bytes_used; tgt_device->bytes_used = src_device->bytes_used;
tgt_device->commit_bytes_used = src_device->bytes_used;
if (fs_info->sb->s_bdev == src_device->bdev) if (fs_info->sb->s_bdev == src_device->bdev)
fs_info->sb->s_bdev = tgt_device->bdev; fs_info->sb->s_bdev = tgt_device->bdev;
if (fs_info->fs_devices->latest_bdev == src_device->bdev) if (fs_info->fs_devices->latest_bdev == src_device->bdev)
......
...@@ -3446,7 +3446,8 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors) ...@@ -3446,7 +3446,8 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
btrfs_set_stack_device_id(dev_item, dev->devid); btrfs_set_stack_device_id(dev_item, dev->devid);
btrfs_set_stack_device_total_bytes(dev_item, btrfs_set_stack_device_total_bytes(dev_item,
dev->commit_total_bytes); dev->commit_total_bytes);
btrfs_set_stack_device_bytes_used(dev_item, dev->bytes_used); btrfs_set_stack_device_bytes_used(dev_item,
dev->commit_bytes_used);
btrfs_set_stack_device_io_align(dev_item, dev->io_align); btrfs_set_stack_device_io_align(dev_item, dev->io_align);
btrfs_set_stack_device_io_width(dev_item, dev->io_width); btrfs_set_stack_device_io_width(dev_item, dev->io_width);
btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); btrfs_set_stack_device_sector_size(dev_item, dev->sector_size);
......
...@@ -1869,6 +1869,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ...@@ -1869,6 +1869,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
sizeof(*root->fs_info->super_copy)); sizeof(*root->fs_info->super_copy));
btrfs_update_commit_device_size(root->fs_info); btrfs_update_commit_device_size(root->fs_info);
btrfs_update_commit_device_bytes_used(root, cur_trans);
spin_lock(&root->fs_info->trans_lock); spin_lock(&root->fs_info->trans_lock);
cur_trans->state = TRANS_STATE_UNBLOCKED; cur_trans->state = TRANS_STATE_UNBLOCKED;
......
...@@ -2370,6 +2370,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path, ...@@ -2370,6 +2370,7 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_root *root, char *device_path,
ASSERT(list_empty(&srcdev->resized_list)); ASSERT(list_empty(&srcdev->resized_list));
device->commit_total_bytes = srcdev->commit_total_bytes; device->commit_total_bytes = srcdev->commit_total_bytes;
device->bytes_used = srcdev->bytes_used; device->bytes_used = srcdev->bytes_used;
device->commit_bytes_used = device->bytes_used;
device->dev_root = fs_info->dev_root; device->dev_root = fs_info->dev_root;
device->bdev = bdev; device->bdev = bdev;
device->in_fs_metadata = 1; device->in_fs_metadata = 1;
...@@ -6009,6 +6010,7 @@ static void fill_device_from_item(struct extent_buffer *leaf, ...@@ -6009,6 +6010,7 @@ static void fill_device_from_item(struct extent_buffer *leaf,
device->total_bytes = device->disk_total_bytes; device->total_bytes = device->disk_total_bytes;
device->commit_total_bytes = device->disk_total_bytes; device->commit_total_bytes = device->disk_total_bytes;
device->bytes_used = btrfs_device_bytes_used(leaf, dev_item); device->bytes_used = btrfs_device_bytes_used(leaf, dev_item);
device->commit_bytes_used = device->bytes_used;
device->type = btrfs_device_type(leaf, dev_item); device->type = btrfs_device_type(leaf, dev_item);
device->io_align = btrfs_device_io_align(leaf, dev_item); device->io_align = btrfs_device_io_align(leaf, dev_item);
device->io_width = btrfs_device_io_width(leaf, dev_item); 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,3 +6560,28 @@ void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info)
unlock_chunks(fs_info->dev_root); unlock_chunks(fs_info->dev_root);
mutex_unlock(&fs_devices->device_list_mutex); mutex_unlock(&fs_devices->device_list_mutex);
} }
/* Must be invoked during the transaction commit */
void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
struct btrfs_transaction *transaction)
{
struct extent_map *em;
struct map_lookup *map;
struct btrfs_device *dev;
int i;
if (list_empty(&transaction->pending_chunks))
return;
/* In order to kick the device replace finish process */
lock_chunks(root);
list_for_each_entry(em, &transaction->pending_chunks, list) {
map = (struct map_lookup *)em->bdev;
for (i = 0; i < map->num_stripes; i++) {
dev = map->stripes[i].dev;
dev->commit_bytes_used = dev->bytes_used;
}
}
unlock_chunks(root);
}
...@@ -95,6 +95,8 @@ struct btrfs_device { ...@@ -95,6 +95,8 @@ struct btrfs_device {
*/ */
u64 commit_total_bytes; u64 commit_total_bytes;
/* bytes used on the current transaction */
u64 commit_bytes_used;
/* /*
* used to manage the device which is resized * used to manage the device which is resized
* *
...@@ -420,4 +422,6 @@ static inline void btrfs_dev_stat_reset(struct btrfs_device *dev, ...@@ -420,4 +422,6 @@ static inline void btrfs_dev_stat_reset(struct btrfs_device *dev,
} }
void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info); void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info);
void btrfs_update_commit_device_bytes_used(struct btrfs_root *root,
struct btrfs_transaction *transaction);
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册