Skip to content

Commit 99dfe2d

Browse files
committed
Merge tag 'block-7.0-20260216' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull more block updates from Jens Axboe: - Fix partial IOVA mapping cleanup in error handling - Minor prep series ignoring discard return value, as the inline value is always known - Ensure BLK_FEAT_STABLE_WRITES is set for drbd - Fix leak of folio in bio_iov_iter_bounce_read() - Allow IOC_PR_READ_* for read-only open - Another debugfs deadlock fix - A few doc updates * tag 'block-7.0-20260216' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux: blk-mq: use NOIO context to prevent deadlock during debugfs creation blk-stat: convert struct blk_stat_callback to kernel-doc block: fix enum descriptions kernel-doc block: update docs for bio and bvec_iter block: change return type to void nvmet: ignore discard return value md: ignore discard return value block: fix partial IOVA mapping cleanup in blk_rq_dma_map_iova block: fix folio leak in bio_iov_iter_bounce_read() block: allow IOC_PR_READ_* ioctls with BLK_OPEN_READ drbd: always set BLK_FEAT_STABLE_WRITES
2 parents 7b751b0 + dfe48ea commit 99dfe2d

18 files changed

Lines changed: 183 additions & 106 deletions

File tree

block/bio.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1382,8 +1382,10 @@ static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter)
13821382
ret = iov_iter_extract_bvecs(iter, bio->bi_io_vec + 1, len,
13831383
&bio->bi_vcnt, bio->bi_max_vecs - 1, 0);
13841384
if (ret <= 0) {
1385-
if (!bio->bi_vcnt)
1385+
if (!bio->bi_vcnt) {
1386+
folio_put(folio);
13861387
return ret;
1388+
}
13871389
break;
13881390
}
13891391
len -= ret;

block/blk-lib.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,14 @@ struct bio *blk_alloc_discard_bio(struct block_device *bdev,
6060
return bio;
6161
}
6262

63-
int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
63+
void __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
6464
sector_t nr_sects, gfp_t gfp_mask, struct bio **biop)
6565
{
6666
struct bio *bio;
6767

6868
while ((bio = blk_alloc_discard_bio(bdev, &sector, &nr_sects,
6969
gfp_mask)))
7070
*biop = bio_chain_and_submit(*biop, bio);
71-
return 0;
7271
}
7372
EXPORT_SYMBOL(__blkdev_issue_discard);
7473

