From: Matthew Dillon Date: Tue, 5 Jul 2005 02:38:34 +0000 (+0000) Subject: * Fix a number of alignment errors that was causing garbage to be parsed. X-Git-Tag: v2.0.1~6699 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/36d6bdee113b682f2ab32b81472139ebfccbcd8e * Fix a number of alignment errors that was causing garbage to be parsed. * Fix a stream cache bug that was preventing some writes from synchronizing properly. * Report PAD headers as PAD headers rather then as unknown data. --- diff --git a/sbin/jscan/dump_mirror.c b/sbin/jscan/dump_mirror.c index 13b470e0ac..b966629b58 100644 --- a/sbin/jscan/dump_mirror.c +++ b/sbin/jscan/dump_mirror.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/jscan/dump_mirror.c,v 1.1 2005/07/05 00:26:03 dillon Exp $ + * $DragonFly: src/sbin/jscan/dump_mirror.c,v 1.2 2005/07/05 02:38:34 dillon Exp $ */ #include "jscan.h" @@ -43,7 +43,7 @@ static int dump_mirror_subrecord(struct jstream *js, off_t *off, off_t recsize, int level, struct jattr *jattr); static int dump_mirror_payload(int16_t rectype, struct jstream *js, off_t off, int recsize, int level, struct jattr *jattr); -static int dump_mirror_rebuild(u_int16_t rectype, struct jattr *jattr); +static int dump_mirror_rebuild(u_int16_t rectype, struct jstream *js, struct jattr *jattr); void dump_mirror(struct jfile *jf) @@ -67,8 +67,10 @@ dump_mirror_stream(struct jstream *js) jsread(js, 0, &head, sizeof(head)); sid = head.streamid & JREC_STREAMID_MASK; - if (debug_opt) - printf("STREAM %04x {\n", (int)(u_int16_t)head.streamid); + if (debug_opt) { + printf("STREAM %04x DATA (%lld) {\n", + (int)(u_int16_t)head.streamid, js->js_normalized_total); + } if (sid >= JREC_STREAMID_JMIN && sid < JREC_STREAMID_JMAX) { off_t off = sizeof(head); dump_mirror_toprecord(js, &off, js->js_normalized_total - @@ -99,8 +101,10 @@ dump_mirror_stream(struct jstream *js) } } umask(save_umask); - if (debug_opt) + if (debug_opt) { printf("}\n"); + fflush(stdout); + } } static int @@ -154,11 +158,17 @@ dump_mirror_toprecord(struct jstream *js, off_t *off, off_t recsize, int level) *off = base + sizeof(sub) + payload; if (debug_opt) printf("\n"); + } else if ((sub.rectype & JTYPE_MASK) == JLEAF_PAD) { + if (debug_opt) { + if (payload) + printf(" DATA (%d)", payload); + printf("\n"); + } } else { if (debug_opt) - printf("[%d bytes of unknown content]\n", sub.recsize); + printf("[%d bytes of unknown content]\n", payload); } - dump_mirror_rebuild(sub.rectype, &jattr); + dump_mirror_rebuild(sub.rectype, js, &jattr); jattr_reset(&jattr); if (error) break; @@ -202,7 +212,7 @@ dump_mirror_subrecord(struct jstream *js, off_t *off, off_t recsize, int level, if (debug_opt) { printf("%*.*s", level * 4, level * 4, ""); printf("@%lld ", base); - printf("RECORD %s [%04x/%d]", type_to_name(sub.rectype), + printf("SRECORD %s [%04x/%d]", type_to_name(sub.rectype), (int)(u_int16_t)sub.rectype, sub.recsize); } if (sub.recsize == -1) { @@ -241,6 +251,12 @@ dump_mirror_subrecord(struct jstream *js, off_t *off, off_t recsize, int level, *off = base + sizeof(sub) + payload; if (debug_opt) printf("\n"); + } else if ((sub.rectype & JTYPE_MASK) == JLEAF_PAD) { + if (debug_opt) { + if (payload) + printf(" DATA (%d)", payload); + printf("\n"); + } } else { if (debug_opt) printf("[%d bytes of unknown content]\n", sub.recsize); @@ -268,22 +284,41 @@ dump_mirror_payload(int16_t rectype, struct jstream *js, off_t off, int recsize, int level __unused, struct jattr *jattr) { const char *buf; + struct jattr_data *data; int error; if (jattr == NULL) return (0); - error = jsreadp(js, off, (const void **)&buf, recsize); - if (error) - return (error); + if ((rectype & ~JMASK_LAST) != JLEAF_FILEDATA) { + error = jsreadp(js, off, (const void **)&buf, recsize); + if (error) + return (error); + } else { + buf = NULL; + error = 0; + } switch(rectype & ~JMASK_LAST) { case JLEAF_PAD: case JLEAF_ABORT: break; + case JLEAF_SYMLINKDATA: case JLEAF_FILEDATA: - jattr->data = dupdata(buf, recsize); - jattr->datalen = recsize; + printf("DOING FILEDATA1 %p off %08llx bytes %d\n", jattr->last_data, off, recsize); + if ((data = jattr->last_data) == NULL) { + jattr->data.off = off; + jattr->data.bytes = recsize; + jattr->last_data = &jattr->data; + } else { + data->next = malloc(sizeof(jattr->data)); + data = data->next; + data->off = off; + data->bytes = recsize; + data->next = NULL; + jattr->last_data = data; + } + printf("DOING FILEDATA2 %p\n", jattr->last_data); break; case JLEAF_PATH1: jattr->path1 = dupdatapath(buf, recsize); @@ -329,10 +364,6 @@ dump_mirror_payload(int16_t rectype, struct jstream *js, off_t off, break; case JLEAF_RESERVED_0F: break; - case JLEAF_SYMLINKDATA: - jattr->data = dupdata(buf, recsize); - jattr->datalen = recsize; - break; case JLEAF_SEEKPOS: jattr->seekpos = buf_to_int64(buf, recsize); break; @@ -376,8 +407,9 @@ dump_mirror_payload(int16_t rectype, struct jstream *js, off_t off, } static int -dump_mirror_rebuild(u_int16_t rectype, struct jattr *jattr) +dump_mirror_rebuild(u_int16_t rectype, struct jstream *js, struct jattr *jattr) { + struct jattr_data *data; int error = 0; int fd; @@ -399,10 +431,14 @@ again: break; case JTYPE_WRITE: case JTYPE_PUTPAGES: - if (jattr->pathref && jattr->seekpos != -1 && jattr->data) { + if (jattr->pathref && jattr->seekpos != -1) { if ((fd = open(jattr->pathref, O_RDWR)) >= 0) { lseek(fd, jattr->seekpos, 0); - write(fd, jattr->data, jattr->datalen); + for (data = &jattr->data; data; data = data->next) { + printf("WRITEBLOCK @ %016llx/%d\n", data->off, data->bytes); + if (data->bytes) + jsreadcallback(js, write, fd, data->off, data->bytes); + } close(fd); } } diff --git a/sbin/jscan/jattr.h b/sbin/jscan/jattr.h index 39c8108a98..f824915e7c 100644 --- a/sbin/jscan/jattr.h +++ b/sbin/jscan/jattr.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/jscan/jattr.h,v 1.1 2005/07/05 00:26:03 dillon Exp $ + * $DragonFly: src/sbin/jscan/jattr.h,v 1.2 2005/07/05 02:38:34 dillon Exp $ */ struct jattr { @@ -49,8 +49,12 @@ struct jattr { char *comm; char *attrname; char *pathref; - char *data; - int datalen; + struct jattr_data { + struct jattr_data *next; + off_t off; + int bytes; + } data; + struct jattr_data *last_data; int64_t seekpos; int64_t inum; int nlink; diff --git a/sbin/jscan/jscan.h b/sbin/jscan/jscan.h index 3f964c7617..58379ad579 100644 --- a/sbin/jscan/jscan.h +++ b/sbin/jscan/jscan.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/jscan/jscan.h,v 1.3 2005/07/05 00:26:03 dillon Exp $ + * $DragonFly: src/sbin/jscan/jscan.h,v 1.4 2005/07/05 02:38:34 dillon Exp $ */ #include @@ -89,7 +89,6 @@ struct jstream { * chain. */ struct jstream *js_cache; - off_t js_cache_off; char js_data[4]; /* variable length (original data) */ }; @@ -135,4 +134,6 @@ int dump_debug_payload(int16_t rectype, struct jstream *js, off_t off, int jsreadany(struct jstream *js, off_t off, const void **bufp); int jsreadp(struct jstream *js, off_t off, const void **bufp, int bytes); int jsread(struct jstream *js, off_t off, void *buf, int bytes); +int jsreadcallback(struct jstream *js, ssize_t (*func)(int, const void *, size_t), int fd, off_t off, int bytes); + diff --git a/sbin/jscan/jstream.c b/sbin/jscan/jstream.c index 57e6fd5ecd..d390e26f30 100644 --- a/sbin/jscan/jstream.c +++ b/sbin/jscan/jstream.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/jscan/jstream.c,v 1.2 2005/07/05 00:26:03 dillon Exp $ + * $DragonFly: src/sbin/jscan/jstream.c,v 1.3 2005/07/05 02:38:34 dillon Exp $ */ #include "jscan.h" @@ -115,7 +115,12 @@ jscan_stream(struct jfile *jf) js = NULL; break; } - js->js_size = recsize; + + /* + * note: recsize is aligned (the actual record size), + * head.recsize is unaligned (the actual payload size). + */ + js->js_size = head.recsize; bcopy(js->js_data + recsize - sizeof(tail), &tail, sizeof(tail)); if (tail.endmagic != JREC_ENDMAGIC) { jf_warn(jf, "bad endmagic, searching for new record"); @@ -162,7 +167,7 @@ jscan_stream(struct jfile *jf) js = NULL; break; } - js->js_size = recsize; + js->js_size = tail.recsize; bcopy(js->js_data + recsize - sizeof(tail), &tail, sizeof(tail)); bcopy(js->js_data, &head, sizeof(head)); if (head.begmagic != JREC_BEGMAGIC) { @@ -360,6 +365,31 @@ jsreadp(struct jstream *js, off_t off, const void **bufp, return(error); } +int +jsreadcallback(struct jstream *js, ssize_t (*func)(int, const void *, size_t), + int fd, off_t off, int bytes) +{ + const void *bufp; + int res; + int n; + int r; + + res = 0; + while (bytes && (n = jsreadany(js, off, &bufp)) > 0) { + if (n > bytes) + n = bytes; + r = func(fd, bufp, n); + if (r != n) { + if (res == 0) + res = -1; + } + res += n; + bytes -= n; + off += n; + } + return(res); +} + /* * Return the largest contiguous buffer starting at the specified offset, * or 0. @@ -370,11 +400,10 @@ jsreadany(struct jstream *js, off_t off, const void **bufp) struct jstream *scan; int n; - if ((scan = js->js_cache) == NULL || scan->js_cache_off > off) + if ((scan = js->js_cache) == NULL || scan->js_normalized_off > off) scan = js; while (scan && scan->js_normalized_off <= off) { js->js_cache = scan; - js->js_cache_off = scan->js_normalized_off; if (scan->js_normalized_off + scan->js_normalized_size > off) { n = (int)(off - scan->js_normalized_off); *bufp = scan->js_normalized_base + n; diff --git a/sbin/jscan/subs.c b/sbin/jscan/subs.c index fc849cf757..00fb3f6cac 100644 --- a/sbin/jscan/subs.c +++ b/sbin/jscan/subs.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sbin/jscan/subs.c,v 1.3 2005/07/05 00:26:03 dillon Exp $ + * $DragonFly: src/sbin/jscan/subs.c,v 1.4 2005/07/05 02:38:34 dillon Exp $ */ #include "jscan.h" @@ -234,6 +234,7 @@ void jattr_reset(struct jattr *jattr) { struct jattr *undo; + struct jattr_data *data; if (jattr->path1) free(jattr->path1); @@ -249,8 +250,10 @@ jattr_reset(struct jattr *jattr) free(jattr->attrname); if (jattr->pathref) free(jattr->pathref); - if (jattr->data) - free(jattr->data); + while ((data = jattr->data.next) != NULL) { + jattr->data.next = data->next; + free(data); + } if ((undo = jattr->undo) != NULL) jattr_reset(jattr->undo); bzero(jattr, sizeof(*jattr));