aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2015-06-30 19:47:49 -0400
committerMike Snitzer <snitzer@redhat.com>2015-06-30 20:07:21 -0400
commit17dbe96d4f8a6f87004e6cfb5944872dfe2edb9f (patch)
treea73a85862357cd762f83a4396d3d0a3c26f04991
parent6c47fab39f1c7a2940176b0ba16f4224ffd5d99a (diff)
downloadlinux-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.c5
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);