Commit d1cf752d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'block-6.17-20250828' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

 - Fix a lockdep spotted issue on recursive locking for zoned writes, in
   case of errors

 - Update bcache MAINTAINERS entry address for Coly

 - Fix for a ublk release issue, with selftests

 - Fix for a regression introduced in this cycle, where it assumed
   q->rq_qos was always set if the bio flag indicated that

 - Fix for a regression introduced in this cycle, where loop retrieving
   block device sizes got broken

* tag 'block-6.17-20250828' of git://git.kernel.dk/linux:
  bcache: change maintainer's email address
  ublk selftests: add --no_ublk_fixed_fd for not using registered ublk char device
  ublk: avoid ublk_io_release() called after ublk char dev is closed
  block: validate QoS before calling __rq_qos_done_bio()
  blk-zoned: Fix a lockdep complaint about recursive locking
  loop: fix zero sized loop for block special file
parents 220374ab 95a7c500
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4205,7 +4205,7 @@ W: http://www.baycom.org/~tom/ham/ham.html
F:	drivers/net/hamradio/baycom*
BCACHE (BLOCK LAYER CACHE)
M:	Coly Li <colyli@kernel.org>
M:	Coly Li <colyli@fnnas.com>
M:	Kent Overstreet <kent.overstreet@linux.dev>
L:	linux-bcache@vger.kernel.org
S:	Maintained
+8 −5
Original line number Diff line number Diff line
@@ -149,11 +149,14 @@ static inline void rq_qos_done_bio(struct bio *bio)
	q = bdev_get_queue(bio->bi_bdev);

	/*
	 * If a bio has BIO_QOS_xxx set, it implicitly implies that
	 * q->rq_qos is present. So, we skip re-checking q->rq_qos
	 * here as an extra optimization and directly call
	 * __rq_qos_done_bio().
	 * A BIO may carry BIO_QOS_* flags even if the associated request_queue
	 * does not have rq_qos enabled. This can happen with stacked block
	 * devices — for example, NVMe multipath, where it's possible that the
	 * bottom device has QoS enabled but the top device does not. Therefore,
	 * always verify that q->rq_qos is present and QoS is enabled before
	 * calling __rq_qos_done_bio().
	 */
	if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos)
		__rq_qos_done_bio(q->rq_qos, bio);
}

+6 −5
Original line number Diff line number Diff line
@@ -1286,14 +1286,14 @@ static void blk_zone_wplug_bio_work(struct work_struct *work)
	struct block_device *bdev;
	unsigned long flags;
	struct bio *bio;
	bool prepared;

	/*
	 * Submit the next plugged BIO. If we do not have any, clear
	 * the plugged flag.
	 */
	spin_lock_irqsave(&zwplug->lock, flags);

