dm snapshot: cope with chunk size larger than origin
authorMikulas Patocka <mpatocka@redhat.com>
Thu, 10 Dec 2009 23:51:54 +0000 (23:51 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 18 Dec 2009 22:05:02 +0000 (14:05 -0800)
commit 8e87b9b81b3c370f7e53c1ab6e1c3519ef37a644 upstream.

Under some special conditions the snapshot hash_size is calculated as zero.
This patch instead sets a minimum value of 64, the same as for the
pending exception table.

rounddown_pow_of_two(0) is an undefined operation (it expands to shift
by -1).  init_exception_table with an argument of 0 would fail with -ENOMEM.

The way to trigger the problem is to create a snapshot with a chunk size
that is larger than the origin device.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/md/dm-snap.c

index d135212958f1567a24c58ddcb1de9a0cfb0610e5..8a4a9c838afdd57ffe04fc02b63be12e343d7db3 100644 (file)
@@ -553,6 +553,8 @@ static int init_hash_tables(struct dm_snapshot *s)
        hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
        hash_size = min(hash_size, max_buckets);
 
+       if (hash_size < 64)
+               hash_size = 64;
        hash_size = rounddown_pow_of_two(hash_size);
        if (init_exception_table(&s->complete, hash_size,
                                 DM_CHUNK_CONSECUTIVE_BITS))