diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2020-03-22 20:42:27 +0100 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2020-03-24 13:09:49 -0400 |
commit | 31843edab7cb3924006544b901c9cab33941b684 (patch) | |
tree | fa7c14f97320a2c77e4392c1af7707918fcba0ce /drivers/md | |
parent | 84597a44a9d86ac949900441cea7da0af0f2f473 (diff) | |
download | linux-31843edab7cb3924006544b901c9cab33941b684.tar.bz2 |
dm integrity: improve discard in journal mode
When we discard something that is present in the journal, we flush the
journal first, so that discarded blocks are not overwritten by the journal
content.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-integrity.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 21eb35c606be..b989d109d55d 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -1943,6 +1943,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map unsigned journal_section, journal_entry; unsigned journal_read_pos; struct completion read_comp; + bool discard_retried = false; bool need_sync_io = ic->internal_hash && dio->op == REQ_OP_READ; if (unlikely(dio->op == REQ_OP_DISCARD) && ic->mode != 'D') need_sync_io = true; @@ -2059,6 +2060,21 @@ offload_to_thread: } } } + if (ic->mode == 'J' && likely(dio->op == REQ_OP_DISCARD) && !discard_retried) { + sector_t next_sector; + unsigned new_pos = find_journal_node(ic, dio->range.logical_sector, &next_sector); + if (unlikely(new_pos != NOT_FOUND) || + unlikely(next_sector < dio->range.logical_sector - dio->range.n_sectors)) { + remove_range_unlocked(ic, &dio->range); + spin_unlock_irq(&ic->endio_wait.lock); + queue_work(ic->commit_wq, &ic->commit_work); + flush_workqueue(ic->commit_wq); + queue_work(ic->writer_wq, &ic->writer_work); + flush_workqueue(ic->writer_wq); + discard_retried = true; + goto lock_retry; + } + } spin_unlock_irq(&ic->endio_wait.lock); if (unlikely(journal_read_pos != NOT_FOUND)) { |