]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
If optional discard support in dm-crypt is enabled, discards requests
authorMilan Broz <mbroz@redhat.com>
Tue, 9 Aug 2011 23:13:33 +0000 (09:13 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 9 Aug 2011 23:17:56 +0000 (09:17 +1000)
bypass the crypt queue and blocks of the underlying device are discarded.
For the read path, discarded blocks are handled the same as normal
ciphertext blocks, thus decrypted.

So if the underlying device announces discarded regions return zeroes,
dm-crypt must disable this flag because after decryption there is just
random noise instead of zeroes.

Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
drivers/md/dm-crypt.c
drivers/md/dm-table.c
include/linux/device-mapper.h

index 49da55c1528aa01137a61c98d6033c9b84dc2e05..a9c709f193dc85a23523033174198a3784a75fc9 100644 (file)
@@ -1698,6 +1698,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        }
 
        ti->num_flush_requests = 1;
+       ti->discard_zeroes_data_unsupported = 1;
        return 0;
 
 bad:
index 8b040f5c14f583ef3f4e35b40ba361de33a208dd..509bfe4b02f3f969c03fc6871924c72a7d075248 100644 (file)
@@ -1308,6 +1308,22 @@ static bool dm_table_is_nonrot(struct dm_table *t)
        return 1;
 }
 
+static bool dm_table_discard_zeroes_data(struct dm_table *t)
+{
+       struct dm_target *ti;
+       unsigned i = 0;
+
+       /* Ensure that all targets supports discard_zeroes_data. */
+       while (i < dm_table_get_num_targets(t)) {
+               ti = dm_table_get_target(t, i++);
+
+               if (ti->discard_zeroes_data_unsupported)
+                       return 0;
+       }
+
+       return 1;
+}
+
 void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
                               struct queue_limits *limits)
 {
@@ -1335,6 +1351,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
        else
                queue_flag_clear_unlocked(QUEUE_FLAG_NONROT, q);
 
+       if (!dm_table_discard_zeroes_data(t))
+               q->limits.discard_zeroes_data = 0;
+
        dm_table_set_integrity(t);
 
        /*
index 3fa1f3d90ce0e21cb3ba27fa98d3201252f91f8e..99e3e50b5c571a3cb9448b69891b95796f1f6ddf 100644 (file)
@@ -197,6 +197,11 @@ struct dm_target {
         * whether or not its underlying devices have support.
         */
        unsigned discards_supported:1;
+
+       /*
+        * Set if this target does not return zeroes on discarded blocks.
+        */
+       unsigned discard_zeroes_data_unsupported:1;
 };
 
 /* Each target can link one of these into the table */