diff options
-rw-r--r-- | drivers/md/dm-snap.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 8a4a9c838afd..48978ab42ae5 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -523,6 +523,25 @@ static int dm_add_exception(void *context, chunk_t old, chunk_t new) | |||
523 | return 0; | 523 | return 0; |
524 | } | 524 | } |
525 | 525 | ||
526 | #define min_not_zero(l, r) (((l) == 0) ? (r) : (((r) == 0) ? (l) : min(l, r))) | ||
527 | |||
528 | /* | ||
529 | * Return a minimum chunk size of all snapshots that have the specified origin. | ||
530 | * Return zero if the origin has no snapshots. | ||
531 | */ | ||
532 | static sector_t __minimum_chunk_size(struct origin *o) | ||
533 | { | ||
534 | struct dm_snapshot *snap; | ||
535 | unsigned chunk_size = 0; | ||
536 | |||
537 | if (o) | ||
538 | list_for_each_entry(snap, &o->snapshots, list) | ||
539 | chunk_size = min_not_zero(chunk_size, | ||
540 | snap->store->chunk_size); | ||
541 | |||
542 | return chunk_size; | ||
543 | } | ||
544 | |||
526 | /* | 545 | /* |
527 | * Hard coded magic. | 546 | * Hard coded magic. |
528 | */ | 547 | */ |
@@ -1395,8 +1414,6 @@ static int origin_map(struct dm_target *ti, struct bio *bio, | |||
1395 | return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED; | 1414 | return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED; |
1396 | } | 1415 | } |
1397 | 1416 | ||
1398 | #define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) | ||
1399 | |||
1400 | /* | 1417 | /* |
1401 | * Set the target "split_io" field to the minimum of all the snapshots' | 1418 | * Set the target "split_io" field to the minimum of all the snapshots' |
1402 | * chunk sizes. | 1419 | * chunk sizes. |
@@ -1404,19 +1421,12 @@ static int origin_map(struct dm_target *ti, struct bio *bio, | |||
1404 | static void origin_resume(struct dm_target *ti) | 1421 | static void origin_resume(struct dm_target *ti) |
1405 | { | 1422 | { |
1406 | struct dm_dev *dev = ti->private; | 1423 | struct dm_dev *dev = ti->private; |
1407 | struct dm_snapshot *snap; | ||
1408 | struct origin *o; | ||
1409 | unsigned chunk_size = 0; | ||
1410 | 1424 | ||
1411 | down_read(&_origins_lock); | 1425 | down_read(&_origins_lock); |
1412 | o = __lookup_origin(dev->bdev); | ||
1413 | if (o) | ||
1414 | list_for_each_entry (snap, &o->snapshots, list) | ||
1415 | chunk_size = min_not_zero(chunk_size, | ||
1416 | snap->store->chunk_size); | ||
1417 | up_read(&_origins_lock); | ||
1418 | 1426 | ||
1419 | ti->split_io = chunk_size; | 1427 | ti->split_io = __minimum_chunk_size(__lookup_origin(dev->bdev)); |
1428 | |||
1429 | up_read(&_origins_lock); | ||
1420 | } | 1430 | } |
1421 | 1431 | ||
1422 | static int origin_status(struct dm_target *ti, status_type_t type, char *result, | 1432 | static int origin_status(struct dm_target *ti, status_type_t type, char *result, |