]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Merge tag 'for-5.6/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Mar 2020 19:02:45 +0000 (13:02 -0600)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Mar 2020 19:02:45 +0000 (13:02 -0600)
Pull device mapper fixes from Mike Snitzer:

 - Fix request-based DM's congestion_fn and actually wire it up to the
   bdi.

 - Extend dm-bio-record to track additional struct bio members needed by
   DM integrity target.

 - Fix DM core to properly advertise that a device is suspended during
   unload (between the presuspend and postsuspend hooks). This change is
   a prereq for related DM integrity and DM writecache fixes. It
   elevates DM integrity's 'suspending' state tracking to DM core.

 - Four stable fixes for DM integrity target.

 - Fix crash in DM cache target due to incorrect work item cancelling.

 - Fix DM thin metadata lockdep warning that was introduced during 5.6
   merge window.

 - Fix DM zoned target's chunk work refcounting that regressed during
   recent conversion to refcount_t.

 - Bump the minor version for DM core and all target versions that have
   seen interface changes or important fixes during the 5.6 cycle.

* tag 'for-5.6/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm: bump version of core and various targets
  dm: fix congested_fn for request-based device
  dm integrity: use dm_bio_record and dm_bio_restore
  dm bio record: save/restore bi_end_io and bi_integrity
  dm zoned: Fix reference counter initial value of chunk works
  dm writecache: verify watermark during resume
  dm: report suspended device during destroy
  dm thin metadata: fix lockdep complaint
  dm cache: fix a crash due to incorrect work item cancelling
  dm integrity: fix invalid table returned due to argument count mismatch
  dm integrity: fix a deadlock due to offloading to an incorrect workqueue
  dm integrity: fix recalculation when moving from journal mode to bitmap mode

drivers/md/dm-bio-record.h
drivers/md/dm-cache-target.c
drivers/md/dm-integrity.c
drivers/md/dm-mpath.c
drivers/md/dm-thin-metadata.c
drivers/md/dm-verity-target.c
drivers/md/dm-writecache.c
drivers/md/dm-zoned-target.c
drivers/md/dm.c
include/uapi/linux/dm-ioctl.h

index c82578af56a5bbff035a272f258327a7fce6ecfd..2ea0360108e1d41b57a39b5c5df715c52a641442 100644 (file)
 struct dm_bio_details {
        struct gendisk *bi_disk;
        u8 bi_partno;
+       int __bi_remaining;
        unsigned long bi_flags;
        struct bvec_iter bi_iter;
+       bio_end_io_t *bi_end_io;
+#if defined(CONFIG_BLK_DEV_INTEGRITY)
+       struct bio_integrity_payload *bi_integrity;
+#endif
 };
 
 static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
@@ -30,6 +35,11 @@ static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
        bd->bi_partno = bio->bi_partno;
        bd->bi_flags = bio->bi_flags;
        bd->bi_iter = bio->bi_iter;
+       bd->__bi_remaining = atomic_read(&bio->__bi_remaining);
+       bd->bi_end_io = bio->bi_end_io;
+#if defined(CONFIG_BLK_DEV_INTEGRITY)
+       bd->bi_integrity = bio_integrity(bio);
+#endif
 }
 
 static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
@@ -38,6 +48,11 @@ static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
        bio->bi_partno = bd->bi_partno;
        bio->bi_flags = bd->bi_flags;
        bio->bi_iter = bd->bi_iter;
+       atomic_set(&bio->__bi_remaining, bd->__bi_remaining);
+       bio->bi_end_io = bd->bi_end_io;
+#if defined(CONFIG_BLK_DEV_INTEGRITY)
+       bio->bi_integrity = bd->bi_integrity;
+#endif
 }
 
 #endif
index 2d32821b3a5b8fdac87c54a7778b635fd62f8c7d..d3bb355819a421fbdda41cb5880321d248d29699 100644 (file)
@@ -2846,8 +2846,8 @@ static void cache_postsuspend(struct dm_target *ti)
        prevent_background_work(cache);
        BUG_ON(atomic_read(&cache->nr_io_migrations));
 
-       cancel_delayed_work(&cache->waker);
-       flush_workqueue(cache->wq);
+       cancel_delayed_work_sync(&cache->waker);
+       drain_workqueue(cache->wq);
        WARN_ON(cache->tracker.in_flight);
 
        /*
@@ -3492,7 +3492,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
 static struct target_type cache_target = {
        .name = "cache",
-       .version = {2, 1, 0},
+       .version = {2, 2, 0},
        .module = THIS_MODULE,
        .ctr = cache_ctr,
        .dtr = cache_dtr,
index b225b3e445fa43aa57c51828f7f6bea09351fb0c..2f03fecd312d8b4c8995c7fe275a6d5fac76045b 100644 (file)
@@ -6,6 +6,8 @@
  * This file is released under the GPL.
  */
 
