Skip to content

Commit 1480df8

Browse files
committed
btrfs: extend trim callchains to pass the operation type
Preparatory work for more than trim/discard operation that can be performed on the unused space from an ioctl. As FITRIM is not extensible, we'll need a new one. Now we extend any caller that takes part in the trim/discard to take one parameter defining the type of operation. The operation multiplexer btrfs_issue_clear_op() will be extended in followup patches. Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 6032937 commit 1480df8

File tree

8 files changed

+71
-41
lines changed

8 files changed

+71
-41
lines changed

fs/btrfs/discard.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,13 +539,13 @@ static void btrfs_discard_workfn(struct work_struct *work)
539539
btrfs_trim_block_group_bitmaps(block_group, &trimmed,
540540
block_group->discard_cursor,
541541
btrfs_block_group_end(block_group),
542-
minlen, maxlen, true);
542+
minlen, maxlen, true, BTRFS_CLEAR_OP_DISCARD);
543543
discard_ctl->discard_bitmap_bytes += trimmed;
544544
} else {
545545
btrfs_trim_block_group_extents(block_group, &trimmed,
546546
block_group->discard_cursor,
547547
btrfs_block_group_end(block_group),
548-
minlen, true);
548+
minlen, true, BTRFS_CLEAR_OP_DISCARD);
549549
discard_ctl->discard_extent_bytes += trimmed;
550550
}
551551

fs/btrfs/extent-tree.c

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,8 +1247,20 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
12471247
return ret;
12481248
}
12491249

1250+
static int btrfs_issue_clear_op(struct block_device *bdev, u64 start, u64 size,
1251+
enum btrfs_clear_op_type clear)
1252+
{
1253+
switch (clear) {
1254+
case BTRFS_CLEAR_OP_DISCARD:
1255+
return blkdev_issue_discard(bdev, start >> SECTOR_SHIFT,
1256+
size >> SECTOR_SHIFT, GFP_NOFS);
1257+
default:
1258+
return -EOPNOTSUPP;
1259+
}
1260+
}
1261+
12501262
static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
1251-
u64 *discarded_bytes)
1263+
u64 *discarded_bytes, enum btrfs_clear_op_type clear)
12521264
{
12531265
int j, ret = 0;
12541266
u64 bytes_left, end;
@@ -1293,11 +1305,8 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
12931305
bytes_left = end - start;
12941306
continue;
12951307
}
1296-
12971308
if (size) {
1298-
ret = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT,
1299-
size >> SECTOR_SHIFT,
1300-
GFP_NOFS);
1309+
ret = btrfs_issue_clear_op(bdev, start, size, clear);
13011310
if (!ret)
13021311
*discarded_bytes += size;
13031312
else if (ret != -EOPNOTSUPP)
@@ -1315,9 +1324,7 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
13151324
while (bytes_left) {
13161325
u64 bytes_to_discard = min(BTRFS_MAX_DISCARD_CHUNK_SIZE, bytes_left);
13171326

1318-
ret = blkdev_issue_discard(bdev, start >> SECTOR_SHIFT,
1319-
bytes_to_discard >> SECTOR_SHIFT,
1320-
GFP_NOFS);
1327+
ret = btrfs_issue_clear_op(bdev, start, bytes_left, clear);
13211328

13221329
if (ret) {
13231330
if (ret != -EOPNOTSUPP)
@@ -1338,7 +1345,8 @@ static int btrfs_issue_discard(struct block_device *bdev, u64 start, u64 len,
13381345
return ret;
13391346
}
13401347

1341-
static int do_discard_extent(struct btrfs_discard_stripe *stripe, u64 *bytes)
1348+
static int do_discard_extent(struct btrfs_discard_stripe *stripe, u64 *bytes,
1349+
enum btrfs_clear_op_type clear)
13421350
{
13431351
struct btrfs_device *dev = stripe->dev;
13441352
struct btrfs_fs_info *fs_info = dev->fs_info;
@@ -1367,7 +1375,7 @@ static int do_discard_extent(struct btrfs_discard_stripe *stripe, u64 *bytes)
13671375
&discarded);
13681376
discarded += src_disc;
13691377
} else if (bdev_max_discard_sectors(stripe->dev->bdev)) {
1370-
ret = btrfs_issue_discard(dev->bdev, phys, len, &discarded);
1378+
ret = btrfs_issue_discard(dev->bdev, phys, len, &discarded, clear);
13711379
} else {
13721380
ret = 0;
13731381
*bytes = 0;
@@ -1379,7 +1387,8 @@ static int do_discard_extent(struct btrfs_discard_stripe *stripe, u64 *bytes)
13791387
}
13801388

13811389
int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
1382-
u64 num_bytes, u64 *actual_bytes)
1390+
u64 num_bytes, u64 *actual_bytes,
1391+
enum btrfs_clear_op_type clear)
13831392
{
13841393
int ret = 0;
13851394
u64 discarded_bytes = 0;
@@ -1418,7 +1427,7 @@ int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
14181427
&stripe->dev->dev_state))
14191428
continue;
14201429

1421-
ret = do_discard_extent(stripe, &bytes);
1430+
ret = do_discard_extent(stripe, &bytes, clear);
14221431
if (ret) {
14231432
/*
14241433
* Keep going if discard is not supported by the
@@ -2840,7 +2849,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
28402849

28412850
if (btrfs_test_opt(fs_info, DISCARD_SYNC))
28422851
ret = btrfs_discard_extent(fs_info, start,
2843-
end + 1 - start, NULL);
2852+
end + 1 - start, NULL,
2853+
BTRFS_CLEAR_OP_DISCARD);
28442854

28452855
next_state = btrfs_next_extent_state(unpin, cached_state);
28462856
btrfs_clear_extent_dirty(unpin, start, end, &cached_state);
@@ -2897,8 +2907,11 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans)
28972907
list_for_each_entry_safe(block_group, tmp, deleted_bgs, bg_list) {
28982908
ret = -EROFS;
28992909
if (!TRANS_ABORTED(trans))
2900-
ret = btrfs_discard_extent(fs_info, block_group->start,
2901-
block_group->length, NULL);
2910+
ret = btrfs_discard_extent(fs_info,
2911+
block_group->start,
2912+
block_group->length,
2913+
NULL,
2914+
BTRFS_CLEAR_OP_DISCARD);
29022915

29032916
/*
29042917
* Not strictly necessary to lock, as the block_group should be
@@ -6413,7 +6426,8 @@ void btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, u64 start, u6
64136426
* it while performing the free space search since we have already
64146427
* held back allocations.
64156428
*/
6416-
static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
6429+
static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed,
6430+
enum btrfs_clear_op_type clear)
64176431
{
64186432
u64 start = BTRFS_DEVICE_RANGE_RESERVED, len = 0, end = 0;
64196433
int ret;
@@ -6478,8 +6492,7 @@ static int btrfs_trim_free_extents(struct btrfs_device *device, u64 *trimmed)
64786492
break;
64796493
}
64806494

6481-
ret = btrfs_issue_discard(device->bdev, start, len,
6482-
&bytes);
6495+
ret = btrfs_issue_discard(device->bdev, start, len, &bytes, clear);
64836496
if (!ret)
64846497
btrfs_set_extent_bit(&device->alloc_state, start,
64856498
start + bytes - 1, CHUNK_TRIMMED, NULL);
@@ -6561,7 +6574,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
65616574
&group_trimmed,
65626575
start,
65636576
end,
6564-
range->minlen);
6577+
range->minlen,
6578+
BTRFS_CLEAR_OP_DISCARD);
65656579

65666580
trimmed += group_trimmed;
65676581
if (ret) {
@@ -6582,7 +6596,8 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range)
65826596
if (test_bit(BTRFS_DEV_STATE_MISSING, &device->dev_state))
65836597
continue;
65846598

6585-
ret = btrfs_trim_free_extents(device, &group_trimmed);
6599+
ret = btrfs_trim_free_extents(device, &group_trimmed,
6600+
BTRFS_CLEAR_OP_DISCARD);
65866601

65876602
trimmed += group_trimmed;
65886603
if (ret) {

fs/btrfs/extent-tree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
163163
struct extent_buffer *parent);
164164
void btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, u64 start, u64 end);
165165
int btrfs_discard_extent(struct btrfs_fs_info *fs_info, u64 bytenr,
166-
u64 num_bytes, u64 *actual_bytes);
166+
u64 num_bytes, u64 *actual_bytes,
167+
enum btrfs_clear_op_type clear);
167168
int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range);
168169

169170
#endif

fs/btrfs/free-space-cache.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3650,7 +3650,8 @@ static int do_trimming(struct btrfs_block_group *block_group,
36503650
u64 *total_trimmed, u64 start, u64 bytes,
36513651
u64 reserved_start, u64 reserved_bytes,
36523652
enum btrfs_trim_state reserved_trim_state,
3653-
struct btrfs_trim_range *trim_entry)
3653+
struct btrfs_trim_range *trim_entry,
3654+
enum btrfs_clear_op_type clear)
36543655
{
36553656
struct btrfs_space_info *space_info = block_group->space_info;
36563657
struct btrfs_fs_info *fs_info = block_group->fs_info;
@@ -3672,7 +3673,7 @@ static int do_trimming(struct btrfs_block_group *block_group,
36723673
spin_unlock(&block_group->lock);
36733674
spin_unlock(&space_info->lock);
36743675

3675-
ret = btrfs_discard_extent(fs_info, start, bytes, &trimmed);
3676+
ret = btrfs_discard_extent(fs_info, start, bytes, &trimmed, clear);
36763677
if (!ret) {
36773678
*total_trimmed += trimmed;
36783679
trim_state = BTRFS_TRIM_STATE_TRIMMED;
@@ -3709,7 +3710,7 @@ static int do_trimming(struct btrfs_block_group *block_group,
37093710
*/
37103711
static int trim_no_bitmap(struct btrfs_block_group *block_group,
37113712
u64 *total_trimmed, u64 start, u64 end, u64 minlen,
3712-
bool async)
3713+
bool async, enum btrfs_clear_op_type clear)
37133714
{
37143715
struct btrfs_discard_ctl *discard_ctl =
37153716
&block_group->fs_info->discard_ctl;
@@ -3798,7 +3799,7 @@ static int trim_no_bitmap(struct btrfs_block_group *block_group,
37983799

37993800
ret = do_trimming(block_group, total_trimmed, start, bytes,
38003801
extent_start, extent_bytes, extent_trim_state,
3801-
&trim_entry);
3802+
&trim_entry, clear);
38023803
if (ret) {
38033804
block_group->discard_cursor = start + bytes;
38043805
break;
@@ -3875,7 +3876,7 @@ static void end_trimming_bitmap(struct btrfs_free_space_ctl *ctl,
38753876
*/
38763877
static int trim_bitmaps(struct btrfs_block_group *block_group,
38773878
u64 *total_trimmed, u64 start, u64 end, u64 minlen,
3878-
u64 maxlen, bool async)
3879+
u64 maxlen, bool async, enum btrfs_clear_op_type clear)
38793880
{
38803881
struct btrfs_discard_ctl *discard_ctl =
38813882
&block_group->fs_info->discard_ctl;
@@ -3984,7 +3985,7 @@ static int trim_bitmaps(struct btrfs_block_group *block_group,
39843985
mutex_unlock(&ctl->cache_writeout_mutex);
39853986

39863987
ret = do_trimming(block_group, total_trimmed, start, bytes,
3987-
start, bytes, 0, &trim_entry);
3988+
start, bytes, 0, &trim_entry, clear);
39883989
if (ret) {
39893990
reset_trimming_bitmap(ctl, offset);
39903991
block_group->discard_cursor =
@@ -4018,7 +4019,8 @@ static int trim_bitmaps(struct btrfs_block_group *block_group,
40184019
}
40194020

40204021
int btrfs_trim_block_group(struct btrfs_block_group *block_group,
4021-
u64 *trimmed, u64 start, u64 end, u64 minlen)
4022+
u64 *trimmed, u64 start, u64 end, u64 minlen,
4023+
enum btrfs_clear_op_type clear)
40224024
{
40234025
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
40244026
int ret;
@@ -4036,11 +4038,11 @@ int btrfs_trim_block_group(struct btrfs_block_group *block_group,
40364038
btrfs_freeze_block_group(block_group);
40374039
spin_unlock(&block_group->lock);
40384040

4039-
ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, false);
4041+
ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, false, clear);
40404042
if (ret)
40414043
goto out;
40424044

4043-
ret = trim_bitmaps(block_group, trimmed, start, end, minlen, 0, false);
4045+
ret = trim_bitmaps(block_group, trimmed, start, end, minlen, 0, false, clear);
40444046
div64_u64_rem(end, BITS_PER_BITMAP * ctl->unit, &rem);
40454047
/* If we ended in the middle of a bitmap, reset the trimming flag */
40464048
if (rem)
@@ -4052,7 +4054,7 @@ int btrfs_trim_block_group(struct btrfs_block_group *block_group,
40524054

40534055
int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group,
40544056
u64 *trimmed, u64 start, u64 end, u64 minlen,
4055-
bool async)
4057+
bool async, enum btrfs_clear_op_type clear)
40564058
{
40574059
int ret;
40584060

@@ -4066,15 +4068,16 @@ int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group,
40664068
btrfs_freeze_block_group(block_group);
40674069
spin_unlock(&block_group->lock);
40684070

4069-
ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, async);
4071+
ret = trim_no_bitmap(block_group, trimmed, start, end, minlen, async, clear);
40704072
btrfs_unfreeze_block_group(block_group);
40714073

40724074
return ret;
40734075
}
40744076

40754077
int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group,
40764078
u64 *trimmed, u64 start, u64 end, u64 minlen,
4077-
u64 maxlen, bool async)
4079+
u64 maxlen, bool async,
4080+
enum btrfs_clear_op_type clear)
40784081
{
40794082
int ret;
40804083

@@ -4089,7 +4092,7 @@ int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group,
40894092
spin_unlock(&block_group->lock);
40904093

40914094
ret = trim_bitmaps(block_group, trimmed, start, end, minlen, maxlen,
4092-
async);
4095+
async, clear);
40934096

40944097
btrfs_unfreeze_block_group(block_group);
40954098

fs/btrfs/free-space-cache.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,15 @@ void btrfs_return_cluster_to_free_space(
159159
struct btrfs_block_group *block_group,
160160
struct btrfs_free_cluster *cluster);
161161
int btrfs_trim_block_group(struct btrfs_block_group *block_group,
162-
u64 *trimmed, u64 start, u64 end, u64 minlen);
162+
u64 *trimmed, u64 start, u64 end, u64 minlen,
163+
enum btrfs_clear_op_type clear);
163164
int btrfs_trim_block_group_extents(struct btrfs_block_group *block_group,
164165
u64 *trimmed, u64 start, u64 end, u64 minlen,
165-
bool async);
166+
bool async, enum btrfs_clear_op_type clear);
166167
int btrfs_trim_block_group_bitmaps(struct btrfs_block_group *block_group,
167168
u64 *trimmed, u64 start, u64 end, u64 minlen,
168-
u64 maxlen, bool async);
169+
u64 maxlen, bool async,
170+
enum btrfs_clear_op_type clear);
169171

