Root/
1 | /* |
2 | * Copyright (C) 2010-2011 Red Hat, Inc. |
3 | * |
4 | * This file is released under the GPL. |
5 | */ |
6 | |
7 | #ifndef DM_THIN_METADATA_H |
8 | #define DM_THIN_METADATA_H |
9 | |
10 | #include "persistent-data/dm-block-manager.h" |
11 | |
12 | #define THIN_METADATA_BLOCK_SIZE 4096 |
13 | |
14 | /* |
15 | * The metadata device is currently limited in size. |
16 | * |
17 | * We have one block of index, which can hold 255 index entries. Each |
18 | * index entry contains allocation info about 16k metadata blocks. |
19 | */ |
20 | #define THIN_METADATA_MAX_SECTORS (255 * (1 << 14) * (THIN_METADATA_BLOCK_SIZE / (1 << SECTOR_SHIFT))) |
21 | |
22 | /* |
23 | * A metadata device larger than 16GB triggers a warning. |
24 | */ |
25 | #define THIN_METADATA_MAX_SECTORS_WARNING (16 * (1024 * 1024 * 1024 >> SECTOR_SHIFT)) |
26 | |
27 | /*----------------------------------------------------------------*/ |
28 | |
29 | struct dm_pool_metadata; |
30 | struct dm_thin_device; |
31 | |
32 | /* |
33 | * Device identifier |
34 | */ |
35 | typedef uint64_t dm_thin_id; |
36 | |
37 | /* |
38 | * Reopens or creates a new, empty metadata volume. |
39 | */ |
40 | struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, |
41 | sector_t data_block_size, |
42 | bool format_device); |
43 | |
44 | int dm_pool_metadata_close(struct dm_pool_metadata *pmd); |
45 | |
46 | /* |
47 | * Compat feature flags. Any incompat flags beyond the ones |
48 | * specified below will prevent use of the thin metadata. |
49 | */ |
50 | #define THIN_FEATURE_COMPAT_SUPP 0UL |
51 | #define THIN_FEATURE_COMPAT_RO_SUPP 0UL |
52 | #define THIN_FEATURE_INCOMPAT_SUPP 0UL |
53 | |
54 | /* |
55 | * Device creation/deletion. |
56 | */ |
57 | int dm_pool_create_thin(struct dm_pool_metadata *pmd, dm_thin_id dev); |
58 | |
59 | /* |
60 | * An internal snapshot. |
61 | * |
62 | * You can only snapshot a quiesced origin i.e. one that is either |
63 | * suspended or not instanced at all. |
64 | */ |
65 | int dm_pool_create_snap(struct dm_pool_metadata *pmd, dm_thin_id dev, |
66 | dm_thin_id origin); |
67 | |
68 | /* |
69 | * Deletes a virtual device from the metadata. It _is_ safe to call this |
70 | * when that device is open. Operations on that device will just start |
71 | * failing. You still need to call close() on the device. |
72 | */ |
73 | int dm_pool_delete_thin_device(struct dm_pool_metadata *pmd, |
74 | dm_thin_id dev); |
75 | |
76 | /* |
77 | * Commits _all_ metadata changes: device creation, deletion, mapping |
78 | * updates. |
79 | */ |
80 | int dm_pool_commit_metadata(struct dm_pool_metadata *pmd); |
81 | |
82 | /* |
83 | * Discards all uncommitted changes. Rereads the superblock, rolling back |
84 | * to the last good transaction. Thin devices remain open. |
85 | * dm_thin_aborted_changes() tells you if they had uncommitted changes. |
86 | * |
87 | * If this call fails it's only useful to call dm_pool_metadata_close(). |
88 | * All other methods will fail with -EINVAL. |
89 | */ |
90 | int dm_pool_abort_metadata(struct dm_pool_metadata *pmd); |
91 | |
92 | /* |
93 | * Set/get userspace transaction id. |
94 | */ |
95 | int dm_pool_set_metadata_transaction_id(struct dm_pool_metadata *pmd, |
96 | uint64_t current_id, |
97 | uint64_t new_id); |
98 | |
99 | int dm_pool_get_metadata_transaction_id(struct dm_pool_metadata *pmd, |
100 | uint64_t *result); |
101 | |
102 | /* |
103 | * Hold/get root for userspace transaction. |
104 | * |
105 | * The metadata snapshot is a copy of the current superblock (minus the |
106 | * space maps). Userland can access the data structures for READ |
107 | * operations only. A small performance hit is incurred by providing this |
108 | * copy of the metadata to userland due to extra copy-on-write operations |
109 | * on the metadata nodes. Release this as soon as you finish with it. |
110 | */ |
111 | int dm_pool_reserve_metadata_snap(struct dm_pool_metadata *pmd); |
112 | int dm_pool_release_metadata_snap(struct dm_pool_metadata *pmd); |
113 | |
114 | int dm_pool_get_metadata_snap(struct dm_pool_metadata *pmd, |
115 | dm_block_t *result); |
116 | |
117 | /* |
118 | * Actions on a single virtual device. |
119 | */ |
120 | |
121 | /* |
122 | * Opening the same device more than once will fail with -EBUSY. |
123 | */ |
124 | int dm_pool_open_thin_device(struct dm_pool_metadata *pmd, dm_thin_id dev, |
125 | struct dm_thin_device **td); |
126 | |
127 | int dm_pool_close_thin_device(struct dm_thin_device *td); |
128 | |
129 | dm_thin_id dm_thin_dev_id(struct dm_thin_device *td); |
130 | |
131 | struct dm_thin_lookup_result { |
132 | dm_block_t block; |
133 | unsigned shared:1; |
134 | }; |
135 | |
136 | /* |
137 | * Returns: |
138 | * -EWOULDBLOCK iff @can_block is set and would block. |
139 | * -ENODATA iff that mapping is not present. |
140 | * 0 success |
141 | */ |
142 | int dm_thin_find_block(struct dm_thin_device *td, dm_block_t block, |
143 | int can_block, struct dm_thin_lookup_result *result); |
144 | |
145 | /* |
146 | * Obtain an unused block. |
147 | */ |
148 | int dm_pool_alloc_data_block(struct dm_pool_metadata *pmd, dm_block_t *result); |
149 | |
150 | /* |
151 | * Insert or remove block. |
152 | */ |
153 | int dm_thin_insert_block(struct dm_thin_device *td, dm_block_t block, |
154 | dm_block_t data_block); |
155 | |
156 | int dm_thin_remove_block(struct dm_thin_device *td, dm_block_t block); |
157 | |
158 | /* |
159 | * Queries. |
160 | */ |
161 | bool dm_thin_changed_this_transaction(struct dm_thin_device *td); |
162 | |
163 | bool dm_thin_aborted_changes(struct dm_thin_device *td); |
164 | |
165 | int dm_thin_get_highest_mapped_block(struct dm_thin_device *td, |
166 | dm_block_t *highest_mapped); |
167 | |
168 | int dm_thin_get_mapped_count(struct dm_thin_device *td, dm_block_t *result); |
169 | |
170 | int dm_pool_get_free_block_count(struct dm_pool_metadata *pmd, |
171 | dm_block_t *result); |
172 | |
173 | int dm_pool_get_free_metadata_block_count(struct dm_pool_metadata *pmd, |
174 | dm_block_t *result); |
175 | |
176 | int dm_pool_get_metadata_dev_size(struct dm_pool_metadata *pmd, |
177 | dm_block_t *result); |
178 | |
179 | int dm_pool_get_data_block_size(struct dm_pool_metadata *pmd, sector_t *result); |
180 | |
181 | int dm_pool_get_data_dev_size(struct dm_pool_metadata *pmd, dm_block_t *result); |
182 | |
183 | /* |
184 | * Returns -ENOSPC if the new size is too small and already allocated |
185 | * blocks would be lost. |
186 | */ |
187 | int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_size); |
188 | |
189 | /* |
190 | * Flicks the underlying block manager into read only mode, so you know |
191 | * that nothing is changing. |
192 | */ |
193 | void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd); |
194 | |
195 | /*----------------------------------------------------------------*/ |
196 | |
197 | #endif |
198 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9