diff --git a/kernel-shared/disk-io.c b/kernel-shared/disk-io.c index c118b5fd..82e1c82f 100644 --- a/kernel-shared/disk-io.c +++ b/kernel-shared/disk-io.c @@ -513,12 +513,12 @@ err: int write_and_map_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb) { int ret; - int dev_nr; + int mirror_num; + int max_mirror; u64 length; u64 *raid_map = NULL; struct btrfs_multi_bio *multi = NULL; - dev_nr = 0; length = eb->len; ret = btrfs_map_block(fs_info, WRITE, eb->start, &length, &multi, 0, &raid_map); @@ -529,6 +529,7 @@ int write_and_map_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb) goto out; } + /* RAID56 write back need RMW */ if (raid_map) { ret = write_raid56_with_parity(fs_info, eb, multi, length, raid_map); @@ -537,28 +538,30 @@ int write_and_map_eb(struct btrfs_fs_info *fs_info, struct extent_buffer *eb) error( "failed to write raid56 stripe for bytenr %llu length %llu: %m", eb->start, length); - goto out; + } else { + ret = 0; } - } else while (dev_nr < multi->num_stripes) { - eb->fd = multi->stripes[dev_nr].dev->fd; - eb->dev_bytenr = multi->stripes[dev_nr].physical; - multi->stripes[dev_nr].dev->total_ios++; - dev_nr++; - ret = write_extent_to_disk(eb); + goto out; + } + + /* For non-RAID56, we just writeback data to each mirror */ + max_mirror = btrfs_num_copies(fs_info, eb->start, eb->len); + for (mirror_num = 1; mirror_num <= max_mirror; mirror_num++) { + ret = write_data_to_disk(fs_info, eb->data, eb->start, eb->len, + mirror_num); if (ret < 0) { errno = -ret; error( -"failed to write bytenr %llu length %u devid %llu dev_bytenr %llu: %m", - eb->start, eb->len, - multi->stripes[dev_nr].dev->devid, - eb->dev_bytenr); + "failed to write bytenr %llu length %u to mirror %d: %m", + eb->start, eb->len, mirror_num); goto out; } } + out: kfree(raid_map); kfree(multi); - return 0; + return ret; } int write_tree_block(struct btrfs_trans_handle *trans, diff --git a/kernel-shared/extent_io.c b/kernel-shared/extent_io.c index af09ade4..8b2d1b95 100644 --- a/kernel-shared/extent_io.c +++ b/kernel-shared/extent_io.c @@ -808,22 +808,6 @@ out: return ret; } -int write_extent_to_disk(struct extent_buffer *eb) -{ - int ret; - ret = btrfs_pwrite(eb->fd, eb->data, eb->len, eb->dev_bytenr, - eb->fs_info->zoned); - if (ret < 0) - goto out; - if (ret != eb->len) { - ret = -EIO; - goto out; - } - ret = 0; -out: - return ret; -} - int read_data_from_disk(struct btrfs_fs_info *info, void *buf, u64 offset, u64 bytes, int mirror) { @@ -934,6 +918,7 @@ int write_data_to_disk(struct btrfs_fs_info *info, void *buf, u64 offset, dev_bytenr = multi->stripes[dev_nr].physical; this_len = min(this_len, bytes_left); dev_nr++; + device->total_ios++; ret = btrfs_pwrite(device->fd, buf + total_write, this_len, dev_bytenr, info->zoned); diff --git a/kernel-shared/extent_io.h b/kernel-shared/extent_io.h index a4c21360..b787c19e 100644 --- a/kernel-shared/extent_io.h +++ b/kernel-shared/extent_io.h @@ -152,7 +152,6 @@ void free_extent_buffer(struct extent_buffer *eb); void free_extent_buffer_nocache(struct extent_buffer *eb); int read_extent_from_disk(struct extent_buffer *eb, unsigned long offset, unsigned long len); -int write_extent_to_disk(struct extent_buffer *eb); int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, unsigned long start, unsigned long len); void read_extent_buffer(const struct extent_buffer *eb, void *dst, diff --git a/kernel-shared/volumes.c b/kernel-shared/volumes.c index ba9a7306..e5c2b703 100644 --- a/kernel-shared/volumes.c +++ b/kernel-shared/volumes.c @@ -30,6 +30,7 @@ #include "kernel-shared/volumes.h" #include "zoned.h" #include "common/utils.h" +#include "common/device-utils.h" #include "kernel-lib/raid56.h" const struct btrfs_raid_attr btrfs_raid_array[BTRFS_NR_RAID_TYPES] = { @@ -2725,7 +2726,8 @@ int write_raid56_with_parity(struct btrfs_fs_info *info, } for (i = 0; i < multi->num_stripes; i++) { - ret = write_extent_to_disk(ebs[i]); + ret = btrfs_pwrite(ebs[i]->fd, ebs[i]->data, ebs[i]->len, + ebs[i]->dev_bytenr, info->zoned); if (ret < 0) goto out_free_split; }