Skip to content

Commit c30c65f

Browse files
committed
Merge tag 'block-6.13-20241213' of git://git.kernel.dk/linux
Pull block fixes from Jens Axboe: - Series from Damien fixing issues with the zoned write plugging - Fix for a potential UAF in block cgroups - Fix deadlock around queue freezing and the sysfs lock - Various little cleanups and fixes * tag 'block-6.13-20241213' of git://git.kernel.dk/linux: block: Fix potential deadlock while freezing queue and acquiring sysfs_lock block: Fix queue_iostats_passthrough_show() blk-mq: Clean up blk_mq_requeue_work() mq-deadline: Remove a local variable blk-iocost: Avoid using clamp() on inuse in __propagate_weights() block: Make bio_iov_bvec_set() accept pointer to const iov_iter block: get wp_offset by bdev_offset_from_zone_start blk-cgroup: Fix UAF in blkcg_unpin_online() MAINTAINERS: update Coly Li's email address block: Prevent potential deadlocks in zone write plug error recovery dm: Fix dm-zoned-reclaim zone write pointer alignment block: Ignore REQ_NOWAIT for zone reset and zone finish operations block: Use a zone write plug BIO work for REQ_NOWAIT BIOs
2 parents 2a816e4 + be26ba9 commit c30c65f

File tree

13 files changed

+279
-329
lines changed

13 files changed

+279
-329
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3893,7 +3893,7 @@ W: http://www.baycom.org/~tom/ham/ham.html
38933893
F: drivers/net/hamradio/baycom*
38943894

38953895
BCACHE (BLOCK LAYER CACHE)
3896-
M: Coly Li <colyli@suse.de>
3896+
M: Coly Li <colyli@kernel.org>
38973897
M: Kent Overstreet <[email protected]>
38983898
38993899
S: Maintained

block/bio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,7 +1171,7 @@ void __bio_release_pages(struct bio *bio, bool mark_dirty)
11711171
}
11721172
EXPORT_SYMBOL_GPL(__bio_release_pages);
11731173

1174-
void bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
1174+
void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter)
11751175
{
11761176
WARN_ON_ONCE(bio->bi_max_vecs);
11771177

block/blk-cgroup.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,10 +1324,14 @@ void blkcg_unpin_online(struct cgroup_subsys_state *blkcg_css)
13241324
struct blkcg *blkcg = css_to_blkcg(blkcg_css);
13251325

13261326
do {
1327+
struct blkcg *parent;
1328+
13271329
if (!refcount_dec_and_test(&blkcg->online_pin))
13281330
break;
1331+
1332+
parent = blkcg_parent(blkcg);
13291333
blkcg_destroy_blkgs(blkcg);
1330-
blkcg = blkcg_parent(blkcg);
1334+
blkcg = parent;
13311335
} while (blkcg);
13321336
}
13331337

block/blk-iocost.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1098,7 +1098,14 @@ static void __propagate_weights(struct ioc_gq *iocg, u32 active, u32 inuse,
10981098
inuse = DIV64_U64_ROUND_UP(active * iocg->child_inuse_sum,
10991099
iocg->child_active_sum);
11001100
} else {
1101-
inuse = clamp_t(u32, inuse, 1, active);
1101+
/*
1102+
* It may be tempting to turn this into a clamp expression with
1103+
* a lower limit of 1 but active may be 0, which cannot be used
1104+
* as an upper limit in that situation. This expression allows
1105+
* active to clamp inuse unless it is 0, in which case inuse
1106+
* becomes 1.
1107+
*/
1108+
inuse = min(inuse, active) ?: 1;
11021109
}
11031110

11041111
iocg->last_inuse = iocg->inuse;

block/blk-map.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter)
574574
bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL);
575575
if (!bio)
576576
return -ENOMEM;
577-
bio_iov_bvec_set(bio, (struct iov_iter *)iter);
577+
bio_iov_bvec_set(bio, iter);
578578

