Skip to content

Commit 0b02de8

Browse files
committed
Merge branch 'block-6.17' into for-next
* block-6.17: block: tone down bio_check_eod loop: use vfs_getattr_nosec for accurate file size loop: Consolidate size calculation logic into lo_calculate_size() block: remove newlines from the warnings in blk_validate_integrity_limits block: handle pi_tuple_size in queue_limits_stack_integrity selftests: ublk: Use ARRAY_SIZE() macro to improve code md: fix sync_action incorrect display during resync md: add helper rdev_needs_recovery() md: keep recovery_cp in mdp_superblock_s md: add legacy_async_del_gendisk mode
2 parents c17b750 + d0a2b52 commit 0b02de8

6 files changed

Lines changed: 123 additions & 58 deletions

File tree

block/blk-core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ static inline int bio_check_eod(struct bio *bio)
557557
sector_t maxsector = bdev_nr_sectors(bio->bi_bdev);
558558
unsigned int nr_sectors = bio_sectors(bio);
559559

560-
if (nr_sectors &&
560+
if (nr_sectors && maxsector &&
561561
(nr_sectors > maxsector ||
562562
bio->bi_iter.bi_sector > maxsector - nr_sectors)) {
563563
pr_info_ratelimited("%s: attempt to access beyond end of device\n"

block/blk-settings.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,25 +157,22 @@ static int blk_validate_integrity_limits(struct queue_limits *lim)
157157
switch (bi->csum_type) {
158158
case BLK_INTEGRITY_CSUM_NONE:
159159
if (bi->pi_tuple_size) {
160-
pr_warn("pi_tuple_size must be 0 when checksum type \
161-
is none\n");
160+
pr_warn("pi_tuple_size must be 0 when checksum type is none\n");
162161
return -EINVAL;
163162
}
164163
break;
165164
case BLK_INTEGRITY_CSUM_CRC:
166165
case BLK_INTEGRITY_CSUM_IP:
167166
if (bi->pi_tuple_size != sizeof(struct t10_pi_tuple)) {
168-
pr_warn("pi_tuple_size mismatch for T10 PI: expected \
169-
%zu, got %u\n",
167+
pr_warn("pi_tuple_size mismatch for T10 PI: expected %zu, got %u\n",
170168
sizeof(struct t10_pi_tuple),
171169
bi->pi_tuple_size);
172170
return -EINVAL;
173171
}
174172
break;
175173
case BLK_INTEGRITY_CSUM_CRC64:
176174
if (bi->pi_tuple_size != sizeof(struct crc64_pi_tuple)) {
177-
pr_warn("pi_tuple_size mismatch for CRC64 PI: \
178-
expected %zu, got %u\n",
175+
pr_warn("pi_tuple_size mismatch for CRC64 PI: expected %zu, got %u\n",
179176
sizeof(struct crc64_pi_tuple),
180177
bi->pi_tuple_size);
181178
return -EINVAL;
@@ -972,6 +969,8 @@ bool queue_limits_stack_integrity(struct queue_limits *t,
972969
goto incompatible;
973970
if (ti->csum_type != bi->csum_type)
974971
goto incompatible;
972+
if (ti->pi_tuple_size != bi->pi_tuple_size)
973+
goto incompatible;
975974
if ((ti->flags & BLK_INTEGRITY_REF_TAG) !=
976975
(bi->flags & BLK_INTEGRITY_REF_TAG))
977976
goto incompatible;
@@ -980,6 +979,7 @@ bool queue_limits_stack_integrity(struct queue_limits *t,
980979
ti->flags |= (bi->flags & BLK_INTEGRITY_DEVICE_CAPABLE) |
981980
(bi->flags & BLK_INTEGRITY_REF_TAG);
982981
ti->csum_type = bi->csum_type;
982+
ti->pi_tuple_size = bi->pi_tuple_size;
983983
ti->metadata_size = bi->metadata_size;
984984
ti->pi_offset = bi->pi_offset;
985985
ti->interval_exp = bi->interval_exp;

drivers/block/loop.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -137,32 +137,36 @@ static void loop_global_unlock(struct loop_device *lo, bool global)
137137
static int max_part;
138138
static int part_shift;
139139

140-
static loff_t get_size(loff_t offset, loff_t sizelimit, struct file *file)
140+
static loff_t lo_calculate_size(struct loop_device *lo, struct file *file)
141141
{
142+
struct kstat stat;
142143
loff_t loopsize;
144+
int ret;
143145

144-
/* Compute loopsize in bytes */
145-
loopsize = i_size_read(file->f_mapping->host);
146-
if (offset > 0)
147-
loopsize -= offset;
146+
/*
147+
* Get the accurate file size. This provides better results than
148+
* cached inode data, particularly for network filesystems where
149+
* metadata may be stale.
150+
*/
151+
ret = vfs_getattr_nosec(&file->f_path, &stat, STATX_SIZE, 0);
152+
if (ret)
153+
return 0;
154+
155+
loopsize = stat.size;
156+
if (lo->lo_offset > 0)
157+
loopsize -= lo->lo_offset;
148158
/* offset is beyond i_size, weird but possible */
149159
if (loopsize < 0)
150160
return 0;
151-
152-
if (sizelimit > 0 && sizelimit < loopsize)
153-
loopsize = sizelimit;
161+
if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
162+
loopsize = lo->lo_sizelimit;
154163
/*
155164
* Unfortunately, if we want to do I/O on the device,
156165
* the number of 512-byte sectors has to fit into a sector_t.
157166
*/
158167
return loopsize >> 9;
159168
}
160169

161-
static loff_t get_loop_size(struct loop_device *lo, struct file *file)
162-
{
163-
return get_size(lo->lo_offset, lo->lo_sizelimit, file);
164-
}
165-
166170
/*
167171
* We support direct I/O only if lo_offset is aligned with the logical I/O size
168172
* of backing device, and the logical block size of loop is bigger than that of
@@ -569,7 +573,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
569573
error = -EINVAL;
570574

571575
/* size of the new backing store needs to be the same */
572-
if (get_loop_size(lo, file) != get_loop_size(lo, old_file))
576+
if (lo_calculate_size(lo, file) != lo_calculate_size(lo, old_file))
573577
goto out_err;
574578

575579
/*
@@ -1063,7 +1067,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode,
10631067
loop_update_dio(lo);
10641068
loop_sysfs_init(lo);
10651069

1066-
size = get_loop_size(lo, file);
1070+
size = lo_calculate_size(lo, file);
10671071
loop_set_size(lo, size);
10681072

10691073
/* Order wrt reading lo_state in loop_validate_file(). */
@@ -1255,8 +1259,7 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
12551259
if (partscan)
12561260
clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
12571261
if (!err && size_changed) {
1258-
loff_t new_size = get_size(lo->lo_offset, lo->lo_sizelimit,
1259-
lo->lo_backing_file);
1262+
loff_t new_size = lo_calculate_size(lo, lo->lo_backing_file);
12601263
loop_set_size(lo, new_size);
12611264
}
12621265
out_unlock:
@@ -1399,7 +1402,7 @@ static int loop_set_capacity(struct loop_device *lo)
13991402
if (unlikely(lo->lo_state != Lo_bound))
14001403
return -ENXIO;
14011404

1402-
size = get_loop_size(lo, lo->lo_backing_file);
1405+
size = lo_calculate_size(lo, lo->lo_backing_file);
14031406
loop_set_size(lo, size);
14041407

14051408
return 0;

drivers/md/md.c

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ static int start_readonly;
339339
* so all the races disappear.
340340
*/
341341
static bool create_on_open = true;
342+
static bool legacy_async_del_gendisk = true;
342343

343344
/*
344345
* We have a system wide 'event count' that is incremented
@@ -877,15 +878,18 @@ void mddev_unlock(struct mddev *mddev)
877878
export_rdev(rdev, mddev);
878879
}
879880

880-
/* Call del_gendisk after release reconfig_mutex to avoid
881-
* deadlock (e.g. call del_gendisk under the lock and an
882-
* access to sysfs files waits the lock)
883-
* And MD_DELETED is only used for md raid which is set in
884-
* do_md_stop. dm raid only uses md_stop to stop. So dm raid
885-
* doesn't need to check MD_DELETED when getting reconfig lock
886-
*/
887-
if (test_bit(MD_DELETED, &mddev->flags))
888-
del_gendisk(mddev->gendisk);
881+
if (!legacy_async_del_gendisk) {
882+
/*
883+
* Call del_gendisk after release reconfig_mutex to avoid
884+
* deadlock (e.g. call del_gendisk under the lock and an
885+
* access to sysfs files waits the lock)
886+
* And MD_DELETED is only used for md raid which is set in
887+
* do_md_stop. dm raid only uses md_stop to stop. So dm raid
888+
* doesn't need to check MD_DELETED when getting reconfig lock
889+
*/
890+
if (test_bit(MD_DELETED, &mddev->flags))
891+
del_gendisk(mddev->gendisk);
892+
}
889893
}
890894
EXPORT_SYMBOL_GPL(mddev_unlock);
891895

@@ -1419,7 +1423,7 @@ static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, stru
14191423
else {
14201424
if (sb->events_hi == sb->cp_events_hi &&
14211425
sb->events_lo == sb->cp_events_lo) {
1422-
mddev->resync_offset = sb->resync_offset;
1426+
mddev->resync_offset = sb->recovery_cp;
14231427
} else
14241428
mddev->resync_offset = 0;
14251429
}
@@ -1547,13 +1551,13 @@ static void super_90_sync(struct mddev *mddev, struct md_rdev *rdev)
15471551
mddev->minor_version = sb->minor_version;
15481552
if (mddev->in_sync)
15491553
{
1550-
sb->resync_offset = mddev->resync_offset;
1554+
sb->recovery_cp = mddev->resync_offset;
15511555
sb->cp_events_hi = (mddev->events>>32);
15521556
sb->cp_events_lo = (u32)mddev->events;
15531557
if (mddev->resync_offset == MaxSector)
15541558
sb->state = (1<< MD_SB_CLEAN);
15551559
} else
1556-
sb->resync_offset = 0;
1560+
sb->recovery_cp = 0;
15571561

15581562
sb->layout = mddev->layout;
15591563
sb->chunk_size = mddev->chunk_sectors << 9;
@@ -4835,9 +4839,42 @@ metadata_store(struct mddev *mddev, const char *buf, size_t len)
48354839
static struct md_sysfs_entry md_metadata =
48364840
__ATTR_PREALLOC(metadata_version, S_IRUGO|S_IWUSR, metadata_show, metadata_store);
48374841

4842+
static bool rdev_needs_recovery(struct md_rdev *rdev, sector_t sectors)
4843+
{
4844+
return rdev->raid_disk >= 0 &&
4845+
!test_bit(Journal, &rdev->flags) &&
4846+
!test_bit(Faulty, &rdev->flags) &&
4847+
!test_bit(In_sync, &rdev->flags) &&
4848+
rdev->recovery_offset < sectors;
4849+
}
4850+
4851+
static enum sync_action md_get_active_sync_action(struct mddev *mddev)
4852+
{
4853+
struct md_rdev *rdev;
4854+
bool is_recover = false;
4855+
4856+
if (mddev->resync_offset < MaxSector)
4857+
return ACTION_RESYNC;
4858+
4859+
if (mddev->reshape_position != MaxSector)
4860+
return ACTION_RESHAPE;
4861+
4862+
rcu_read_lock();
4863+
rdev_for_each_rcu(rdev, mddev) {
4864+
if (rdev_needs_recovery(rdev, MaxSector)) {
4865+
is_recover = true;
4866+
break;
4867+
}
4868+
}
4869+
rcu_read_unlock();
4870+
4871+
return is_recover ? ACTION_RECOVER : ACTION_IDLE;
4872+
}
4873+
48384874
enum sync_action md_sync_action(struct mddev *mddev)
48394875
{
48404876
unsigned long recovery = mddev->recovery;
4877+
enum sync_action active_action;
48414878

48424879
/*
48434880
* frozen has the highest priority, means running sync_thread will be
@@ -4861,8 +4898,17 @@ enum sync_action md_sync_action(struct mddev *mddev)
48614898
!test_bit(MD_RECOVERY_NEEDED, &recovery))
48624899
return ACTION_IDLE;
48634900

4864-
if (test_bit(MD_RECOVERY_RESHAPE, &recovery) ||
4865-
mddev->reshape_position != MaxSector)
4901+
/*
4902+
* Check if any sync operation (resync/recover/reshape) is
4903+
* currently active. This ensures that only one sync operation
4904+
* can run at a time. Returns the type of active operation, or
4905+
* ACTION_IDLE if none are active.
4906+
*/
4907+
active_action = md_get_active_sync_action(mddev);
4908+
if (active_action != ACTION_IDLE)
4909+
return active_action;
4910+
4911+
if (test_bit(MD_RECOVERY_RESHAPE, &recovery))
48664912
return ACTION_RESHAPE;
48674913

48684914
if (test_bit(MD_RECOVERY_RECOVER, &recovery))
@@ -5818,6 +5864,13 @@ static void md_kobj_release(struct kobject *ko)
58185864
{
58195865
struct mddev *mddev = container_of(ko, struct mddev, kobj);
58205866

5867+
if (legacy_async_del_gendisk) {
5868+
if (mddev->sysfs_state)
5869+
sysfs_put(mddev->sysfs_state);
5870+
if (mddev->sysfs_level)
5871+
sysfs_put(mddev->sysfs_level);
5872+
del_gendisk(mddev->gendisk);
5873+
}
58215874
put_disk(mddev->gendisk);
58225875
}
58235876

@@ -6021,6 +6074,9 @@ static int md_alloc_and_put(dev_t dev, char *name)
60216074
{
60226075
struct mddev *mddev = md_alloc(dev, name);
60236076

6077+
if (legacy_async_del_gendisk)
6078+
pr_warn("md: async del_gendisk mode will be removed in future, please upgrade to mdadm-4.5+\n");
6079+
60246080
if (IS_ERR(mddev))
60256081
return PTR_ERR(mddev);
60266082
mddev_put(mddev);
@@ -6431,10 +6487,22 @@ static void md_clean(struct mddev *mddev)
64316487
mddev->persistent = 0;
64326488
mddev->level = LEVEL_NONE;
64336489
mddev->clevel[0] = 0;
6434-
/* if UNTIL_STOP is set, it's cleared here */
6435-
mddev->hold_active = 0;
6436-
/* Don't clear MD_CLOSING, or mddev can be opened again. */
6437-
mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
6490+
6491+
/*
6492+
* For legacy_async_del_gendisk mode, it can stop the array in the
6493+
* middle of assembling it, then it still can access the array. So
6494+
* it needs to clear MD_CLOSING. If not legacy_async_del_gendisk,
6495+
* it can't open the array again after stopping it. So it doesn't
6496+
* clear MD_CLOSING.
6497+
*/
6498+
if (legacy_async_del_gendisk && mddev->hold_active) {
6499+
clear_bit(MD_CLOSING, &mddev->flags);
6500+
} else {
6501+
/* if UNTIL_STOP is set, it's cleared here */
6502+
mddev->hold_active = 0;
6503+
/* Don't clear MD_CLOSING, or mddev can be opened again. */
6504+
mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
6505+
}
64386506
mddev->sb_flags = 0;
64396507
mddev->ro = MD_RDWR;
64406508
mddev->metadata_type[0] = 0;
@@ -6658,7 +6726,8 @@ static int do_md_stop(struct mddev *mddev, int mode)
66586726

66596727
export_array(mddev);
66606728
md_clean(mddev);
6661-
set_bit(MD_DELETED, &mddev->flags);
6729+
if (!legacy_async_del_gendisk)
6730+
set_bit(MD_DELETED, &mddev->flags);
66626731
}
66636732
md_new_event();
66646733
sysfs_notify_dirent_safe(mddev->sysfs_state);
@@ -8968,11 +9037,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action)
89689037
start = MaxSector;
89699038
rcu_read_lock();
89709039
rdev_for_each_rcu(rdev, mddev)
8971-
if (rdev->raid_disk >= 0 &&
8972-
!test_bit(Journal, &rdev->flags) &&
8973-
!test_bit(Faulty, &rdev->flags) &&
8974-
!test_bit(In_sync, &rdev->flags) &&
8975-
rdev->recovery_offset < start)
9040+
if (rdev_needs_recovery(rdev, start))
89769041
start = rdev->recovery_offset;
89779042
rcu_read_unlock();
89789043

@@ -9331,12 +9396,8 @@ void md_do_sync(struct md_thread *thread)
93319396
test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) {
93329397
rcu_read_lock();
93339398
rdev_for_each_rcu(rdev, mddev)
9334-
if (rdev->raid_disk >= 0 &&
9335-
mddev->delta_disks >= 0 &&
9336-
!test_bit(Journal, &rdev->flags) &&
9337-
!test_bit(Faulty, &rdev->flags) &&
9338-
!test_bit(In_sync, &rdev->flags) &&
9339-
rdev->recovery_offset < mddev->curr_resync)
9399+
if (mddev->delta_disks >= 0 &&
9400+
rdev_needs_recovery(rdev, mddev->curr_resync))
93409401
rdev->recovery_offset = mddev->curr_resync;
93419402
rcu_read_unlock();
93429403
}
@@ -10392,6 +10453,7 @@ module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR);
1039210453
module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR);
1039310454
module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR);
1039410455
module_param(create_on_open, bool, S_IRUSR|S_IWUSR);
10456+
module_param(legacy_async_del_gendisk, bool, 0600);
1039510457

1039610458
MODULE_LICENSE("GPL");
1039710459
MODULE_DESCRIPTION("MD RAID framework");

include/uapi/linux/raid/md_p.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ typedef struct mdp_superblock_s {
173173
#else
174174
#error unspecified endianness
175175
#endif
176-
__u32 resync_offset; /* 11 resync checkpoint sector count */
176+
__u32 recovery_cp; /* 11 resync checkpoint sector count */
177177
/* There are only valid for minor_version > 90 */
178178
__u64 reshape_position; /* 12,13 next address in array-space for reshape */
179179
__u32 new_level; /* 14 new level we are reshaping to */

tools/testing/selftests/ublk/kublk.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ static int cmd_dev_get_features(void)
14001400

14011401
if (!((1ULL << i) & features))
14021402
continue;
1403-
if (i < sizeof(feat_map) / sizeof(feat_map[0]))
1403+
if (i < ARRAY_SIZE(feat_map))
14041404
feat = feat_map[i];
14051405
else
14061406
feat = "unknown";
@@ -1477,7 +1477,7 @@ static void __cmd_create_help(char *exe, bool recovery)
14771477
printf("\tdefault: nr_queues=2(max 32), depth=128(max 1024), dev_id=-1(auto allocation)\n");
14781478
printf("\tdefault: nthreads=nr_queues");
14791479

1480-
for (i = 0; i < sizeof(tgt_ops_list) / sizeof(tgt_ops_list[0]); i++) {
1480+
for (i = 0; i < ARRAY_SIZE(tgt_ops_list); i++) {
14811481
const struct ublk_tgt_ops *ops = tgt_ops_list[i];
14821482

14831483
if (ops->usage)

0 commit comments

Comments
 (0)