Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
1da177e4 LT |
2 | * Copyright (C) 2001-2002 Sistina Software (UK) Limited. |
3 | * | |
4 | * This file is released under the GPL. | |
5 | */ | |
6 | ||
7 | #ifndef DM_SNAPSHOT_H | |
8 | #define DM_SNAPSHOT_H | |
9 | ||
586e80e6 | 10 | #include <linux/device-mapper.h> |
aea53d92 | 11 | #include "dm-exception-store.h" |
ca3a931f | 12 | #include "dm-bio-list.h" |
1da177e4 | 13 | #include <linux/blkdev.h> |
ca3a931f | 14 | #include <linux/workqueue.h> |
1da177e4 LT |
15 | |
16 | struct exception_table { | |
17 | uint32_t hash_mask; | |
d74f81f8 | 18 | unsigned hash_shift; |
1da177e4 LT |
19 | struct list_head *table; |
20 | }; | |
21 | ||
cd45daff MP |
22 | #define DM_TRACKED_CHUNK_HASH_SIZE 16 |
23 | #define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \ | |
24 | (DM_TRACKED_CHUNK_HASH_SIZE - 1)) | |
25 | ||
1da177e4 LT |
26 | struct dm_snapshot { |
27 | struct rw_semaphore lock; | |
72727bad | 28 | struct dm_target *ti; |
1da177e4 LT |
29 | |
30 | struct dm_dev *origin; | |
31 | struct dm_dev *cow; | |
32 | ||
33 | /* List of snapshots per Origin */ | |
34 | struct list_head list; | |
35 | ||
36 | /* Size of data blocks saved - must be a power of 2 */ | |
37 | chunk_t chunk_size; | |
38 | chunk_t chunk_mask; | |
39 | chunk_t chunk_shift; | |
40 | ||
41 | /* You can't use a snapshot if this is 0 (e.g. if full) */ | |
42 | int valid; | |
aa14edeb AK |
43 | |
44 | /* Origin writes don't trigger exceptions until this is set */ | |
45 | int active; | |
1da177e4 LT |
46 | |
47 | /* Used for display of table */ | |
48 | char type; | |
49 | ||
92e86812 MP |
50 | mempool_t *pending_pool; |
51 | ||
879129d2 MP |
52 | atomic_t pending_exceptions_count; |
53 | ||
1da177e4 LT |
54 | struct exception_table pending; |
55 | struct exception_table complete; | |
56 | ||
ca3a931f AK |
57 | /* |
58 | * pe_lock protects all pending_exception operations and access | |
59 | * as well as the snapshot_bios list. | |
60 | */ | |
61 | spinlock_t pe_lock; | |
62 | ||
1da177e4 | 63 | /* The on disk metadata handler */ |
1ae25f9c | 64 | struct dm_exception_store store; |
1da177e4 | 65 | |
eb69aca5 | 66 | struct dm_kcopyd_client *kcopyd_client; |
ca3a931f AK |
67 | |
68 | /* Queue of snapshot writes for ksnapd to flush */ | |
69 | struct bio_list queued_bios; | |
70 | struct work_struct queued_bios_work; | |
cd45daff MP |
71 | |
72 | /* Chunks with outstanding reads */ | |
73 | mempool_t *tracked_chunk_pool; | |
74 | spinlock_t tracked_chunk_lock; | |
75 | struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE]; | |
1da177e4 LT |
76 | }; |
77 | ||
1da177e4 LT |
78 | /* |
79 | * Return the number of sectors in the device. | |
80 | */ | |
81 | static inline sector_t get_dev_size(struct block_device *bdev) | |
82 | { | |
83 | return bdev->bd_inode->i_size >> SECTOR_SHIFT; | |
84 | } | |
85 | ||
86 | static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector) | |
87 | { | |
88 | return (sector & ~s->chunk_mask) >> s->chunk_shift; | |
89 | } | |
90 | ||
91 | static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk) | |
92 | { | |
93 | return chunk << s->chunk_shift; | |
94 | } | |
95 | ||
96 | static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs) | |
97 | { | |
98 | /* | |
99 | * There is only ever one instance of a particular block | |
100 | * device so we can compare pointers safely. | |
101 | */ | |
102 | return lhs == rhs; | |
103 | } | |
104 | ||
105 | #endif |