Date: Tue, 30 Aug 2005 00:09:14 GMT From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82811 for review Message-ID: <200508300009.j7U09EI4010073@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82811 Change 82811 by peter@peter_daintree on 2005/08/30 00:08:21 IFC @82810 Affected files ... .. //depot/projects/hammer/bin/sh/sh.1#18 integrate .. //depot/projects/hammer/lib/libc/string/strcspn.3#2 integrate .. //depot/projects/hammer/lib/libc/string/strspn.3#2 integrate .. //depot/projects/hammer/sys/dev/wi/if_wi.c#42 integrate .. //depot/projects/hammer/sys/kern/uipc_mbuf.c#31 integrate .. //depot/projects/hammer/sys/sys/mbuf.h#43 integrate .. //depot/projects/hammer/tools/tools/recoverdisk/README#3 integrate .. //depot/projects/hammer/tools/tools/recoverdisk/recoverdisk.c#4 integrate Differences ... ==== //depot/projects/hammer/bin/sh/sh.1#18 (text+ko) ==== @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 -.\" $FreeBSD: src/bin/sh/sh.1,v 1.104 2005/08/29 06:47:43 jcamou Exp $ +.\" $FreeBSD: src/bin/sh/sh.1,v 1.105 2005/08/29 21:28:12 jcamou Exp $ .\" .Dd August 17, 2005 .Dt SH 1 @@ -426,7 +426,8 @@ .Pp An alias name may be escaped in a command line, so that it is not replaced by its alias value, by using quoting characters within or -adjacent to the alias name. This is most often done by prefixing +adjacent to the alias name. +This is most often done by prefixing an alias name with a backslash to execute a function, built-in, or normal program with the same name. See the ==== //depot/projects/hammer/lib/libc/string/strcspn.3#2 (text+ko) ==== @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strcspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.7 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strcspn.3,v 1.8 2005/08/29 20:41:58 garys Exp $ .\" .Dd June 4, 1993 .Dt STRCSPN 3 @@ -63,6 +63,13 @@ .Em complement of .Fa charset ) . +In other words, it computes the string array index in +.Fa s +of the first character of +.Fa s +which is also in +.Fa charset , +else the index of the first null character. .Sh RETURN VALUES The .Fn strcspn ==== //depot/projects/hammer/lib/libc/string/strspn.3#2 (text+ko) ==== @@ -34,7 +34,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)strspn.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.8 2001/10/01 16:09:00 ru Exp $ +.\" $FreeBSD: src/lib/libc/string/strspn.3,v 1.9 2005/08/29 20:41:58 garys Exp $ .\" .Dd June 4, 1993 .Dt STRSPN 3 @@ -56,8 +56,15 @@ .Fa s as long as the characters from .Fa s -occur in string +occur in the null-terminated string .Fa charset . +In other words, it computes the string array index in +.Fa s +of the first character of +.Fa s +which is not in +.Fa charset , +else the index of the first null character. .Sh RETURN VALUES The .Fn strspn ==== //depot/projects/hammer/sys/dev/wi/if_wi.c#42 (text+ko) ==== @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.188 2005/08/29 15:46:41 imp Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.189 2005/08/29 20:06:02 scottl Exp $"); #define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ #define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ @@ -2444,7 +2444,6 @@ if (i == 0) { device_printf(sc->sc_dev, "wi_cmd: busy bit won't clear.\n" ); sc->wi_gone = 1; - count--; return(ETIMEDOUT); } @@ -2468,7 +2467,6 @@ s = CSR_READ_2(sc, WI_STATUS); CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); if (s & WI_STAT_CMD_RESULT) { - count--; return(EIO); } break; @@ -2476,7 +2474,6 @@ DELAY(WI_DELAY); } - count--; if (i == WI_TIMEOUT) { device_printf(sc->sc_dev, "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s); ==== //depot/projects/hammer/sys/kern/uipc_mbuf.c#31 (text+ko) ==== @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/uipc_mbuf.c,v 1.149 2005/07/30 01:32:16 sam Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/uipc_mbuf.c,v 1.152 2005/08/29 20:15:33 andre Exp $"); #include "opt_mac.h" #include "opt_param.h" @@ -270,6 +270,125 @@ } /* + * Clean up mbuf (chain) from any tags and packet headers. + * If "all" is set then the first mbuf in the chain will be + * cleaned too. + */ +void +m_demote(struct mbuf *m0, int all) +{ + struct mbuf *m; + + for (m = all ? m0 : m0->m_next; m != NULL; m = m->m_next) { + if (m->m_flags & M_PKTHDR) { + m_tag_delete_chain(m, NULL); + m->m_flags &= ~M_PKTHDR; + bzero(&m->m_pkthdr, sizeof(struct pkthdr)); + } + if (m->m_type & MT_HEADER) + m->m_type = MT_DATA; + if (m != m0 && m->m_nextpkt) + m->m_nextpkt = NULL; + m->m_flags = m->m_flags & (M_EXT|M_EOR|M_RDONLY|M_FREELIST); + } +} + +/* + * Sanity checks on mbuf (chain). + * Returns 0 bad, 1 good, panic worse. + * sanitize, 0 run M_SANITY_ACTION, 1 garble things so they blow up later. + */ +int +m_sanity(struct mbuf *m0, int sanitize) +{ + struct mbuf *m; + caddr_t a, b; + int pktlen = 0; + +#define M_SANITY_ACTION(s) return (0) +/* #define M_SANITY_ACTION(s) panic("mbuf %p: " s, m) */ + + m = m0; + while (m) { + /* + * Basic pointer checks. If any of these fails then some + * unrelated kernel memory before or after us is trashed. + * No way to recover from that. + */ + a = (m->m_flags & M_EXT ? m->m_ext.ext_buf : + (m->m_flags & M_PKTHDR ? (caddr_t)(&m->m_pktdat) : + (caddr_t)(&m->m_dat)) ); + b = (caddr_t)(a + (m->m_flags & M_EXT ? m->m_ext.ext_size : + (m->m_flags & M_PKTHDR ? MHLEN : MLEN))); + if ((caddr_t)m->m_data < a) + M_SANITY_ACTION("m_data outside mbuf data range left"); + if ((caddr_t)m->m_data > b) + M_SANITY_ACTION("m_data outside mbuf data range right"); + if ((caddr_t)m->m_data + m->m_len > b) + M_SANITY_ACTION("m_data + m_len exeeds mbuf space"); + if (m->m_flags & M_PKTHDR && m->m_pkthdr.header) { + if ((caddr_t)m->m_pkthdr.header < a || + (caddr_t)m->m_pkthdr.header > b) + M_SANITY_ACTION("m_pkthdr.header outside mbuf data range"); + } + + /* m->m_nextpkt may only be set on first mbuf in chain. */ + if (m != m0 && m->m_nextpkt) { + if (sanitize) { + m_freem(m->m_nextpkt); + m->m_nextpkt = (struct mbuf *)0xDEADC0DE; + } else + M_SANITY_ACTION("m->m_nextpkt on in-chain mbuf"); + } + + /* correct type correlations. */ + if (m->m_type == MT_HEADER && !(m->m_flags & M_PKTHDR)) { + if (sanitize) + m->m_type = MT_DATA; + else + M_SANITY_ACTION("MT_HEADER set but not M_PKTHDR"); + } + + /* packet length (not mbuf length!) calculation */ + if (m0->m_flags & M_PKTHDR) + pktlen += m->m_len; + + /* m_tags may only be attached to first mbuf in chain. */ + if (m != m0 && m->m_flags & M_PKTHDR && + !SLIST_EMPTY(&m->m_pkthdr.tags)) { + if (sanitize) { + m_tag_delete_chain(m, NULL); + /* put in 0xDEADC0DE perhaps? */ + } + else + M_SANITY_ACTION("m_tags on in-chain mbuf"); + } + + /* M_PKTHDR may only be set on first mbuf in chain */ + if (m != m0 && m->m_flags & M_PKTHDR) { + if (sanitize) { + bzero(&m->m_pkthdr, sizeof(m->m_pkthdr)); + m->m_flags &= ~M_PKTHDR; + /* put in 0xDEADCODE and leave hdr flag in */ + } else + M_SANITY_ACTION("M_PKTHDR on in-chain mbuf"); + } + + m = m->m_next; + } + if (pktlen && pktlen != m0->m_pkthdr.len) { + if (sanitize) + m0->m_pkthdr.len = 0; + else + M_SANITY_ACTION("m_pkthdr.len != mbuf chain length"); + } +#undef M_SANITY_ACTION + + return 1; +} + + +/* * "Move" mbuf pkthdr from "from" to "to". * "from" must have M_PKTHDR set, and "to" must be empty. */ @@ -439,6 +558,151 @@ } /* + * Returns mbuf chain with new head for the prepending case. + * Copies from mbuf (chain) n from off for len to mbuf (chain) m + * either prepending or appending the data. + * The resulting mbuf (chain) m is fully writeable. + * m is destination (is made writeable) + * n is source, off is offset in source, len is len from offset + * dir, 0 append, 1 prepend + * how, wait or nowait + */ + +static int +m_bcopyxxx(void *s, void *t, u_int len) +{ + bcopy(s, t, (size_t)len); + return 0; +} + +struct mbuf * +m_copymdata(struct mbuf *m, struct mbuf *n, int off, int len, + int prep, int how) +{ + struct mbuf *mm, *x, *z; + caddr_t p; + int i, mlen, nlen = 0; + caddr_t buf[MLEN]; + + KASSERT(m != NULL && n != NULL, ("m_copymdata, no target or source")); + KASSERT(off >= 0, ("m_copymdata, negative off %d", off)); + KASSERT(len >= 0, ("m_copymdata, negative len %d", len)); + KASSERT(prep == 0 || prep == 1, ("m_copymdata, unknown direction %d", prep)); + + /* Make sure environment is sane. */ + for (z = m; z != NULL; z = z->m_next) { + mlen += z->m_len; + if (!M_WRITABLE(z)) { + /* Make clusters writeable. */ + if (z->m_flags & M_RDONLY) + return NULL; /* Can't handle ext ref. */ + x = m_getcl(how, MT_DATA, 0); + if (!x) + return NULL; + bcopy(z->m_ext.ext_buf, x->m_ext.ext_buf, x->m_ext.ext_size); + p = x->m_ext.ext_buf + (z->m_data - z->m_ext.ext_buf); + MEXT_REM_REF(z); /* XXX */ + z->m_data = p; + x->m_flags &= ~M_EXT; + (void)m_free(x); + } + } + mm = prep ? m : z; + for (z = n; z != NULL; z = z->m_next) + nlen += z->m_len; + if (len == M_COPYALL) + len = nlen - off; + if (off + len > nlen || len < 1) + return NULL; + + /* + * Append/prepend the data. Allocating mbufs as necessary. + */ + /* Shortcut if enough free space in first/last mbuf. */ + if (!prep && M_TRAILINGSPACE(mm) >= len) { + m_apply(n, off, len, m_bcopyxxx, mtod(mm, caddr_t) + + mm->m_len); + mm->m_len += len; + mm->m_pkthdr.len += len; + return m; + } + if (prep && M_LEADINGSPACE(mm) >= len) { + mm->m_data = mtod(mm, caddr_t) - len; + m_apply(n, off, len, m_bcopyxxx, mtod(mm, caddr_t)); + mm->m_len += len; + mm->m_pkthdr.len += len; + return mm; + } + + /* Expand first/last mbuf to cluster if possible. */ + if (!prep && !(mm->m_flags & M_EXT) && len > M_TRAILINGSPACE(mm)) { + bcopy(mm->m_data, &buf, mm->m_len); + m_clget(mm, how); + if (!(mm->m_flags & M_EXT)) + return NULL; + bcopy(&buf, mm->m_ext.ext_buf, mm->m_len); + mm->m_data = mm->m_ext.ext_buf; + mm->m_pkthdr.header = NULL; + } + if (prep && !(mm->m_flags & M_EXT) && len > M_LEADINGSPACE(mm)) { + bcopy(mm->m_data, &buf, mm->m_len); + m_clget(mm, how); + if (!(mm->m_flags & M_EXT)) + return NULL; + bcopy(&buf, (caddr_t *)mm->m_ext.ext_buf + + mm->m_ext.ext_size - mm->m_len, mm->m_len); + mm->m_data = (caddr_t)mm->m_ext.ext_buf + + mm->m_ext.ext_size - mm->m_len; + mm->m_pkthdr.header = NULL; + } + + /* Append/prepend as many mbuf (clusters) as necessary to fit len. */ + if (!prep && len > M_TRAILINGSPACE(mm)) { + if (!m_getm(mm, len - M_TRAILINGSPACE(mm), how, MT_DATA)) + return NULL; + } + if (prep && len > M_LEADINGSPACE(mm)) { + if (!(z = m_getm(NULL, len - M_LEADINGSPACE(mm), how, MT_DATA))) + return NULL; + i = 0; + for (x = z; x != NULL; x = x->m_next) { + i += x->m_flags & M_EXT ? x->m_ext.ext_size : + (x->m_flags & M_PKTHDR ? MHLEN : MLEN); + if (!x->m_next) + break; + } + z->m_data += i - len; + m_move_pkthdr(mm, z); + x->m_next = mm; + mm = z; + } + + /* Seek to start position in source mbuf. Optimization for long chains. */ + while (off > 0) { + if (off < n->m_len) + break; + off -= n->m_len; + n = n->m_next; + } + + /* Copy data into target mbuf. */ + z = mm; + while (len > 0) { + KASSERT(z != NULL, ("m_copymdata, falling off target edge")); + i = M_TRAILINGSPACE(z); + m_apply(n, off, i, m_bcopyxxx, mtod(z, caddr_t) + z->m_len); + z->m_len += i; + /* fixup pkthdr.len if necessary */ + if ((prep ? mm : m)->m_flags & M_PKTHDR) + (prep ? mm : m)->m_pkthdr.len += i; + off += i; + len -= i; + z = z->m_next; + } + return (prep ? mm : m); +} + +/* * Copy an entire packet, including header (which must be present). * An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'. * Note that the copy is read-only, because clusters are not copied, ==== //depot/projects/hammer/sys/sys/mbuf.h#43 (text+ko) ==== @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * @(#)mbuf.h 8.5 (Berkeley) 2/19/95 - * $FreeBSD: src/sys/sys/mbuf.h,v 1.172 2005/07/30 01:32:16 sam Exp $ + * $FreeBSD: src/sys/sys/mbuf.h,v 1.175 2005/08/29 20:15:33 andre Exp $ */ #ifndef _SYS_MBUF_H_ @@ -573,10 +573,13 @@ void m_copyback(struct mbuf *, int, int, c_caddr_t); void m_copydata(const struct mbuf *, int, int, caddr_t); struct mbuf *m_copym(struct mbuf *, int, int, int); +struct mbuf *m_copymdata(struct mbuf *, struct mbuf *, + int, int, int, int); struct mbuf *m_copypacket(struct mbuf *, int); void m_copy_pkthdr(struct mbuf *, struct mbuf *); struct mbuf *m_copyup(struct mbuf *n, int len, int dstoff); struct mbuf *m_defrag(struct mbuf *, int); +void m_demote(struct mbuf *, int); struct mbuf *m_devget(char *, int, int, struct ifnet *, void (*)(char *, caddr_t, u_int)); struct mbuf *m_dup(struct mbuf *, int); @@ -592,6 +595,7 @@ void m_print(const struct mbuf *, int); struct mbuf *m_pulldown(struct mbuf *, int, int, int *); struct mbuf *m_pullup(struct mbuf *, int); +int m_sanity(struct mbuf *, int); struct mbuf *m_split(struct mbuf *, int, int); struct mbuf *m_uiotombuf(struct uio *, int, int, int); ==== //depot/projects/hammer/tools/tools/recoverdisk/README#3 (text+ko) ==== @@ -1,7 +1,7 @@ -$FreeBSD: src/tools/tools/recoverdisk/README,v 1.2 2005/02/07 11:26:53 obrien Exp $ +$FreeBSD: src/tools/tools/recoverdisk/README,v 1.3 2005/08/29 23:08:01 sobomax Exp $ -This is a small tool which will read an entire disk(partition) using -1M blocks and optionally write the read data to a file or disk. +This is a small tool which will read an entire disk(partition) or file +using 1M blocks and optionally write the read data to a file or disk. If a read error happens, the 1M block gets put on the end of the worklist and will be retried with 64k blocksize. @@ -20,3 +20,6 @@ touch myfloppy.flp recoverdisk /dev/fd0 myfloppy.flp +or recover a single file from the unreadable media: + + recoverdisk /cdrom/file.avi file.avi ==== //depot/projects/hammer/tools/tools/recoverdisk/recoverdisk.c#4 (text+ko) ==== @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $FreeBSD: src/tools/tools/recoverdisk/recoverdisk.c,v 1.4 2004/10/23 15:58:50 des Exp $ + * $FreeBSD: src/tools/tools/recoverdisk/recoverdisk.c,v 1.5 2005/08/29 23:08:01 sobomax Exp $ */ #include <stdio.h> #include <stdint.h> @@ -18,9 +18,11 @@ #include <unistd.h> #include <sys/queue.h> #include <sys/disk.h> +#include <sys/stat.h> #define BIGSIZE (1024 * 1024) #define MEDIUMSIZE (64 * 1024) +#define MINSIZE (512) struct lump { off_t start; @@ -53,10 +55,11 @@ struct lump *lp; off_t t, d; size_t i, j; - int error; + int error, flags; u_char *buf; - u_int sectorsize; + u_int sectorsize, minsize; time_t t1, t2; + struct stat sb; if (argc < 2) @@ -68,22 +71,35 @@ fdr = open(argv[1], O_RDONLY); if (fdr < 0) err(1, "Cannot open read descriptor %s", argv[1]); + + error = fstat(fdr, &sb); + if (error < 0) + err(1, "fstat failed"); + flags = O_WRONLY; + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { + error = ioctl(fdr, DIOCGSECTORSIZE, §orsize); + if (error < 0) + err(1, "DIOCGSECTORSIZE failed"); + minsize = sectorsize; + + error = ioctl(fdr, DIOCGMEDIASIZE, &t); + if (error < 0) + err(1, "DIOCGMEDIASIZE failed"); + } else { + sectorsize = 1; + t = sb.st_size; + minsize = MINSIZE; + flags |= O_CREAT | O_TRUNC; + } + if (argc > 2) { - fdw = open(argv[2], O_WRONLY); + fdw = open(argv[2], flags, DEFFILEMODE); if (fdw < 0) err(1, "Cannot open write descriptor %s", argv[2]); } else { fdw = -1; } - error = ioctl(fdr, DIOCGSECTORSIZE, §orsize); - if (error < 0) - err(1, "DIOCGSECTORSIZE failed"); - - error = ioctl(fdr, DIOCGMEDIASIZE, &t); - if (error < 0) - err(1, "DIOCGMEDIASIZE failed"); - new_lump(0, t, 0); d = 0; @@ -100,7 +116,7 @@ if (lp->state == 1) i = MEDIUMSIZE; if (lp->state > 1) - i = sectorsize; + i = minsize; time(&t2); if (t1 != t2 || lp->len < BIGSIZE) { printf("\r%13jd %7zu %13jd %3d %13jd %13jd %.8f",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508300009.j7U09EI4010073>