Skip to content

Commit d8ba32c

Browse files
committed
Merge tag 'block-6.19-20251218' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull block fixes from Jens Axboe: - ublk selftests for missing coverage - two fixes for the block integrity code - fix for the newly added newly added PR read keys ioctl, limiting the memory that can be allocated - work around for a deadlock that can occur with ublk, where partition scanning ends up recursing back into file closure, which needs the same mutex grabbed. Not the prettiest thing in the world, but an acceptable work-around until we can eliminate the reliance on disk->open_mutex for this - fix for a race between enabling writeback throttling and new IO submissions - move a bit of bio flag handling code. No changes, but needed for a patchset for a future kernel - fix for an init time id leak failure in rnbd - loop/zloop state check fix * tag 'block-6.19-20251218' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: block: validate interval_exp integrity limit block: validate pi_offset integrity limit block: rnbd-clt: Fix leaked ID in init_dev() ublk: fix deadlock when reading partition table block: add allocation size check in blkdev_pr_read_keys() Documentation: admin-guide: blockdev: replace zone_capacity with zone_capacity_mb when creating devices zloop: use READ_ONCE() to read lo->lo_state in queue_rq path loop: use READ_ONCE() to read lo->lo_state without locking block: fix race between wbt_enable_default and IO submission selftests: ublk: add user copy test cases selftests: ublk: add support for user copy to kublk selftests: ublk: forbid multiple data copy modes selftests: ublk: don't share backing files between ublk servers selftests: ublk: use auto_zc for PER_IO_DAEMON tests in stress_04 selftests: ublk: fix fio arguments in run_io_and_recover() selftests: ublk: remove unused ios map in seq_io.bt selftests: ublk: correct last_rw map type in seq_io.bt selftests: ublk: fix overflow in ublk_queue_auto_zc_fallback() block: move around bio flagging helpers
2 parents d245b2e + af65faf commit d8ba32c

35 files changed

Lines changed: 450 additions & 91 deletions

Documentation/admin-guide/blockdev/zoned_loop.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ MB and a zone capacity of 63 MB::
134134

135135
$ modprobe zloop
136136
$ mkdir -p /var/local/zloop/0
137-
$ echo "add capacity_mb=2048,zone_size_mb=64,zone_capacity=63MB" > /dev/zloop-control
137+
$ echo "add capacity_mb=2048,zone_size_mb=64,zone_capacity_mb=63" > /dev/zloop-control
138138

139139
For the device created (/dev/zloop0), the zone backing files are all created
140140
under the default base directory (/var/local/zloop)::

block/bfq-iosched.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7181,7 +7181,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
71817181

71827182
blk_stat_disable_accounting(bfqd->queue);
71837183
blk_queue_flag_clear(QUEUE_FLAG_DISABLE_WBT_DEF, bfqd->queue);
7184-
set_bit(ELEVATOR_FLAG_ENABLE_WBT_ON_EXIT, &e->flags);
7184+
wbt_enable_default(bfqd->queue->disk);
71857185

71867186
kfree(bfqd);
71877187
}

block/blk-settings.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,9 @@ static int blk_validate_integrity_limits(struct queue_limits *lim)
161161
return -EINVAL;
162162
}
163163

164-
if (bi->pi_tuple_size > bi->metadata_size) {
165-
pr_warn("pi_tuple_size (%u) exceeds metadata_size (%u)\n",
166-
bi->pi_tuple_size,
167-
bi->metadata_size);
164+
if (bi->pi_offset + bi->pi_tuple_size > bi->metadata_size) {
165+
pr_warn("pi_offset (%u) + pi_tuple_size (%u) exceeds metadata_size (%u)\n",
166+
bi->pi_offset, bi->pi_tuple_size, bi->metadata_size);
168167
return -EINVAL;
169168
}
170169

@@ -194,8 +193,13 @@ static int blk_validate_integrity_limits(struct queue_limits *lim)
194193
break;
195194
}
196195

197-
if (!bi->interval_exp)
196+
if (!bi->interval_exp) {
198197
bi->interval_exp = ilog2(lim->logical_block_size);
198+
} else if (bi->interval_exp < SECTOR_SHIFT ||
199+
bi->interval_exp > ilog2(lim->logical_block_size)) {
200+
pr_warn("invalid interval_exp %u\n", bi->interval_exp);
201+
return -EINVAL;
202+
}
199203

