diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-17 18:29:49 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-17 18:29:49 -0400 |
| commit | a4d1dbed0e27030b3c3ca2d1d5c33a1b45bc53d2 (patch) | |
| tree | 6f92002ba36efbee3adc1e7b2a0d4b0621c1f1a6 | |
| parent | c2e7b207058d4ff6a9010430763fb561f307eb67 (diff) | |
| parent | b3a834b1596ac668df206aa2bb1f191c31f5f5e4 (diff) | |
Merge branch 'for-4.7/core' of git://git.kernel.dk/linux-block
Pull core block layer updates from Jens Axboe:
"This is the core block IO changes for this merge window. Nothing
earth shattering in here, it's mostly just fixes. In detail:
- Fix for a long standing issue where wrong ordering in blk-mq caused
order_to_size() to spew a warning. From Bart.
- Async discard support from Christoph. Basically just splitting our
sync interface into a submit + wait part.
- Add a cleaner interface for flagging whether a device has a write
back cache or not. We've previously overloaded blk_queue_flush()
with this, but let's make it more explicit. Drivers cleaned up and
updated in the drivers pull request. From me.
- Fix for a double check for whether IO accounting is enabled or not.
From Michael Callahan.
- Fix for the async discard from Mike Snitzer, reinstating the early
EOPNOTSUPP return if the device doesn't support discards.
- Also from Mike, export bio_inc_remaining() so dm can drop it's
private copy of it.
- From Ming Lin, add support for passing in an offset for request
payloads.
- Tag function export from Sagi, which will be used in NVMe in the
drivers pull.
- Two blktrace related fixes from Shaohua.
- Propagate NOMERGE flag when making a request from a bio, also from
Shaohua.
- An optimization to not parse cgroup paths in blk-throttle, if we
don't need to. From Shaohua"
* 'for-4.7/core' of git://git.kernel.dk/linux-block:
blk-mq: fix undefined behaviour in order_to_size()
blk-throttle: don't parse cgroup path if trace isn't enabled
blktrace: add missed mask name
blktrace: delete garbage for message trace
block: make bio_inc_remaining() interface accessible again
block: reinstate early return of -EOPNOTSUPP from blkdev_issue_discard
block: Minor blk_account_io_start usage cleanup
block: add __blkdev_issue_discard
block: remove struct bio_batch
block: copy NOMERGE flag from bio to request
block: add ability to flag write back caching on a device
blk-mq: Export tagset iter function
block: add offset in blk_add_request_payload()
writeback: Fix performance regression in wb_over_bg_thresh()
| -rw-r--r-- | Documentation/block/queue-sysfs.txt | 9 | ||||
| -rw-r--r-- | block/bio.c | 11 | ||||
| -rw-r--r-- | block/blk-core.c | 5 | ||||
| -rw-r--r-- | block/blk-lib.c | 178 | ||||
| -rw-r--r-- | block/blk-mq-tag.c | 12 | ||||
| -rw-r--r-- | block/blk-mq.c | 5 | ||||
| -rw-r--r-- | block/blk-settings.c | 26 | ||||
| -rw-r--r-- | block/blk-sysfs.c | 39 | ||||
| -rw-r--r-- | block/blk-throttle.c | 5 | ||||
| -rw-r--r-- | drivers/block/skd_main.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 2 | ||||
| -rw-r--r-- | include/linux/bio.h | 11 | ||||
| -rw-r--r-- | include/linux/blk-mq.h | 2 | ||||
| -rw-r--r-- | include/linux/blk_types.h | 2 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 7 | ||||
| -rw-r--r-- | include/linux/blktrace_api.h | 9 | ||||
| -rw-r--r-- | kernel/trace/blktrace.c | 2 |
17 files changed, 190 insertions, 137 deletions
diff --git a/Documentation/block/queue-sysfs.txt b/Documentation/block/queue-sysfs.txt index e5d914845be6..dce25d848d92 100644 --- a/Documentation/block/queue-sysfs.txt +++ b/Documentation/block/queue-sysfs.txt | |||
| @@ -141,6 +141,15 @@ control of this block device to that new IO scheduler. Note that writing | |||
| 141 | an IO scheduler name to this file will attempt to load that IO scheduler | 141 | an IO scheduler name to this file will attempt to load that IO scheduler |
| 142 | module, if it isn't already present in the system. | 142 | module, if it isn't already present in the system. |
| 143 | 143 | ||
| 144 | write_cache (RW) | ||
| 145 | ---------------- | ||
| 146 | When read, this file will display whether the device has write back | ||
| 147 | caching enabled or not. It will return "write back" for the former | ||
| 148 | case, and "write through" for the latter. Writing to this file can | ||
| 149 | change the kernels view of the device, but it doesn't alter the | ||
| 150 | device state. This means that it might not be safe to toggle the | ||
| 151 | setting from "write back" to "write through", since that will also | ||
| 152 | eliminate cache flushes issued by the kernel. | ||
| 144 | 153 | ||
| 145 | 154 | ||
| 146 | Jens Axboe <jens.axboe@oracle.com>, February 2009 | 155 | Jens Axboe <jens.axboe@oracle.com>, February 2009 |
diff --git a/block/bio.c b/block/bio.c index 807d25e466ec..0e4aa42bc30d 100644 --- a/block/bio.c +++ b/block/bio.c | |||
| @@ -311,17 +311,6 @@ static void bio_chain_endio(struct bio *bio) | |||
| 311 | bio_endio(__bio_chain_endio(bio)); | 311 | bio_endio(__bio_chain_endio(bio)); |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | /* | ||
| 315 | * Increment chain count for the bio. Make sure the CHAIN flag update | ||
| 316 | * is visible before the raised count. | ||
| 317 | */ | ||
| 318 | static inline void bio_inc_remaining(struct bio *bio) | ||
| 319 | { | ||
| 320 | bio_set_flag(bio, BIO_CHAIN); | ||
| 321 | smp_mb__before_atomic(); | ||
| 322 | atomic_inc(&bio->__bi_remaining); | ||
| 323 | } | ||
| 324 | |||
| 325 | /** | 314 | /** |
| 326 | * bio_chain - chain bio completions | 315 | * bio_chain - chain bio completions |
| 327 | * @bio: the target bio | 316 | * @bio: the target bio |
diff --git a/block/blk-core.c b/block/blk-core.c index b60537b2c35b..c50227796a26 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -1523,6 +1523,7 @@ EXPORT_SYMBOL(blk_put_request); | |||
| 1523 | * blk_add_request_payload - add a payload to a request | 1523 | * blk_add_request_payload - add a payload to a request |
| 1524 | * @rq: request to update | 1524 | * @rq: request to update |
| 1525 | * @page: page backing the payload | 1525 | * @page: page backing the payload |
| 1526 | * @offset: offset in page | ||
| 1526 | * @len: length of the payload. | 1527 | * @len: length of the payload. |
| 1527 | * | 1528 | * |
| 1528 | * This allows to later add a payload to an already submitted request by | 1529 | * This allows to later add a payload to an already submitted request by |
| @@ -1533,12 +1534,12 @@ EXPORT_SYMBOL(blk_put_request); | |||
| 1533 | * discard requests should ever use it. | 1534 | * discard requests should ever use it. |
| 1534 | */ | 1535 | */ |
| 1535 | void blk_add_request_payload(struct request *rq, struct page *page, | 1536 | void blk_add_request_payload(struct request *rq, struct page *page, |
| 1536 | unsigned int len) | 1537 | int offset, unsigned int len) |
| 1537 | { | 1538 | { |
| 1538 | struct bio *bio = rq->bio; | 1539 | struct bio *bio = rq->bio; |
| 1539 | 1540 | ||
| 1540 | bio->bi_io_vec->bv_page = page; | 1541 | bio->bi_io_vec->bv_page = page; |
| 1541 | bio->bi_io_vec->bv_offset = 0; | 1542 | bio->bi_io_vec->bv_offset = offset; |
| 1542 | bio->bi_io_vec->bv_len = len; | 1543 | bio->bi_io_vec->bv_len = len; |
| 1543 | 1544 | ||
| 1544 | bio->bi_iter.bi_size = len; | 1545 | bio->bi_iter.bi_size = len; |
diff --git a/block/blk-lib.c b/block/blk-lib.c index 9ebf65379556..23d7f301a196 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c | |||
| @@ -9,82 +9,46 @@ | |||
| 9 | 9 | ||
| 10 | #include "blk.h" | 10 | #include "blk.h" |
| 11 | 11 | ||
| 12 | struct bio_batch { | 12 | static struct bio *next_bio(struct bio *bio, int rw, unsigned int nr_pages, |
| 13 | atomic_t done; | 13 | gfp_t gfp) |
| 14 | int error; | ||
| 15 | struct completion *wait; | ||
| 16 | }; | ||
| 17 | |||
| 18 | static void bio_batch_end_io(struct bio *bio) | ||
| 19 | { | 14 | { |
| 20 | struct bio_batch *bb = bio->bi_private; | 15 | struct bio *new = bio_alloc(gfp, nr_pages); |
| 16 | |||
| 17 | if (bio) { | ||
| 18 | bio_chain(bio, new); | ||
| 19 | submit_bio(rw, bio); | ||
| 20 | } | ||
| 21 | 21 | ||
| 22 | if (bio->bi_error && bio->bi_error != -EOPNOTSUPP) | 22 | return new; |
| 23 | bb->error = bio->bi_error; | ||
| 24 | if (atomic_dec_and_test(&bb->done)) | ||
| 25 | complete(bb->wait); | ||
| 26 | bio_put(bio); | ||
| 27 | } | 23 | } |
| 28 | 24 | ||
| 29 | /** | 25 | int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, |
| 30 | * blkdev_issue_discard - queue a discard | 26 | sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop) |
| 31 | * @bdev: blockdev to issue discard for | ||
| 32 | * @sector: start sector | ||
| 33 | * @nr_sects: number of sectors to discard | ||
| 34 | * @gfp_mask: memory allocation flags (for bio_alloc) | ||
| 35 | * @flags: BLKDEV_IFL_* flags to control behaviour | ||
| 36 | * | ||
| 37 | * Description: | ||
| 38 | * Issue a discard request for the sectors in question. | ||
| 39 | */ | ||
| 40 | int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | ||
| 41 | sector_t nr_sects, gfp_t gfp_mask, unsigned long flags) | ||
| 42 | { | 27 | { |
| 43 | DECLARE_COMPLETION_ONSTACK(wait); | ||
| 44 | struct request_queue *q = bdev_get_queue(bdev); | 28 | struct request_queue *q = bdev_get_queue(bdev); |
| 45 | int type = REQ_WRITE | REQ_DISCARD; | 29 | struct bio *bio = *biop; |
| 46 | unsigned int granularity; | 30 | unsigned int granularity; |
| 47 | int alignment; | 31 | int alignment; |
| 48 | struct bio_batch bb; | ||
| 49 | struct bio *bio; | ||
| 50 | int ret = 0; | ||
| 51 | struct blk_plug plug; | ||
| 52 | 32 | ||
| 53 | if (!q) | 33 | if (!q) |
| 54 | return -ENXIO; | 34 | return -ENXIO; |
| 55 | |||
| 56 | if (!blk_queue_discard(q)) | 35 | if (!blk_queue_discard(q)) |
| 57 | return -EOPNOTSUPP; | 36 | return -EOPNOTSUPP; |
| 37 | if ((type & REQ_SECURE) && !blk_queue_secdiscard(q)) | ||
| 38 | return -EOPNOTSUPP; | ||
| 58 | 39 | ||
| 59 | /* Zero-sector (unknown) and one-sector granularities are the same. */ | 40 | /* Zero-sector (unknown) and one-sector granularities are the same. */ |
| 60 | granularity = max(q->limits.discard_granularity >> 9, 1U); | 41 | granularity = max(q->limits.discard_granularity >> 9, 1U); |
| 61 | alignment = (bdev_discard_alignment(bdev) >> 9) % granularity; | 42 | alignment = (bdev_discard_alignment(bdev) >> 9) % granularity; |
| 62 | 43 | ||
| 63 | if (flags & BLKDEV_DISCARD_SECURE) { | ||
| 64 | if (!blk_queue_secdiscard(q)) | ||
| 65 | return -EOPNOTSUPP; | ||
| 66 | type |= REQ_SECURE; | ||
| 67 | } | ||
| 68 | |||
| 69 | atomic_set(&bb.done, 1); | ||
| 70 | bb.error = 0; | ||
| 71 | bb.wait = &wait; | ||
| 72 | |||
| 73 | blk_start_plug(&plug); | ||
| 74 | while (nr_sects) { | 44 | while (nr_sects) { |
| 75 | unsigned int req_sects; | 45 | unsigned int req_sects; |
| 76 | sector_t end_sect, tmp; | 46 | sector_t end_sect, tmp; |
| 77 | 47 | ||
| 78 | bio = bio_alloc(gfp_mask, 1); | ||
| 79 | if (!bio) { | ||
| 80 | ret = -ENOMEM; | ||
| 81 | break; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* Make sure bi_size doesn't overflow */ | 48 | /* Make sure bi_size doesn't overflow */ |
| 85 | req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9); | 49 | req_sects = min_t(sector_t, nr_sects, UINT_MAX >> 9); |
| 86 | 50 | ||
| 87 | /* | 51 | /** |
| 88 | * If splitting a request, and the next starting sector would be | 52 | * If splitting a request, and the next starting sector would be |
| 89 | * misaligned, stop the discard at the previous aligned sector. | 53 | * misaligned, stop the discard at the previous aligned sector. |
| 90 | */ | 54 | */ |
| @@ -98,18 +62,14 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 98 | req_sects = end_sect - sector; | 62 | req_sects = end_sect - sector; |
| 99 | } | 63 | } |
| 100 | 64 | ||
| 65 | bio = next_bio(bio, type, 1, gfp_mask); | ||
| 101 | bio->bi_iter.bi_sector = sector; | 66 | bio->bi_iter.bi_sector = sector; |
| 102 | bio->bi_end_io = bio_batch_end_io; | ||
| 103 | bio->bi_bdev = bdev; | 67 | bio->bi_bdev = bdev; |
| 104 | bio->bi_private = &bb; | ||
| 105 | 68 | ||
| 106 | bio->bi_iter.bi_size = req_sects << 9; | 69 | bio->bi_iter.bi_size = req_sects << 9; |
| 107 | nr_sects -= req_sects; | 70 | nr_sects -= req_sects; |
| 108 | sector = end_sect; | 71 | sector = end_sect; |
| 109 | 72 | ||
| 110 | atomic_inc(&bb.done); | ||
| 111 | submit_bio(type, bio); | ||
| 112 | |||
| 113 | /* | 73 | /* |
| 114 | * We can loop for a long time in here, if someone does | 74 | * We can loop for a long time in here, if someone does |
| 115 | * full device discards (like mkfs). Be nice and allow | 75 | * full device discards (like mkfs). Be nice and allow |
| @@ -118,14 +78,44 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
| 118 | */ | 78 | */ |
| 119 | cond_resched(); | 79 | cond_resched(); |
| 120 | } | 80 | } |
| 121 | blk_finish_plug(&plug); | ||
| 122 | 81 | ||
| 123 | /* Wait for bios in-flight */ | 82 | *biop = bio; |
| 124 | if (!atomic_dec_and_test(&bb.done)) | 83 | return 0; |
| 125 | wait_for_completion_io(&wait); | 84 | } |
| 85 | EXPORT_SYMBOL(__blkdev_issue_discard); | ||
| 86 | |||
| 87 | /** | ||
| 88 | * blkdev_issue_discard - queue a discard | ||
| 89 | * @bdev: blockdev to issue discard for | ||
| 90 | * @sector: start sector | ||
| 91 | * @nr_sects: number of sectors to discard | ||
| 92 | * @gfp_mask: memory allocation flags (for bio_alloc) | ||
| 93 | * @flags: BLKDEV_IFL_* flags to control behaviour | ||
| 94 | * | ||
| 95 | * Description: | ||
| 96 | * Issue a discard request for the sectors in question. | ||
| 97 | */ | ||
| 98 | int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | ||
| 99 | sector_t nr_sects, gfp_t gfp_mask, unsigned long flags) | ||
| 100 | { | ||
| 101 | int type = REQ_WRITE | REQ_DISCARD; | ||
| 102 | struct bio *bio = NULL; | ||
| 103 | struct blk_plug plug; | ||
| 104 | int ret; | ||
| 105 | |||
| 106 | if (flags & BLKDEV_DISCARD_SECURE) | ||
| 107 | type |= REQ_SECURE; | ||
| 108 | |||
| 109 | blk_start_plug(&plug); | ||
| 110 | ret = __blkdev_issue_discard(bdev, sector, nr_sects, gfp_mask, type, | ||
| 111 | &bio); | ||
| 112 | if (!ret && bio) { | ||
| 113 | ret = submit_bio_wait(type, bio); | ||
| 114 | if (ret == -EOPNOTSUPP) | ||
| 115 | ret = 0; | ||
| 116 | } | ||
| 117 | blk_finish_plug(&plug); | ||
| 126 | 118 | ||
| 127 | if (bb.error) | ||
| 128 | return bb.error; | ||
| 129 | return ret; | 119 | return ret; |
| 130 | } | 120 | } |
| 131 | EXPORT_SYMBOL(blkdev_issue_discard); | 121 | EXPORT_SYMBOL(blkdev_issue_discard); |
| @@ -145,11 +135,9 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, | |||
| 145 | sector_t nr_sects, gfp_t gfp_mask, | 135 | sector_t nr_sects, gfp_t gfp_mask, |
| 146 | struct page *page) | 136 | struct page *page) |
| 147 | { | 137 | { |
| 148 | DECLARE_COMPLETION_ONSTACK(wait); | ||
| 149 | struct request_queue *q = bdev_get_queue(bdev); | 138 | struct request_queue *q = bdev_get_queue(bdev); |
| 150 | unsigned int max_write_same_sectors; | 139 | unsigned int max_write_same_sectors; |
| 151 | struct bio_batch bb; | 140 | struct bio *bio = NULL; |
| 152 | struct bio *bio; | ||
| 153 | int ret = 0; | 141 | int ret = 0; |
| 154 | 142 | ||
| 155 | if (!q) | 143 | if (!q) |
| @@ -158,21 +146,10 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, | |||
| 158 | /* Ensure that max_write_same_sectors doesn't overflow bi_size */ | 146 | /* Ensure that max_write_same_sectors doesn't overflow bi_size */ |
| 159 | max_write_same_sectors = UINT_MAX >> 9; | 147 | max_write_same_sectors = UINT_MAX >> 9; |
| 160 | 148 | ||
| 161 | atomic_set(&bb.done, 1); | ||
| 162 | bb.error = 0; | ||
| 163 | bb.wait = &wait; | ||
| 164 | |||
| 165 | while (nr_sects) { | 149 | while (nr_sects) { |
| 166 | bio = bio_alloc(gfp_mask, 1); | 150 | bio = next_bio(bio, REQ_WRITE | REQ_WRITE_SAME, 1, gfp_mask); |
| 167 | if (!bio) { | ||
| 168 | ret = -ENOMEM; | ||
| 169 | break; | ||
| 170 | } | ||
| 171 | |||
| 172 | bio->bi_iter.bi_sector = sector; | 151 | bio->bi_iter.bi_sector = sector; |
| 173 | bio->bi_end_io = bio_batch_end_io; | ||
| 174 | bio->bi_bdev = bdev; | 152 | bio->bi_bdev = bdev; |
| 175 | bio->bi_private = &bb; | ||
| 176 | bio->bi_vcnt = 1; | 153 | bio->bi_vcnt = 1; |
| 177 | bio->bi_io_vec->bv_page = page; | 154 | bio->bi_io_vec->bv_page = page; |
| 178 | bio->bi_io_vec->bv_offset = 0; | 155 | bio->bi_io_vec->bv_offset = 0; |
| @@ -186,18 +163,11 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, | |||
| 186 | bio->bi_iter.bi_size = nr_sects << 9; | 163 | bio->bi_iter.bi_size = nr_sects << 9; |
| 187 | nr_sects = 0; | 164 | nr_sects = 0; |
| 188 | } | 165 | } |
| 189 | |||
| 190 | atomic_inc(&bb.done); | ||
| 191 | submit_bio(REQ_WRITE | REQ_WRITE_SAME, bio); | ||
| 192 | } | 166 | } |
| 193 | 167 | ||
| 194 | /* Wait for bios in-flight */ | 168 | if (bio) |
| 195 | if (!atomic_dec_and_test(&bb.done)) | 169 | ret = submit_bio_wait(REQ_WRITE | REQ_WRITE_SAME, bio); |
| 196 | wait_for_completion_io(&wait); | 170 | return ret != -EOPNOTSUPP ? ret : 0; |
| 197 | |||
| 198 | if (bb.error) | ||
| 199 | return bb.error; | ||
| 200 | return ret; | ||
| 201 | } | 171 | } |
| 202 | EXPORT_SYMBOL(blkdev_issue_write_same); | 172 | EXPORT_SYMBOL(blkdev_issue_write_same); |
| 203 | 173 | ||
| @@ -216,28 +186,15 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, | |||
| 216 | sector_t nr_sects, gfp_t gfp_mask) | 186 | sector_t nr_sects, gfp_t gfp_mask) |
| 217 | { | 187 | { |
| 218 | int ret; | 188 | int ret; |
| 219 | struct bio *bio; | 189 | struct bio *bio = NULL; |
| 220 | struct bio_batch bb; | ||
| 221 | unsigned int sz; | 190 | unsigned int sz; |
| 222 | DECLARE_COMPLETION_ONSTACK(wait); | ||
| 223 | |||
| 224 | atomic_set(&bb.done, 1); | ||
| 225 | bb.error = 0; | ||
| 226 | bb.wait = &wait; | ||
| 227 | 191 | ||
| 228 | ret = 0; | ||
| 229 | while (nr_sects != 0) { | 192 | while (nr_sects != 0) { |
| 230 | bio = bio_alloc(gfp_mask, | 193 | bio = next_bio(bio, WRITE, |
| 231 | min(nr_sects, (sector_t)BIO_MAX_PAGES)); | 194 | min(nr_sects, (sector_t)BIO_MAX_PAGES), |
| 232 | if (!bio) { | 195 | gfp_mask); |
| 233 | ret = -ENOMEM; | ||
| 234 | break; | ||
| 235 | } | ||
| 236 | |||
| 237 | bio->bi_iter.bi_sector = sector; | 196 | bio->bi_iter.bi_sector = sector; |
| 238 | bio->bi_bdev = bdev; | 197 | bio->bi_bdev = bdev; |
| 239 | bio->bi_end_io = bio_batch_end_io; | ||
| 240 | bio->bi_private = &bb; | ||
| 241 | 198 | ||
| 242 | while (nr_sects != 0) { | 199 | while (nr_sects != 0) { |
| 243 | sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects); | 200 | sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects); |
| @@ -247,18 +204,11 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, | |||
| 247 | if (ret < (sz << 9)) | 204 | if (ret < (sz << 9)) |
| 248 | break; | 205 | break; |
| 249 | } | 206 | } |
| 250 | ret = 0; | ||
| 251 | atomic_inc(&bb.done); | ||
| 252 | submit_bio(WRITE, bio); | ||
| 253 | } | 207 | } |
| 254 | 208 | ||
| 255 | /* Wait for bios in-flight */ | 209 | if (bio) |
| 256 | if (!atomic_dec_and_test(&bb.done)) | 210 | return submit_bio_wait(WRITE, bio); |
| 257 | wait_for_completion_io(&wait); | 211 | return 0; |
| 258 | |||
| 259 | if (bb.error) | ||
| 260 | return bb.error; | ||
| 261 | return ret; | ||
| 262 | } | 212 | } |
| 263 | 213 | ||
| 264 | /** | 214 | /** |
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index abdbb47405cb..2fd04286f103 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c | |||
| @@ -474,6 +474,18 @@ void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn, | |||
| 474 | } | 474 | } |
| 475 | EXPORT_SYMBOL(blk_mq_all_tag_busy_iter); | 475 | EXPORT_SYMBOL(blk_mq_all_tag_busy_iter); |
| 476 | 476 | ||
| 477 | void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset, | ||
| 478 | busy_tag_iter_fn *fn, void *priv) | ||
| 479 | { | ||
| 480 | int i; | ||
| 481 | |||
| 482 | for (i = 0; i < tagset->nr_hw_queues; i++) { | ||
| 483 | if (tagset->tags && tagset->tags[i]) | ||
| 484 | blk_mq_all_tag_busy_iter(tagset->tags[i], fn, priv); | ||
| 485 | } | ||
| 486 | } | ||
| 487 | EXPORT_SYMBOL(blk_mq_tagset_busy_iter); | ||
| 488 | |||
| 477 | void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn, | 489 | void blk_mq_queue_tag_busy_iter(struct request_queue *q, busy_iter_fn *fn, |
| 478 | void *priv) | 490 | void *priv) |
| 479 | { | 491 | { |
diff --git a/block/blk-mq.c b/block/blk-mq.c index 1699baf39b78..7df9c9263b21 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -1122,8 +1122,7 @@ static void blk_mq_bio_to_request(struct request *rq, struct bio *bio) | |||
| 1122 | { | 1122 | { |
| 1123 | init_request_from_bio(rq, bio); | 1123 | init_request_from_bio(rq, bio); |
| 1124 | 1124 | ||
| 1125 | if (blk_do_io_stat(rq)) | 1125 | blk_account_io_start(rq, 1); |
| 1126 | blk_account_io_start(rq, 1); | ||
| 1127 | } | 1126 | } |
| 1128 | 1127 | ||
| 1129 | static inline bool hctx_allow_merges(struct blk_mq_hw_ctx *hctx) | 1128 | static inline bool hctx_allow_merges(struct blk_mq_hw_ctx *hctx) |
| @@ -1496,7 +1495,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, | |||
| 1496 | int to_do; | 1495 | int to_do; |
| 1497 | void *p; | 1496 | void *p; |
| 1498 | 1497 | ||
| 1499 | while (left < order_to_size(this_order - 1) && this_order) | 1498 | while (this_order && left < order_to_size(this_order - 1)) |
| 1500 | this_order--; | 1499 | this_order--; |
| 1501 | 1500 | ||
| 1502 | do { | 1501 | do { |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 331e4eee0dda..c903bee43cf8 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
| @@ -846,6 +846,32 @@ void blk_queue_flush_queueable(struct request_queue *q, bool queueable) | |||
| 846 | } | 846 | } |
| 847 | EXPORT_SYMBOL_GPL(blk_queue_flush_queueable); | 847 | EXPORT_SYMBOL_GPL(blk_queue_flush_queueable); |
| 848 | 848 | ||
| 849 | /** | ||
| 850 | * blk_queue_write_cache - configure queue's write cache | ||
| 851 | * @q: the request queue for the device | ||
| 852 | * @wc: write back cache on or off | ||
| 853 | * @fua: device supports FUA writes, if true | ||
| 854 | * | ||
| 855 | * Tell the block layer about the write cache of @q. | ||
| 856 | */ | ||
| 857 | void blk_queue_write_cache(struct request_queue *q, bool wc, bool fua) | ||
| 858 | { | ||
| 859 | spin_lock_irq(q->queue_lock); | ||
| 860 | if (wc) { | ||
| 861 | queue_flag_set(QUEUE_FLAG_WC, q); | ||
| 862 | q->flush_flags = REQ_FLUSH; | ||
| 863 | } else | ||
| 864 | queue_flag_clear(QUEUE_FLAG_WC, q); | ||
| 865 | if (fua) { | ||
| 866 | if (wc) | ||
| 867 | q->flush_flags |= REQ_FUA; | ||
| 868 | queue_flag_set(QUEUE_FLAG_FUA, q); | ||
| 869 | } else | ||
| 870 | queue_flag_clear(QUEUE_FLAG_FUA, q); | ||
| 871 | spin_unlock_irq(q->queue_lock); | ||
| 872 | } | ||
| 873 | EXPORT_SYMBOL_GPL(blk_queue_write_cache); | ||
| 874 | |||
| 849 | static int __init blk_settings_init(void) | 875 | static int __init blk_settings_init(void) |
| 850 | { | 876 | { |
| 851 | blk_max_low_pfn = max_low_pfn - 1; | 877 | blk_max_low_pfn = max_low_pfn - 1; |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 995b58d46ed1..99205965f559 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
| @@ -347,6 +347,38 @@ static ssize_t queue_poll_store(struct request_queue *q, const char *page, | |||
| 347 | return ret; | 347 | return ret; |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | static ssize_t queue_wc_show(struct request_queue *q, char *page) | ||
| 351 | { | ||
| 352 | if (test_bit(QUEUE_FLAG_WC, &q->queue_flags)) | ||
| 353 | return sprintf(page, "write back\n"); | ||
| 354 | |||
| 355 | return sprintf(page, "write through\n"); | ||
| 356 | } | ||
| 357 | |||
| 358 | static ssize_t queue_wc_store(struct request_queue *q, const char *page, | ||
| 359 | size_t count) | ||
| 360 | { | ||
| 361 | int set = -1; | ||
| 362 | |||
| 363 | if (!strncmp(page, "write back", 10)) | ||
| 364 | set = 1; | ||
| 365 | else if (!strncmp(page, "write through", 13) || | ||
| 366 | !strncmp(page, "none", 4)) | ||
| 367 | set = 0; | ||
| 368 | |||
| 369 | if (set == -1) | ||
| 370 | return -EINVAL; | ||
| 371 | |||
| 372 | spin_lock_irq(q->queue_lock); | ||
| 373 | if (set) | ||
| 374 | queue_flag_set(QUEUE_FLAG_WC, q); | ||
| 375 | else | ||
| 376 | queue_flag_clear(QUEUE_FLAG_WC, q); | ||
| 377 | spin_unlock_irq(q->queue_lock); | ||
| 378 | |||
| 379 | return count; | ||
| 380 | } | ||
| 381 | |||
| 350 | static struct queue_sysfs_entry queue_requests_entry = { | 382 | static struct queue_sysfs_entry queue_requests_entry = { |
| 351 | .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, | 383 | .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, |
| 352 | .show = queue_requests_show, | 384 | .show = queue_requests_show, |
| @@ -478,6 +510,12 @@ static struct queue_sysfs_entry queue_poll_entry = { | |||
| 478 | .store = queue_poll_store, | 510 | .store = queue_poll_store, |
| 479 | }; | 511 | }; |
| 480 | 512 | ||
| 513 | static struct queue_sysfs_entry queue_wc_entry = { | ||
| 514 | .attr = {.name = "write_cache", .mode = S_IRUGO | S_IWUSR }, | ||
| 515 | .show = queue_wc_show, | ||
| 516 | .store = queue_wc_store, | ||
| 517 | }; | ||
| 518 | |||
| 481 | static struct attribute *default_attrs[] = { | 519 | static struct attribute *default_attrs[] = { |
| 482 | &queue_requests_entry.attr, | 520 | &queue_requests_entry.attr, |
| 483 | &queue_ra_entry.attr, | 521 | &queue_ra_entry.attr, |
| @@ -503,6 +541,7 @@ static struct attribute *default_attrs[] = { | |||
| 503 | &queue_iostats_entry.attr, | 541 | &queue_iostats_entry.attr, |
| 504 | &queue_random_entry.attr, | 542 | &queue_random_entry.attr, |
| 505 | &queue_poll_entry.attr, | 543 | &queue_poll_entry.attr, |
| 544 | &queue_wc_entry.attr, | ||
| 506 | NULL, | 545 | NULL, |
| 507 | }; | 546 | }; |
| 508 | 547 | ||
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 2149a1ddbacf..47a3e540631a 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
| @@ -211,15 +211,14 @@ static struct throtl_data *sq_to_td(struct throtl_service_queue *sq) | |||
| 211 | * | 211 | * |
| 212 | * The messages are prefixed with "throtl BLKG_NAME" if @sq belongs to a | 212 | * The messages are prefixed with "throtl BLKG_NAME" if @sq belongs to a |
| 213 | * throtl_grp; otherwise, just "throtl". | 213 | * throtl_grp; otherwise, just "throtl". |
| 214 | * | ||
| 215 | * TODO: this should be made a function and name formatting should happen | ||
| 216 | * after testing whether blktrace is enabled. | ||
| 217 | */ | 214 | */ |
| 218 | #define throtl_log(sq, fmt, args...) do { \ | 215 | #define throtl_log(sq, fmt, args...) do { \ |
| 219 | struct throtl_grp *__tg = sq_to_tg((sq)); \ | 216 | struct throtl_grp *__tg = sq_to_tg((sq)); \ |
| 220 | struct throtl_data *__td = sq_to_td((sq)); \ | 217 | struct throtl_data *__td = sq_to_td((sq)); \ |
| 221 | \ | 218 | \ |
| 222 | (void)__td; \ | 219 | (void)__td; \ |
| 220 | if (likely(!blk_trace_note_message_enabled(__td->queue))) \ | ||
| 221 | break; \ | ||
| 223 | if ((__tg)) { \ | 222 | if ((__tg)) { \ |
| 224 | char __pbuf[128]; \ | 223 | char __pbuf[128]; \ |
| 225 | \ | 224 | \ |
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c index 586f9168ffa4..9a9ec212fab8 100644 --- a/drivers/block/skd_main.c +++ b/drivers/block/skd_main.c | |||
| @@ -562,7 +562,7 @@ skd_prep_discard_cdb(struct skd_scsi_request *scsi_req, | |||
| 562 | put_unaligned_be32(count, &buf[16]); | 562 | put_unaligned_be32(count, &buf[16]); |
| 563 | 563 | ||
| 564 | req = skreq->req; | 564 | req = skreq->req; |
| 565 | blk_add_request_payload(req, page, len); | 565 | blk_add_request_payload(req, page, 0, len); |
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | static void skd_request_fn_not_online(struct request_queue *q); | 568 | static void skd_request_fn_not_online(struct request_queue *q); |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index f52b74cf8d1e..69b0a4a7a15f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -779,7 +779,7 @@ static int sd_setup_discard_cmnd(struct scsi_cmnd *cmd) | |||
| 779 | * discarded on disk. This allows us to report completion on the full | 779 | * discarded on disk. This allows us to report completion on the full |
| 780 | * amount of blocks described by the request. | 780 | * amount of blocks described by the request. |
| 781 | */ | 781 | */ |
| 782 | blk_add_request_payload(rq, page, len); | 782 | blk_add_request_payload(rq, page, 0, len); |
| 783 | ret = scsi_init_io(cmd); | 783 | ret = scsi_init_io(cmd); |
| 784 | rq->__data_len = nr_bytes; | 784 | rq->__data_len = nr_bytes; |
| 785 | 785 | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index 6b7481f62218..9faebf7f9a33 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
| @@ -703,6 +703,17 @@ static inline struct bio *bio_list_get(struct bio_list *bl) | |||
| 703 | } | 703 | } |
| 704 | 704 | ||
| 705 | /* | 705 | /* |
| 706 | * Increment chain count for the bio. Make sure the CHAIN flag update | ||
| 707 | * is visible before the raised count. | ||
| 708 | */ | ||
| 709 | static inline void bio_inc_remaining(struct bio *bio) | ||
| 710 | { | ||
| 711 | bio_set_flag(bio, BIO_CHAIN); | ||
| 712 | smp_mb__before_atomic(); | ||
| 713 | atomic_inc(&bio->__bi_remaining); | ||
| 714 | } | ||
| 715 | |||
| 716 | /* | ||
| 706 | * bio_set is used to allow other portions of the IO system to | 717 | * bio_set is used to allow other portions of the IO system to |
| 707 | * allocate their own private memory pools for bio and iovec structures. | 718 | * allocate their own private memory pools for bio and iovec structures. |
| 708 | * These memory pools in turn all allocate from the bio_slab | 719 | * These memory pools in turn all allocate from the bio_slab |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 9ac9799b702b..c808fec1ce44 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
| @@ -240,6 +240,8 @@ void blk_mq_run_hw_queues(struct request_queue *q, bool async); | |||
| 240 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); | 240 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); |
| 241 | void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn, | 241 | void blk_mq_all_tag_busy_iter(struct blk_mq_tags *tags, busy_tag_iter_fn *fn, |
| 242 | void *priv); | 242 | void *priv); |
| 243 | void blk_mq_tagset_busy_iter(struct blk_mq_tag_set *tagset, | ||
| 244 | busy_tag_iter_fn *fn, void *priv); | ||
| 243 | void blk_mq_freeze_queue(struct request_queue *q); | 245 | void blk_mq_freeze_queue(struct request_queue *q); |
| 244 | void blk_mq_unfreeze_queue(struct request_queue *q); | 246 | void blk_mq_unfreeze_queue(struct request_queue *q); |
| 245 | void blk_mq_freeze_queue_start(struct request_queue *q); | 247 | void blk_mq_freeze_queue_start(struct request_queue *q); |
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 86a38ea1823f..77e5d81f07aa 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h | |||
| @@ -208,7 +208,7 @@ enum rq_flag_bits { | |||
| 208 | #define REQ_COMMON_MASK \ | 208 | #define REQ_COMMON_MASK \ |
| 209 | (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ | 209 | (REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \ |
| 210 | REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ | 210 | REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \ |
| 211 | REQ_SECURE | REQ_INTEGRITY) | 211 | REQ_SECURE | REQ_INTEGRITY | REQ_NOMERGE) |
| 212 | #define REQ_CLONE_MASK REQ_COMMON_MASK | 212 | #define REQ_CLONE_MASK REQ_COMMON_MASK |
| 213 | 213 | ||
| 214 | #define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) | 214 | #define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME) |
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 669e419d6234..b79131acf6c0 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
| @@ -491,6 +491,8 @@ struct request_queue { | |||
| 491 | #define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ | 491 | #define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */ |
| 492 | #define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ | 492 | #define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/ |
| 493 | #define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */ | 493 | #define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */ |
| 494 | #define QUEUE_FLAG_WC 23 /* Write back caching */ | ||
| 495 | #define QUEUE_FLAG_FUA 24 /* device supports FUA writes */ | ||
| 494 | 496 | ||
| 495 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 497 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
| 496 | (1 << QUEUE_FLAG_STACKABLE) | \ | 498 | (1 << QUEUE_FLAG_STACKABLE) | \ |
| @@ -779,7 +781,7 @@ extern struct request *blk_make_request(struct request_queue *, struct bio *, | |||
| 779 | extern void blk_rq_set_block_pc(struct request *); | 781 | extern void blk_rq_set_block_pc(struct request *); |
| 780 | extern void blk_requeue_request(struct request_queue *, struct request *); | 782 | extern void blk_requeue_request(struct request_queue *, struct request *); |
| 781 | extern void blk_add_request_payload(struct request *rq, struct page *page, | 783 | extern void blk_add_request_payload(struct request *rq, struct page *page, |
| 782 | unsigned int len); | 784 | int offset, unsigned int len); |
| 783 | extern int blk_lld_busy(struct request_queue *q); | 785 | extern int blk_lld_busy(struct request_queue *q); |
| 784 | extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src, | 786 | extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src, |
| 785 | struct bio_set *bs, gfp_t gfp_mask, | 787 | struct bio_set *bs, gfp_t gfp_mask, |
| @@ -1009,6 +1011,7 @@ extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); | |||
| 1009 | extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); | 1011 | extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); |
| 1010 | extern void blk_queue_flush(struct request_queue *q, unsigned int flush); | 1012 | extern void blk_queue_flush(struct request_queue *q, unsigned int flush); |
| 1011 | extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); | 1013 | extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable); |
| 1014 | extern void blk_queue_write_cache(struct request_queue *q, bool enabled, bool fua); | ||
| 1012 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); | 1015 | extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); |
| 1013 | 1016 | ||
| 1014 | extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); | 1017 | extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); |
| @@ -1128,6 +1131,8 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, | |||
| 1128 | extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *); | 1131 | extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *); |
| 1129 | extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | 1132 | extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector, |
| 1130 | sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); | 1133 | sector_t nr_sects, gfp_t gfp_mask, unsigned long flags); |
| 1134 | extern int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, | ||
| 1135 | sector_t nr_sects, gfp_t gfp_mask, int type, struct bio **biop); | ||
| 1131 | extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, | 1136 | extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector, |
| 1132 | sector_t nr_sects, gfp_t gfp_mask, struct page *page); | 1137 | sector_t nr_sects, gfp_t gfp_mask, struct page *page); |
| 1133 | extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, | 1138 | extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector, |
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index afc1343df3c7..0f3172b8b225 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
| @@ -57,6 +57,14 @@ void __trace_note_message(struct blk_trace *, const char *fmt, ...); | |||
| 57 | } while (0) | 57 | } while (0) |
| 58 | #define BLK_TN_MAX_MSG 128 | 58 | #define BLK_TN_MAX_MSG 128 |
| 59 | 59 | ||
| 60 | static inline bool blk_trace_note_message_enabled(struct request_queue *q) | ||
| 61 | { | ||
| 62 | struct blk_trace *bt = q->blk_trace; | ||
| 63 | if (likely(!bt)) | ||
| 64 | return false; | ||
| 65 | return bt->act_mask & BLK_TC_NOTIFY; | ||
| 66 | } | ||
| 67 | |||
| 60 | extern void blk_add_driver_data(struct request_queue *q, struct request *rq, | 68 | extern void blk_add_driver_data(struct request_queue *q, struct request *rq, |
| 61 | void *data, size_t len); | 69 | void *data, size_t len); |
| 62 | extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | 70 | extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, |
| @@ -79,6 +87,7 @@ extern struct attribute_group blk_trace_attr_group; | |||
| 79 | # define blk_trace_remove(q) (-ENOTTY) | 87 | # define blk_trace_remove(q) (-ENOTTY) |
| 80 | # define blk_add_trace_msg(q, fmt, ...) do { } while (0) | 88 | # define blk_add_trace_msg(q, fmt, ...) do { } while (0) |
| 81 | # define blk_trace_remove_sysfs(dev) do { } while (0) | 89 | # define blk_trace_remove_sysfs(dev) do { } while (0) |
| 90 | # define blk_trace_note_message_enabled(q) (false) | ||
| 82 | static inline int blk_trace_init_sysfs(struct device *dev) | 91 | static inline int blk_trace_init_sysfs(struct device *dev) |
| 83 | { | 92 | { |
| 84 | return 0; | 93 | return 0; |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index f94e7a21f52d..9aef8654e90d 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
| @@ -1349,6 +1349,7 @@ static enum print_line_t print_one_line(struct trace_iterator *iter, | |||
| 1349 | if (t->action == BLK_TN_MESSAGE) { | 1349 | if (t->action == BLK_TN_MESSAGE) { |
| 1350 | log_action(iter, long_act ? "message" : "m"); | 1350 | log_action(iter, long_act ? "message" : "m"); |
| 1351 | blk_log_msg(s, iter->ent); | 1351 | blk_log_msg(s, iter->ent); |
| 1352 | return trace_handle_return(s); | ||
| 1352 | } | 1353 | } |
| 1353 | 1354 | ||
| 1354 | if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) | 1355 | if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act))) |
| @@ -1551,6 +1552,7 @@ static const struct { | |||
| 1551 | { BLK_TC_COMPLETE, "complete" }, | 1552 | { BLK_TC_COMPLETE, "complete" }, |
| 1552 | { BLK_TC_FS, "fs" }, | 1553 | { BLK_TC_FS, "fs" }, |
| 1553 | { BLK_TC_PC, "pc" }, | 1554 | { BLK_TC_PC, "pc" }, |
| 1555 | { BLK_TC_NOTIFY, "notify" }, | ||
| 1554 | { BLK_TC_AHEAD, "ahead" }, | 1556 | { BLK_TC_AHEAD, "ahead" }, |
| 1555 | { BLK_TC_META, "meta" }, | 1557 | { BLK_TC_META, "meta" }, |
| 1556 | { BLK_TC_DISCARD, "discard" }, | 1558 | { BLK_TC_DISCARD, "discard" }, |
