diff options
| author | Mike Snitzer <snitzer@redhat.com> | 2015-06-30 19:47:49 -0400 |
|---|---|---|
| committer | Mike Snitzer <snitzer@redhat.com> | 2015-06-30 20:07:21 -0400 |
| commit | 17dbe96d4f8a6f87004e6cfb5944872dfe2edb9f (patch) | |
| tree | a73a85862357cd762f83a4396d3d0a3c26f04991 | |
| parent | 6c47fab39f1c7a2940176b0ba16f4224ffd5d99a (diff) | |
| download | linux-dm-17dbe96d4f8a6f87004e6cfb5944872dfe2edb9f.tar.gz | |
dm io: fix crash due to client bioset missing integrity_pool
Notice: this object is not reachable from any branch.
If a bio, allocated from a bioset, is submitted to a device that has a
block integrity profile (bio_integrity_enabled() returns true) the block
layer assumes the bioset was also setup using bioset_integrity_create()
-- needed to allow 'struct bio_integrity_payload' allocation to occur as
part of submit_bio().
Fix dm-io to call bioset_integrity_create() on the client's bioset.
Otherwise, a "Kernel BUG" with a trace like the following will be
observed (as seen on s390x using zfcp storage):
[ 791.643338] Call Trace:
[ 791.643339] ([<00000003df98b848>] 0x3df98b848)
[ 791.643341] [<00000000002c5de8>] bio_integrity_alloc+0x48/0xf8
[ 791.643348] [<00000000002c6486>] bio_integrity_prep+0xae/0x2f0
[ 791.643349] [<0000000000371e38>] blk_queue_bio+0x1c8/0x3d8
[ 791.643355] [<000000000036f8d0>] generic_make_request+0xc0/0x100
[ 791.643357] [<000000000036f9b2>] submit_bio+0xa2/0x198
[ 791.643406] [<000003ff801f9774>] dispatch_io+0x15c/0x3b0 [dm_mod]
[ 791.643419] [<000003ff801f9b3e>] dm_io+0x176/0x2f0 [dm_mod]
[ 791.643423] [<000003ff8074b28a>] do_reads+0x13a/0x1a8 [dm_mirror]
[ 791.643425] [<000003ff8074b43a>] do_mirror+0x142/0x298 [dm_mirror]
[ 791.643428] [<0000000000154fca>] process_one_work+0x18a/0x3f8
[ 791.643432] [<000000000015598a>] worker_thread+0x132/0x3b0
[ 791.643435] [<000000000015d49a>] kthread+0xd2/0xd8
[ 791.643438] [<00000000005bc0ca>] kernel_thread_starter+0x6/0xc
[ 791.643446] [<00000000005bc0c4>] kernel_thread_starter+0x0/0xc
It should be noted that this fix will needlessly consume memory if bios
allocated from the client's bioset don't actually need to support block
integrity (e.g. the devices the bios are submitted to don't support
block integrity). Unfortunately we have no clean way to _know_ whether
or not block integrity is required at all the dm_io_client_create()
call-sites.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Cc: stable@vger.kernel.org
Notice: this object is not reachable from any branch.
| -rw-r--r-- | drivers/md/dm-io.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index 74adcd2c967ec..2cd1e0eb092cc 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -62,9 +62,14 @@ struct dm_io_client *dm_io_client_create(void) if (!client->bios) goto bad; + if (bioset_integrity_create(client->bios, min_ios)) + goto bad; + return client; bad: + if (client->bios) + bioset_free(client->bios); if (client->pool) mempool_destroy(client->pool); kfree(client); |
