diff options
author | Mike Snitzer <snitzer@redhat.com> | 2019-07-17 11:12:30 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2019-07-17 11:12:30 -0400 |
commit | 3ee25485ba8e8271fe9401eef5003c20ab648ddf (patch) | |
tree | ba1c9bde48555434b3343143d2f84fcf8770c037 | |
parent | 3b8cafdd5436f9298b3bf6eb831df5eef5ee82b6 (diff) |
dm snapshot: fix oversights in optional discard support
__find_snapshots_sharing_cow() should always be used with _origins_lock
held so fix snapshot_io_hints() accordingly. Also, once a snapshot is
being merged discards must not be allowed -- otherwise incorrect or
duplicate work will be performed.
Fixes: 2e6023850e177d ("dm snapshot: add optional discard support features")
Reported-by: Nikos Tsironis <ntsironis@arrikto.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r-- | drivers/md/dm-snap.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 63916e1dc569..f150f5c5492b 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -2072,6 +2072,12 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio) | |||
2072 | return DM_MAPIO_REMAPPED; | 2072 | return DM_MAPIO_REMAPPED; |
2073 | } | 2073 | } |
2074 | 2074 | ||
2075 | if (unlikely(bio_op(bio) == REQ_OP_DISCARD)) { | ||
2076 | /* Once merging, discards no longer effect change */ | ||
2077 | bio_endio(bio); | ||
2078 | return DM_MAPIO_SUBMITTED; | ||
2079 | } | ||
2080 | |||
2075 | chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector); | 2081 | chunk = sector_to_chunk(s->store, bio->bi_iter.bi_sector); |
2076 | 2082 | ||
2077 | down_write(&s->lock); | 2083 | down_write(&s->lock); |
@@ -2331,6 +2337,8 @@ static void snapshot_io_hints(struct dm_target *ti, struct queue_limits *limits) | |||
2331 | if (snap->discard_zeroes_cow) { | 2337 | if (snap->discard_zeroes_cow) { |
2332 | struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; | 2338 | struct dm_snapshot *snap_src = NULL, *snap_dest = NULL; |
2333 | 2339 | ||
2340 | down_read(&_origins_lock); | ||
2341 | |||
2334 | (void) __find_snapshots_sharing_cow(snap, &snap_src, &snap_dest, NULL); | 2342 | (void) __find_snapshots_sharing_cow(snap, &snap_src, &snap_dest, NULL); |
2335 | if (snap_src && snap_dest) | 2343 | if (snap_src && snap_dest) |
2336 | snap = snap_src; | 2344 | snap = snap_src; |
@@ -2338,6 +2346,8 @@ static void snapshot_io_hints(struct dm_target *ti, struct queue_limits *limits) | |||
2338 | /* All discards are split on chunk_size boundary */ | 2346 | /* All discards are split on chunk_size boundary */ |
2339 | limits->discard_granularity = snap->store->chunk_size; | 2347 | limits->discard_granularity = snap->store->chunk_size; |
2340 | limits->max_discard_sectors = snap->store->chunk_size; | 2348 | limits->max_discard_sectors = snap->store->chunk_size; |
2349 | |||
2350 | up_read(&_origins_lock); | ||
2341 | } | 2351 | } |
2342 | } | 2352 | } |
2343 | 2353 | ||