200204
/*
201205
* The PI generation / validation helpers do not expect intervals to

block/blk-sysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ int blk_register_queue(struct gendisk *disk)
932932
elevator_set_default(q);
933933

934934
blk_queue_flag_set(QUEUE_FLAG_REGISTERED, q);
935-
wbt_enable_default(disk);
935+
wbt_init_enable_default(disk);
936936

937937
/* Now everything is ready and send out KOBJ_ADD uevent */
938938
kobject_uevent(&disk->queue_kobj, KOBJ_ADD);

block/blk-wbt.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ static void wbt_requeue(struct rq_qos *rqos, struct request *rq)
699699
/*
700700
* Enable wbt if defaults are configured that way
701701
*/
702-
void wbt_enable_default(struct gendisk *disk)
702+
static bool __wbt_enable_default(struct gendisk *disk)
703703
{
704704
struct request_queue *q = disk->queue;
705705
struct rq_qos *rqos;
@@ -716,19 +716,31 @@ void wbt_enable_default(struct gendisk *disk)
716716
if (enable && RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT)
717717
RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT;
718718
mutex_unlock(&disk->rqos_state_mutex);
719-
return;
719+
return false;
720720
}
721721
mutex_unlock(&disk->rqos_state_mutex);
722722

723723
/* Queue not registered? Maybe shutting down... */
724724
if (!blk_queue_registered(q))
725-
return;
725+
return false;
726726

727727
if (queue_is_mq(q) && enable)
728-
wbt_init(disk);
728+
return true;
729+
return false;
730+
}
731+
732+
void wbt_enable_default(struct gendisk *disk)
733+
{
734+
__wbt_enable_default(disk);
729735
}
730736
EXPORT_SYMBOL_GPL(wbt_enable_default);
731737

