Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2019-03-20 13:52:40 +0100
committerHannes Reinecke <hare@suse.de>2019-03-20 13:52:40 +0100
commit512ce8f799a37a454d14403d6e0efb76aaaf240b (patch)
tree517dfade5d9508b002903679d7a724aab33740c2
parenta34b660c637a0bd7e46ab4bac6fd9ef435ae3c22 (diff)
- block_dev: fix crash on chained bios with O_DIRECT
(bsc#1128094). - Delete patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch.
-rw-r--r--patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch59
-rw-r--r--patches.fixes/block_dev-fix-crash-on-chained-bios-with-O_DIRECT.patch41
-rw-r--r--series.conf2
3 files changed, 42 insertions, 60 deletions
diff --git a/patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch b/patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch
deleted file mode 100644
index 0671eebfff..0000000000
--- a/patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From: Johannes Thumshirn <jthumshirn@suse.de>
-Date: Wed, 20 Mar 2019 09:40:18 +0100
-Subject: [PATCH] bio: Introduce BIO_ALLOCED flag and check it in bio_free
-Patch-Mainline: submitted linux-block 2019/03/20
-References: bsc#1128094
-
-When we're submitting a bio from stack and this ends up being split, we
-call bio_put(). bio_put() will eventually call bio_free() if the reference
-count drops to 0. But freeing the bio is wrong, as it was never allocated
-out of the bio's mempool.
-
-Flag each normally allocated bio as 'BIO_ALLOCATED' and skip freeing if the
-flag isn't set.
-
-Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
-Signed-off-by: Hannes Reinecke <hare@suse.com>
----
- block/bio.c | 4 ++++
- include/linux/blk_types.h | 2 ++
- 2 files changed, 6 insertions(+)
-
-diff --git a/block/bio.c b/block/bio.c
-index 336eb9eab377..073cd81877fa 100644
---- a/block/bio.c
-+++ b/block/bio.c
-@@ -253,6 +253,9 @@ static void bio_free(struct bio *bio)
-
- bio_uninit(bio);
-
-+ if (!bio_flagged(bio, BIO_ALLOCED))
-+ return;
-+
- if (bs) {
- bvec_free(bs->bvec_pool, bio->bi_io_vec, BVEC_POOL_IDX(bio));
-
-@@ -518,6 +521,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs,
- bvl = bio->bi_inline_vecs;
- }
-
-+ bio_set_flag(bio, BIO_ALLOCED);
- bio->bi_pool = bs;
- bio->bi_max_vecs = nr_iovecs;
- bio->bi_io_vec = bvl;
-diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
-index f6ea9d9656b5..bf6d5f4df94a 100644
---- a/include/linux/blk_types.h
-+++ b/include/linux/blk_types.h
-@@ -162,6 +162,8 @@ struct bio {
- * throttling rules. Don't do it again. */
- #define BIO_TRACE_COMPLETION 10 /* bio_endio() should trace the final completion
- * of this bio. */
-+#define BIO_ALLOCED 13 /* bio has been allocated by bio_alloc_bioset */
-+
- /* See BVEC_POOL_OFFSET below before adding new flags */
-
- /*
---
-2.16.4
-
diff --git a/patches.fixes/block_dev-fix-crash-on-chained-bios-with-O_DIRECT.patch b/patches.fixes/block_dev-fix-crash-on-chained-bios-with-O_DIRECT.patch
new file mode 100644
index 0000000000..8f2f809fd5
--- /dev/null
+++ b/patches.fixes/block_dev-fix-crash-on-chained-bios-with-O_DIRECT.patch
@@ -0,0 +1,41 @@
+From: Hannes Reinecke <hare@suse.de>
+Date: Wed, 20 Mar 2019 08:58:07 +0100
+Subject: [PATCH] block_dev: fix crash on chained bios with O_DIRECT
+Patch-Mainline: submitted linux-block 2019/03/20
+References: bsc#1128094
+
+__blkdev_direct_IO_simple() is allocating a bio on the stack.
+When that bio needs to be split bio_chain_endio() invokes bio_put()
+on this bio, causing the kernel to crash in mempool_free() as the
+bio was never allocated from a mempool in the first place.
+So call bio_get() before submitting to avoid this problem.
+
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+---
+ fs/block_dev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 7a9a14df1d82..4acd35663ae7 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -256,6 +256,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
+ task_io_account_write(ret);
+ }
+
++ bio_get(&bio);
+ qc = submit_bio(&bio);
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+@@ -275,7 +276,7 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
+
+ if (unlikely(bio.bi_status))
+ ret = blk_status_to_errno(bio.bi_status);
+-
++ bio_put(&bio);
+ out:
+ if (vecs != inline_vecs)
+ kfree(vecs);
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index f0ce00d257..43a2a4ccb2 100644
--- a/series.conf
+++ b/series.conf
@@ -20965,7 +20965,7 @@
patches.suse/cifs-fix-set-info.patch
patches.suse/0001-drm-vmwgfx-Don-t-double-free-the-mode-stored-in-par-.patch
patches.arch/pseries-energy-Use-OF-accessor-function-to-read-ibm-.patch
- patches.fixes/bio-Introduce-BIO_ALLOCED-flag-and-check-it-in-bio_f.patch
+ patches.fixes/block_dev-fix-crash-on-chained-bios-with-O_DIRECT.patch
patches.fixes/ch-add-missing-mutex_lock-mutex_unlock-in-ch_release.patch
patches.fixes/ch-fixup-refcounting-imbalance-for-SCSI-devices.patch