aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2012-03-28 13:41:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-02 12:27:19 -0400
commit94b1a66ccfb495935057de978ef4a6fc22de85d8 (patch)
treec3d3f87cb00e44bd79bd2f761a7832c9d6c35f85 /drivers/md
parent48d068c8d59686d228c8154d0781ed5e48361109 (diff)
dm crypt: add missing error handling
commit 72c6e7afc43e19f68a31dea204fc366624d6eee9 upstream. 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> Reviewed-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-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 adedca602bc..6f906bc9328 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1045,16 +1045,14 @@ static void kcryptd_queue_io(struct dm_crypt_io *io)
1045 queue_work(cc->io_queue, &io->work); 1045 queue_work(cc->io_queue, &io->work);
1046} 1046}
1047 1047
1048static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, 1048static void kcryptd_crypt_write_io_submit(struct dm_crypt_io *io, int async)
1049 int error, int async)
1050{ 1049{
1051 struct bio *clone = io->ctx.bio_out; 1050 struct bio *clone = io->ctx.bio_out;
1052 struct crypt_config *cc = io->target->private; 1051 struct crypt_config *cc = io->target->private;
1053 1052
1054 if (unlikely(error < 0)) { 1053 if (unlikely(io->error < 0)) {
1055 crypt_free_buffer_pages(cc, clone); 1054 crypt_free_buffer_pages(cc, clone);
1056 bio_put(clone); 1055 bio_put(clone);
1057 io->error = -EIO;
1058 crypt_dec_pending(io); 1056 crypt_dec_pending(io);
1059 return; 1057 return;
1060 } 1058 }
@@ -1105,12 +1103,16 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
1105 sector += bio_sectors(clone); 1103 sector += bio_sectors(clone);
1106 1104
1107 crypt_inc_pending(io); 1105 crypt_inc_pending(io);
1106
1108 r = crypt_convert(cc, &io->ctx); 1107 r = crypt_convert(cc, &io->ctx);
1108 if (r < 0)
1109 io->error = -EIO;
1110
1109 crypt_finished = atomic_dec_and_test(&io->ctx.pending); 1111 crypt_finished = atomic_dec_and_test(&io->ctx.pending);
1110 1112
1111 /* Encryption was already finished, submit io now */ 1113 /* Encryption was already finished, submit io now */
1112 if (crypt_finished) { 1114 if (crypt_finished) {
1113 kcryptd_crypt_write_io_submit(io, r, 0); 1115 kcryptd_crypt_write_io_submit(io, 0);
1114 1116
1115 /* 1117 /*
1116 * If there was an error, do not try next fragments. 1118 * If there was an error, do not try next fragments.
@@ -1161,11 +1163,8 @@ static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
1161 crypt_dec_pending(io); 1163 crypt_dec_pending(io);
1162} 1164}
1163 1165
1164static void kcryptd_crypt_read_done(struct dm_crypt_io *io, int error) 1166static void kcryptd_crypt_read_done(struct dm_crypt_io *io)
1165{ 1167{
1166 if (unlikely(error < 0))
1167 io->error = -EIO;
1168
1169 crypt_dec_pending(io); 1168 crypt_dec_pending(io);
1170} 1169}
1171 1170
@@ -1180,9 +1179,11 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
1180 io->sector); 1179 io->sector);
1181 1180
1182 r = crypt_convert(cc, &io->ctx); 1181 r = crypt_convert(cc, &io->ctx);
1182 if (r < 0)
1183 io->error = -EIO;
1183 1184
1184 if (atomic_dec_and_test(&io->ctx.pending)) 1185 if (atomic_dec_and_test(&io->ctx.pending))
1185 kcryptd_crypt_read_done(io, r); 1186 kcryptd_crypt_read_done(io);
1186 1187
1187 crypt_dec_pending(io); 1188 crypt_dec_pending(io);
1188} 1189}
@@ -1203,15 +1204,18 @@ static void kcryptd_async_done(struct crypto_async_request *async_req,
1203 if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post) 1204 if (!error && cc->iv_gen_ops && cc->iv_gen_ops->post)
1204 error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq); 1205 error = cc->iv_gen_ops->post(cc, iv_of_dmreq(cc, dmreq), dmreq);
1205 1206
1207 if (error < 0)
1208 io->error = -EIO;
1209
1206 mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool); 1210 mempool_free(req_of_dmreq(cc, dmreq), cc->req_pool);
1207 1211
1208 if (!atomic_dec_and_test(&ctx->pending)) 1212 if (!atomic_dec_and_test(&ctx->pending))
1209 return; 1213 return;
1210 1214
1211 if (bio_data_dir(io->base_bio) == READ) 1215 if (bio_data_dir(io->base_bio) == READ)
1212 kcryptd_crypt_read_done(io, error); 1216 kcryptd_crypt_read_done(io);
1213 else 1217 else
1214 kcryptd_crypt_write_io_submit(io, error, 1); 1218 kcryptd_crypt_write_io_submit(io, 1);
1215} 1219}
1216 1220
1217static void kcryptd_crypt(struct work_struct *work) 1221static void kcryptd_crypt(struct work_struct *work)