738+
void wbt_init_enable_default(struct gendisk *disk)
739+
{
740+
if (__wbt_enable_default(disk))
741+
WARN_ON_ONCE(wbt_init(disk));
742+
}
743+
732744
u64 wbt_default_latency_nsec(struct request_queue *q)
733745
{
734746
/*

block/blk-wbt.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifdef CONFIG_BLK_WBT
66

77
int wbt_init(struct gendisk *disk);
8+
void wbt_init_enable_default(struct gendisk *disk);
89
void wbt_disable_default(struct gendisk *disk);
910
void wbt_enable_default(struct gendisk *disk);
1011

@@ -16,6 +17,10 @@ u64 wbt_default_latency_nsec(struct request_queue *);
1617

1718
#else
1819

20+
static inline void wbt_init_enable_default(struct gendisk *disk)
21+
{
22+
}
23+
1924
static inline void wbt_disable_default(struct gendisk *disk)
2025
{
2126
}

block/elevator.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -633,14 +633,10 @@ static int elevator_change_done(struct request_queue *q,
633633
.et = ctx->old->et,
634634
.data = ctx->old->elevator_data
635635
};
636-
bool enable_wbt = test_bit(ELEVATOR_FLAG_ENABLE_WBT_ON_EXIT,
637-
&ctx->old->flags);
638636

639637
elv_unregister_queue(q, ctx->old);
640638
blk_mq_free_sched_res(&res, ctx->old->type, q->tag_set);
641639
kobject_put(&ctx->old->kobj);
642-
if (enable_wbt)
643-
wbt_enable_default(q->disk);
644640
}
645641
if (ctx->new) {
646642
ret = elv_register_queue(q, ctx->new, !ctx->no_uevent);

block/elevator.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ struct elevator_queue
156156

157157
#define ELEVATOR_FLAG_REGISTERED 0
158158
#define ELEVATOR_FLAG_DYING 1
159-
#define ELEVATOR_FLAG_ENABLE_WBT_ON_EXIT 2
160159

161160
/*
162161
* block elevator interface

block/ioctl.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,12 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode,
442442
if (copy_from_user(&read_keys, arg, sizeof(read_keys)))
443443
return -EFAULT;
444444

445-
keys_info_len = struct_size(keys_info, keys, read_keys.num_keys);
446-
if (keys_info_len == SIZE_MAX)
445+
if (read_keys.num_keys > PR_KEYS_MAX)
447446
return -EINVAL;
448447

449-
keys_info = kzalloc(keys_info_len, GFP_KERNEL);
448+
keys_info_len = struct_size(keys_info, keys, read_keys.num_keys);
449+
450+
keys_info = kvzalloc(keys_info_len, GFP_KERNEL);
450451
if (!keys_info)
451452
return -ENOMEM;
452453

@@ -473,7 +474,7 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode,
473474
if (copy_to_user(arg, &read_keys, sizeof(read_keys)))
474475
ret = -EFAULT;
475476
out:
476-
kfree(keys_info);
477+
kvfree(keys_info);
477478
return ret;
478479
}
479480

drivers/block/loop.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ static int loop_configure(struct loop_device *lo, blk_mode_t mode,
10821082
/* Order wrt reading lo_state in loop_validate_file(). */
10831083
wmb();
10841084

1085-
lo->lo_state = Lo_bound;
1085+
WRITE_ONCE(lo->lo_state, Lo_bound);
10861086
if (part_shift)
10871087
lo->lo_flags |= LO_FLAGS_PARTSCAN;
10881088
partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
@@ -1179,7 +1179,7 @@ static void __loop_clr_fd(struct loop_device *lo)
11791179
if (!part_shift)
11801180
set_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
11811181
mutex_lock(&lo->lo_mutex);
1182-
lo->lo_state = Lo_unbound;
1182+
WRITE_ONCE(lo->lo_state, Lo_unbound);
11831183
mutex_unlock(&lo->lo_mutex);
11841184

11851185
/*
@@ -1218,7 +1218,7 @@ static int loop_clr_fd(struct loop_device *lo)
12181218

12191219
lo->lo_flags |= LO_FLAGS_AUTOCLEAR;
12201220
if (disk_openers(lo->lo_disk) == 1)
1221-
lo->lo_state = Lo_rundown;
1221+
WRITE_ONCE(lo->lo_state, Lo_rundown);
12221222
loop_global_unlock(lo, true);
12231223

12241224
return 0;
@@ -1743,7 +1743,7 @@ static void lo_release(struct gendisk *disk)
17431743

17441744
mutex_lock(&lo->lo_mutex);
17451745
if (lo->lo_state == Lo_bound && (lo->lo_flags & LO_FLAGS_AUTOCLEAR))
1746-
lo->lo_state = Lo_rundown;
1746+
WRITE_ONCE(lo->lo_state, Lo_rundown);
17471747

17481748
need_clear = (lo->lo_state == Lo_rundown);
17491749
mutex_unlock(&lo->lo_mutex);
@@ -1858,7 +1858,7 @@ static blk_status_t loop_queue_rq(struct blk_mq_hw_ctx *hctx,
18581858

18591859
blk_mq_start_request(rq);
18601860

1861-
if (lo->lo_state != Lo_bound)
1861+
if (data_race(READ_ONCE(lo->lo_state)) != Lo_bound)
18621862
return BLK_STS_IOERR;
18631863

18641864
switch (req_op(rq)) {
@@ -2016,7 +2016,7 @@ static int loop_add(int i)
20162016
lo->worker_tree = RB_ROOT;
20172017
INIT_LIST_HEAD(&lo->idle_worker_list);
20182018
timer_setup(&lo->timer, loop_free_idle_workers_timer, TIMER_DEFERRABLE);
2019-
lo->lo_state = Lo_unbound;
2019+
WRITE_ONCE(lo->lo_state, Lo_unbound);
20202020

20212021
err = mutex_lock_killable(&loop_ctl_mutex);
20222022
if (err)
@@ -2174,7 +2174,7 @@ static int loop_control_remove(int idx)
21742174
goto mark_visible;
21752175
}
21762176
/* Mark this loop device as no more bound, but not quite unbound yet */
2177-
lo->lo_state = Lo_deleting;
2177+
WRITE_ONCE(lo->lo_state, Lo_deleting);
21782178
mutex_unlock(&lo->lo_mutex);
21792179

21802180
loop_remove(lo);
@@ -2197,8 +2197,12 @@ static int loop_control_get_free(int idx)
21972197
if (ret)
21982198
return ret;
21992199
idr_for_each_entry(&loop_index_idr, lo, id) {
2200-
/* Hitting a race results in creating a new loop device which is harmless. */
2201-
if (lo->idr_visible && data_race(lo->lo_state) == Lo_unbound)
2200+
/*
2201+
* Hitting a race results in creating a new loop device
2202+
* which is harmless.
2203+
*/
2204+
if (lo->idr_visible &&
2205+
data_race(READ_ONCE(lo->lo_state)) == Lo_unbound)
22022206
goto found;
22032207
}
22042208
mutex_unlock(&loop_ctl_mutex);

0 commit comments

Comments
 (0)