@@ -21,6 +21,7 @@
#include <stdint.h>
#include <math.h>
#include "kerncompat.h"
+#include "kernel-lib/list.h"
#include "kernel-lib/radix-tree.h"
#include "kernel-lib/rbtree.h"
#include "kernel-shared/ctree.h"
@@ -3013,6 +3014,15 @@ static int free_chunk_dev_extent_items(struct btrfs_trans_handle *trans,
struct btrfs_chunk);
num_stripes = btrfs_chunk_num_stripes(path->nodes[0], chunk);
for (i = 0; i < num_stripes; i++) {
+ u64 devid = btrfs_stripe_devid_nr(path->nodes[0], chunk, i);
+ u64 offset = btrfs_stripe_offset_nr(path->nodes[0], chunk, i);
+ u64 length = btrfs_stripe_length(fs_info, path->nodes[0],
+ chunk);
+
+ ret = btrfs_reset_chunk_zones(fs_info, devid, offset, length);
+ if (ret < 0)
+ goto out;
+
ret = free_dev_extent_item(trans, fs_info,
btrfs_stripe_devid_nr(path->nodes[0], chunk, i),
btrfs_stripe_offset_nr(path->nodes[0], chunk, i));
@@ -886,6 +886,34 @@ bool btrfs_redirty_extent_buffer_for_zoned(struct btrfs_fs_info *fs_info,
return false;
}
+int btrfs_reset_chunk_zones(struct btrfs_fs_info *fs_info, u64 devid,
+ u64 offset, u64 length)
+{
+ struct btrfs_device *device;
+
+ list_for_each_entry(device, &fs_info->fs_devices->devices,
+ dev_list) {
+ struct btrfs_zoned_device_info *zinfo;
+ struct blk_zone *reset;
+
+ if (device->devid != devid)
+ continue;
+
+ zinfo = device->zone_info;
+ if (!zone_is_sequential(zinfo, offset))
+ continue;
+
+ reset = &zinfo->zones[offset / zinfo->zone_size];
+ if (btrfs_reset_dev_zone(device->fd, reset)) {
+ error("zoned: failed to reset zone %llu: %m",
+ offset / zinfo->zone_size);
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
#endif
int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info)
@@ -89,6 +89,8 @@ int btrfs_load_block_group_zone_info(struct btrfs_fs_info *fs_info,
struct btrfs_block_group *cache);
bool btrfs_redirty_extent_buffer_for_zoned(struct btrfs_fs_info *fs_info,
u64 start, u64 end);
+int btrfs_reset_chunk_zones(struct btrfs_fs_info *fs_info, u64 devid,
+ u64 offset, u64 length);
#else
#define sbread(fd, buf, offset) \
pread64(fd, buf, BTRFS_SUPER_INFO_SIZE, offset)
@@ -130,6 +132,12 @@ static inline bool btrfs_redirty_extent_buffer_for_zoned(
return false;
}
+static inline int btrfs_reset_chunk_zones(struct btrfs_fs_info *fs_info,
+ u64 devid, u64 offset, u64 length)
+{
+ return 0;
+}
+
#endif /* BTRFS_ZONED */
static inline bool btrfs_dev_is_sequential(struct btrfs_device *device, u64 pos)
When freeing a chunk, we can/should reset the underlying device zones for the chunk. This commit introduces btrfs_reset_chunk_zones() and reset the zones. Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> --- kernel-shared/extent-tree.c | 10 ++++++++++ kernel-shared/zoned.c | 28 ++++++++++++++++++++++++++++ kernel-shared/zoned.h | 8 ++++++++ 3 files changed, 46 insertions(+)