Commit 4b6c093e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'block-5.9-2020-08-14' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
 "A few fixes on the block side of things:

   - Discard granularity fix (Coly)

   - rnbd cleanups (Guoqing)

   - md error handling fix (Dan)

   - md sysfs fix (Junxiao)

   - Fix flush request accounting, which caused an IO slowdown for some
     configurations (Ming)

   - Properly propagate loop flag for partition scanning (Lennart)"

* tag 'block-5.9-2020-08-14' of git://git.kernel.dk/linux-block:
  block: fix double account of flush request's driver tag
  loop: unset GENHD_FL_NO_PART_SCAN on LOOP_CONFIGURE
  rnbd: no need to set bi_end_io in rnbd_bio_map_kern
  rnbd: remove rnbd_dev_submit_io
  md-cluster: Fix potential error pointer dereference in resize_bitmaps()
  block: check queue's limits.discard_granularity in __blkdev_issue_discard()
  md: get sysfs entry after redundancy attr group create
parents d84835b1 c1e2b842
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -308,9 +308,16 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
	flush_rq->mq_ctx = first_rq->mq_ctx;
	flush_rq->mq_hctx = first_rq->mq_hctx;

	if (!q->elevator)
	if (!q->elevator) {
		flush_rq->tag = first_rq->tag;
	else

		/*
		 * We borrow data request's driver tag, so have to mark
		 * this flush request as INFLIGHT for avoiding double
		 * account of this driver tag
		 */
		flush_rq->rq_flags |= RQF_MQ_INFLIGHT;
	} else
		flush_rq->internal_tag = first_rq->internal_tag;

	flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
+9 −0
Original line number Diff line number Diff line
@@ -47,6 +47,15 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
		op = REQ_OP_DISCARD;
	}

	/* In case the discard granularity isn't set by buggy device driver */
	if (WARN_ON_ONCE(!q->limits.discard_granularity)) {
		char dev_name[BDEVNAME_SIZE];

		bdevname(bdev, dev_name);
		pr_err_ratelimited("%s: Error: discard_granularity is 0.\n", dev_name);
		return -EOPNOTSUPP;
	}

	bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
	if ((sector | nr_sects) & bs_mask)
		return -EINVAL;
+2 −0
Original line number Diff line number Diff line
@@ -1171,6 +1171,8 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
	if (part_shift)
		lo->lo_flags |= LO_FLAGS_PARTSCAN;
	partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
	if (partscan)
		lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;

	/* Grab the block_device to prevent its destruction after we
	 * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev).
+3 −34
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ void rnbd_dev_close(struct rnbd_dev *dev)
	kfree(dev);
}

static void rnbd_dev_bi_end_io(struct bio *bio)
void rnbd_dev_bi_end_io(struct bio *bio)
{
	struct rnbd_dev_blk_io *io = bio->bi_private;

@@ -63,7 +63,7 @@ static void rnbd_dev_bi_end_io(struct bio *bio)
 *	Map the kernel address into a bio suitable for io to a block
 *	device. Returns an error pointer in case of error.
 */
static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
			      unsigned int len, gfp_t gfp_mask)
{
	unsigned long kaddr = (unsigned long)data;
@@ -99,36 +99,5 @@ static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
		offset = 0;
	}

	bio->bi_end_io = bio_put;
	return bio;
}

int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data,
		       size_t len, u32 bi_size, enum rnbd_io_flags flags,
		       short prio, void *priv)
{
	struct rnbd_dev_blk_io *io;
	struct bio *bio;

	/* Generate bio with pages pointing to the rdma buffer */
	bio = rnbd_bio_map_kern(data, dev->ibd_bio_set, len, GFP_KERNEL);
	if (IS_ERR(bio))
		return PTR_ERR(bio);

	io = container_of(bio, struct rnbd_dev_blk_io, bio);

	io->dev	= dev;
	io->priv = priv;

	bio->bi_end_io = rnbd_dev_bi_end_io;
	bio->bi_private	= io;
	bio->bi_opf = rnbd_to_bio_flags(flags);
	bio->bi_iter.bi_sector = sector;
	bio->bi_iter.bi_size = bi_size;
	bio_set_prio(bio, prio);
	bio_set_dev(bio, dev->bdev);

	submit_bio(bio);

	return 0;
}
+5 −14
Original line number Diff line number Diff line
@@ -41,6 +41,11 @@ void rnbd_dev_close(struct rnbd_dev *dev);

void rnbd_endio(void *priv, int error);

void rnbd_dev_bi_end_io(struct bio *bio);

struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
			      unsigned int len, gfp_t gfp_mask);

static inline int rnbd_dev_get_max_segs(const struct rnbd_dev *dev)
{
	return queue_max_segments(bdev_get_queue(dev->bdev));
@@ -75,18 +80,4 @@ static inline int rnbd_dev_get_discard_alignment(const struct rnbd_dev *dev)
	return bdev_get_queue(dev->bdev)->limits.discard_alignment;
}

/**
 * rnbd_dev_submit_io() - Submit an I/O to the disk
 * @dev:	device to that the I/O is submitted
 * @sector:	address to read/write data to
 * @data:	I/O data to write or buffer to read I/O date into
 * @len:	length of @data
 * @bi_size:	Amount of data that will be read/written
 * @prio:       IO priority
 * @priv:	private data passed to @io_fn
 */
int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data,
			size_t len, u32 bi_size, enum rnbd_io_flags flags,
			short prio, void *priv);

#endif /* RNBD_SRV_DEV_H */
Loading