mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-05 05:42:36 +00:00
Btrfs: fix wrong disk size when writing super blocks
total_size will be changed when resizing a device, 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. Fix it. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
1c43366d3b
commit
935e5cc935
7 changed files with 83 additions and 5 deletions
|
@ -168,6 +168,8 @@ no_valid_dev_replace_entry_found:
|
|||
dev_replace->srcdev->total_bytes;
|
||||
dev_replace->tgtdev->disk_total_bytes =
|
||||
dev_replace->srcdev->disk_total_bytes;
|
||||
dev_replace->tgtdev->commit_total_bytes =
|
||||
dev_replace->srcdev->commit_total_bytes;
|
||||
dev_replace->tgtdev->bytes_used =
|
||||
dev_replace->srcdev->bytes_used;
|
||||
}
|
||||
|
@ -329,6 +331,20 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
|
|||
args->start.tgtdev_name[0] == '\0')
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Here we commit the transaction to make sure commit_total_bytes
|
||||
* of all the devices are updated.
|
||||
*/
|
||||
trans = btrfs_attach_transaction(root);
|
||||
if (!IS_ERR(trans)) {
|
||||
ret = btrfs_commit_transaction(trans, root);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else if (PTR_ERR(trans) != -ENOENT) {
|
||||
return PTR_ERR(trans);
|
||||
}
|
||||
|
||||
/* the disk copy procedure reuses the scrub code */
|
||||
mutex_lock(&fs_info->volume_mutex);
|
||||
ret = btrfs_dev_replace_find_srcdev(root, args->start.srcdevid,
|
||||
args->start.srcdev_name,
|
||||
|
@ -539,6 +555,8 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
|
|||
memcpy(src_device->uuid, uuid_tmp, sizeof(src_device->uuid));
|
||||
tgt_device->total_bytes = src_device->total_bytes;
|
||||
tgt_device->disk_total_bytes = src_device->disk_total_bytes;
|
||||
ASSERT(list_empty(&src_device->resized_list));
|
||||
tgt_device->commit_total_bytes = src_device->commit_total_bytes;
|
||||
tgt_device->bytes_used = src_device->bytes_used;
|
||||
if (fs_info->sb->s_bdev == src_device->bdev)
|
||||
fs_info->sb->s_bdev = tgt_device->bdev;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue