Skip to content

Commit 1767a72

Browse files
committed
Merge tag 'for-6.1-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - revert memory optimization for scrub blocks, this misses errors in 2nd and following blocks - add exception for ENOMEM as reason for transaction abort to not print stack trace, syzbot has reported many - zoned fixes: - fix locking imbalance during scrub - initialize zones for seeding device - initialize zones for cloned device structures - when looking up device, change assertion to a real check as some of the search parameters can be passed by ioctl, reported by syzbot - fix error pointer check in self tests * tag 'for-6.1-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: zoned: fix locking imbalance on scrub btrfs: zoned: initialize device's zone info for seeding btrfs: zoned: clone zoned device info when cloning a device Revert "btrfs: scrub: use larger block size for data extent scrub" btrfs: don't print stack trace when transaction is aborted due to ENOMEM btrfs: selftests: fix wrong error check in btrfs_free_dummy_root() btrfs: fix match incorrectly in dev_args_match_device
2 parents f014699 + c62f6be commit 1767a72

File tree

9 files changed

+109
-25
lines changed

9 files changed

+109
-25
lines changed

fs/btrfs/ctree.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,22 @@ noinline void btrfs_release_path(struct btrfs_path *p)
113113
}
114114
}
115115

116+
/*
117+
* We want the transaction abort to print stack trace only for errors where the
118+
* cause could be a bug, eg. due to ENOSPC, and not for common errors that are
119+
* caused by external factors.
120+
*/
121+
bool __cold abort_should_print_stack(int errno)
122+
{
123+
switch (errno) {
124+
case -EIO:
125+
case -EROFS:
126+
case -ENOMEM:
127+
return false;
128+
}
129+
return true;
130+
}
131+
116132
/*
117133
* safely gets a reference on the root node of a tree. A lock
118134
* is not taken, so a concurrent writer may put a different node

fs/btrfs/ctree.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3796,9 +3796,11 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
37963796
const char *function,
37973797
unsigned int line, int errno, bool first_hit);
37983798

3799+
bool __cold abort_should_print_stack(int errno);
3800+
37993801
/*
38003802
* Call btrfs_abort_transaction as early as possible when an error condition is
3801-
* detected, that way the exact line number is reported.
3803+
* detected, that way the exact stack trace is reported for some errors.
38023804
*/
38033805
#define btrfs_abort_transaction(trans, errno) \
38043806
do { \
@@ -3807,10 +3809,11 @@ do { \
38073809
if (!test_and_set_bit(BTRFS_FS_STATE_TRANS_ABORTED, \
38083810
&((trans)->fs_info->fs_state))) { \
38093811
first = true; \
3810-
if ((errno) != -EIO && (errno) != -EROFS) { \
3811-
WARN(1, KERN_DEBUG \
3812+
if (WARN(abort_should_print_stack(errno), \
3813+
KERN_DEBUG \
38123814
"BTRFS: Transaction aborted (error %d)\n", \
3813-
(errno)); \
3815+
(errno))) { \
3816+
/* Stack trace printed. */ \
38143817
} else { \
38153818
btrfs_debug((trans)->fs_info, \
38163819
"Transaction aborted (error %d)", \

fs/btrfs/disk-io.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2551,7 +2551,9 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
25512551
fs_info->dev_root = root;
25522552
}
25532553
/* Initialize fs_info for all devices in any case */
2554-
btrfs_init_devices_late(fs_info);
2554+
ret = btrfs_init_devices_late(fs_info);
2555+
if (ret)
2556+
goto out;
25552557

25562558
/*
25572559
* This tree can share blocks with some other fs tree during relocation

fs/btrfs/scrub.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2672,17 +2672,11 @@ static int scrub_extent(struct scrub_ctx *sctx, struct map_lookup *map,
26722672
u8 csum[BTRFS_CSUM_SIZE];
26732673
u32 blocksize;
26742674

2675-
/*
2676-
* Block size determines how many scrub_block will be allocated. Here
2677-
* we use BTRFS_STRIPE_LEN (64KiB) as default limit, so we won't
2678-
* allocate too many scrub_block, while still won't cause too large
2679-
* bios for large extents.
2680-
*/
26812675
if (flags & BTRFS_EXTENT_FLAG_DATA) {
26822676
if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK)
26832677
blocksize = map->stripe_len;
26842678
else
2685-
blocksize = BTRFS_STRIPE_LEN;
2679+
blocksize = sctx->fs_info->sectorsize;
26862680
spin_lock(&sctx->stat_lock);
26872681
sctx->stat.data_extents_scrubbed++;
26882682
sctx->stat.data_bytes_scrubbed += len;
@@ -3917,7 +3911,6 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
39173911

39183912
if (sctx->is_dev_replace && btrfs_is_zoned(fs_info)) {
39193913
if (!test_bit(BLOCK_GROUP_FLAG_TO_COPY, &cache->runtime_flags)) {
3920-
spin_unlock(&cache->lock);
39213914
btrfs_put_block_group(cache);
39223915
goto skip;
39233916
}

fs/btrfs/tests/btrfs-tests.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void btrfs_free_dummy_fs_info(struct btrfs_fs_info *fs_info)
200200

201201
void btrfs_free_dummy_root(struct btrfs_root *root)
202202
{
203-
if (!root)
203+
if (IS_ERR_OR_NULL(root))
204204
return;
205205
/* Will be freed by btrfs_free_fs_roots */
206206
if (WARN_ON(test_bit(BTRFS_ROOT_IN_RADIX, &root->state)))

fs/btrfs/volumes.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,18 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig)
10111011
rcu_assign_pointer(device->name, name);
10121012
}
10131013

1014+
if (orig_dev->zone_info) {
1015+
struct btrfs_zoned_device_info *zone_info;
1016+
1017+
zone_info = btrfs_clone_dev_zone_info(orig_dev);
1018+
if (!zone_info) {
1019+
btrfs_free_device(device);
1020+
ret = -ENOMEM;
1021+
goto error;
1022+
}
1023+
device->zone_info = zone_info;
1024+
}
1025+
10141026
list_add(&device->dev_list, &fs_devices->devices);
10151027
device->fs_devices = fs_devices;
10161028
fs_devices->num_devices++;
@@ -6918,18 +6930,18 @@ static bool dev_args_match_fs_devices(const struct btrfs_dev_lookup_args *args,
69186930
static bool dev_args_match_device(const struct btrfs_dev_lookup_args *args,
69196931
const struct btrfs_device *device)
69206932
{
6921-
ASSERT((args->devid != (u64)-1) || args->missing);
6933+
if (args->missing) {
6934+
if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
6935+
!device->bdev)
6936+
return true;
6937+
return false;
6938+
}
69226939

6923-
if ((args->devid != (u64)-1) && device->devid != args->devid)
6940+
if (device->devid != args->devid)
69246941
return false;
69256942
if (args->uuid && memcmp(device->uuid, args->uuid, BTRFS_UUID_SIZE) != 0)
69266943
return false;
6927-
if (!args->missing)
6928-
return true;
6929-
if (test_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state) &&
6930-
!device->bdev)
6931-
return true;
6932-
return false;
6944+
return true;
69336945
}
69346946

69356947
/*
@@ -7744,10 +7756,11 @@ int btrfs_read_chunk_tree(struct btrfs_fs_info *fs_info)
77447756
return ret;
77457757
}
77467758

7747-
void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
7759+
int btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
77487760
{
77497761
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices, *seed_devs;
77507762
struct btrfs_device *device;
7763+
int ret = 0;
77517764

77527765
fs_devices->fs_info = fs_info;
77537766

@@ -7756,12 +7769,18 @@ void btrfs_init_devices_late(struct btrfs_fs_info *fs_info)
77567769
device->fs_info = fs_info;
77577770

77587771
list_for_each_entry(seed_devs, &fs_devices->seed_list, seed_list) {
7759-
list_for_each_entry(device, &seed_devs->devices, dev_list)
7772+
list_for_each_entry(device, &seed_devs->devices, dev_list) {
77607773
device->fs_info = fs_info;
7774+
ret = btrfs_get_dev_zone_info(device, false);
7775+
if (ret)
7776+
break;
7777+
}
77617778

77627779
seed_devs->fs_info = fs_info;
77637780
}
77647781
mutex_unlock(&fs_devices->device_list_mutex);
7782+
7783+
return ret;
77657784
}
77667785

77677786
static u64 btrfs_dev_stats_value(const struct extent_buffer *eb,

fs/btrfs/volumes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ int find_free_dev_extent(struct btrfs_device *device, u64 num_bytes,
671671
void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
672672
int btrfs_get_dev_stats(struct btrfs_fs_info *fs_info,
673673
struct btrfs_ioctl_get_dev_stats *stats);
674-
void btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
674+
int btrfs_init_devices_late(struct btrfs_fs_info *fs_info);
675675
int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
676676
int btrfs_run_dev_stats(struct btrfs_trans_handle *trans);
677677
void btrfs_rm_dev_replace_remove_srcdev(struct btrfs_device *srcdev);

fs/btrfs/zoned.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,46 @@ void btrfs_destroy_dev_zone_info(struct btrfs_device *device)
639639
device->zone_info = NULL;
640640
}
641641

642+
struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev)
643+
{
644+
struct btrfs_zoned_device_info *zone_info;
645+
646+
zone_info = kmemdup(orig_dev->zone_info, sizeof(*zone_info), GFP_KERNEL);
647+
if (!zone_info)
648+
return NULL;
649+
650+
zone_info->seq_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
651+
if (!zone_info->seq_zones)
652+
goto out;
653+
654+
bitmap_copy(zone_info->seq_zones, orig_dev->zone_info->seq_zones,
655+
zone_info->nr_zones);
656+
657+
zone_info->empty_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
658+
if (!zone_info->empty_zones)
659+
goto out;
660+
661+
bitmap_copy(zone_info->empty_zones, orig_dev->zone_info->empty_zones,
662+
zone_info->nr_zones);
663+
664+
zone_info->active_zones = bitmap_zalloc(zone_info->nr_zones, GFP_KERNEL);
665+
if (!zone_info->active_zones)
666+
goto out;
667+
668+
bitmap_copy(zone_info->active_zones, orig_dev->zone_info->active_zones,
669+
zone_info->nr_zones);
670+
zone_info->zone_cache = NULL;
671+
672+
return zone_info;
673+
674+
out:
675+
bitmap_free(zone_info->seq_zones);
676+
bitmap_free(zone_info->empty_zones);
677+
bitmap_free(zone_info->active_zones);
678+
kfree(zone_info);
679+
return NULL;
680+
}
681+
642682
int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
643683
struct blk_zone *zone)
644684
{

fs/btrfs/zoned.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int btrfs_get_dev_zone(struct btrfs_device *device, u64 pos,
3636
int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info);
3737
int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache);
3838
void btrfs_destroy_dev_zone_info(struct btrfs_device *device);
39+
struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(struct btrfs_device *orig_dev);
3940
int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info);
4041
int btrfs_check_mountopts_zoned(struct btrfs_fs_info *info);
4142
int btrfs_sb_log_location_bdev(struct block_device *bdev, int mirror, int rw,
@@ -103,6 +104,16 @@ static inline int btrfs_get_dev_zone_info(struct btrfs_device *device,
103104

104105
static inline void btrfs_destroy_dev_zone_info(struct btrfs_device *device) { }
105106

107+
/*
108+
* In case the kernel is compiled without CONFIG_BLK_DEV_ZONED we'll never call
109+
* into btrfs_clone_dev_zone_info() so it's safe to return NULL here.
110+
*/
111+
static inline struct btrfs_zoned_device_info *btrfs_clone_dev_zone_info(
112+
struct btrfs_device *orig_dev)
113+
{
114+
return NULL;
115+
}
116+
106117
static inline int btrfs_check_zoned_mode(const struct btrfs_fs_info *fs_info)
107118
{
108119
if (!btrfs_is_zoned(fs_info))

0 commit comments

Comments
 (0)