+#include "dm-bio-record.h"
+
 #include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/device-mapper.h>
@@ -201,17 +203,19 @@ struct dm_integrity_c {
        __u8 log2_blocks_per_bitmap_bit;
 
        unsigned char mode;
-       int suspending;
 
        int failed;
 
        struct crypto_shash *internal_hash;
 
+       struct dm_target *ti;
+
        /* these variables are locked with endio_wait.lock */
        struct rb_root in_progress;
        struct list_head wait_list;
        wait_queue_head_t endio_wait;
        struct workqueue_struct *wait_wq;
+       struct workqueue_struct *offload_wq;
 
        unsigned char commit_seq;
        commit_id_t commit_ids[N_COMMIT_IDS];
@@ -293,11 +297,7 @@ struct dm_integrity_io {
 
        struct completion *completion;
 
-       struct gendisk *orig_bi_disk;
-       u8 orig_bi_partno;
-       bio_end_io_t *orig_bi_end_io;
-       struct bio_integrity_payload *orig_bi_integrity;
-       struct bvec_iter orig_bi_iter;
+       struct dm_bio_details bio_details;
 };
 
 struct journal_completion {
@@ -1439,7 +1439,7 @@ static void dec_in_flight(struct dm_integrity_io *dio)
                        dio->range.logical_sector += dio->range.n_sectors;
                        bio_advance(bio, dio->range.n_sectors << SECTOR_SHIFT);
                        INIT_WORK(&dio->work, integrity_bio_wait);
-                       queue_work(ic->wait_wq, &dio->work);
+                       queue_work(ic->offload_wq, &dio->work);
                        return;
                }
                do_endio_flush(ic, dio);
@@ -1450,14 +1450,9 @@ static void integrity_end_io(struct bio *bio)
 {
        struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io));
 
-       bio->bi_iter = dio->orig_bi_iter;
-       bio->bi_disk = dio->orig_bi_disk;
-       bio->bi_partno = dio->orig_bi_partno;
-       if (dio->orig_bi_integrity) {
-               bio->bi_integrity = dio->orig_bi_integrity;
+       dm_bio_restore(&dio->bio_details, bio);
+       if (bio->bi_integrity)
                bio->bi_opf |= REQ_INTEGRITY;
-       }
-       bio->bi_end_io = dio->orig_bi_end_io;
 
        if (dio->completion)
                complete(dio->completion);
@@ -1542,7 +1537,7 @@ static void integrity_metadata(struct work_struct *w)
                        }
                }
 
-               __bio_for_each_segment(bv, bio, iter, dio->orig_bi_iter) {
+               __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) {
                        unsigned pos;
                        char *mem, *checksums_ptr;
 
@@ -1586,7 +1581,7 @@ again:
                if (likely(checksums != checksums_onstack))
                        kfree(checksums);
        } else {
-               struct bio_integrity_payload *bip = dio->orig_bi_integrity;
+               struct bio_integrity_payload *bip = dio->bio_details.bi_integrity;
 
                if (bip) {
                        struct bio_vec biv;
@@ -1865,7 +1860,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map
 
        if (need_sync_io && from_map) {
                INIT_WORK(&dio->work, integrity_bio_wait);
-               queue_work(ic->metadata_wq, &dio->work);
+               queue_work(ic->offload_wq, &dio->work);
                return;
        }
 
@@ -2005,20 +2000,13 @@ offload_to_thread:
        } else
                dio->completion = NULL;
 
-       dio->orig_bi_iter = bio->bi_iter;
-
-       dio->orig_bi_disk = bio->bi_disk;
-       dio->orig_bi_partno = bio->bi_partno;
+       dm_bio_record(&dio->bio_details, bio);
        bio_set_dev(bio, ic->dev->bdev);
-
-       dio->orig_bi_integrity = bio_integrity(bio);
        bio->bi_integrity = NULL;
        bio->bi_opf &= ~REQ_INTEGRITY;
-
-       dio->orig_bi_end_io = bio->bi_end_io;
        bio->bi_end_io = integrity_end_io;
-
        bio->bi_iter.bi_size = dio->range.n_sectors << SECTOR_SHIFT;
+
        generic_make_request(bio);
 
        if (need_sync_io) {
@@ -2315,7 +2303,7 @@ static void integrity_writer(struct work_struct *w)
        unsigned prev_free_sectors;
 
        /* the following test is not needed, but it tests the replay code */
-       if (READ_ONCE(ic->suspending) && !ic->meta_dev)
+       if (unlikely(dm_suspended(ic->ti)) && !ic->meta_dev)
                return;
 
        spin_lock_irq(&ic->endio_wait.lock);
@@ -2376,7 +2364,7 @@ static void integrity_recalc(struct work_struct *w)
 
 next_chunk:
 
-       if (unlikely(READ_ONCE(ic->suspending)))
+       if (unlikely(dm_suspended(ic->ti)))
                goto unlock_ret;
 
        range.logical_sector = le64_to_cpu(ic->sb->recalc_sector);
@@ -2501,7 +2489,7 @@ static void bitmap_block_work(struct work_struct *w)
                                    dio->range.n_sectors, BITMAP_OP_TEST_ALL_SET)) {
                        remove_range(ic, &dio->range);
                        INIT_WORK(&dio->work, integrity_bio_wait);
-                       queue_work(ic->wait_wq, &dio->work);
+                       queue_work(ic->offload_wq, &dio->work);
                } else {
                        block_bitmap_op(ic, ic->journal, dio->range.logical_sector,
                                        dio->range.n_sectors, BITMAP_OP_SET);
@@ -2524,7 +2512,7 @@ static void bitmap_block_work(struct work_struct *w)
 
                remove_range(ic, &dio->range);
                INIT_WORK(&dio->work, integrity_bio_wait);
-               queue_work(ic->wait_wq, &dio->work);
+               queue_work(ic->offload_wq, &dio->work);
        }
 
        queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, ic->bitmap_flush_interval);
