Enabling support for FLUSH and FUA flags
authorvenkat <venkat@fsl.cs.sunysb.edu>
Wed, 21 Dec 2016 23:09:03 +0000 (18:09 -0500)
committervenkat <venkat@fsl.cs.sunysb.edu>
Wed, 21 Dec 2016 23:25:07 +0000 (18:25 -0500)
In order device-mapper target to support FLUSH and FUA requests
one has to set flush_supported flag on the target instance.
This commit does it.

Then dmdedup needs to flush underlying data and metadata devices
when FLUSH and FUA flags are set on a request. This was already done
by the previous code. However, sometimes we see empty write
requests the sole goal of which is to flush the data. This patch
handles this scenario correctly.

drivers/md/dm-dedup-target.c

index 202375fa52026fa140bbbf55db779cfe635280bd..95adbcc7388cdc99b9810f734366a521f852a507 100644 (file)
@@ -60,6 +60,12 @@ static uint64_t bio_lbn(struct dedup_config *dc, struct bio *bio)
        return lbn;
 }
 
+static void do_io_remap_device(struct dedup_config *dc, struct bio *bio)
+{
+       bio->bi_bdev = dc->data_dev->bdev;
+       generic_make_request(bio);
+}
+
 static void do_io(struct dedup_config *dc, struct bio *bio, uint64_t pbn)
 {
        int offset;
@@ -67,9 +73,7 @@ static void do_io(struct dedup_config *dc, struct bio *bio, uint64_t pbn)
        offset = sector_div(bio->bi_iter.bi_sector, dc->sectors_per_block);
        bio->bi_iter.bi_sector = (sector_t)pbn * dc->sectors_per_block + offset;
 
-       bio->bi_bdev = dc->data_dev->bdev;
-
-       generic_make_request(bio);
+       do_io_remap_device(dc, bio);
 }
 
 static int handle_read(struct dedup_config *dc, struct bio *bio)
@@ -369,6 +373,14 @@ static void process_bio(struct dedup_config *dc, struct bio *bio)
 {
        int r;
 
+       if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) && !bio_sectors(bio)) {
+               r = dc->mdops->flush_meta(dc->bmd);
+               if (r == 0)
+                       dc->writes_after_flush = 0;
+               do_io_remap_device(dc, bio);
+               return;
+       }
+
        switch (bio_data_dir(bio)) {
        case READ:
                r = handle_read(dc, bio);
@@ -750,6 +762,9 @@ static int dm_dedup_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        if (r)
                goto bad_kvstore_init;
 
+       ti->num_flush_bios = 1;
+       ti->flush_supported = true;
+
        ti->private = dc;
 
        return 0;