579579
/* check that the data layout matches the hardware restrictions */
580580
ret = bio_split_rw_at(bio, lim, &nsegs, max_bytes);

block/blk-mq-sysfs.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,13 @@ void blk_mq_sysfs_unregister_hctxs(struct request_queue *q)
275275
struct blk_mq_hw_ctx *hctx;
276276
unsigned long i;
277277

278-
mutex_lock(&q->sysfs_dir_lock);
278+
lockdep_assert_held(&q->sysfs_dir_lock);
279+
279280
if (!q->mq_sysfs_init_done)
280-
goto unlock;
281+
return;
281282

282283
queue_for_each_hw_ctx(q, hctx, i)
283284
blk_mq_unregister_hctx(hctx);
284-
285-
unlock:
286-
mutex_unlock(&q->sysfs_dir_lock);
287285
}
288286

289287
int blk_mq_sysfs_register_hctxs(struct request_queue *q)
@@ -292,18 +290,16 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
292290
unsigned long i;
293291
int ret = 0;
294292

295-
mutex_lock(&q->sysfs_dir_lock);
293+
lockdep_assert_held(&q->sysfs_dir_lock);
294+
296295
if (!q->mq_sysfs_init_done)
297-
goto unlock;
296+
return ret;
298297

299298
queue_for_each_hw_ctx(q, hctx, i) {
300299
ret = blk_mq_register_hctx(hctx);
301300
if (ret)
302301
break;
303302
}
304303

305-
unlock:
306-
mutex_unlock(&q->sysfs_dir_lock);
307-
308304
return ret;
309305
}

block/blk-mq.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,19 +1544,17 @@ static void blk_mq_requeue_work(struct work_struct *work)
15441544

15451545
while (!list_empty(&rq_list)) {
15461546
rq = list_entry(rq_list.next, struct request, queuelist);
1547+
list_del_init(&rq->queuelist);
15471548
/*
1548-
* If RQF_DONTPREP ist set, the request has been started by the
1549+
* If RQF_DONTPREP is set, the request has been started by the
15491550
* driver already and might have driver-specific data allocated
15501551
* already. Insert it into the hctx dispatch list to avoid
15511552
* block layer merges for the request.
15521553
*/
1553-
if (rq->rq_flags & RQF_DONTPREP) {
1554-
list_del_init(&rq->queuelist);
1554+
if (rq->rq_flags & RQF_DONTPREP)
15551555
blk_mq_request_bypass_insert(rq, 0);
1556-
} else {
1557-
list_del_init(&rq->queuelist);
1556+
else
15581557
blk_mq_insert_request(rq, BLK_MQ_INSERT_AT_HEAD);
1559-
}
15601558
}
15611559