@@ -2804,8 +2792,6 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
 
        del_timer_sync(&ic->autocommit_timer);
 
-       WRITE_ONCE(ic->suspending, 1);
-
        if (ic->recalc_wq)
                drain_workqueue(ic->recalc_wq);
 
@@ -2834,8 +2820,6 @@ static void dm_integrity_postsuspend(struct dm_target *ti)
 #endif
        }
 
-       WRITE_ONCE(ic->suspending, 0);
-
        BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress));
 
        ic->journal_uptodate = true;
@@ -2888,17 +2872,24 @@ static void dm_integrity_resume(struct dm_target *ti)
        } else {
                replay_journal(ic);
                if (ic->mode == 'B') {
-                       int mode;
                        ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP);
                        ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit;
                        r = sync_rw_sb(ic, REQ_OP_WRITE, REQ_FUA);
                        if (unlikely(r))
                                dm_integrity_io_error(ic, "writing superblock", r);
 
-                       mode = ic->recalculate_flag ? BITMAP_OP_SET : BITMAP_OP_CLEAR;
-                       block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, mode);
-                       block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, mode);
-                       block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, mode);
+                       block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
+                       block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
+                       block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR);
+                       if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
+                           le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors) {
+                               block_bitmap_op(ic, ic->journal, le64_to_cpu(ic->sb->recalc_sector),
+                                               ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET);
+                               block_bitmap_op(ic, ic->recalc_bitmap, le64_to_cpu(ic->sb->recalc_sector),
+                                               ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET);
+                               block_bitmap_op(ic, ic->may_write_bitmap, le64_to_cpu(ic->sb->recalc_sector),
+                                               ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET);
+                       }
                        rw_journal_sectors(ic, REQ_OP_WRITE, REQ_FUA | REQ_SYNC, 0,
                                           ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL);
                }
@@ -2967,7 +2958,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type,
                        DMEMIT(" meta_device:%s", ic->meta_dev->name);
                if (ic->sectors_per_block != 1)
                        DMEMIT(" block_size:%u", ic->sectors_per_block << SECTOR_SHIFT);
-               if (ic->recalculate_flag)
+               if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING))
                        DMEMIT(" recalculate");
                DMEMIT(" journal_sectors:%u", ic->initial_sectors - SB_SECTORS);
                DMEMIT(" interleave_sectors:%u", 1U << ic->sb->log2_interleave_sectors);
@@ -3623,6 +3614,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        }
        ti->private = ic;
        ti->per_io_data_size = sizeof(struct dm_integrity_io);
+       ic->ti = ti;
 
        ic->in_progress = RB_ROOT;
        INIT_LIST_HEAD(&ic->wait_list);
@@ -3836,6 +3828,14 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
                goto bad;
        }
 
+       ic->offload_wq = alloc_workqueue("dm-integrity-offload", WQ_MEM_RECLAIM,
+                                         METADATA_WORKQUEUE_MAX_ACTIVE);
+       if (!ic->offload_wq) {
+               ti->error = "Cannot allocate workqueue";
+               r = -ENOMEM;
+               goto bad;
+       }
+
        ic->commit_wq = alloc_workqueue("dm-integrity-commit", WQ_MEM_RECLAIM, 1);
        if (!ic->commit_wq) {
                ti->error = "Cannot allocate workqueue";
@@ -4140,6 +4140,8 @@ static void dm_integrity_dtr(struct dm_target *ti)
                destroy_workqueue(ic->metadata_wq);
        if (ic->wait_wq)
                destroy_workqueue(ic->wait_wq);
+       if (ic->offload_wq)
+               destroy_workqueue(ic->offload_wq);
        if (ic->commit_wq)
                destroy_workqueue(ic->commit_wq);
        if (ic->writer_wq)
@@ -4200,7 +4202,7 @@ static void dm_integrity_dtr(struct dm_target *ti)
 
 static struct target_type integrity_target = {
        .name                   = "integrity",
-       .version                = {1, 4, 0},
+       .version                = {1, 5, 0},
        .module                 = THIS_MODULE,
        .features               = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY,
        .ctr                    = dm_integrity_ctr,
index 2bc18c9c3abcfc60e0763976704c878aea7fd13f..58fd137b6ae1a041c8503a62bef175a27a70ff16 100644 (file)
@@ -2053,7 +2053,7 @@ static int multipath_busy(struct dm_target *ti)
  *---------------------------------------------------------------*/
 static struct target_type multipath_target = {
        .name = "multipath",
-       .version = {1, 13, 0},
+       .version = {1, 14, 0},
        .features = DM_TARGET_SINGLETON | DM_TARGET_IMMUTABLE |
                    DM_TARGET_PASSES_INTEGRITY,
        .module = THIS_MODULE,
index fc9947d6210c202273d2c44a3198e88429530e76..76b6b323bf4bd560f1b83eead235ffcaf373ad86 100644 (file)
@@ -960,9 +960,9 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd)
                        DMWARN("%s: __commit_transaction() failed, error = %d",
                               __func__, r);
        }
+       pmd_write_unlock(pmd);
        if (!pmd->fail_io)
                __destroy_persistent_data_objects(pmd);
-       pmd_write_unlock(pmd);
 
        kfree(pmd);
        return 0;
index 0d61e9c6798650bc46bc34aa98b29564fe21d9c9..eec9f252e9354bd8746e3f647ff1b1e8eb610aef 100644 (file)
@@ -1221,7 +1221,7 @@ bad:
 
 static struct target_type verity_target = {
        .name           = "verity",
-       .version        = {1, 5, 0},
+       .version        = {1, 6, 0},
        .module         = THIS_MODULE,
        .ctr            = verity_ctr,
        .dtr            = verity_dtr,
index b9e27e37a94373c1cbc8ca52f3b64c0d72d46228..a09bdc000e6462738be71b70686d2a0d67ab3009 100644 (file)
@@ -625,6 +625,12 @@ static void writecache_add_to_freelist(struct dm_writecache *wc, struct wc_entry
        wc->freelist_size++;
 }
 
+static inline void writecache_verify_watermark(struct dm_writecache *wc)
+{
+       if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark))
+               queue_work(wc->writeback_wq, &wc->writeback_work);
+}
+
 static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc, sector_t expected_sector)
 {
        struct wc_entry *e;
@@ -650,8 +656,8 @@ static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc, s
                list_del(&e->lru);
        }
        wc->freelist_size--;
-       if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark))
-               queue_work(wc->writeback_wq, &wc->writeback_work);
+
+       writecache_verify_watermark(wc);
 
        return e;
 }
@@ -842,7 +848,7 @@ static void writecache_suspend(struct dm_target *ti)
        }
        wc_unlock(wc);
 
-       flush_workqueue(wc->writeback_wq);
+       drain_workqueue(wc->writeback_wq);
 
        wc_lock(wc);
        if (flush_on_suspend)
@@ -965,6 +971,8 @@ erase_this:
                writecache_commit_flushed(wc, false);
        }
 
+       writecache_verify_watermark(wc);
+
        wc_unlock(wc);
 }
 
@@ -2312,7 +2320,7 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
 
 static struct target_type writecache_target = {
        .name                   = "writecache",
-       .version                = {1, 1, 1},
+       .version                = {1, 2, 0},
        .module                 = THIS_MODULE,
        .ctr                    = writecache_ctr,
        .dtr                    = writecache_dtr,
index 70a1063161c04aef304eb3e008c0842f0ccf5e62..f4f83d39b3dcf03d2736fa762ded17160e0e56a2 100644 (file)
@@ -533,8 +533,9 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio)
 
        /* Get the BIO chunk work. If one is not active yet, create one */
        cw = radix_tree_lookup(&dmz->chunk_rxtree, chunk);