again:
	spin_lock_irqsave(&zwplug->lock, flags);
	bio = bio_list_pop(&zwplug->bio_list);
	if (!bio) {
		zwplug->flags &= ~BLK_ZONE_WPLUG_PLUGGED;
@@ -1304,13 +1304,14 @@ static void blk_zone_wplug_bio_work(struct work_struct *work)
	trace_blk_zone_wplug_bio(zwplug->disk->queue, zwplug->zone_no,
				 bio->bi_iter.bi_sector, bio_sectors(bio));

	if (!blk_zone_wplug_prepare_bio(zwplug, bio)) {
	prepared = blk_zone_wplug_prepare_bio(zwplug, bio);
	spin_unlock_irqrestore(&zwplug->lock, flags);

	if (!prepared) {
		blk_zone_wplug_bio_io_error(zwplug, bio);
		goto again;
	}

	spin_unlock_irqrestore(&zwplug->lock, flags);

	bdev = bio->bi_bdev;

	/*
+16 −10
Original line number Diff line number Diff line
@@ -139,10 +139,14 @@ static int part_shift;

static loff_t lo_calculate_size(struct loop_device *lo, struct file *file)
{
	struct kstat stat;
	loff_t loopsize;
	int ret;

	if (S_ISBLK(file_inode(file)->i_mode)) {
		loopsize = i_size_read(file->f_mapping->host);
	} else {
		struct kstat stat;

		/*
		 * Get the accurate file size. This provides better results than
		 * cached inode data, particularly for network filesystems where
@@ -153,6 +157,8 @@ static loff_t lo_calculate_size(struct loop_device *lo, struct file *file)
			return 0;

		loopsize = stat.size;
	}

	if (lo->lo_offset > 0)
		loopsize -= lo->lo_offset;
	/* offset is beyond i_size, weird but possible */
+70 −2
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ struct ublk_device {
	struct mutex cancel_mutex;
	bool canceling;
	pid_t 	ublksrv_tgid;
	struct delayed_work	exit_work;
};

/* header of ublk_params */
@@ -1595,12 +1596,62 @@ static void ublk_set_canceling(struct ublk_device *ub, bool canceling)
		ublk_get_queue(ub, i)->canceling = canceling;
}

static int ublk_ch_release(struct inode *inode, struct file *filp)
static bool ublk_check_and_reset_active_ref(struct ublk_device *ub)
{
	struct ublk_device *ub = filp->private_data;
	int i, j;

	if (!(ub->dev_info.flags & (UBLK_F_SUPPORT_ZERO_COPY |
					UBLK_F_AUTO_BUF_REG)))
		return false;

	for (i = 0; i < ub->dev_info.nr_hw_queues; i++) {
		struct ublk_queue *ubq = ublk_get_queue(ub, i);

		for (j = 0; j < ubq->q_depth; j++) {
			struct ublk_io *io = &ubq->ios[j];
			unsigned int refs = refcount_read(&io->ref) +
				io->task_registered_buffers;

			/*
			 * UBLK_REFCOUNT_INIT or zero means no active
			 * reference
			 */
			if (refs != UBLK_REFCOUNT_INIT && refs != 0)
				return true;

			/* reset to zero if the io hasn't active references */
			refcount_set(&io->ref, 0);
			io->task_registered_buffers = 0;
		}
	}
	return false;
}

static void ublk_ch_release_work_fn(struct work_struct *work)
{
	struct ublk_device *ub =
		container_of(work, struct ublk_device, exit_work.work);
	struct gendisk *disk;
	int i;

	/*
	 * For zero-copy and auto buffer register modes, I/O references
	 * might not be dropped naturally when the daemon is killed, but
	 * io_uring guarantees that registered bvec kernel buffers are
	 * unregistered finally when freeing io_uring context, then the
	 * active references are dropped.
	 *
	 * Wait until active references are dropped for avoiding use-after-free
	 *
	 * registered buffer may be unregistered in io_ring's release hander,
	 * so have to wait by scheduling work function for avoiding the two
	 * file release dependency.
	 */
	if (ublk_check_and_reset_active_ref(ub)) {
		schedule_delayed_work(&ub->exit_work, 1);
		return;
	}

	/*
	 * disk isn't attached yet, either device isn't live, or it has
	 * been removed already, so we needn't to do anything
@@ -1673,6 +1724,23 @@ static int ublk_ch_release(struct inode *inode, struct file *filp)
	ublk_reset_ch_dev(ub);
out:
	clear_bit(UB_STATE_OPEN, &ub->state);

	/* put the reference grabbed in ublk_ch_release() */
	ublk_put_device(ub);
}

static int ublk_ch_release(struct inode *inode, struct file *filp)
{
	struct ublk_device *ub = filp->private_data;

	/*
	 * Grab ublk device reference, so it won't be gone until we are
	 * really released from work function.
	 */
	ublk_get_device(ub);

	INIT_DELAYED_WORK(&ub->exit_work, ublk_ch_release_work_fn);
	schedule_delayed_work(&ub->exit_work, 0);
	return 0;
}

Loading