diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-29 17:10:37 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-29 17:10:37 -0400 |
commit | 374bf8831aa99a445d6d26c56a65fb35db747d91 (patch) | |
tree | fa7f85706041be3969a2d0397f08f4f933b54a81 | |
parent | 6474924e2b5ddb0030c355558966adcbe3b49022 (diff) | |
parent | 9ae3b3f52c62ddd5eb12c57f195f4f38121faa01 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe:
"Two fixes that should go into this release.
One is an nvme regression fix from Keith, fixing a missing queue
freeze if the controller is being reset. This causes the reset to
hang.
The other is a fix for a leak of the bio protection info, if smaller
sized O_DIRECT is used. This fix should be more involved as we have
other problematic paths in the kernel, but given as this isn't a
regression in this series, we'll tackle those for 4.13"
* 'for-linus' of git://git.kernel.dk/linux-block:
block: provide bio_uninit() free freeing integrity/task associations
nvme/pci: Fix stuck nvme reset
-rw-r--r-- | block/bio.c | 12 | ||||
-rw-r--r-- | drivers/nvme/host/pci.c | 3 | ||||
-rw-r--r-- | fs/block_dev.c | 5 | ||||
-rw-r--r-- | include/linux/bio.h | 1 |
4 files changed, 16 insertions, 5 deletions
diff --git a/block/bio.c b/block/bio.c index 888e7801c638..26b0810fb8ea 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -240,20 +240,21 @@ fallback: | |||
240 | return bvl; | 240 | return bvl; |
241 | } | 241 | } |
242 | 242 | ||
243 | static void __bio_free(struct bio *bio) | 243 | void bio_uninit(struct bio *bio) |
244 | { | 244 | { |
245 | bio_disassociate_task(bio); | 245 | bio_disassociate_task(bio); |
246 | 246 | ||
247 | if (bio_integrity(bio)) | 247 | if (bio_integrity(bio)) |
248 | bio_integrity_free(bio); | 248 | bio_integrity_free(bio); |
249 | } | 249 | } |
250 | EXPORT_SYMBOL(bio_uninit); | ||
250 | 251 | ||
251 | static void bio_free(struct bio *bio) | 252 | static void bio_free(struct bio *bio) |
252 | { | 253 | { |
253 | struct bio_set *bs = bio->bi_pool; | 254 | struct bio_set *bs = bio->bi_pool; |
254 | void *p; | 255 | void *p; |
255 | 256 | ||
256 | __bio_free(bio); | 257 | bio_uninit(bio); |
257 | 258 | ||
258 | if (bs) { | 259 | if (bs) { |
259 | bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio)); | 260 | bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio)); |
@@ -271,6 +272,11 @@ static void bio_free(struct bio *bio) | |||
271 | } | 272 | } |
272 | } | 273 | } |
273 | 274 | ||
275 | /* | ||
276 | * Users of this function have their own bio allocation. Subsequently, | ||
277 | * they must remember to pair any call to bio_init() with bio_uninit() | ||
278 | * when IO has completed, or when the bio is released. | ||
279 | */ | ||
274 | void bio_init(struct bio *bio, struct bio_vec *table, | 280 | void bio_init(struct bio *bio, struct bio_vec *table, |
275 | unsigned short max_vecs) | 281 | unsigned short max_vecs) |
276 | { | 282 | { |
@@ -297,7 +303,7 @@ void bio_reset(struct bio *bio) | |||
297 | { | 303 | { |
298 | unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS); | 304 | unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS); |
299 | 305 | ||
300 | __bio_free(bio); | 306 | bio_uninit(bio); |
301 | 307 | ||
302 | memset(bio, 0, BIO_RESET_BYTES); | 308 | memset(bio, 0, BIO_RESET_BYTES); |
303 | bio->bi_flags = flags; | 309 | bio->bi_flags = flags; |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 951042a375d6..40c7581caeb0 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -1805,7 +1805,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) | |||
1805 | if (pci_is_enabled(pdev)) { | 1805 | if (pci_is_enabled(pdev)) { |
1806 | u32 csts = readl(dev->bar + NVME_REG_CSTS); | 1806 | u32 csts = readl(dev->bar + NVME_REG_CSTS); |
1807 | 1807 | ||
1808 | if (dev->ctrl.state == NVME_CTRL_LIVE) | 1808 | if (dev->ctrl.state == NVME_CTRL_LIVE || |
1809 | dev->ctrl.state == NVME_CTRL_RESETTING) | ||
1809 | nvme_start_freeze(&dev->ctrl); | 1810 | nvme_start_freeze(&dev->ctrl); |
1810 | dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) || | 1811 | dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) || |
1811 | pdev->error_state != pci_channel_io_normal); | 1812 | pdev->error_state != pci_channel_io_normal); |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 519599dddd36..0a7404ef9335 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -263,7 +263,10 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter, | |||
263 | kfree(vecs); | 263 | kfree(vecs); |
264 | 264 | ||
265 | if (unlikely(bio.bi_error)) | 265 | if (unlikely(bio.bi_error)) |
266 | return bio.bi_error; | 266 | ret = bio.bi_error; |
267 | |||
268 | bio_uninit(&bio); | ||
269 | |||
267 | return ret; | 270 | return ret; |
268 | } | 271 | } |
269 | 272 | ||
diff --git a/include/linux/bio.h b/include/linux/bio.h index d1b04b0e99cf..a7e29fa0981f 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h | |||
@@ -426,6 +426,7 @@ extern void bio_advance(struct bio *, unsigned); | |||
426 | 426 | ||
427 | extern void bio_init(struct bio *bio, struct bio_vec *table, | 427 | extern void bio_init(struct bio *bio, struct bio_vec *table, |
428 | unsigned short max_vecs); | 428 | unsigned short max_vecs); |
429 | extern void bio_uninit(struct bio *); | ||
429 | extern void bio_reset(struct bio *); | 430 | extern void bio_reset(struct bio *); |
430 | void bio_chain(struct bio *, struct bio *); | 431 | void bio_chain(struct bio *, struct bio *); |
431 | 432 | ||