170172
bool btrfs_free_space_cache_v1_active(struct btrfs_fs_info *fs_info);
171173
int btrfs_set_free_space_cache_v1_active(struct btrfs_fs_info *fs_info, bool active);

fs/btrfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3286,7 +3286,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
32863286
btrfs_discard_extent(fs_info,
32873287
ordered_extent->disk_bytenr,
32883288
ordered_extent->disk_num_bytes,
3289-
NULL);
3289+
NULL, BTRFS_CLEAR_OP_DISCARD);
32903290
btrfs_free_reserved_extent(fs_info,
32913291
ordered_extent->disk_bytenr,
32923292
ordered_extent->disk_num_bytes, true);

fs/btrfs/volumes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3460,7 +3460,8 @@ int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset)
34603460
* filesystem's point of view.
34613461
*/
34623462
if (btrfs_is_zoned(fs_info)) {
3463-
ret = btrfs_discard_extent(fs_info, chunk_offset, length, NULL);
3463+
ret = btrfs_discard_extent(fs_info, chunk_offset, length, NULL,
3464+
BTRFS_CLEAR_OP_DISCARD);
34643465
if (ret)
34653466
btrfs_info(fs_info,
34663467
"failed to reset zone %llu after relocation",

include/uapi/linux/btrfs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,14 @@ enum btrfs_err_code {
10961096
BTRFS_ERROR_DEV_RAID1C4_MIN_NOT_MET,
10971097
};
10981098

1099+
/*
1100+
* Type of operation that will be used to clear unused blocks.
1101+
*/
1102+
enum btrfs_clear_op_type {
1103+
BTRFS_CLEAR_OP_DISCARD,
1104+
BTRFS_NR_CLEAR_OP_TYPES,
1105+
};
1106+
10991107
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
11001108
struct btrfs_ioctl_vol_args)
11011109
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \

0 commit comments

Comments
 (0)