+static void kcryptd_do_work(void *data)
+{
+ struct crypt_io *io = (struct crypt_io *) data;
+ struct crypt_config *cc = (struct crypt_config *) io->target->private;
+ struct convert_context ctx;
+ int r;
+
+ crypt_convert_init(cc, &ctx, io->bio, io->bio,
+ io->bio->bi_sector - io->target->begin, 0);
+ r = crypt_convert(cc, &ctx);
+
+ dec_pending(io, r);
+}
+static void kcryptd_queue_io(struct crypt_io *io)
+{
+ /* with the work struct in crypt_io we can only queue whole io's */
+ BUG_ON(atomic_read(&io->pending) != 1);
+
+ INIT_WORK(&io->work, kcryptd_do_work, io);
+ queue_work(_kcryptd_workqueue, &io->work);
+}
+/*
+ * Construct an encryption mapping:
+ * <cipher> <key> <iv_offset> <dev_path> <start>
+ */
+static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+{
+ struct crypt_config *cc;
+ struct crypto_tfm *tfm;
+ char *tmp;
+ char *cipher;
+ char *mode;
+ int crypto_flags;
+ int key_size;
+
+ if (argc != 5) {
+ ti->error = "dm-crypt: Not enough arguments";
+ return -EINVAL;
+ }
+
+ tmp = argv[0];
+ cipher = strsep(&tmp, "-");
+ mode = strsep(&tmp, "-");
+
+ if (tmp)
+ DMWARN("dm-crypt: Unexpected additional cipher options");