The origin needs to find minimum chunksize of all snapshots. This logic is moved to separate function because it will be used at other place in snapshot merge. Signed-off-by: Mikulas Patocka --- drivers/md/dm-snap.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) Index: linux-2.6.28-rc5-devel/drivers/md/dm-snap.c =================================================================== --- linux-2.6.28-rc5-devel.orig/drivers/md/dm-snap.c 2008-11-25 16:10:52.000000000 +0100 +++ linux-2.6.28-rc5-devel/drivers/md/dm-snap.c 2008-11-25 16:10:58.000000000 +0100 @@ -250,6 +250,25 @@ static void unregister_snapshot(struct d up_write(&_origins_lock); } +#define min_not_zero(l, r) (((l) == 0) ? (r) : (((r) == 0) ? (l) : min(l, r))) + +/* + * Return a minimum chunk size of all snapshots that have the specified origin. + * Return zero if the origin has no snapshots. + */ + +static unsigned minimum_chunk_size(struct origin *o) +{ + struct dm_snapshot *snap; + unsigned chunk_size = 0; + + if (o) + list_for_each_entry (snap, &o->snapshots, list) + chunk_size = min_not_zero(chunk_size, snap->chunk_size); + + return chunk_size; +} + /* * Implementation of the exception hash tables. * The lowest hash_shift bits of the chunk number are ignored, allowing @@ -1250,8 +1269,6 @@ static int origin_map(struct dm_target * return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : DM_MAPIO_REMAPPED; } -#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) - /* * Set the target "split_io" field to the minimum of all the snapshots' * chunk sizes. @@ -1259,18 +1276,12 @@ static int origin_map(struct dm_target * static void origin_resume(struct dm_target *ti) { struct dm_dev *dev = ti->private; - struct dm_snapshot *snap; struct origin *o; - unsigned chunk_size = 0; down_read(&_origins_lock); o = __lookup_origin(dev->bdev); - if (o) - list_for_each_entry (snap, &o->snapshots, list) - chunk_size = min_not_zero(chunk_size, snap->chunk_size); + ti->split_io = minimum_chunk_size(o); up_read(&_origins_lock); - - ti->split_io = chunk_size; } static int origin_status(struct dm_target *ti, status_type_t type, char *result,