Skip to content

Commit 72c6e7a

Browse files
Mikulas Patockakergon
authored andcommitted
dm crypt: add missing error handling
Always set io->error to -EIO when an error is detected in dm-crypt. There were cases where an error code would be set only if we finish processing the last sector. If there were other encryption operations in flight, the error would be ignored and bio would be returned with success as if no error happened. This bug is present in kcryptd_crypt_write_convert, kcryptd_crypt_read_convert and kcryptd_async_done. Signed-off-by: Mikulas Patocka <[email protected]> Cc: [email protected] Reviewed-by: Milan Broz <[email protected]> Signed-off-by: Alasdair G Kergon <[email protected]>
1 parent aeb2dea commit 72c6e7a

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

drivers/md/dm-crypt.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,16 +1044,14 @@ static void kcryptd_queue_io(struct dm_crypt_io *io)
10441044
queue_work(cc->io_queue, &io->work);
10451045
}
10461046

1047-
static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io,
1048-
int error, int async)
1047+
static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
10491048
{
10501049
struct bio *clone = io->ctx.bio_out;
10511050
struct crypt_config *cc = io->target->private;
10521051

1053-
if (unlikely(error < 0)) {
1052+
if (unlikely(io->error < 0)) {
10541053
crypt_free_buffer_pages(cc, clone);
10551054
bio_put(clone);
1056-
io->error = -EIO;
10571055
crypt_dec_pending(io);
10581056
return;
10591057
}
@@ -1104,12 +1102,16 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
11041102
sector += bio_sectors(clone);
11051103

11061104
crypt_inc_pending(io);
1105+
11071106
r = crypt_convert(cc, &io->ctx);
1107+
if (r < 0)
1108+
io->error = -EIO;
1109+
11081110
crypt_finished = atomic_dec_and_test(&io->ctx.pending);
11091111

11101112
/* Encryption was already finished, submit io now */
11111113
if (crypt_finished) {
1112-
kcryptd_crypt_write_io_submit(io, r, 0);
1114+
kcryptd_crypt_write_io_submit(io, 0);
11131115

11141116
/*
11151117
* If there was an error, do not try next fragments.
@@ -1160,11 +1162,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
11601162
crypt_dec_pending(io);
11611163
}
11621164

1163-
static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error)
1165+
static void kcryptd_crypt_read_done(struct dm_crypt_io *io)
11641166
{
1165-
if (unlikely(error < 0))
1166-
io->error = -EIO;
1167-
11681167
crypt_dec_pending(io);
11691168
}
11701169

@@ -1179,9 +1178,11 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
11791178
io->sector);
11801179

11811180
r = crypt_convert(cc, &io->ctx);
1181+
if (r < 0)
1182+
io->error = -EIO;
11821183

11831184
if (atomic_dec_and_test(&io->ctx.pending))
1184-
kcryptd_crypt_read_done(io, r);
1185+
kcryptd_crypt_read_done(io);
11851186

11861187
crypt_dec_pending(io);
11871188
}
@@ -1202,15 +1203,18 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
12021203
if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post)
12031204
error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq);
12041205

1206+
if (error < 0)
1207+
io->error = -EIO;
1208+
12051209
mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
12061210

12071211
if (!atomic_dec_and_test(&ctx->pending))
12081212
return;
12091213

12101214
if (bio_data_dir(io->base_bio) == READ)
1211-
kcryptd_crypt_read_done(io, error);
1215+
kcryptd_crypt_read_done(io);
12121216
else
1213-
kcryptd_crypt_write_io_submit(io, error, 1);
1217+
kcryptd_crypt_write_io_submit(io, 1);
12141218
}
12151219

12161220
static void kcryptd_crypt(struct work_struct *work)

0 commit comments

Comments
 (0)