aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2012-03-28 13:41:22 -0400
committerAlasdair G Kergon <agk@redhat.com>2012-03-28 13:41:22 -0400
commit72c6e7afc43e19f68a31dea204fc366624d6eee9 (patch)
tree888dfad9bcbcff78cf707e63b3c4389b589b8c4d
parentaeb2deae2660a1773c83d3c6e9e6575daa3855d6 (diff)
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 <mpatocka@redhat.com> Cc: stable@kernel.org Reviewed-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r--drivers/md/dm-crypt.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 6c83ad901770..87de0d6b49f2 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1044,16 +1044,14 @@ static void kcryptd_queue_io(struct dm_crypt_io *io)
1044 queue_work(cc->io_queue, &io->work); 1044 queue_work(cc->io_queue, &io->work);
1045} 1045}
1046 1046
1047static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, 1047static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
1048 int error, int async)
1049{ 1048{
1050 struct bio *clone = io->ctx.bio_out; 1049 struct bio *clone = io->ctx.bio_out;
1051 struct crypt_config *cc = io->target->private; 1050 struct crypt_config *cc = io->target->private;
1052 1051
1053 if (unlikely(error < 0)) { 1052 if (unlikely(io->error < 0)) {
1054 crypt_free_buffer_pages(cc, clone); 1053 crypt_free_buffer_pages(cc, clone);
1055 bio_put(clone); 1054 bio_put(clone);
1056 io->error = -EIO;
1057 crypt_dec_pending(io); 1055 crypt_dec_pending(io);
1058 return; 1056 return;
1059 } 1057 }
@@ -1104,12 +1102,16 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
1104 sector += bio_sectors(clone); 1102 sector += bio_sectors(clone);
1105 1103
1106 crypt_inc_pending(io); 1104 crypt_inc_pending(io);
1105
1107 r = crypt_convert(cc, &io->ctx); 1106 r = crypt_convert(cc, &io->ctx);
1107 if (r < 0)
1108 io->error = -EIO;
1109
1108 crypt_finished = atomic_dec_and_test(&io->ctx.pending); 1110 crypt_finished = atomic_dec_and_test(&io->ctx.pending);
1109 1111
1110 /* Encryption was already finished, submit io now */ 1112 /* Encryption was already finished, submit io now */
1111 if (crypt_finished) { 1113 if (crypt_finished) {
1112 kcryptd_crypt_write_io_submit(io, r, 0); 1114 kcryptd_crypt_write_io_submit(io, 0);
1113 1115
1114 /* 1116 /*
1115 * If there was an error, do not try next fragments. 1117 * 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)
1160 crypt_dec_pending(io); 1162 crypt_dec_pending(io);
1161} 1163}
1162 1164
1163static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error) 1165static void kcryptd_crypt_read_done(struct dm_crypt_io *io)
1164{ 1166{
1165 if (unlikely(error < 0))
1166 io->error = -EIO;
1167
1168 crypt_dec_pending(io); 1167 crypt_dec_pending(io);
1169} 1168}
1170 1169
@@ -1179,9 +1178,11 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
1179 io->sector); 1178 io->sector);
1180 1179
1181 r = crypt_convert(cc, &io->ctx); 1180 r = crypt_convert(cc, &io->ctx);
1181 if (r < 0)
1182 io->error = -EIO;
1182 1183
1183 if (atomic_dec_and_test(&io->ctx.pending)) 1184 if (atomic_dec_and_test(&io->ctx.pending))
1184 kcryptd_crypt_read_done(io, r); 1185 kcryptd_crypt_read_done(io);
1185 1186
1186 crypt_dec_pending(io); 1187 crypt_dec_pending(io);
1187} 1188}
@@ -1202,15 +1203,18 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
1202 if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) 1203 if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post)
1203 error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq); 1204 error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq);
1204 1205
1206 if (error < 0)
1207 io->error = -EIO;
1208
1205 mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); 1209 mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
1206 1210
1207 if (!atomic_dec_and_test(&ctx->pending)) 1211 if (!atomic_dec_and_test(&ctx->pending))
1208 return; 1212 return;
1209 1213
1210 if (bio_data_dir(io->base_bio) == READ) 1214 if (bio_data_dir(io->base_bio) == READ)
1211 kcryptd_crypt_read_done(io, error); 1215 kcryptd_crypt_read_done(io);
1212 else 1216 else
1213 kcryptd_crypt_write_io_submit(io, error, 1); 1217 kcryptd_crypt_write_io_submit(io, 1);
1214} 1218}
1215 1219
1216static void kcryptd_crypt(struct work_struct *work) 1220static void kcryptd_crypt(struct work_struct *work)