Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block layer fixes from Jens Axboe:
 "A small collection of fixes for the current kernel.  This contains:

   - Two error handling fixes from Jan Kara.  One for null_blk on
     failure to add a device, and the other for the block/scsi_ioctl
     SCSI_IOCTL_SEND_COMMAND fixing up the error jump point.

   - A commit added in the merge window for the bio integrity bits
     unfortunately disabled merging for all requests if
     CONFIG_BLK_DEV_INTEGRITY wasn't set.  Reverse the logic, so that
     integrity checking wont disallow merges when not enabled.

   - A fix from Ming Lei for merging and generating too many segments.
     This caused a BUG in virtio_blk.

   - Two error handling printk() fixups from Robert Elliott, improving
     the information given when we rate limit.

   - Error handling fixup on elevator_init() failure from Sudip
     Mukherjee.

   - A fix from Tony Battersby, fixing up a memory leak in the
     scatterlist handling with scsi-mq"

* 'for-linus' of git://git.kernel.dk/linux-block:
  block: Fix merge logic when CONFIG_BLK_DEV_INTEGRITY is not defined
  lib/scatterlist: fix memory leak with scsi-mq
  block: fix wrong error return in elevator_init()
  scsi: Fix error handling in SCSI_IOCTL_SEND_COMMAND
  null_blk: Cleanup error recovery in null_add_dev()
  blk-merge: recaculate segment if it isn't less than max segments
  fs: clarify rate limit suppressed buffer I/O errors
  fs: merge I/O error prints into one line
parents 7f474df0 cb1a5ab6
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -99,16 +99,17 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
{
	bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
			&q->queue_flags);
	bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);

	if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
			bio->bi_vcnt < queue_max_segments(q))
			merge_not_need)
		bio->bi_phys_segments = bio->bi_vcnt;
	else {
		struct bio *nxt = bio->bi_next;

		bio->bi_next = NULL;
		bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio,
				no_sg_merge);
				no_sg_merge && merge_not_need);
		bio->bi_next = nxt;
	}

+3 −1
Original line number Diff line number Diff line
@@ -229,7 +229,9 @@ int elevator_init(struct request_queue *q, char *name)
	}

	err = e->ops.elevator_init_fn(q, e);
	return 0;
	if (err)
		elevator_put(e);
	return err;
}
EXPORT_SYMBOL(elevator_init);

+1 −2
Original line number Diff line number Diff line
@@ -508,7 +508,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,

	if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) {
		err = DRIVER_ERROR << 24;
		goto out;
		goto error;
	}

	memset(sense, 0, sizeof(sense));
@@ -517,7 +517,6 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,

	blk_execute_rq(q, disk, rq, 0);

out:
	err = rq->errors & 0xff;	/* only 8 bit SCSI status */
	if (err) {
		if (rq->sense_len && rq->sense) {
+7 −7
Original line number Diff line number Diff line
@@ -450,14 +450,10 @@ static int init_driver_queues(struct nullb *nullb)

		ret = setup_commands(nq);
		if (ret)
			goto err_queue;
			return ret;
		nullb->nr_queues++;
	}

	return 0;
err_queue:
	cleanup_queues(nullb);
	return ret;
}

static int null_add_dev(void)
@@ -507,7 +503,9 @@ static int null_add_dev(void)
			goto out_cleanup_queues;
		}
		blk_queue_make_request(nullb->q, null_queue_bio);
		init_driver_queues(nullb);
		rv = init_driver_queues(nullb);
		if (rv)
			goto out_cleanup_blk_queue;
	} else {
		nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node);
		if (!nullb->q) {
@@ -516,7 +514,9 @@ static int null_add_dev(void)
		}
		blk_queue_prep_rq(nullb->q, null_rq_prep_fn);
		blk_queue_softirq_done(nullb->q, null_softirq_done_fn);
		init_driver_queues(nullb);
		rv = init_driver_queues(nullb);
		if (rv)
			goto out_cleanup_blk_queue;
	}

	nullb->q->queuedata = nullb;
+9 −29
Original line number Diff line number Diff line
@@ -128,21 +128,15 @@ __clear_page_buffers(struct page *page)
	page_cache_release(page);
}


static int quiet_error(struct buffer_head *bh)
{
	if (!test_bit(BH_Quiet, &bh->b_state) && printk_ratelimit())
		return 0;
	return 1;
}


static void buffer_io_error(struct buffer_head *bh)
static void buffer_io_error(struct buffer_head *bh, char *msg)
{
	char b[BDEVNAME_SIZE];
	printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n",

	if (!test_bit(BH_Quiet, &bh->b_state))
		printk_ratelimited(KERN_ERR
			"Buffer I/O error on dev %s, logical block %llu%s\n",
			bdevname(bh->b_bdev, b),
			(unsigned long long)bh->b_blocknr);
			(unsigned long long)bh->b_blocknr, msg);
}

/*
@@ -177,17 +171,10 @@ EXPORT_SYMBOL(end_buffer_read_sync);

void end_buffer_write_sync(struct buffer_head *bh, int uptodate)
{
	char b[BDEVNAME_SIZE];

	if (uptodate) {
		set_buffer_uptodate(bh);
	} else {
		if (!quiet_error(bh)) {
			buffer_io_error(bh);
			printk(KERN_WARNING "lost page write due to "
					"I/O error on %s\n",
				       bdevname(bh->b_bdev, b));
		}
		buffer_io_error(bh, ", lost sync page write");
		set_buffer_write_io_error(bh);
		clear_buffer_uptodate(bh);
	}
@@ -304,8 +291,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
		set_buffer_uptodate(bh);
	} else {
		clear_buffer_uptodate(bh);
		if (!quiet_error(bh))
			buffer_io_error(bh);
		buffer_io_error(bh, ", async page read");
		SetPageError(page);
	}

@@ -353,7 +339,6 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate)
 */
void end_buffer_async_write(struct buffer_head *bh, int uptodate)
{
	char b[BDEVNAME_SIZE];
	unsigned long flags;
	struct buffer_head *first;
	struct buffer_head *tmp;
@@ -365,12 +350,7 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate)
	if (uptodate) {
		set_buffer_uptodate(bh);
	} else {
		if (!quiet_error(bh)) {
			buffer_io_error(bh);
			printk(KERN_WARNING "lost page write due to "
					"I/O error on %s\n",
			       bdevname(bh->b_bdev, b));
		}
		buffer_io_error(bh, ", lost async page write");
		set_bit(AS_EIO, &page->mapping->flags);
		set_buffer_write_io_error(bh);
		clear_buffer_uptodate(bh);
Loading