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>
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
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
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,
36 extern errno_t ccreg40_set_cluster_size(reiser4_place_t *place,
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. */
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 */
52 + /* Total number of units in a disk cluster */
57 - /* If a hole is detected. */
58 + /* Indicates if cluster has a hole in key space */
61 /* The cluster size & the buffer for the data. */
62 uint8_t data[64 * 1024];
67 static errno_t ccreg40_check_item(reiser4_object_t *cc, void *data) {
68 ccreg40_hint_t *hint = (ccreg40_hint_t *)data;
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);
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) {
114 - ccreg40_set_cluster_size(&cc->body, hint->clsize);
116 + /* check cluster shift. */
117 + result = ccreg40_get_cluster_shift(&cc->body, &shift);
120 + if (shift == UNPREPPED_CLUSTER_SHIFT) {
121 + fsck_mess("Found unprepped disk cluster ");
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));
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 "
137 + hint->maxreal - hint->found + 1, hint->found);
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);
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),
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.
183 static errno_t ccreg40_check_cluster(reiser4_object_t *cc,
184 ccreg40_hint_t *hint,
188 + errno_t 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
210 /* set offset of the cluster to be deleted. */
211 - hint->clstart = ccreg40_clstart(hint->prev_found,
213 + hint->cut_from = ccreg40_clstart(hint->prev_found,
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 ?
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)) {
236 /* set offset of the cluster to be deleted. */
237 - hint->clstart = ccreg40_clstart(hint->prev_found,
239 + hint->cut_from = ccreg40_clstart(hint->prev_found,
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 ?
249 @@ -192,16 +192,13 @@ static errno_t ccreg40_check_cluster(rei
253 + /* finish with this object */
256 /* Update the cluster data. */
257 aal_memset(hint->data, 0, hint->clsize);
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)))
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.
283 if (ccreg40_clsame(hint->found, hint->sdsize - 1, hint->clsize))
284 - lcl_size = hint->sdsize % hint->clsize;
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);
295 @@ -256,8 +256,23 @@ errno_t ccreg40_check_struct(reiser4_obj
297 lookup = obj40_check_item(cc, ccreg40_check_item, NULL, &hint);
299 - if (repair_error_fatal(lookup))
301 + if (repair_error_fatal(lookup)) {
302 + if ((lookup & RE_FATAL) && mode == RM_BUILD) {
304 + * Delete item found in this iteration
307 + res |= obj40_cut(cc, &trans, hint.cut_from,
308 + hint.cut_size, NULL, NULL);
311 + hint.seek = hint.maxreal + 1;
312 + obj40_seek(cc, hint.seek);
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,
326 + /* check cluster found in previous iteration */
327 if ((res |= ccreg40_check_cluster(cc, &hint, mode)) < 0)
330 if (res & RE_FATAL) {
331 - /* Delete the whole cluster. */
334 + * Delete cluster found in previous iteration
336 if (mode == RM_BUILD) {
338 - res |= obj40_cut(cc, &trans, hint.clstart,
339 + res |= obj40_cut(cc, &trans, hint.cut_from,
340 hint.clsize, NULL, NULL);
343 --- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40.c
344 +++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40.c
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) {
354 @@ -17,10 +17,12 @@ uint32_t ccreg40_get_cluster_size(reiser
355 hint.specific = &chint;
358 - if (objcall(place, object->fetch_units, &hint) != 1)
361 - return 1 << chint.shift;
362 + if (objcall(place, object->fetch_units, &hint) != 1) {
363 + aal_error("Can not extract cluster shift.");
366 + *shift = chint.shift;
370 errno_t ccreg40_set_cluster_size(reiser4_place_t *place, uint32_t cluster) {