-       if (!cw) {
-
+       if (cw) {
+               dmz_get_chunk_work(cw);
+       } else {
                /* Create a new chunk work */
                cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOIO);
                if (unlikely(!cw)) {
@@ -543,7 +544,7 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio)
                }
 
                INIT_WORK(&cw->work, dmz_chunk_work);
-               refcount_set(&cw->refcount, 0);
+               refcount_set(&cw->refcount, 1);
                cw->target = dmz;
                cw->chunk = chunk;
                bio_list_init(&cw->bio_list);
@@ -556,7 +557,6 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio)
        }
 
        bio_list_add(&cw->bio_list, bio);
-       dmz_get_chunk_work(cw);
 
        dmz_reclaim_bio_acc(dmz->reclaim);
        if (queue_work(dmz->chunk_wq, &cw->work))
@@ -967,7 +967,7 @@ static int dmz_iterate_devices(struct dm_target *ti,
 
 static struct target_type dmz_type = {
        .name            = "zoned",
-       .version         = {1, 0, 0},
+       .version         = {1, 1, 0},
        .features        = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM,
        .module          = THIS_MODULE,
        .ctr             = dmz_ctr,
index b89f07ee2efff2c19207f2b820011af901e3a3cb..0413018c83058f0907795484064e4373d8775215 100644 (file)
@@ -1788,7 +1788,8 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
                         * With request-based DM we only need to check the
                         * top-level queue for congestion.
                         */
-                       r = md->queue->backing_dev_info->wb.state & bdi_bits;
+                       struct backing_dev_info *bdi = md->queue->backing_dev_info;
+                       r = bdi->wb.congested->state & bdi_bits;
                } else {
                        map = dm_get_live_table_fast(md);
                        if (map)
@@ -1854,15 +1855,6 @@ static const struct dax_operations dm_dax_ops;
 
 static void dm_wq_work(struct work_struct *work);
 
-static void dm_init_normal_md_queue(struct mapped_device *md)
-{
-       /*
-        * Initialize aspects of queue that aren't relevant for blk-mq
-        */
-       md->queue->backing_dev_info->congested_data = md;
-       md->queue->backing_dev_info->congested_fn = dm_any_congested;
-}
-
 static void cleanup_mapped_device(struct mapped_device *md)
 {
        if (md->wq)
@@ -2249,6 +2241,12 @@ struct queue_limits *dm_get_queue_limits(struct mapped_device *md)
 }
 EXPORT_SYMBOL_GPL(dm_get_queue_limits);
 
+static void dm_init_congested_fn(struct mapped_device *md)
+{
+       md->queue->backing_dev_info->congested_data = md;
+       md->queue->backing_dev_info->congested_fn = dm_any_congested;
+}
+
 /*
  * Setup the DM device's queue based on md's type
  */
@@ -2265,11 +2263,12 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
                        DMERR("Cannot initialize queue for request-based dm-mq mapped device");
                        return r;
                }
+               dm_init_congested_fn(md);
                break;
        case DM_TYPE_BIO_BASED:
        case DM_TYPE_DAX_BIO_BASED:
        case DM_TYPE_NVME_BIO_BASED:
-               dm_init_normal_md_queue(md);
+               dm_init_congested_fn(md);
                break;
        case DM_TYPE_NONE:
                WARN_ON_ONCE(true);
@@ -2368,6 +2367,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
        map = dm_get_live_table(md, &srcu_idx);
        if (!dm_suspended_md(md)) {
                dm_table_presuspend_targets(map);
+               set_bit(DMF_SUSPENDED, &md->flags);
                dm_table_postsuspend_targets(map);
        }
        /* dm_put_live_table must be before msleep, otherwise deadlock is possible */
index 2df8ceca1f9b8479ff0537d421baec643a7de2cc..6622912c2342edc0acf9a55f8a1affa2f12a4763 100644 (file)
@@ -272,9 +272,9 @@ enum {
 #define DM_DEV_SET_GEOMETRY    _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
 
 #define DM_VERSION_MAJOR       4
-#define DM_VERSION_MINOR       41
+#define DM_VERSION_MINOR       42
 #define DM_VERSION_PATCHLEVEL  0
-#define DM_VERSION_EXTRA       "-ioctl (2019-09-16)"
+#define DM_VERSION_EXTRA       "-ioctl (2020-02-27)"
 
 /* Status bits */
 #define DM_READONLY_FLAG       (1 << 0) /* In/Out */