Commit cbe232ab authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-5.19/dm-fixes-4' of...

Merge tag 'for-5.19/dm-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:

 - Fix DM era to commit metadata during suspend using drain_workqueue
   instead of flush_workqueue.

 - Fix DM core's dm_io_complete to not return early if io error is
   BLK_STS_AGAIN but bio polling is not in use.

 - Fix DM core's dm_io_complete BLK_STS_DM_REQUEUE handling when dm_io
   represents a split bio.

 - Fix recent DM mirror log regression by clearing bits up to
   BITS_PER_LONG boundary.

* tag 'for-5.19/dm-fixes-4' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm mirror log: clear log bits up to BITS_PER_LONG boundary
  dm: fix BLK_STS_DM_REQUEUE handling when dm_io represents split bio
  dm: do not return early from dm_io_complete if BLK_STS_AGAIN without polling
  dm era: commit metadata in postsuspend after worker stops
parents 43627618 90736eb3
...@@ -272,6 +272,7 @@ struct dm_io { ...@@ -272,6 +272,7 @@ struct dm_io {
atomic_t io_count; atomic_t io_count;
struct mapped_device *md; struct mapped_device *md;
struct bio *split_bio;
/* The three fields represent mapped part of original bio */ /* The three fields represent mapped part of original bio */
struct bio *orig_bio; struct bio *orig_bio;
unsigned int sector_offset; /* offset to end of orig_bio */ unsigned int sector_offset; /* offset to end of orig_bio */
......
...@@ -1400,7 +1400,7 @@ static void start_worker(struct era *era) ...@@ -1400,7 +1400,7 @@ static void start_worker(struct era *era)
static void stop_worker(struct era *era) static void stop_worker(struct era *era)
{ {
atomic_set(&era->suspended, 1); atomic_set(&era->suspended, 1);
flush_workqueue(era->wq); drain_workqueue(era->wq);
} }
/*---------------------------------------------------------------- /*----------------------------------------------------------------
...@@ -1570,6 +1570,12 @@ static void era_postsuspend(struct dm_target *ti) ...@@ -1570,6 +1570,12 @@ static void era_postsuspend(struct dm_target *ti)
} }
stop_worker(era); stop_worker(era);
r = metadata_commit(era->md);
if (r) {
DMERR("%s: metadata_commit failed", __func__);
/* FIXME: fail mode */
}
} }
static int era_preresume(struct dm_target *ti) static int era_preresume(struct dm_target *ti)
......
...@@ -615,7 +615,7 @@ static int disk_resume(struct dm_dirty_log *log) ...@@ -615,7 +615,7 @@ static int disk_resume(struct dm_dirty_log *log)
log_clear_bit(lc, lc->clean_bits, i); log_clear_bit(lc, lc->clean_bits, i);
/* clear any old bits -- device has shrunk */ /* clear any old bits -- device has shrunk */
for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++) for (i = lc->region_count; i % BITS_PER_LONG; i++)
log_clear_bit(lc, lc->clean_bits, i); log_clear_bit(lc, lc->clean_bits, i);
/* copy clean across to sync */ /* copy clean across to sync */
......
...@@ -594,6 +594,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio) ...@@ -594,6 +594,7 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
atomic_set(&io->io_count, 2); atomic_set(&io->io_count, 2);
this_cpu_inc(*md->pending_io); this_cpu_inc(*md->pending_io);
io->orig_bio = bio; io->orig_bio = bio;
io->split_bio = NULL;
io->md = md; io->md = md;
spin_lock_init(&io->lock); spin_lock_init(&io->lock);
io->start_time = jiffies; io->start_time = jiffies;
...@@ -887,7 +888,7 @@ static void dm_io_complete(struct dm_io *io) ...@@ -887,7 +888,7 @@ static void dm_io_complete(struct dm_io *io)
{ {
blk_status_t io_error; blk_status_t io_error;
struct mapped_device *md = io->md; struct mapped_device *md = io->md;
struct bio *bio = io->orig_bio; struct bio *bio = io->split_bio ? io->split_bio : io->orig_bio;
if (io->status == BLK_STS_DM_REQUEUE) { if (io->status == BLK_STS_DM_REQUEUE) {
unsigned long flags; unsigned long flags;
...@@ -939,9 +940,11 @@ static void dm_io_complete(struct dm_io *io) ...@@ -939,9 +940,11 @@ static void dm_io_complete(struct dm_io *io)
if (io_error == BLK_STS_AGAIN) { if (io_error == BLK_STS_AGAIN) {
/* io_uring doesn't handle BLK_STS_AGAIN (yet) */ /* io_uring doesn't handle BLK_STS_AGAIN (yet) */
queue_io(md, bio); queue_io(md, bio);
return;
} }
} }
return; if (io_error == BLK_STS_DM_REQUEUE)
return;
} }
if (bio_is_flush_with_data(bio)) { if (bio_is_flush_with_data(bio)) {
...@@ -1691,9 +1694,11 @@ static void dm_split_and_process_bio(struct mapped_device *md, ...@@ -1691,9 +1694,11 @@ static void dm_split_and_process_bio(struct mapped_device *md,
* Remainder must be passed to submit_bio_noacct() so it gets handled * Remainder must be passed to submit_bio_noacct() so it gets handled
* *after* bios already submitted have been completely processed. * *after* bios already submitted have been completely processed.
*/ */
bio_trim(bio, io->sectors, ci.sector_count); WARN_ON_ONCE(!dm_io_flagged(io, DM_IO_WAS_SPLIT));
trace_block_split(bio, bio->bi_iter.bi_sector); io->split_bio = bio_split(bio, io->sectors, GFP_NOIO,
bio_inc_remaining(bio); &md->queue->bio_split);
bio_chain(io->split_bio, bio);
trace_block_split(io->split_bio, bio->bi_iter.bi_sector);
submit_bio_noacct(bio); submit_bio_noacct(bio);
out: out:
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment