diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 8980f129b31f47c8310eacf04357b968066bfcb2..31b6cc71ee96e44af2756a99ed4e2191a7149f7a 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -503,11 +503,9 @@ static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx, struct dm_table *map; map = dm_get_live_table(md, &srcu_idx); - if (!map) { - DMERR_LIMIT("%s: mapping table unavailable, erroring io", - dm_device_name(md)); + if (unlikely(!map)) { dm_put_live_table(md, srcu_idx); - return BLK_STS_IOERR; + return BLK_STS_RESOURCE; } ti = dm_table_find_target(map, 0); dm_put_live_table(md, srcu_idx); diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0c9ce43f3b53e799de8434bb754ed254020cd0a4..06318a0efc67e2267a955a6f64004e8c6f7edcdd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1684,15 +1684,10 @@ static blk_qc_t dm_submit_bio(struct bio *bio) struct dm_table *map; map = dm_get_live_table(md, &srcu_idx); - if (unlikely(!map)) { - DMERR_LIMIT("%s: mapping table unavailable, erroring io", - dm_device_name(md)); - bio_io_error(bio); - goto out; - } - /* If suspended, queue this IO for later */ - if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) { + /* If suspended, or map not yet available, queue this IO for later */ + if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || + unlikely(!map)) { if (bio->bi_opf & REQ_NOWAIT) bio_wouldblock_error(bio); else if (bio->bi_opf & REQ_RAHEAD) @@ -2609,6 +2604,10 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags) } map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock)); + if (!map) { + /* avoid deadlock with fs/namespace.c:do_mount() */ + suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG; + } r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE, DMF_SUSPENDED); if (r)