updated on Thu Jan 26 16:09:46 UTC 2012
[aur-mirror.git] / reiser4progs / reiser4progs-fsck-handle-unprepped-cluster.patch
blobf7b4bbbd3efb5cefb1ade085ceb5273ee1894fe8
1 . Handle orphan "unprepped" clusters;
2 . Don't repair the value of cluster shift in ctail item
3 in all circumstances. If cluster shift is wrong, then
4 remove the whole cluster.
6 Signed-off-by: Edward Shishkin <edward.shishkin@gmail.com>
7 ---
8 plugin/object/ccreg40/ccreg40.c | 12 +-
9 plugin/object/ccreg40/ccreg40.h | 9 +
10 plugin/object/ccreg40/ccreg40_repair.c | 196 +++++++++++++++++----------------
11 3 files changed, 121 insertions(+), 96 deletions(-)
13 --- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40.h
14 +++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40.h
15 @@ -11,6 +11,12 @@
16 #include "reiser4/plugin.h"
17 #include "plugin/object/obj40/obj40.h"
19 +#define MIN_VALID_CLUSTER_SHIFT (0xc)
20 +#define MAX_VALID_CLUSTER_SHIFT (0x10)
21 +#define UNPREPPED_CLUSTER_SHIFT (0xff)
23 +#define ccreg40_cloff(off, size) ((off) & ((size) - 1))
25 #define ccreg40_clstart(off, size) ((off) & ~((size) - 1))
27 #define ccreg40_clnext(off, size) (ccreg40_clstart(off, size) + (size))
28 @@ -22,7 +28,8 @@ extern errno_t ccreg40_check_struct(reis
29 place_func_t func,
30 void *data, uint8_t mode);
32 -extern uint32_t ccreg40_get_cluster_size(reiser4_place_t *place);
33 +extern errno_t ccreg40_get_cluster_shift(reiser4_place_t *place,
34 + uint8_t *shift);
36 extern errno_t ccreg40_set_cluster_size(reiser4_place_t *place,
37 uint32_t cluster);
38 --- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40_repair.c
39 +++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40_repair.c
40 @@ -25,80 +25,81 @@ typedef struct ccreg40_hint {
41 uint64_t seek; /* expected offset for lookup */
42 uint64_t found; /* what has been really found */
43 uint64_t maxreal; /* maximal (key) offset in the found item */
45 - /* Bytes all clusters takes on disk. */
46 - uint32_t bytes;
47 uint64_t sdsize;
48 + /* The following two fields are to delete wrecks of a disk cluster */
49 + uint64_t cut_from; /* offset to cut from */
50 + uint32_t cut_size; /* how many bytes to cut */
51 + uint32_t clsize;
52 + /* Total number of units in a disk cluster */
53 + uint32_t bytes;
54 uint32_t adler;
55 uint8_t mode;
57 - /* If a hole is detected. */
58 + /* Indicates if cluster has a hole in key space */
59 uint8_t hole;
61 /* The cluster size & the buffer for the data. */
62 uint8_t data[64 * 1024];
63 - uint64_t clstart;
64 - uint32_t clsize;
65 } ccreg40_hint_t;
67 static errno_t ccreg40_check_item(reiser4_object_t *cc, void *data) {
68 ccreg40_hint_t *hint = (ccreg40_hint_t *)data;
69 - uint32_t clsize;
70 - errno_t res = 0;
72 + uint8_t shift;
73 + errno_t result;
75 hint->found = objcall(&cc->body.key, get_offset);
76 hint->maxreal = obj40_place_maxreal(&cc->body);
78 aal_assert("vpf-1871", hint->maxreal >= hint->found);
79 aal_assert("vpf-1872", hint->seek <= hint->found);
81 - /* Check the item plugin. */
82 + /* check item plugin */
83 if (cc->body.plug != reiser4_psctail(cc)) {
84 - fsck_mess("The file [%s] (%s), node [%llu], item "
85 - "[%u]: item of the illegal plugin (%s) "
86 - "with the key of this object found.%s",
87 - print_inode(obj40_core, &cc->info.object),
88 - reiser4_psobj(cc)->p.label, place_blknr(&cc->body),
89 - cc->body.pos.item, cc->body.plug->p.label,
90 - hint->mode == RM_BUILD ? " Removed." : "");
92 - return hint->mode == RM_BUILD ? -ESTRUCT : RE_FATAL;
93 + fsck_mess("Found item of illegal plugin (%s) "
94 + "with the key of this object ",
95 + cc->body.plug->p.label);
96 + goto fatal;
99 - /* Check the shift. */
100 - clsize = ccreg40_get_cluster_size(&cc->body);
102 - if (hint->clsize != clsize) {
103 - fsck_mess("The file [%s] (%s), node [%llu], item [%u]: item "
104 - "of the wrong cluster size (%d) found, Should be "
105 - "(%d).%s", print_inode(obj40_core, &cc->info.object),
106 - reiser4_psobj(cc)->p.label, place_blknr(&cc->body),
107 - cc->body.pos.item, clsize, hint->clsize,
108 - hint->mode != RM_CHECK ? " Fixed." : "");
110 - /* Just fix the shift if wrong. */
111 - if (hint->mode == RM_CHECK) {
112 - res |= RE_FIXABLE;
113 - } else {
114 - ccreg40_set_cluster_size(&cc->body, hint->clsize);
116 + /* check cluster shift. */
117 + result = ccreg40_get_cluster_shift(&cc->body, &shift);
118 + if (result < 0)
119 + return result;
120 + if (shift == UNPREPPED_CLUSTER_SHIFT) {
121 + fsck_mess("Found unprepped disk cluster ");
122 + goto fatal;
124 + if (shift < MIN_VALID_CLUSTER_SHIFT ||
125 + shift > MAX_VALID_CLUSTER_SHIFT ||
126 + shift != aal_log2(hint->clsize)) {
127 + fsck_mess("Found item with wrong cluster shift %d, "
128 + "should be %d", shift, aal_log2(hint->clsize));
129 + goto fatal;
131 + if (hint->seek &&
132 + !ccreg40_clsame(hint->prev_found, hint->found, hint->clsize) &&
133 + ccreg40_cloff(hint->found, hint->clsize) != 0){
134 + fsck_mess("Found item of lenght (%llu) which has wrong "
135 + "offset %llu, should be a multiple of logical "
136 + "cluster size ",
137 + hint->maxreal - hint->found + 1, hint->found);
138 + goto fatal;
141 if (!ccreg40_clsame(hint->found, hint->maxreal, hint->clsize)) {
142 - /* The item covers the cluster border. Delete it. */
143 - fsck_mess("The file [%s] (%s), node [%llu], item [%u]: "
144 - "item of the lenght (%llu) found, it cannot "
145 - "contain data of 2 clusters.%s",
146 - print_inode(obj40_core, &cc->info.object),
147 - reiser4_psobj(cc)->p.label,
148 - place_blknr(&cc->body), cc->body.pos.item,
149 - hint->maxreal - hint->found + 1,
150 - hint->mode == RM_BUILD ? " Removed." : "");
152 - return hint->mode == RM_BUILD ? -ESTRUCT : RE_FATAL;
153 + fsck_mess("Found item of length %llu and offset %llu, "
154 + "which contains logical cluster boundary ",
155 + hint->maxreal - hint->found + 1, hint->found);
156 + goto fatal;
159 - return res;
160 + return 0;
161 + fatal:
162 + fsck_mess("(file [%s] (%s), node [%llu], item [%u]). %s",
163 + print_inode(obj40_core, &cc->info.object),
164 + reiser4_psobj(cc)->p.label,
165 + place_blknr(&cc->body),
166 + cc->body.pos.item,
167 + hint->mode == RM_BUILD ? " Removed." : "");
168 + hint->cut_from = hint->found;
169 + hint->cut_size = hint->maxreal - hint->found + 1;
171 + return hint->mode == RM_BUILD ? -ESTRUCT : RE_FATAL;
174 static int64_t ccreg40_read_item(reiser4_place_t *place, ccreg40_hint_t *hint) {
175 @@ -133,23 +134,21 @@ static errno_t ccreg40_check_crc(ccreg40
176 return adler == disk ? 0 : RE_FATAL;
180 + * Read a found item to the stream.
181 + * Check a checksum, if the previous iteration completed a disk cluster.
182 + */
183 static errno_t ccreg40_check_cluster(reiser4_object_t *cc,
184 ccreg40_hint_t *hint,
185 uint8_t mode)
187 - errno_t result;
188 + errno_t result = 0;
189 errno_t res;
190 - int start;
191 - uint32_t lcl_size;
193 - result = 0;
194 - /* true, if the found item is the
195 - first one in the disk cluster */
196 - start = (ccreg40_clstart(hint->found, hint->clsize) == hint->found);
197 + uint32_t lcl_bytes;
199 if ((cc->body.plug == NULL) ||
200 - (hint->seek && start) ||
201 - !ccreg40_clsame(hint->prev_found, hint->found, hint->clsize)) {
202 + (hint->seek != 0 &&
203 + !ccreg40_clsame(hint->prev_found, hint->found, hint->clsize))) {
204 /* Cluster is over */
206 if (hint->prev_found > hint->sdsize) {
207 @@ -158,31 +157,32 @@ static errno_t ccreg40_check_cluster(rei
208 result = RE_FATAL;
210 /* set offset of the cluster to be deleted. */
211 - hint->clstart = ccreg40_clstart(hint->prev_found,
212 - hint->clsize);
213 + hint->cut_from = ccreg40_clstart(hint->prev_found,
214 + hint->clsize);
215 fsck_mess("The file [%s] (%s): the cluster at [%llu] "
216 "offset %u bytes long is orphan.%s",
217 print_inode(obj40_core, &cc->info.object),
218 - reiser4_psobj(cc)->p.label, hint->clstart,
219 + reiser4_psobj(cc)->p.label, hint->cut_from,
220 hint->clsize, hint->mode != RM_CHECK ?
221 " Removed." : "");
224 - * If there still is a hole in the logical cluster,
225 - * then check a checksum (no hole means no checksum)
226 + * If there still is a hole in the keyspace, then
227 + * check a checksum (no such hole means that no
228 + * checksum was appended)
230 - else if (hint->hole && ccreg40_check_crc(hint)) {
231 + else if (hint->bytes && hint->hole && ccreg40_check_crc(hint)) {
232 /* wrong checksum */
233 hint->bytes = 0;
234 result = RE_FATAL;
236 /* set offset of the cluster to be deleted. */
237 - hint->clstart = ccreg40_clstart(hint->prev_found,
238 - hint->clsize);
239 + hint->cut_from = ccreg40_clstart(hint->prev_found,
240 + hint->clsize);
241 fsck_mess("The file [%s] (%s): the cluster at [%llu] "
242 "offset %u bytes long is corrupted.%s",
243 print_inode(obj40_core, &cc->info.object),
244 - reiser4_psobj(cc)->p.label, hint->clstart,
245 + reiser4_psobj(cc)->p.label, hint->cut_from,
246 hint->clsize, hint->mode != RM_CHECK ?
247 " Removed." : "");
249 @@ -192,16 +192,13 @@ static errno_t ccreg40_check_cluster(rei
250 hint->adler = 0;
252 if (!cc->body.plug)
253 + /* finish with this object */
254 return result;
256 /* Update the cluster data. */
257 aal_memset(hint->data, 0, hint->clsize);
260 /* An item found. */
261 - aal_assert("edward-1",
262 - ccreg40_clstart(hint->found, hint->clsize) ==
263 - ccreg40_clstart(hint->maxreal, hint->clsize));
265 if ((res = ccreg40_read_item(&cc->body, hint)))
266 return res;
267 @@ -209,16 +206,19 @@ static errno_t ccreg40_check_cluster(rei
268 hint->prev_found = hint->found;
269 hint->bytes += objcall(&cc->body, object->bytes);
271 - * Calculate a size of logical cluster
272 - * and figure out, if there is a hole
273 - * for the found items in the logical cluster.
274 + * Calculate actual number of file's bytes in the
275 + * logical cluster and figure out, if corresponding
276 + * disk cluster has a hole in key space.
278 + * We need this to figure out if disk cluster contains
279 + * appended checksum.
281 - lcl_size = 0;
282 + lcl_bytes = 0;
283 if (ccreg40_clsame(hint->found, hint->sdsize - 1, hint->clsize))
284 - lcl_size = hint->sdsize % hint->clsize;
285 - if (lcl_size == 0)
286 - lcl_size = hint->clsize;
287 - hint->hole = (hint->bytes != lcl_size);
288 + lcl_bytes = hint->sdsize % hint->clsize;
289 + if (lcl_bytes == 0)
290 + lcl_bytes = hint->clsize;
291 + hint->hole = (hint->bytes != lcl_bytes);
293 return result;
295 @@ -256,8 +256,23 @@ errno_t ccreg40_check_struct(reiser4_obj
296 /* Get next item. */
297 lookup = obj40_check_item(cc, ccreg40_check_item, NULL, &hint);
299 - if (repair_error_fatal(lookup))
300 - return lookup;
301 + if (repair_error_fatal(lookup)) {
302 + if ((lookup & RE_FATAL) && mode == RM_BUILD) {
303 + /*
304 + * Delete item found in this iteration
305 + */
306 + res &= ~RE_FATAL;
307 + res |= obj40_cut(cc, &trans, hint.cut_from,
308 + hint.cut_size, NULL, NULL);
309 + if (res < 0)
310 + return res;
311 + hint.seek = hint.maxreal + 1;
312 + obj40_seek(cc, hint.seek);
313 + continue;
315 + else
316 + return lookup;
318 else if (lookup == ABSENT)
319 cc->body.plug = NULL;
321 @@ -267,16 +282,17 @@ errno_t ccreg40_check_struct(reiser4_obj
322 "registered yet.", print_key(obj40_core,
323 &info->object));
326 + /* check cluster found in previous iteration */
327 if ((res |= ccreg40_check_cluster(cc, &hint, mode)) < 0)
328 return res;
330 if (res & RE_FATAL) {
331 - /* Delete the whole cluster. */
333 + /*
334 + * Delete cluster found in previous iteration
335 + */
336 if (mode == RM_BUILD) {
337 res &= ~RE_FATAL;
338 - res |= obj40_cut(cc, &trans, hint.clstart,
339 + res |= obj40_cut(cc, &trans, hint.cut_from,
340 hint.clsize, NULL, NULL);
341 if (res < 0)
342 return res;
343 --- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40.c
344 +++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40.c
345 @@ -8,7 +8,7 @@
346 #include "ccreg40.h"
347 #include "plugin/object/obj40/obj40_repair.h"
349 -uint32_t ccreg40_get_cluster_size(reiser4_place_t *place) {
350 +errno_t ccreg40_get_cluster_shift(reiser4_place_t *place, uint8_t *shift) {
351 trans_hint_t hint;
352 ctail_hint_t chint;
354 @@ -17,10 +17,12 @@ uint32_t ccreg40_get_cluster_size(reiser
355 hint.specific = &chint;
356 hint.count = 1;
358 - if (objcall(place, object->fetch_units, &hint) != 1)
359 - return MAX_UINT32;
361 - return 1 << chint.shift;
362 + if (objcall(place, object->fetch_units, &hint) != 1) {
363 + aal_error("Can not extract cluster shift.");
364 + return -EINVAL;
366 + *shift = chint.shift;
367 + return 0;
370 errno_t ccreg40_set_cluster_size(reiser4_place_t *place, uint32_t cluster) {