aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Snitzer <snitzer@redhat.com>2019-07-17 11:12:30 -0400
committerMike Snitzer <snitzer@redhat.com>2019-07-17 11:12:30 -0400
commit3ee25485ba8e8271fe9401eef5003c20ab648ddf (patch)
treeba1c9bde48555434b3343143d2f84fcf8770c037
parent3b8cafdd5436f9298b3bf6eb831df5eef5ee82b6 (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.c10
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