Skip to content

Commit 9b82b46

Browse files
committed
btrfs: add mode to clear chunk map status to CLEAR_FREE ioctl
The trim status is tracked for each chunk in the fs_info::mapping_tree and updated as trim is called either manually by 'fstrim' or automatically when discard=async is enabled. With the new modes it's necessary to allow clearing the cache otherwise on a fully or partially trimmed filesystem the ioctl won't work as expected. Add separate clear free operation to reset just the trim status bits from all chunks. This should be called namely when the clearing operation is *not* trim (e.g. zeroout or secure erase). Signed-off-by: David Sterba <[email protected]>
1 parent 0519183 commit 9b82b46

File tree

4 files changed

+26
-0
lines changed

4 files changed

+26
-0
lines changed

fs/btrfs/ioctl.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5234,6 +5234,19 @@ static int btrfs_ioctl_clear_free(struct file *file, void __user *arg)
52345234
if (args.type >= BTRFS_NR_CLEAR_OP_TYPES)
52355235
return -EOPNOTSUPP;
52365236

5237+
if (args.type == BTRFS_CLEAR_OP_RESET_CHUNK_STATUS_CACHE) {
5238+
write_lock(&fs_info->mapping_tree_lock);
5239+
for (struct rb_node *node = rb_first_cached(&fs_info->mapping_tree);
5240+
node; node = rb_next(node)) {
5241+
struct btrfs_chunk_map *map;
5242+
5243+
map = rb_entry(node, struct btrfs_chunk_map, rb_node);
5244+
btrfs_chunk_map_clear_bits(map, CHUNK_TRIMMED);
5245+
}
5246+
write_unlock(&fs_info->mapping_tree_lock);
5247+
return 0;
5248+
}
5249+
52375250
ret = mnt_want_write_file(file);
52385251
if (ret)
52395252
return ret;

fs/btrfs/volumes.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8022,6 +8022,11 @@ static int verify_chunk_dev_extent_mapping(struct btrfs_fs_info *fs_info)
80228022
return ret;
80238023
}
80248024

8025+
void btrfs_chunk_map_clear_bits(struct btrfs_chunk_map *map, unsigned int bits)
8026+
{
8027+
chunk_map_device_clear_bits(map, bits);
8028+
}
8029+
80258030
/*
80268031
* Ensure that all dev extents are mapped to correct chunk, otherwise
80278032
* later chunk allocation/free would cause unexpected behavior.

fs/btrfs/volumes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ struct btrfs_chunk_map *btrfs_find_chunk_map_nolock(struct btrfs_fs_info *fs_inf
785785
u64 logical, u64 length);
786786
struct btrfs_chunk_map *btrfs_get_chunk_map(struct btrfs_fs_info *fs_info,
787787
u64 logical, u64 length);
788+
void btrfs_chunk_map_clear_bits(struct btrfs_chunk_map *map, unsigned int bits);
788789
void btrfs_remove_chunk_map(struct btrfs_fs_info *fs_info, struct btrfs_chunk_map *map);
789790
struct btrfs_super_block *btrfs_read_disk_super(struct block_device *bdev,
790791
int copy_num, bool drop_cache);

include/uapi/linux/btrfs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,13 @@ enum btrfs_clear_op_type {
11191119
BTRFS_CLEAR_OP_ZERO_NOUNMAP,
11201120
/* Request unmapping the blocks and don't fall back to writing zeros. */
11211121
BTRFS_CLEAR_OP_ZERO_NOFALLBACK,
1122+
1123+
/*
1124+
* Only reset status of previously cleared (by any operation) chunks,
1125+
* tracked in memory since the last mount. Without that repeated calls
1126+
* to clear will skip already processed chunks.
1127+
*/
1128+
BTRFS_CLEAR_OP_RESET_CHUNK_STATUS_CACHE,
11221129
BTRFS_NR_CLEAR_OP_TYPES,
11231130
};
11241131

0 commit comments

Comments
 (0)