Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 336172 Details for
Bug 453038
sys-fs/reiser4progs-1.0.7 ‒ w/ patches from reiserfs-devel mailing list
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Fixes segmentation fault problem in fsck.
reiser4progs-1.0.7-handle-unprepped-items-by-fsck.patch (text/plain), 11.99 KB, created by
tao
on 2013-01-19 21:29:09 UTC
(
hide
)
Description:
Fixes segmentation fault problem in fsck.
Filename:
MIME Type:
Creator:
tao
Created:
2013-01-19 21:29:09 UTC
Size:
11.99 KB
patch
obsolete
>. Handle orphan "unprepped" clusters; >. Don't repair the value of cluster shift in ctail item > in all circumstances. If cluster shift is wrong, then > remove the whole cluster. > >Signed-off-by: Edward Shishkin <edward.shishkin@xxxxxxxxx> >--- > plugin/object/ccreg40/ccreg40.c | 12 +- > plugin/object/ccreg40/ccreg40.h | 9 + > plugin/object/ccreg40/ccreg40_repair.c | 196 +++++++++++++++++---------------- > 3 files changed, 121 insertions(+), 96 deletions(-) > >--- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40.h >+++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40.h >@@ -11,6 +11,12 @@ > #include "reiser4/plugin.h" > #include "plugin/object/obj40/obj40.h" > >+#define MIN_VALID_CLUSTER_SHIFT (0xc) >+#define MAX_VALID_CLUSTER_SHIFT (0x10) >+#define UNPREPPED_CLUSTER_SHIFT (0xff) >+ >+#define ccreg40_cloff(off, size) ((off) & ((size) - 1)) >+ > #define ccreg40_clstart(off, size) ((off) & ~((size) - 1)) > > #define ccreg40_clnext(off, size) (ccreg40_clstart(off, size) + (size)) >@@ -22,7 +28,8 @@ extern errno_t ccreg40_check_struct(reis > place_func_t func, > void *data, uint8_t mode); > >-extern uint32_t ccreg40_get_cluster_size(reiser4_place_t *place); >+extern errno_t ccreg40_get_cluster_shift(reiser4_place_t *place, >+ uint8_t *shift); > > extern errno_t ccreg40_set_cluster_size(reiser4_place_t *place, > uint32_t cluster); >--- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40_repair.c >+++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40_repair.c >@@ -25,80 +25,81 @@ typedef struct ccreg40_hint { > uint64_t seek; /* expected offset for lookup */ > uint64_t found; /* what has been really found */ > uint64_t maxreal; /* maximal (key) offset in the found item */ >- >- /* Bytes all clusters takes on disk. */ >- uint32_t bytes; > uint64_t sdsize; >+ /* The following two fields are to delete wrecks of a disk cluster */ >+ uint64_t cut_from; /* offset to cut from */ >+ uint32_t cut_size; /* how many bytes to cut */ >+ uint32_t clsize; >+ /* Total number of units in a disk cluster */ >+ uint32_t bytes; > uint32_t adler; > uint8_t mode; >- >- /* If a hole is detected. */ >+ /* Indicates if cluster has a hole in key space */ > uint8_t hole; >- > /* The cluster size & the buffer for the data. */ > uint8_t data[64 * 1024]; >- uint64_t clstart; >- uint32_t clsize; > } ccreg40_hint_t; > > static errno_t ccreg40_check_item(reiser4_object_t *cc, void *data) { > ccreg40_hint_t *hint = (ccreg40_hint_t *)data; >- uint32_t clsize; >- errno_t res = 0; >- >+ uint8_t shift; >+ errno_t result; >+ > hint->found = objcall(&cc->body.key, get_offset); > hint->maxreal = obj40_place_maxreal(&cc->body); > > aal_assert("vpf-1871", hint->maxreal >= hint->found); > aal_assert("vpf-1872", hint->seek <= hint->found); > >- /* Check the item plugin. */ >+ /* check item plugin */ > if (cc->body.plug != reiser4_psctail(cc)) { >- fsck_mess("The file [%s] (%s), node [%llu], item " >- "[%u]: item of the illegal plugin (%s) " >- "with the key of this object found.%s", >- print_inode(obj40_core, &cc->info.object), >- reiser4_psobj(cc)->p.label, place_blknr(&cc->body), >- cc->body.pos.item, cc->body.plug->p.label, >- hint->mode == RM_BUILD ? " Removed." : ""); >- >- return hint->mode == RM_BUILD ? -ESTRUCT : RE_FATAL; >+ fsck_mess("Found item of illegal plugin (%s) " >+ "with the key of this object ", >+ cc->body.plug->p.label); >+ goto fatal; > } >- >- /* Check the shift. */ >- clsize = ccreg40_get_cluster_size(&cc->body); >- >- if (hint->clsize != clsize) { >- fsck_mess("The file [%s] (%s), node [%llu], item [%u]: item " >- "of the wrong cluster size (%d) found, Should be " >- "(%d).%s", print_inode(obj40_core, &cc->info.object), >- reiser4_psobj(cc)->p.label, place_blknr(&cc->body), >- cc->body.pos.item, clsize, hint->clsize, >- hint->mode != RM_CHECK ? " Fixed." : ""); >- >- /* Just fix the shift if wrong. */ >- if (hint->mode == RM_CHECK) { >- res |= RE_FIXABLE; >- } else { >- ccreg40_set_cluster_size(&cc->body, hint->clsize); >- } >+ /* check cluster shift. */ >+ result = ccreg40_get_cluster_shift(&cc->body, &shift); >+ if (result < 0) >+ return result; >+ if (shift == UNPREPPED_CLUSTER_SHIFT) { >+ fsck_mess("Found unprepped disk cluster "); >+ goto fatal; >+ } >+ if (shift < MIN_VALID_CLUSTER_SHIFT || >+ shift > MAX_VALID_CLUSTER_SHIFT || >+ shift != aal_log2(hint->clsize)) { >+ fsck_mess("Found item with wrong cluster shift %d, " >+ "should be %d", shift, aal_log2(hint->clsize)); >+ goto fatal; >+ } >+ if (hint->seek && >+ !ccreg40_clsame(hint->prev_found, hint->found, hint->clsize) && >+ ccreg40_cloff(hint->found, hint->clsize) != 0){ >+ fsck_mess("Found item of lenght (%llu) which has wrong " >+ "offset %llu, should be a multiple of logical " >+ "cluster size ", >+ hint->maxreal - hint->found + 1, hint->found); >+ goto fatal; > } >- > if (!ccreg40_clsame(hint->found, hint->maxreal, hint->clsize)) { >- /* The item covers the cluster border. Delete it. */ >- fsck_mess("The file [%s] (%s), node [%llu], item [%u]: " >- "item of the lenght (%llu) found, it cannot " >- "contain data of 2 clusters.%s", >- print_inode(obj40_core, &cc->info.object), >- reiser4_psobj(cc)->p.label, >- place_blknr(&cc->body), cc->body.pos.item, >- hint->maxreal - hint->found + 1, >- hint->mode == RM_BUILD ? " Removed." : ""); >- >- return hint->mode == RM_BUILD ? -ESTRUCT : RE_FATAL; >+ fsck_mess("Found item of length %llu and offset %llu, " >+ "which contains logical cluster boundary ", >+ hint->maxreal - hint->found + 1, hint->found); >+ goto fatal; > } >- >- return res; >+ return 0; >+ fatal: >+ fsck_mess("(file [%s] (%s), node [%llu], item [%u]). %s", >+ print_inode(obj40_core, &cc->info.object), >+ reiser4_psobj(cc)->p.label, >+ place_blknr(&cc->body), >+ cc->body.pos.item, >+ hint->mode == RM_BUILD ? " Removed." : ""); >+ hint->cut_from = hint->found; >+ hint->cut_size = hint->maxreal - hint->found + 1; >+ >+ return hint->mode == RM_BUILD ? -ESTRUCT : RE_FATAL; > } > > static int64_t ccreg40_read_item(reiser4_place_t *place, ccreg40_hint_t *hint) { >@@ -133,23 +134,21 @@ static errno_t ccreg40_check_crc(ccreg40 > return adler == disk ? 0 : RE_FATAL; > } > >+/* >+ * Read a found item to the stream. >+ * Check a checksum, if the previous iteration completed a disk cluster. >+ */ > static errno_t ccreg40_check_cluster(reiser4_object_t *cc, > ccreg40_hint_t *hint, > uint8_t mode) > { >- errno_t result; >+ errno_t result = 0; > errno_t res; >- int start; >- uint32_t lcl_size; >- >- result = 0; >- /* true, if the found item is the >- first one in the disk cluster */ >- start = (ccreg40_clstart(hint->found, hint->clsize) == hint->found); >+ uint32_t lcl_bytes; > > if ((cc->body.plug == NULL) || >- (hint->seek && start) || >- !ccreg40_clsame(hint->prev_found, hint->found, hint->clsize)) { >+ (hint->seek != 0 && >+ !ccreg40_clsame(hint->prev_found, hint->found, hint->clsize))) { > /* Cluster is over */ > > if (hint->prev_found > hint->sdsize) { >@@ -158,31 +157,32 @@ static errno_t ccreg40_check_cluster(rei > result = RE_FATAL; > > /* set offset of the cluster to be deleted. */ >- hint->clstart = ccreg40_clstart(hint->prev_found, >- hint->clsize); >+ hint->cut_from = ccreg40_clstart(hint->prev_found, >+ hint->clsize); > fsck_mess("The file [%s] (%s): the cluster at [%llu] " > "offset %u bytes long is orphan.%s", > print_inode(obj40_core, &cc->info.object), >- reiser4_psobj(cc)->p.label, hint->clstart, >+ reiser4_psobj(cc)->p.label, hint->cut_from, > hint->clsize, hint->mode != RM_CHECK ? > " Removed." : ""); > } > /** >- * If there still is a hole in the logical cluster, >- * then check a checksum (no hole means no checksum) >+ * If there still is a hole in the keyspace, then >+ * check a checksum (no such hole means that no >+ * checksum was appended) > */ >- else if (hint->hole && ccreg40_check_crc(hint)) { >+ else if (hint->bytes && hint->hole && ccreg40_check_crc(hint)) { > /* wrong checksum */ > hint->bytes = 0; > result = RE_FATAL; > > /* set offset of the cluster to be deleted. */ >- hint->clstart = ccreg40_clstart(hint->prev_found, >- hint->clsize); >+ hint->cut_from = ccreg40_clstart(hint->prev_found, >+ hint->clsize); > fsck_mess("The file [%s] (%s): the cluster at [%llu] " > "offset %u bytes long is corrupted.%s", > print_inode(obj40_core, &cc->info.object), >- reiser4_psobj(cc)->p.label, hint->clstart, >+ reiser4_psobj(cc)->p.label, hint->cut_from, > hint->clsize, hint->mode != RM_CHECK ? > " Removed." : ""); > } >@@ -192,16 +192,13 @@ static errno_t ccreg40_check_cluster(rei > hint->adler = 0; > > if (!cc->body.plug) >+ /* finish with this object */ > return result; > > /* Update the cluster data. */ > aal_memset(hint->data, 0, hint->clsize); > } >- > /* An item found. */ >- aal_assert("edward-1", >- ccreg40_clstart(hint->found, hint->clsize) == >- ccreg40_clstart(hint->maxreal, hint->clsize)); > > if ((res = ccreg40_read_item(&cc->body, hint))) > return res; >@@ -209,16 +206,19 @@ static errno_t ccreg40_check_cluster(rei > hint->prev_found = hint->found; > hint->bytes += objcall(&cc->body, object->bytes); > /** >- * Calculate a size of logical cluster >- * and figure out, if there is a hole >- * for the found items in the logical cluster. >+ * Calculate actual number of file's bytes in the >+ * logical cluster and figure out, if corresponding >+ * disk cluster has a hole in key space. >+ * >+ * We need this to figure out if disk cluster contains >+ * appended checksum. > */ >- lcl_size = 0; >+ lcl_bytes = 0; > if (ccreg40_clsame(hint->found, hint->sdsize - 1, hint->clsize)) >- lcl_size = hint->sdsize % hint->clsize; >- if (lcl_size == 0) >- lcl_size = hint->clsize; >- hint->hole = (hint->bytes != lcl_size); >+ lcl_bytes = hint->sdsize % hint->clsize; >+ if (lcl_bytes == 0) >+ lcl_bytes = hint->clsize; >+ hint->hole = (hint->bytes != lcl_bytes); > > return result; > } >@@ -256,8 +256,23 @@ errno_t ccreg40_check_struct(reiser4_obj > /* Get next item. */ > lookup = obj40_check_item(cc, ccreg40_check_item, NULL, &hint); > >- if (repair_error_fatal(lookup)) >- return lookup; >+ if (repair_error_fatal(lookup)) { >+ if ((lookup & RE_FATAL) && mode == RM_BUILD) { >+ /* >+ * Delete item found in this iteration >+ */ >+ res &= ~RE_FATAL; >+ res |= obj40_cut(cc, &trans, hint.cut_from, >+ hint.cut_size, NULL, NULL); >+ if (res < 0) >+ return res; >+ hint.seek = hint.maxreal + 1; >+ obj40_seek(cc, hint.seek); >+ continue; >+ } >+ else >+ return lookup; >+ } > else if (lookup == ABSENT) > cc->body.plug = NULL; > >@@ -267,16 +282,17 @@ errno_t ccreg40_check_struct(reiser4_obj > "registered yet.", print_key(obj40_core, > &info->object)); > } >- >+ /* check cluster found in previous iteration */ > if ((res |= ccreg40_check_cluster(cc, &hint, mode)) < 0) > return res; > > if (res & RE_FATAL) { >- /* Delete the whole cluster. */ >- >+ /* >+ * Delete cluster found in previous iteration >+ */ > if (mode == RM_BUILD) { > res &= ~RE_FATAL; >- res |= obj40_cut(cc, &trans, hint.clstart, >+ res |= obj40_cut(cc, &trans, hint.cut_from, > hint.clsize, NULL, NULL); > if (res < 0) > return res; >--- reiser4progs-1.0.7.orig/plugin/object/ccreg40/ccreg40.c >+++ reiser4progs-1.0.7/plugin/object/ccreg40/ccreg40.c >@@ -8,7 +8,7 @@ > #include "ccreg40.h" > #include "plugin/object/obj40/obj40_repair.h" > >-uint32_t ccreg40_get_cluster_size(reiser4_place_t *place) { >+errno_t ccreg40_get_cluster_shift(reiser4_place_t *place, uint8_t *shift) { > trans_hint_t hint; > ctail_hint_t chint; > >@@ -17,10 +17,12 @@ uint32_t ccreg40_get_cluster_size(reiser > hint.specific = &chint; > hint.count = 1; > >- if (objcall(place, object->fetch_units, &hint) != 1) >- return MAX_UINT32; >- >- return 1 << chint.shift; >+ if (objcall(place, object->fetch_units, &hint) != 1) { >+ aal_error("Can not extract cluster shift."); >+ return -EINVAL; >+ } >+ *shift = chint.shift; >+ return 0; > } > > errno_t ccreg40_set_cluster_size(reiser4_place_t *place, uint32_t cluster) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 453038
:
336170
| 336172 |
336174