diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2009-12-10 18:52:08 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-10 18:52:08 -0500 |
commit | 7e201b35132a1f02c931a0a06760766c846bb49b (patch) | |
tree | 02ab2bcf4609763ab9780db2a87b9f37aa77186f /drivers/md/dm-snap.c | |
parent | 102c6ddb1d081a6a1fede38c43a42c9811313ec7 (diff) |
dm snapshot: abstract minimum_chunk_size fn
The origin needs to find minimum chunksize of all snapshots. This logic is
moved to a separate function because it will be used at another place in
the snapshot merge patches.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Reviewed-by: Mike Snitzer <snitzer@redhat.com>
Reviewed-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-snap.c')
-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, |