btrfs-progs: zoned: reset zone of freed block group
When freeing a chunk, we can/should reset the underlying device zones for the chunk. Introduce btrfs_reset_chunk_zones() and reset the zones. Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
869d9ee552
commit
5fd9956f63
|
@ -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,14 @@ 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));
|
||||
|
|
|
@ -881,6 +881,33 @@ 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)
|
||||
|
|
|
@ -92,6 +92,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
|
||||
|
||||
|
@ -135,6 +137,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)
|
||||
|
|
Loading…
Reference in New Issue