Merge tag 'block-7.2-20260731' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

Pull block fixes from Jens Axboe:

 - A set of fixes for s390/dasd, via Stefan

 - Fix for a missing stop of the timeout timer, if a disk has never been
   added

 - Clear kernel owned fields on ublk setup by default

* tag 'block-7.2-20260731' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
  s390/dasd: Fix undersized format-check buffer
  s390/dasd: Fix potential NULL pointer dereference
  s390/dasd: Fix path verification interrupted by concurrent dasd_sleep_on_immediatly
  block: stop the timeout timer when releasing a never added disk
  ublk: reset kernel-owned dev_info fields in ublk_ctrl_add_dev()
This commit is contained in:
Linus Torvalds
2026-07-31 16:42:34 -07:00
5 changed files with 38 additions and 10 deletions
+8 -4
View File
@@ -1281,14 +1281,18 @@ static void disk_release(struct device *dev)
/*
* To undo the all initialization from blk_mq_init_allocated_queue in
* case of a probe failure where add_disk is never called we have to
* call blk_mq_exit_queue here. We can't do this for the more common
* teardown case (yet) as the tagset can be gone by the time the disk
* is released once it was added.
* call blk_mq_exit_queue here, after stopping the timer and work items
* that I/O issued before add_disk may have left pending. We can't do
* this for the more common teardown case (yet) as the tagset can be
* gone by the time the disk is released once it was added.
*/
if (queue_is_mq(disk->queue) &&
test_bit(GD_OWNS_QUEUE, &disk->state) &&
!test_bit(GD_ADDED, &disk->state))
!test_bit(GD_ADDED, &disk->state)) {
blk_sync_queue(disk->queue);
blk_mq_cancel_work_sync(disk->queue);
blk_mq_exit_queue(disk->queue);
}
blkcg_exit_disk(disk);
+9
View File
@@ -4764,6 +4764,15 @@ static int ublk_ctrl_add_dev(const struct ublksrv_ctrl_cmd *header)
/* update device id */
ub->dev_info.dev_id = ub->ub_number;
/*
* ->state and ->ublksrv_pid are owned by the driver and only read back
* by userspace, but they come from the copied-in dev_info, so reset
* them. Otherwise a device added with ->state != DEAD looks live while
* ->ub_disk is still NULL.
*/
ub->dev_info.state = UBLK_S_DEV_DEAD;
ub->dev_info.ublksrv_pid = -1;
/*
* 64bit flags will be copied back to userspace as feature
* negotiation result, so have to clear flags which driver
+13 -1
View File
@@ -21,6 +21,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <asm/machine.h>
#include <asm/ccwdev.h>
@@ -2511,6 +2512,13 @@ static inline int _dasd_term_running_cqr(struct dasd_device *device)
if (list_empty(&device->ccw_queue))
return 0;
cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist);
/*
* Path verification requests must not be terminated. They are critical
* for bringing paths back online. Terminating them would cause rc=-EIO
* because CLEARED requests skip the retry path.
*/
if (test_bit(DASD_CQR_VERIFY_PATH, &cqr->flags))
return -EAGAIN;
rc = device->discipline->term_IO(cqr);
if (!rc)
/*
@@ -2535,7 +2543,11 @@ int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr)
return -EIO;
}
spin_lock_irq(get_ccwdev_lock(device->cdev));
rc = _dasd_term_running_cqr(device);
while ((rc = _dasd_term_running_cqr(device)) == -EAGAIN) {
spin_unlock_irq(get_ccwdev_lock(device->cdev));
msleep(1);
spin_lock_irq(get_ccwdev_lock(device->cdev));
}
if (rc) {
spin_unlock_irq(get_ccwdev_lock(device->cdev));
return rc;
+7 -4
View File
@@ -20,6 +20,7 @@
#include <linux/seq_file.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/overflow.h>
#include <asm/css_chars.h>
#include <asm/machine.h>
@@ -3475,11 +3476,11 @@ static int dasd_eckd_check_device_format(struct dasd_device *base,
{
struct dasd_eckd_private *private = base->private;
struct eckd_count *fmt_buffer;
struct irb irb;
size_t fmt_buffer_size;
unsigned int trkcount;
int rpt_max, rpt_exp;
int fmt_buffer_size;
struct irb irb;
int trk_per_cyl;
int trkcount;
int tpm = 0;
int rc;
@@ -3490,7 +3491,9 @@ static int dasd_eckd_check_device_format(struct dasd_device *base,
rpt_exp = recs_per_track(&private->rdc_data, 0, cdata->expect.blksize);
trkcount = cdata->expect.stop_unit - cdata->expect.start_unit + 1;
fmt_buffer_size = trkcount * rpt_max * sizeof(struct eckd_count);
if (check_mul_overflow(trkcount, rpt_max, &fmt_buffer_size) ||
check_mul_overflow(fmt_buffer_size, sizeof(struct eckd_count), &fmt_buffer_size))
return -EINVAL;
fmt_buffer = kzalloc(fmt_buffer_size, GFP_KERNEL | GFP_DMA);
if (!fmt_buffer)
+1 -1
View File
@@ -324,7 +324,7 @@ out_err:
static int dasd_release_space(struct dasd_device *device,
struct format_data_t *rdata)
{
if (!device->discipline->is_ese && !device->discipline->is_ese(device))
if (!device->discipline->is_ese || !device->discipline->is_ese(device))
return -ENOTSUPP;
if (!device->discipline->release_space)
return -ENOTSUPP;