diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-29 14:57:10 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-29 14:57:10 -0400 |
| commit | d506aa68c23db708ad45ca8c17f0d7f5d7029a37 (patch) | |
| tree | 90c38b2938564e6486d51417ac51ecfed17b0d3d | |
| parent | 7f474df0a7b7dadfc01ba778460a91f554ca1481 (diff) | |
| parent | cb1a5ab6ece7a37da4ac98ee26b0475b7c3ea79e (diff) | |
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
| -rw-r--r-- | block/blk-merge.c | 5 | ||||
| -rw-r--r-- | block/elevator.c | 4 | ||||
| -rw-r--r-- | block/scsi_ioctl.c | 3 | ||||
| -rw-r--r-- | drivers/block/null_blk.c | 14 | ||||
| -rw-r--r-- | fs/buffer.c | 38 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 4 | ||||
| -rw-r--r-- | lib/scatterlist.c | 6 |
7 files changed, 28 insertions, 46 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index ba99351c0f58..b3ac40aef46b 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
| @@ -99,16 +99,17 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio) | |||
| 99 | { | 99 | { |
| 100 | bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, | 100 | bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, |
| 101 | &q->queue_flags); | 101 | &q->queue_flags); |
| 102 | bool merge_not_need = bio->bi_vcnt < queue_max_segments(q); | ||
| 102 | 103 | ||
| 103 | if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && | 104 | if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && |
| 104 | bio->bi_vcnt < queue_max_segments(q)) | 105 | merge_not_need) |
| 105 | bio->bi_phys_segments = bio->bi_vcnt; | 106 | bio->bi_phys_segments = bio->bi_vcnt; |
| 106 | else { | 107 | else { |
| 107 | struct bio *nxt = bio->bi_next; | 108 | struct bio *nxt = bio->bi_next; |
| 108 | 109 | ||
| 109 | bio->bi_next = NULL; | 110 | bio->bi_next = NULL; |
| 110 | bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, | 111 | bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, |
| 111 | no_sg_merge); | 112 | no_sg_merge && merge_not_need); |
| 112 | bio->bi_next = nxt; | 113 | bio->bi_next = nxt; |
| 113 | } | 114 | } |
| 114 | 115 | ||
diff --git a/block/elevator.c b/block/elevator.c index 24c28b659bb3..afa3b037a17c 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
| @@ -229,7 +229,9 @@ int elevator_init(struct request_queue *q, char *name) | |||
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | err = e->ops.elevator_init_fn(q, e); | 231 | err = e->ops.elevator_init_fn(q, e); |
| 232 | return 0; | 232 | if (err) |
| 233 | elevator_put(e); | ||
| 234 | return err; | ||
| 233 | } | 235 | } |
| 234 | EXPORT_SYMBOL(elevator_init); | 236 | EXPORT_SYMBOL(elevator_init); |
| 235 | 237 | ||
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index abb2e65b24cc..1e053d911240 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
| @@ -508,7 +508,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
| 508 | 508 | ||
| 509 | if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) { | 509 | if (bytes && blk_rq_map_kern(q, rq, buffer, bytes, __GFP_WAIT)) { |
| 510 | err = DRIVER_ERROR << 24; | 510 | err = DRIVER_ERROR << 24; |
| 511 | goto out; | 511 | goto error; |
| 512 | } | 512 | } |
| 513 | 513 | ||
| 514 | memset(sense, 0, sizeof(sense)); | 514 | memset(sense, 0, sizeof(sense)); |
| @@ -517,7 +517,6 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode, | |||
| 517 | 517 | ||
| 518 | blk_execute_rq(q, disk, rq, 0); | 518 | blk_execute_rq(q, disk, rq, 0); |
| 519 | 519 | ||
| 520 | out: | ||
| 521 | err = rq->errors & 0xff; /* only 8 bit SCSI status */ | 520 | err = rq->errors & 0xff; /* only 8 bit SCSI status */ |
| 522 | if (err) { | 521 | if (err) { |
| 523 | if (rq->sense_len && rq->sense) { | 522 | if (rq->sense_len && rq->sense) { |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index 2671a3f02f0c..8001e812018b 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
| @@ -450,14 +450,10 @@ static int init_driver_queues(struct nullb *nullb) | |||
| 450 | 450 | ||
| 451 | ret = setup_commands(nq); | 451 | ret = setup_commands(nq); |
| 452 | if (ret) | 452 | if (ret) |
| 453 | goto err_queue; | 453 | return ret; |
| 454 | nullb->nr_queues++; | 454 | nullb->nr_queues++; |
| 455 | } | 455 | } |
| 456 | |||
| 457 | return 0; | 456 | return 0; |
| 458 | err_queue: | ||
| 459 | cleanup_queues(nullb); | ||
| 460 | return ret; | ||
| 461 | } | 457 | } |
| 462 | 458 | ||
| 463 | static int null_add_dev(void) | 459 | static int null_add_dev(void) |
| @@ -507,7 +503,9 @@ static int null_add_dev(void) | |||
| 507 | goto out_cleanup_queues; | 503 | goto out_cleanup_queues; |
| 508 | } | 504 | } |
| 509 | blk_queue_make_request(nullb->q, null_queue_bio); | 505 | blk_queue_make_request(nullb->q, null_queue_bio); |
| 510 | init_driver_queues(nullb); | 506 | rv = init_driver_queues(nullb); |
| 507 | if (rv) | ||
| 508 | goto out_cleanup_blk_queue; | ||
| 511 | } else { | 509 | } else { |
| 512 | nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node); | 510 | nullb->q = blk_init_queue_node(null_request_fn, &nullb->lock, home_node); |
| 513 | if (!nullb->q) { | 511 | if (!nullb->q) { |
| @@ -516,7 +514,9 @@ static int null_add_dev(void) | |||
| 516 | } | 514 | } |
| 517 | blk_queue_prep_rq(nullb->q, null_rq_prep_fn); | 515 | blk_queue_prep_rq(nullb->q, null_rq_prep_fn); |
| 518 | blk_queue_softirq_done(nullb->q, null_softirq_done_fn); | 516 | blk_queue_softirq_done(nullb->q, null_softirq_done_fn); |
| 519 | init_driver_queues(nullb); | 517 | rv = init_driver_queues(nullb); |
| 518 | if (rv) | ||
| 519 | goto out_cleanup_blk_queue; | ||
| 520 | } | 520 | } |
| 521 | 521 | ||
| 522 | nullb->q->queuedata = nullb; | 522 | nullb->q->queuedata = nullb; |
diff --git a/fs/buffer.c b/fs/buffer.c index 6c48f20eddd4..20805db2c987 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -128,21 +128,15 @@ __clear_page_buffers(struct page *page) | |||
| 128 | page_cache_release(page); | 128 | page_cache_release(page); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | 131 | static void buffer_io_error(struct buffer_head *bh, char *msg) | |
| 132 | static int quiet_error(struct buffer_head *bh) | ||
| 133 | { | ||
| 134 | if (!test_bit(BH_Quiet, &bh->b_state) && printk_ratelimit()) | ||
| 135 | return 0; | ||
| 136 | return 1; | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
| 140 | static void buffer_io_error(struct buffer_head *bh) | ||
| 141 | { | 132 | { |
| 142 | char b[BDEVNAME_SIZE]; | 133 | char b[BDEVNAME_SIZE]; |
| 143 | printk(KERN_ERR "Buffer I/O error on device %s, logical block %Lu\n", | 134 | |
| 135 | if (!test_bit(BH_Quiet, &bh->b_state)) | ||
| 136 | printk_ratelimited(KERN_ERR | ||
| 137 | "Buffer I/O error on dev %s, logical block %llu%s\n", | ||
| 144 | bdevname(bh->b_bdev, b), | 138 | bdevname(bh->b_bdev, b), |
| 145 | (unsigned long long)bh->b_blocknr); | 139 | (unsigned long long)bh->b_blocknr, msg); |
| 146 | } | 140 | } |
| 147 | 141 | ||
| 148 | /* | 142 | /* |
| @@ -177,17 +171,10 @@ EXPORT_SYMBOL(end_buffer_read_sync); | |||
| 177 | 171 | ||
| 178 | void end_buffer_write_sync(struct buffer_head *bh, int uptodate) | 172 | void end_buffer_write_sync(struct buffer_head *bh, int uptodate) |
| 179 | { | 173 | { |
| 180 | char b[BDEVNAME_SIZE]; | ||
| 181 | |||
| 182 | if (uptodate) { | 174 | if (uptodate) { |
| 183 | set_buffer_uptodate(bh); | 175 | set_buffer_uptodate(bh); |
| 184 | } else { | 176 | } else { |
| 185 | if (!quiet_error(bh)) { | 177 | buffer_io_error(bh, ", lost sync page write"); |
| 186 | buffer_io_error(bh); | ||
| 187 | printk(KERN_WARNING "lost page write due to " | ||
| 188 | "I/O error on %s\n", | ||
| 189 | bdevname(bh->b_bdev, b)); | ||
| 190 | } | ||
| 191 | set_buffer_write_io_error(bh); | 178 | set_buffer_write_io_error(bh); |
| 192 | clear_buffer_uptodate(bh); | 179 | clear_buffer_uptodate(bh); |
| 193 | } | 180 | } |
| @@ -304,8 +291,7 @@ static void end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 304 | set_buffer_uptodate(bh); | 291 | set_buffer_uptodate(bh); |
| 305 | } else { | 292 | } else { |
| 306 | clear_buffer_uptodate(bh); | 293 | clear_buffer_uptodate(bh); |
| 307 | if (!quiet_error(bh)) | 294 | buffer_io_error(bh, ", async page read"); |
| 308 | buffer_io_error(bh); | ||
| 309 | SetPageError(page); | 295 | SetPageError(page); |
| 310 | } | 296 | } |
| 311 | 297 | ||
| @@ -353,7 +339,6 @@ still_busy: | |||
| 353 | */ | 339 | */ |
| 354 | void end_buffer_async_write(struct buffer_head *bh, int uptodate) | 340 | void end_buffer_async_write(struct buffer_head *bh, int uptodate) |
| 355 | { | ||