block/blk-mq-debugfs.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -613,11 +613,6 @@ static void debugfs_create_files(struct request_queue *q, struct dentry *parent,
613613
const struct blk_mq_debugfs_attr *attr)
614614
{
615615
lockdep_assert_held(&q->debugfs_mutex);
616-
/*
617-
* Creating new debugfs entries with queue freezed has the risk of
618-
* deadlock.
619-
*/
620-
WARN_ON_ONCE(q->mq_freeze_depth != 0);
621616
/*
622617
* debugfs_mutex should not be nested under other locks that can be
623618
* grabbed while queue is frozen.
@@ -693,12 +688,13 @@ void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
693688
void blk_mq_debugfs_register_hctxs(struct request_queue *q)
694689
{
695690
struct blk_mq_hw_ctx *hctx;
691+
unsigned int memflags;
696692
unsigned long i;
697693

698-
mutex_lock(&q->debugfs_mutex);
694+
memflags = blk_debugfs_lock(q);
699695
queue_for_each_hw_ctx(q, hctx, i)
700696
blk_mq_debugfs_register_hctx(q, hctx);
701-
mutex_unlock(&q->debugfs_mutex);
697+
blk_debugfs_unlock(q, memflags);
702698
}
703699

704700
void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)

block/blk-mq-dma.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,17 +121,20 @@ static bool blk_rq_dma_map_iova(struct request *req, struct device *dma_dev,
121121
error = dma_iova_link(dma_dev, state, vec->paddr, mapped,
122122
vec->len, dir, attrs);
123123
if (error)
124-
break;
124+
goto out_unlink;
125125
mapped += vec->len;
126126
} while (blk_map_iter_next(req, &iter->iter, vec));
127127

128128
error = dma_iova_sync(dma_dev, state, 0, mapped);
129-
if (error) {
130-
iter->status = errno_to_blk_status(error);
131-
return false;
132-
}
129+
if (error)
130+
goto out_unlink;
133131

134132
return true;
133+
134+
out_unlink:
135+
dma_iova_destroy(dma_dev, state, mapped, dir, attrs);
136+
iter->status = errno_to_blk_status(error);
137+
return false;
135138
}
136139

137140
static inline void blk_rq_map_iter_init(struct request *rq,

block/blk-mq-sched.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -390,25 +390,26 @@ static void blk_mq_sched_tags_teardown(struct request_queue *q, unsigned int fla
390390
void blk_mq_sched_reg_debugfs(struct request_queue *q)
391391
{
392392
struct blk_mq_hw_ctx *hctx;
393+
unsigned int memflags;
393394
unsigned long i;
394395

395-
mutex_lock(&q->debugfs_mutex);
396+
memflags = blk_debugfs_lock(q);
396397
blk_mq_debugfs_register_sched(q);
397398
queue_for_each_hw_ctx(q, hctx, i)
398399
blk_mq_debugfs_register_sched_hctx(q, hctx);
399-
mutex_unlock(&q->debugfs_mutex);
400+
blk_debugfs_unlock(q, memflags);
400401
}
401402

402403
void blk_mq_sched_unreg_debugfs(struct request_queue *q)
403404
{
404405
struct blk_mq_hw_ctx *hctx;
405406
unsigned long i;
406407

407-
mutex_lock(&q->debugfs_mutex);
408+
blk_debugfs_lock_nomemsave(q);
408409
queue_for_each_hw_ctx(q, hctx, i)
409410
blk_mq_debugfs_unregister_sched_hctx(hctx);
410411
blk_mq_debugfs_unregister_sched(q);
411-
mutex_unlock(&q->debugfs_mutex);
412+
blk_debugfs_unlock_nomemrestore(q);
412413
}
413414

414415
void blk_mq_free_sched_tags(struct elevator_tags *et,

block/blk-stat.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* timer fires, @cpu_stat is flushed to @stat and @timer_fn is invoked.
1818
*/
1919
struct blk_stat_callback {
20-
/*
20+
/**
2121
* @list: RCU list of callbacks for a &struct request_queue.
2222
*/
2323
struct list_head list;
@@ -50,7 +50,7 @@ struct blk_stat_callback {
5050
struct blk_rq_stat *stat;
5151

5252
/**
53-
* @fn: Callback function.
53+
* @timer_fn: Callback function.
5454
*/
5555
void (*timer_fn)(struct blk_stat_callback *);
5656

@@ -59,6 +59,9 @@ struct blk_stat_callback {
5959
*/
6060
void *data;
6161

62+
/**
63+
* @rcu: rcu list head
64+
*/
6265
struct rcu_head rcu;
6366
};
6467

@@ -126,6 +129,8 @@ void blk_stat_free_callback(struct blk_stat_callback *cb);
126129
* blk_stat_is_active() - Check if a block statistics callback is currently
127130
* gathering statistics.
128131
* @cb: The callback.
132+
*
133+
* Returns: %true iff the callback is active.
129134
*/
130135
static inline bool blk_stat_is_active(struct blk_stat_callback *cb)
131136
{

block/blk-sysfs.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -892,13 +892,13 @@ static void blk_debugfs_remove(struct gendisk *disk)
892892
{
893893
struct request_queue *q = disk->queue;
894894

895-
mutex_lock(&q->debugfs_mutex);
895+
blk_debugfs_lock_nomemsave(q);
896896
blk_trace_shutdown(q);
897897
debugfs_remove_recursive(q->debugfs_dir);
898898
q->debugfs_dir = NULL;
899899
q->sched_debugfs_dir = NULL;
900900
q->rqos_debugfs_dir = NULL;
901-
mutex_unlock(&q->debugfs_mutex);
901+
blk_debugfs_unlock_nomemrestore(q);
902902
}
903903

904904
/**
@@ -908,6 +908,7 @@ static void blk_debugfs_remove(struct gendisk *disk)
908908
int blk_register_queue(struct gendisk *disk)
909909
{
910910
struct request_queue *q = disk->queue;
911+
unsigned int memflags;
911912
int ret;
912913

913914
ret = kobject_add(&disk->queue_kobj, &disk_to_dev(disk)->kobj, "queue");
@@ -921,11 +922,11 @@ int blk_register_queue(struct gendisk *disk)
921922
}
922923
mutex_lock(&q->sysfs_lock);
923924

924-
mutex_lock(&q->debugfs_mutex);
925+
memflags = blk_debugfs_lock(q);
925926
q->debugfs_dir = debugfs_create_dir(disk->disk_name, blk_debugfs_root);
926927
if (queue_is_mq(q))
927928
blk_mq_debugfs_register(q);
928-
mutex_unlock(&q->debugfs_mutex);
929+
blk_debugfs_unlock(q, memflags);
929930

930931
ret = disk_register_independent_access_ranges(disk);
931932
if (ret)

block/blk-wbt.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ void wbt_init_enable_default(struct gendisk *disk)
776776
{
777777
struct request_queue *q = disk->queue;
778778
struct rq_wb *rwb;
779+
unsigned int memflags;
779780

780781
if (!__wbt_enable_default(disk))
781782
return;
@@ -789,9 +790,9 @@ void wbt_init_enable_default(struct gendisk *disk)
789790
return;
790791
}
791792

792-
mutex_lock(&q->debugfs_mutex);
793+
memflags = blk_debugfs_lock(q);
793794
blk_mq_debugfs_register_rq_qos(q);
794-
mutex_unlock(&q->debugfs_mutex);
795+
blk_debugfs_unlock(q, memflags);
795796
}
796797

797798
static u64 wbt_default_latency_nsec(struct request_queue *q)
@@ -1015,9 +1016,10 @@ int wbt_set_lat(struct gendisk *disk, s64 val)
10151016
blk_mq_unquiesce_queue(q);
10161017
out:
10171018
blk_mq_unfreeze_queue(q, memflags);
1018-
mutex_lock(&q->debugfs_mutex);
1019+
1020+
memflags = blk_debugfs_lock(q);
10191021
blk_mq_debugfs_register_rq_qos(q);
1020-
mutex_unlock(&q->debugfs_mutex);
1022+
blk_debugfs_unlock(q, memflags);
10211023

10221024
return ret;
10231025
}

block/blk.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,4 +729,35 @@ static inline void blk_unfreeze_release_lock(struct request_queue *q)
729729
}
730730
#endif
731731

732+
/*
733+
* debugfs directory and file creation can trigger fs reclaim, which can enter
734+
* back into the block layer request_queue. This can cause deadlock if the
735+
* queue is frozen. Use NOIO context together with debugfs_mutex to prevent fs
736+
* reclaim from triggering block I/O.
737+
*/
738+
static inline void blk_debugfs_lock_nomemsave(struct request_queue *q)
739+
{
740+
mutex_lock(&q->debugfs_mutex);
741+
}
742+
743+
static inline void blk_debugfs_unlock_nomemrestore(struct request_queue *q)
744+
{
745+
mutex_unlock(&q->debugfs_mutex);
746+
}
747+
748+
static inline unsigned int __must_check blk_debugfs_lock(struct request_queue *q)
749+
{
750+
unsigned int memflags = memalloc_noio_save();
751+
752+
blk_debugfs_lock_nomemsave(q);
753+
return memflags;
754+
}
755+
756+
static inline void blk_debugfs_unlock(struct request_queue *q,
757+
unsigned int memflags)
758+
{
759+
blk_debugfs_unlock_nomemrestore(q);
760+
memalloc_noio_restore(memflags);
761+
}
762+
732763
#endif /* BLK_INTERNAL_H */

block/ioctl.c

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -318,19 +318,31 @@ int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode,
318318
EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
319319
#endif
320320

321-
static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode)
321+
enum pr_direction {
322+
PR_IN, /* read from device */
323+
PR_OUT, /* write to device */
324+
};
325+
326+
static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode,
327+
enum pr_direction dir)
322328
{
323329
/* no sense to make reservations for partitions */
324330
if (bdev_is_partition(bdev))
325331
return false;
326332

327333
if (capable(CAP_SYS_ADMIN))
328334
return true;
335+
329336
/*
330-
* Only allow unprivileged reservations if the file descriptor is open
331-
* for writing.
337+
* Only allow unprivileged reservation _out_ commands if the file
338+
* descriptor is open for writing. Allow reservation _in_ commands if
339+
* the file descriptor is open for reading since they do not modify the
340+
* device.
332341
*/
333-
return mode & BLK_OPEN_WRITE;
342+
if (dir == PR_IN)
343+
return mode & BLK_OPEN_READ;
344+
else
345+
return mode & BLK_OPEN_WRITE;
334346
}
335347

336348
static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode,
@@ -339,7 +351,7 @@ static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode,
339351
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
340352
struct pr_registration reg;
341353

342-
if (!blkdev_pr_allowed(bdev, mode))
354+
if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
343355
return -EPERM;
344356
if (!ops || !ops->pr_register)
345357
return -EOPNOTSUPP;
@@ -357,7 +369,7 @@ static int blkdev_pr_reserve(struct block_device *bdev, blk_mode_t mode,
357369
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
358370
struct pr_reservation rsv;
359371

360-
if (!blkdev_pr_allowed(bdev, mode))
372+
if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
361373
return -EPERM;
362374
if (!ops || !ops->pr_reserve)
363375
return -EOPNOTSUPP;
@@ -375,7 +387,7 @@ static int blkdev_pr_release(struct block_device *bdev, blk_mode_t mode,
375387
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
376388
struct pr_reservation rsv;
377389

378-
if (!blkdev_pr_allowed(bdev, mode))
390+
if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
379391
return -EPERM;
380392
if (!ops || !ops->pr_release)
381393
return -EOPNOTSUPP;
@@ -393,7 +405,7 @@ static int blkdev_pr_preempt(struct block_device *bdev, blk_mode_t mode,
393405
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
394406
struct pr_preempt p;
395407

396-
if (!blkdev_pr_allowed(bdev, mode))
408+
if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
397409
return -EPERM;
398410
if (!ops || !ops->pr_preempt)
399411
return -EOPNOTSUPP;
@@ -411,7 +423,7 @@ static int blkdev_pr_clear(struct block_device *bdev, blk_mode_t mode,
411423
const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
412424
struct pr_clear c;
413425

414-
if (!blkdev_pr_allowed(bdev, mode))
426+
if (!blkdev_pr_allowed(bdev, mode, PR_OUT))
415427
return -EPERM;
416428
if (!ops || !ops->pr_clear)
417429
return -EOPNOTSUPP;
@@ -434,7 +446,7 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode,
434446
size_t keys_copy_len;
435447
int ret;
436448

437-
if (!blkdev_pr_allowed(bdev, mode))
449+
if (!blkdev_pr_allowed(bdev, mode, PR_IN))
438450
return -EPERM;
439451
if (!ops || !ops->pr_read_keys)
440452
return -EOPNOTSUPP;
@@ -486,7 +498,7 @@ static int blkdev_pr_read_reservation(struct block_device *bdev,
486498
struct pr_read_reservation out = {};
487499
int ret;
488500

489-
if (!blkdev_pr_allowed(bdev, mode))
501+
if (!blkdev_pr_allowed(bdev, mode, PR_IN))
490502
return -EPERM;
491503
if (!ops || !ops->pr_read_reservation)
492504
return -EOPNOTSUPP;

0 commit comments

Comments
 (0)