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

Merge tag 'block-5.12-2021-03-27' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:

 - Fix regression from this merge window with the xarray partition
   change, which allowed partition counts that overflow the u8 that
   holds the partition number (Ming)

 - Fix zone append warning (Johannes)

 - Segmentation count fix for multipage bvecs (David)

 - Partition scan fix (Chris)

* tag 'block-5.12-2021-03-27' of git://git.kernel.dk/linux-block:
  block: don't create too many partitions
  block: support zone append bvecs
  block: recalculate segment count for multi-segment discards correctly
  block: clear GD_NEED_PART_SCAN later in bdev_disk_changed
parents e8cfe8fa e82fc785
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -949,7 +949,7 @@ void bio_release_pages(struct bio *bio, bool mark_dirty)
}
EXPORT_SYMBOL_GPL(bio_release_pages);

static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
static void __bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
{
	WARN_ON_ONCE(bio->bi_max_vecs);

@@ -959,11 +959,26 @@ static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
	bio->bi_iter.bi_size = iter->count;
	bio_set_flag(bio, BIO_NO_PAGE_REF);
	bio_set_flag(bio, BIO_CLONED);
}

static int bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter)
{
	__bio_iov_bvec_set(bio, iter);
	iov_iter_advance(iter, iter->count);
	return 0;
}

static int bio_iov_bvec_set_append(struct bio *bio, struct iov_iter *iter)
{
	struct request_queue *q = bio->bi_bdev->bd_disk->queue;
	struct iov_iter i = *iter;

	iov_iter_truncate(&i, queue_max_zone_append_sectors(q) << 9);
	__bio_iov_bvec_set(bio, &i);
	iov_iter_advance(iter, i.count);
	return 0;
}

#define PAGE_PTRS_PER_BVEC     (sizeof(struct bio_vec) / sizeof(struct page *))

/**
@@ -1094,8 +1109,8 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
	int ret = 0;

	if (iov_iter_is_bvec(iter)) {
		if (WARN_ON_ONCE(bio_op(bio) == REQ_OP_ZONE_APPEND))
			return -EINVAL;
		if (bio_op(bio) == REQ_OP_ZONE_APPEND)
			return bio_iov_bvec_set_append(bio, iter);
		return bio_iov_bvec_set(bio, iter);
	}

+8 −0
Original line number Diff line number Diff line
@@ -382,6 +382,14 @@ unsigned int blk_recalc_rq_segments(struct request *rq)
	switch (bio_op(rq->bio)) {
	case REQ_OP_DISCARD:
	case REQ_OP_SECURE_ERASE:
		if (queue_max_discard_segments(rq->q) > 1) {
			struct bio *bio = rq->bio;

			for_each_bio(bio)
				nr_phys_segs++;
			return nr_phys_segs;
		}
		return 1;
	case REQ_OP_WRITE_ZEROES:
		return 0;
	case REQ_OP_WRITE_SAME:
+7 −0
Original line number Diff line number Diff line
@@ -322,6 +322,13 @@ static struct block_device *add_partition(struct gendisk *disk, int partno,
	const char *dname;
	int err;

	/*
	 * disk_max_parts() won't be zero, either GENHD_FL_EXT_DEVT is set
	 * or 'minors' is passed to alloc_disk().
	 */
	if (partno >= disk_max_parts(disk))
		return ERR_PTR(-EINVAL);

	/*
	 * Partitions are not supported on zoned block devices that are used as
	 * such.
+2 −2
Original line number Diff line number Diff line
@@ -1240,13 +1240,13 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate)

	lockdep_assert_held(&bdev->bd_mutex);

	clear_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state);

rescan:
	ret = blk_drop_partitions(bdev);
	if (ret)
		return ret;

	clear_bit(GD_NEED_PART_SCAN, &disk->state);

	/*
	 * Historically we only set the capacity to zero for devices that
	 * support partitions (independ of actually having partitions created).