]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Add a num_write_bios function to struct target.
authorAlasdair G Kergon <agk@redhat.com>
Sun, 17 Feb 2013 23:03:35 +0000 (10:03 +1100)
committerStephen Rothwell <sfr@canb.auug.org.au>
Sun, 17 Feb 2013 23:04:52 +0000 (10:04 +1100)
If an instance of a target sets this, it will be queried before the
target's mapping function is called on a write bio, and the response
controls the number of copies of the write bio that the target will
receive.

This provides a convenient way for a target to send the same data to
more than one device.  The new cache target uses this in writethrough
mode, to send the data both to the cache and the backing device.

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

index add7654181a72011be869d8c7ccb52f033f8e014..7b0e9940bbff6399824ddea85bff10ab02c03610 100644 (file)
@@ -1169,15 +1169,23 @@ static void __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti
 {
        struct bio *bio = ci->bio;
        struct dm_target_io *tio;
+       unsigned target_bio_nr;
+       unsigned num_target_bios = 1;
 
-       tio = alloc_tio(ci, ti, nr_iovecs, 0);
-
-       if (split_bvec)
-               clone_split_bio(tio, bio, sector, idx, offset, len);
-       else
-               clone_bio(tio, bio, sector, idx, bv_count, len);
+       /*
+        * Does the target want to receive duplicate copies of the bio?
+        */
+       if (bio_data_dir(bio) == WRITE && ti->num_write_bios)
+               num_target_bios = ti->num_write_bios(ti, bio);
 
-       __map_bio(tio);
+       for (target_bio_nr = 0; target_bio_nr < num_target_bios; target_bio_nr++) {
+               tio = alloc_tio(ci, ti, nr_iovecs, target_bio_nr);
+               if (split_bvec)
+                       clone_split_bio(tio, bio, sector, idx, offset, len);
+               else
+                       clone_bio(tio, bio, sector, idx, bv_count, len);
+               __map_bio(tio);
+       }
 }
 
 typedef unsigned (*get_num_bios_fn)(struct dm_target *ti);
index 0d6116f84e0a0753cd7ae44402531aafba89f3c4..fadca426cb1f9568350c0d9daf80dbd70fb4afb5 100644 (file)
@@ -175,6 +175,14 @@ struct target_type {
 #define DM_TARGET_IMMUTABLE            0x00000004
 #define dm_target_is_immutable(type)   ((type)->features & DM_TARGET_IMMUTABLE)
 
+/*
+ * Some targets need to be sent the same WRITE bio severals times so
+ * that they can send copies of it to different devices.  This function
+ * examines any supplied bio and returns the number of copies of it the
+ * target requires.
+ */
+typedef unsigned (*dm_num_write_bios_fn) (struct dm_target *ti, struct bio *bio);
+
 struct dm_target {
        struct dm_table *table;
        struct target_type *type;
@@ -214,6 +222,13 @@ struct dm_target {
         */
        unsigned per_bio_data_size;
 
+       /*
+        * If defined, this function is called to find out how many
+        * duplicate bios should be sent to the target when writing
+        * data.
+        */
+       dm_num_write_bios_fn num_write_bios;
+
        /* target specific data */
        void *private;