15621560
while (!list_empty(&flush_list)) {
@@ -4455,7 +4453,8 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
44554453
unsigned long i, j;
44564454

44574455
/* protect against switching io scheduler */
4458-
mutex_lock(&q->sysfs_lock);
4456+
lockdep_assert_held(&q->sysfs_lock);
4457+
44594458
for (i = 0; i < set->nr_hw_queues; i++) {
44604459
int old_node;
44614460
int node = blk_mq_get_hctx_node(set, i);
@@ -4488,7 +4487,6 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
44884487

44894488
xa_for_each_start(&q->hctx_table, j, hctx, j)
44904489
blk_mq_exit_hctx(q, set, hctx, j);
4491-
mutex_unlock(&q->sysfs_lock);
44924490

44934491
/* unregister cpuhp callbacks for exited hctxs */
44944492
blk_mq_remove_hw_queues_cpuhp(q);
@@ -4520,10 +4518,14 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
45204518

45214519
xa_init(&q->hctx_table);
45224520

4521+
mutex_lock(&q->sysfs_lock);
4522+
45234523
blk_mq_realloc_hw_ctxs(set, q);
45244524
if (!q->nr_hw_queues)
45254525
goto err_hctxs;
45264526

4527+
mutex_unlock(&q->sysfs_lock);
4528+
45274529
INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
45284530
blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
45294531

@@ -4542,6 +4544,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
45424544
return 0;
45434545

45444546
err_hctxs:
4547+
mutex_unlock(&q->sysfs_lock);
45454548
blk_mq_release(q);
45464549
err_exit:
45474550
q->mq_ops = NULL;
@@ -4922,12 +4925,12 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
49224925
return false;
49234926

49244927
/* q->elevator needs protection from ->sysfs_lock */
4925-
mutex_lock(&q->sysfs_lock);
4928+
lockdep_assert_held(&q->sysfs_lock);
49264929

49274930
/* the check has to be done with holding sysfs_lock */
49284931
if (!q->elevator) {
49294932
kfree(qe);
4930-
goto unlock;
4933+
goto out;
49314934
}
49324935

49334936
INIT_LIST_HEAD(&qe->node);
@@ -4937,9 +4940,7 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
49374940
__elevator_get(qe->type);
49384941
list_add(&qe->node, head);
49394942
elevator_disable(q);
4940-
unlock:
4941-
mutex_unlock(&q->sysfs_lock);
4942-
4943+
out:
49434944
return true;
49444945
}
49454946

@@ -4968,11 +4969,9 @@ static void blk_mq_elv_switch_back(struct list_head *head,
49684969
list_del(&qe->node);
49694970
kfree(qe);
49704971

4971-
mutex_lock(&q->sysfs_lock);
49724972
elevator_switch(q, t);
49734973
/* drop the reference acquired in blk_mq_elv_switch_none */
49744974
elevator_put(t);
4975-
mutex_unlock(&q->sysfs_lock);
49764975
}
49774976

49784977
static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
@@ -4992,8 +4991,11 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
49924991
if (set->nr_maps == 1 && nr_hw_queues == set->nr_hw_queues)
49934992
return;
49944993

4995-
list_for_each_entry(q, &set->tag_list, tag_set_list)
4994+
list_for_each_entry(q, &set->tag_list, tag_set_list) {
4995+
mutex_lock(&q->sysfs_dir_lock);
4996+
mutex_lock(&q->sysfs_lock);
49964997
blk_mq_freeze_queue(q);
4998+
}
49974999
/*
49985000
* Switch IO scheduler to 'none', cleaning up the data associated
49995001
* with the previous scheduler. We will switch back once we are done
@@ -5049,8 +5051,11 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
50495051
list_for_each_entry(q, &set->tag_list, tag_set_list)
50505052
blk_mq_elv_switch_back(&head, q);
50515053

5052-
list_for_each_entry(q, &set->tag_list, tag_set_list)
5054+
list_for_each_entry(q, &set->tag_list, tag_set_list) {
50535055
blk_mq_unfreeze_queue(q);
5056+
mutex_unlock(&q->sysfs_lock);
5057+
mutex_unlock(&q->sysfs_dir_lock);
5058+
}
50545059

50555060
/* Free the excess tags when nr_hw_queues shrink. */
50565061
for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)

block/blk-sysfs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static ssize_t queue_nr_zones_show(struct gendisk *disk, char *page)
263263

264264
static ssize_t queue_iostats_passthrough_show(struct gendisk *disk, char *page)
265265
{
266-
return queue_var_show(blk_queue_passthrough_stat(disk->queue), page);
266+
return queue_var_show(!!blk_queue_passthrough_stat(disk->queue), page);
267267
}
268268

269269
static ssize_t queue_iostats_passthrough_store(struct gendisk *disk,
@@ -706,11 +706,11 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
706706
if (entry->load_module)
707707
entry->load_module(disk, page, length);
708708

709-
blk_mq_freeze_queue(q);
710709
mutex_lock(&q->sysfs_lock);
710+
blk_mq_freeze_queue(q);
711711
res = entry->store(disk, page, length);
712-
mutex_unlock(&q->sysfs_lock);
713712
blk_mq_unfreeze_queue(q);
713+
mutex_unlock(&q->sysfs_lock);
714714
return res;
715715
}
716716

0 commit comments

Comments
 (0)