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 | { | 341 | { |
356 | char b[BDEVNAME_SIZE]; | ||
357 | unsigned long flags; | 342 | unsigned long flags; |
358 | struct buffer_head *first; | 343 | struct buffer_head *first; |
359 | struct buffer_head *tmp; | 344 | struct buffer_head *tmp; |
@@ -365,12 +350,7 @@ void end_buffer_async_write(struct buffer_head *bh, int uptodate) | |||
365 | if (uptodate) { | 350 | if (uptodate) { |
366 | set_buffer_uptodate(bh); | 351 | set_buffer_uptodate(bh); |
367 | } else { | 352 | } else { |
368 | if (!quiet_error(bh)) { | 353 | buffer_io_error(bh, ", lost async page write"); |
369 | buffer_io_error(bh); | ||
370 | printk(KERN_WARNING "lost page write due to " | ||
371 | "I/O error on %s\n", | ||
372 | bdevname(bh->b_bdev, b)); | ||
373 | } | ||
374 | set_bit(AS_EIO, &page->mapping->flags); | 354 | set_bit(AS_EIO, &page->mapping->flags); |
375 | set_buffer_write_io_error(bh); | 355 | set_buffer_write_io_error(bh); |
376 | clear_buffer_uptodate(bh); | 356 | clear_buffer_uptodate(bh); |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0207a78a8d82..6cbee8395f60 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -1583,13 +1583,13 @@ static inline bool blk_integrity_merge_rq(struct request_queue *rq, | |||
1583 | struct request *r1, | 1583 | struct request *r1, |
1584 | struct request *r2) | 1584 | struct request *r2) |
1585 | { | 1585 | { |
1586 | return 0; | 1586 | return true; |
1587 | } | 1587 | } |
1588 | static inline bool blk_integrity_merge_bio(struct request_queue *rq, | 1588 | static inline bool blk_integrity_merge_bio(struct request_queue *rq, |
1589 | struct request *r, | 1589 | struct request *r, |
1590 | struct bio *b) | 1590 | struct bio *b) |
1591 | { | 1591 | { |
1592 | return 0; | 1592 | return true; |
1593 | } | 1593 | } |
1594 | static inline bool blk_integrity_is_initialized(struct gendisk *g) | 1594 | static inline bool blk_integrity_is_initialized(struct gendisk *g) |
1595 | { | 1595 | { |
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index 9cdf62f8accd..c9f2e8c6ccc9 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -203,10 +203,10 @@ void __sg_free_table(struct sg_table *table, unsigned int max_ents, | |||
203 | } | 203 | } |
204 | 204 | ||
205 | table->orig_nents -= sg_size; | 205 | table->orig_nents -= sg_size; |
206 | if (!skip_first_chunk) { | 206 | if (skip_first_chunk) |
207 | free_fn(sgl, alloc_size); | ||
208 | skip_first_chunk = false; | 207 | skip_first_chunk = false; |
209 | } | 208 | else |
209 | free_fn(sgl, alloc_size); | ||
210 | sgl = next; | 210 | sgl = next; |
211 | } | 211 | } |
212 | 212 | ||