diff options
author | Milan Broz <mbroz@redhat.com> | 2008-02-07 21:11:27 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2008-02-07 21:11:27 -0500 |
commit | d74f81f8adc504a23be3babf347b9f69e9389924 (patch) | |
tree | 4a687e400479ad330bb36ded54012cd8b8b84ecf /drivers/md/dm-snap.h | |
parent | 4f7f5c675fd6bacaae3c67be44de872dcff0e3b7 (diff) |
dm snapshot: combine consecutive exceptions in memory
Provided sector_t is 64 bits, reduce the in-memory footprint of the
snapshot exception table by the simple method of using unused bits of
the chunk number to combine consecutive entries.
Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-snap.h')
-rw-r--r-- | drivers/md/dm-snap.h | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h index 650e0f1f51d8..93bce5d49742 100644 --- a/drivers/md/dm-snap.h +++ b/drivers/md/dm-snap.h | |||
@@ -16,19 +16,22 @@ | |||
16 | 16 | ||
17 | struct exception_table { | 17 | struct exception_table { |
18 | uint32_t hash_mask; | 18 | uint32_t hash_mask; |
19 | unsigned hash_shift; | ||
19 | struct list_head *table; | 20 | struct list_head *table; |
20 | }; | 21 | }; |
21 | 22 | ||
22 | /* | 23 | /* |
23 | * The snapshot code deals with largish chunks of the disk at a | 24 | * The snapshot code deals with largish chunks of the disk at a |
24 | * time. Typically 64k - 256k. | 25 | * time. Typically 32k - 512k. |
25 | */ | 26 | */ |
26 | /* FIXME: can we get away with limiting these to a uint32_t ? */ | ||
27 | typedef sector_t chunk_t; | 27 | typedef sector_t chunk_t; |
28 | 28 | ||
29 | /* | 29 | /* |
30 | * An exception is used where an old chunk of data has been | 30 | * An exception is used where an old chunk of data has been |
31 | * replaced by a new one. | 31 | * replaced by a new one. |
32 | * If chunk_t is 64 bits in size, the top 8 bits of new_chunk hold the number | ||
33 | * of chunks that follow contiguously. Remaining bits hold the number of the | ||
34 | * chunk within the device. | ||
32 | */ | 35 | */ |
33 | struct dm_snap_exception { | 36 | struct dm_snap_exception { |
34 | struct list_head hash_list; | 37 | struct list_head hash_list; |
@@ -38,6 +41,49 @@ struct dm_snap_exception { | |||
38 | }; | 41 | }; |
39 | 42 | ||
40 | /* | 43 | /* |
44 | * Funtions to manipulate consecutive chunks | ||
45 | */ | ||
46 | # if defined(CONFIG_LBD) || (BITS_PER_LONG == 64) | ||
47 | # define DM_CHUNK_CONSECUTIVE_BITS 8 | ||
48 | # define DM_CHUNK_NUMBER_BITS 56 | ||
49 | |||
50 | static inline chunk_t dm_chunk_number(chunk_t chunk) | ||
51 | { | ||
52 | return chunk & (chunk_t)((1ULL << DM_CHUNK_NUMBER_BITS) - 1ULL); | ||
53 | } | ||
54 | |||
55 | static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e) | ||
56 | { | ||
57 | return e->new_chunk >> DM_CHUNK_NUMBER_BITS; | ||
58 | } | ||
59 | |||
60 | static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) | ||
61 | { | ||
62 | e->new_chunk += (1ULL << DM_CHUNK_NUMBER_BITS); | ||
63 | |||
64 | BUG_ON(!dm_consecutive_chunk_count(e)); | ||
65 | } | ||
66 | |||
67 | # else | ||
68 | # define DM_CHUNK_CONSECUTIVE_BITS 0 | ||
69 | |||
70 | static inline chunk_t dm_chunk_number(chunk_t chunk) | ||
71 | { | ||
72 | return chunk; | ||
73 | } | ||
74 | |||
75 | static inline unsigned dm_consecutive_chunk_count(struct dm_snap_exception *e) | ||
76 | { | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e) | ||
81 | { | ||
82 | } | ||
83 | |||
84 | # endif | ||
85 | |||
86 | /* | ||
41 | * Abstraction to handle the meta/layout of exception stores (the | 87 | * Abstraction to handle the meta/layout of exception stores (the |
42 | * COW device). | 88 | * COW device). |
43 | */ | 89 | */ |