From 59966d51c60f6f98fad5feae4e90d98fdf9b2017 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 14 Mar 2015 13:45:43 +0000 Subject: [PATCH 1/5] restore: Preserve timestamps to the nanosecond. The restore utility already knows the full-resolution timestamps, so the only thing to do is to stop converting the timespecs to timevals and use futimens() and utimensat(). Differential Revision: https://reviews.freebsd.org/D2020 Reviewed by: jhb --- sbin/restore/dirs.c | 16 ++++++++-------- sbin/restore/tape.c | 28 +++++++++++++++------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/sbin/restore/dirs.c b/sbin/restore/dirs.c index b2cd8fd28869..7b308cd02415 100644 --- a/sbin/restore/dirs.c +++ b/sbin/restore/dirs.c @@ -80,8 +80,8 @@ static struct inotab *inotab[HASHSIZE]; */ struct modeinfo { ino_t ino; - struct timeval ctimep[2]; - struct timeval mtimep[2]; + struct timespec ctimep[2]; + struct timespec mtimep[2]; mode_t mode; uid_t uid; gid_t gid; @@ -656,8 +656,8 @@ setdirmodes(int flags) else (void) chown(cp, node.uid, node.gid); (void) chmod(cp, node.mode); - utimes(cp, node.ctimep); - utimes(cp, node.mtimep); + utimensat(AT_FDCWD, cp, node.ctimep, 0); + utimensat(AT_FDCWD, cp, node.mtimep, 0); (void) chflags(cp, node.flags); } ep->e_flags &= ~NEW; @@ -746,13 +746,13 @@ allocinotab(struct context *ctxp, long seekpt) return (itp); node.ino = ctxp->ino; node.mtimep[0].tv_sec = ctxp->atime_sec; - node.mtimep[0].tv_usec = ctxp->atime_nsec / 1000; + node.mtimep[0].tv_nsec = ctxp->atime_nsec; node.mtimep[1].tv_sec = ctxp->mtime_sec; - node.mtimep[1].tv_usec = ctxp->mtime_nsec / 1000; + node.mtimep[1].tv_nsec = ctxp->mtime_nsec; node.ctimep[0].tv_sec = ctxp->atime_sec; - node.ctimep[0].tv_usec = ctxp->atime_nsec / 1000; + node.ctimep[0].tv_nsec = ctxp->atime_nsec; node.ctimep[1].tv_sec = ctxp->birthtime_sec; - node.ctimep[1].tv_usec = ctxp->birthtime_nsec / 1000; + node.ctimep[1].tv_nsec = ctxp->birthtime_nsec; node.extsize = ctxp->extsize; node.mode = ctxp->mode; node.flags = ctxp->file_flags; diff --git a/sbin/restore/tape.c b/sbin/restore/tape.c index 225fe3250bdb..9c9890f1b8a3 100644 --- a/sbin/restore/tape.c +++ b/sbin/restore/tape.c @@ -569,20 +569,20 @@ extractfile(char *name) gid_t gid; mode_t mode; int extsize; - struct timeval mtimep[2], ctimep[2]; + struct timespec mtimep[2], ctimep[2]; struct entry *ep; char *buf; curfile.name = name; curfile.action = USING; mtimep[0].tv_sec = curfile.atime_sec; - mtimep[0].tv_usec = curfile.atime_nsec / 1000; + mtimep[0].tv_nsec = curfile.atime_nsec; mtimep[1].tv_sec = curfile.mtime_sec; - mtimep[1].tv_usec = curfile.mtime_nsec / 1000; + mtimep[1].tv_nsec = curfile.mtime_nsec; ctimep[0].tv_sec = curfile.atime_sec; - ctimep[0].tv_usec = curfile.atime_nsec / 1000; + ctimep[0].tv_nsec = curfile.atime_nsec; ctimep[1].tv_sec = curfile.birthtime_sec; - ctimep[1].tv_usec = curfile.birthtime_nsec / 1000; + ctimep[1].tv_nsec = curfile.birthtime_nsec; extsize = curfile.extsize; uid = getuid(); if (uid == 0) @@ -628,8 +628,10 @@ extractfile(char *name) set_extattr_link(name, buf, extsize); (void) lchown(name, uid, gid); (void) lchmod(name, mode); - (void) lutimes(name, ctimep); - (void) lutimes(name, mtimep); + (void) utimensat(AT_FDCWD, name, ctimep, + AT_SYMLINK_NOFOLLOW); + (void) utimensat(AT_FDCWD, name, mtimep, + AT_SYMLINK_NOFOLLOW); (void) lchflags(name, flags); return (GOOD); } @@ -658,8 +660,8 @@ extractfile(char *name) } (void) chown(name, uid, gid); (void) chmod(name, mode); - (void) utimes(name, ctimep); - (void) utimes(name, mtimep); + (void) utimensat(AT_FDCWD, name, ctimep, 0); + (void) utimensat(AT_FDCWD, name, mtimep, 0); (void) chflags(name, flags); return (GOOD); @@ -688,8 +690,8 @@ extractfile(char *name) } (void) chown(name, uid, gid); (void) chmod(name, mode); - (void) utimes(name, ctimep); - (void) utimes(name, mtimep); + (void) utimensat(AT_FDCWD, name, ctimep, 0); + (void) utimensat(AT_FDCWD, name, mtimep, 0); (void) chflags(name, flags); return (GOOD); @@ -714,8 +716,8 @@ extractfile(char *name) set_extattr_fd(ofile, name, buf, extsize); (void) fchown(ofile, uid, gid); (void) fchmod(ofile, mode); - (void) futimes(ofile, ctimep); - (void) futimes(ofile, mtimep); + (void) futimens(ofile, ctimep); + (void) futimens(ofile, mtimep); (void) fchflags(ofile, flags); (void) close(ofile); return (GOOD); From df57ec493334287c783526f6d5b4e83722031dc6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 14 Mar 2015 14:06:37 +0000 Subject: [PATCH 2/5] Add checksums to identify data and NCQ command error log. MFC after: 2 weeks --- usr.sbin/bhyve/pci_ahci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/usr.sbin/bhyve/pci_ahci.c b/usr.sbin/bhyve/pci_ahci.c index 0bba2ad6c5f9..6a0af28d437d 100644 --- a/usr.sbin/bhyve/pci_ahci.c +++ b/usr.sbin/bhyve/pci_ahci.c @@ -793,6 +793,17 @@ write_prdt(struct ahci_port *p, int slot, uint8_t *cfis, hdr->prdbc = size - len; } +static void +ahci_checksum(uint8_t *buf, int size) +{ + int i; + uint8_t sum = 0; + + for (i = 0; i < size - 1; i++) + sum += buf[i]; + buf[size - 1] = 0x100 - sum; +} + static void ahci_handle_read_log(struct ahci_port *p, int slot, uint8_t *cfis) { @@ -809,6 +820,7 @@ ahci_handle_read_log(struct ahci_port *p, int slot, uint8_t *cfis) memset(buf, 0, sizeof(buf)); memcpy(buf, p->err_cfis, sizeof(p->err_cfis)); + ahci_checksum(buf, sizeof(buf)); if (cfis[2] == ATA_READ_LOG_EXT) ahci_write_fis_piosetup(p); @@ -914,6 +926,8 @@ handle_identify(struct ahci_port *p, int slot, uint8_t *cfis) buf[119] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); buf[120] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); buf[222] = 0x1020; + buf[255] = 0x00a5; + ahci_checksum((uint8_t *)buf, sizeof(buf)); ahci_write_fis_piosetup(p); write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); @@ -962,6 +976,8 @@ handle_atapi_identify(struct ahci_port *p, int slot, uint8_t *cfis) if (p->xfermode & ATA_UDMA0) buf[88] |= (1 << ((p->xfermode & 7) + 8)); buf[222] = 0x1020; + buf[255] = 0x00a5; + ahci_checksum((uint8_t *)buf, sizeof(buf)); ahci_write_fis_piosetup(p); write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); From f4d281428f9eb458ffc19df9a1ed9e2af0950b8e Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 14 Mar 2015 16:02:11 +0000 Subject: [PATCH 3/5] Add a new flag, SBUF_INCLUDENUL, and new get/set/clear functions for flags. The SBUF_INCLUDENUL flag causes the nulterm byte at the end of the string to be counted in the length of the data. If copying the data using the sbuf_data() and sbuf_len() functions, or if writing it automatically with a drain function, the net effect is that the nulterm byte is copied along with the rest of the data. --- share/man/man9/sbuf.9 | 25 ++++++++++++++++++++++++- sys/kern/subr_sbuf.c | 30 +++++++++++++++++++++++++++++- sys/sys/sbuf.h | 4 ++++ 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9 index 495726c5fb16..f696307179ca 100644 --- a/share/man/man9/sbuf.9 +++ b/share/man/man9/sbuf.9 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 11, 2013 +.Dd March 14, 2015 .Dt SBUF 9 .Os .Sh NAME @@ -34,6 +34,9 @@ .Nm sbuf_new_auto , .Nm sbuf_new_for_sysctl , .Nm sbuf_clear , +.Nm sbuf_get_flags , +.Nm sbuf_set_flags , +.Nm sbuf_clear_flags , .Nm sbuf_setpos , .Nm sbuf_bcat , .Nm sbuf_bcopyin , @@ -67,6 +70,12 @@ .Ft void .Fn sbuf_clear "struct sbuf *s" .Ft int +.Fn sbuf_get_flags "struct sbuf *s" +.Ft void +.Fn sbuf_set_flags "struct sbuf *s" "int flags" +.Ft void +.Fn sbuf_clear_flags "struct sbuf *s" "int flags" +.Ft int .Fn sbuf_setpos "struct sbuf *s" "int pos" .Ft int .Fn sbuf_bcat "struct sbuf *s" "const void *buf" "size_t len" @@ -159,6 +168,8 @@ Attempting to extend the sbuf beyond this size results in an overflow condition. .It Dv SBUF_AUTOEXTEND This indicates that the storage buffer may be extended as necessary, so long as resources allow, to hold additional data. +.It Dv SBUF_INCLUDENUL +This causes the final nulterm byte to be counted in the length of the data. .El .Pp Note that if @@ -211,6 +222,18 @@ function invalidates the contents of the and resets its position to zero. .Pp The +.Fn sbuf_get_flags +function returns the current user flags. +The +.Fn sbuf_set_flags +and +.Fn sbuf_get_flags +functions set or clear one or more user flags, respectively. +The user flags are described under the +.Fn sbuf_new +function. +.Pp +The .Fn sbuf_setpos function sets the .Fa sbuf Ns 's diff --git a/sys/kern/subr_sbuf.c b/sys/kern/subr_sbuf.c index 1490bc6ebd44..801deba7915c 100644 --- a/sys/kern/subr_sbuf.c +++ b/sys/kern/subr_sbuf.c @@ -262,6 +262,28 @@ sbuf_uionew(struct sbuf *s, struct uio *uio, int *error) } #endif +int +sbuf_get_flags(struct sbuf *s) +{ + + return (s->s_flags & SBUF_USRFLAGMSK); +} + +void +sbuf_clear_flags(struct sbuf *s, int flags) +{ + + s->s_flags &= ~(flags & SBUF_USRFLAGMSK); +} + +void +sbuf_set_flags(struct sbuf *s, int flags) +{ + + + s->s_flags |= (flags & SBUF_USRFLAGMSK); +} + /* * Clear an sbuf and reset its position. */ @@ -697,11 +719,13 @@ sbuf_finish(struct sbuf *s) assert_sbuf_integrity(s); assert_sbuf_state(s, 0); + s->s_buf[s->s_len] = '\0'; + if (s->s_flags & SBUF_INCLUDENUL) + s->s_len++; if (s->s_drain_func != NULL) { while (s->s_len > 0 && s->s_error == 0) s->s_error = sbuf_drain(s); } - s->s_buf[s->s_len] = '\0'; SBUF_SETFLAG(s, SBUF_FINISHED); #ifdef _KERNEL return (s->s_error); @@ -743,6 +767,10 @@ sbuf_len(struct sbuf *s) if (s->s_error != 0) return (-1); + + /* If finished, nulterm is already in len, else add one. */ + if ((s->s_flags & (SBUF_INCLUDENUL | SBUF_FINISHED)) == SBUF_INCLUDENUL) + return (s->s_len + 1); return (s->s_len); } diff --git a/sys/sys/sbuf.h b/sys/sys/sbuf.h index 9816a4cd6c54..40de36e38d3a 100644 --- a/sys/sys/sbuf.h +++ b/sys/sys/sbuf.h @@ -48,6 +48,7 @@ struct sbuf { ssize_t s_len; /* current length of string */ #define SBUF_FIXEDLEN 0x00000000 /* fixed length buffer (default) */ #define SBUF_AUTOEXTEND 0x00000001 /* automatically extend buffer */ +#define SBUF_INCLUDENUL 0x00000002 /* nulterm byte is counted in len */ #define SBUF_USRFLAGMSK 0x0000ffff /* mask of flags the user may specify */ #define SBUF_DYNAMIC 0x00010000 /* s_buf must be freed */ #define SBUF_FINISHED 0x00020000 /* set by sbuf_finish() */ @@ -64,6 +65,9 @@ __BEGIN_DECLS struct sbuf *sbuf_new(struct sbuf *, char *, int, int); #define sbuf_new_auto() \ sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND) +int sbuf_get_flags(struct sbuf *); +void sbuf_clear_flags(struct sbuf *, int); +void sbuf_set_flags(struct sbuf *, int); void sbuf_clear(struct sbuf *); int sbuf_setpos(struct sbuf *, ssize_t); int sbuf_bcat(struct sbuf *, const void *, size_t); From 1eafc07856a9d787f1e383497f37c624f5b7c72c Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 14 Mar 2015 17:08:28 +0000 Subject: [PATCH 4/5] Set the SBUF_INCLUDENUL flag in sbuf_new_for_sysctl() so that sysctl strings returned to userland include the nulterm byte. Some uses of sbuf_new_for_sysctl() write binary data rather than strings; clear the SBUF_INCLUDENUL flag after calling sbuf_new_for_sysctl() in those cases. (Note that the sbuf code still automatically adds a nulterm byte in sbuf_finish(), but since it's not included in the length it won't get copied to userland along with the binary data.) Remove explicit adding of a nulterm byte in a couple places now that it gets done automatically by the sbuf drain code. PR: 195668 --- sys/dev/cxgb/cxgb_sge.c | 9 --------- sys/dev/cxgbe/t4_main.c | 5 ++--- sys/kern/kern_descrip.c | 2 ++ sys/kern/kern_malloc.c | 1 + sys/kern/kern_proc.c | 3 +++ sys/kern/kern_sysctl.c | 2 +- sys/vm/uma_core.c | 1 + 7 files changed, 10 insertions(+), 13 deletions(-) diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index 7f41656c606a..71087cce3d43 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -3149,9 +3149,6 @@ t3_dump_rspq(SYSCTL_HANDLER_ARGS) } err = sbuf_finish(sb); - /* Output a trailing NUL. */ - if (err == 0) - err = SYSCTL_OUT(req, "", 1); sbuf_delete(sb); return (err); } @@ -3219,9 +3216,6 @@ t3_dump_txq_eth(SYSCTL_HANDLER_ARGS) } err = sbuf_finish(sb); - /* Output a trailing NUL. */ - if (err == 0) - err = SYSCTL_OUT(req, "", 1); sbuf_delete(sb); return (err); } @@ -3279,9 +3273,6 @@ t3_dump_txq_ctrl(SYSCTL_HANDLER_ARGS) } err = sbuf_finish(sb); - /* Output a trailing NUL. */ - if (err == 0) - err = SYSCTL_OUT(req, "", 1); sbuf_delete(sb); return (err); } diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 24471920d9c1..8179a998c676 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -5083,12 +5083,11 @@ sysctl_int_array(SYSCTL_HANDLER_ARGS) int rc, *i; struct sbuf sb; - sbuf_new(&sb, NULL, 32, SBUF_AUTOEXTEND); + sbuf_new_for_sysctl(&sb, NULL, 64, req); for (i = arg1; arg2; arg2 -= sizeof(int), i++) sbuf_printf(&sb, "%d ", *i); sbuf_trim(&sb); - sbuf_finish(&sb); - rc = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); + rc = sbuf_finish(&sb); sbuf_delete(&sb); return (rc); } diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 42ca1efda41f..c21047a5e85d 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -3296,6 +3296,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) name = (int *)arg1; sbuf_new_for_sysctl(&sb, NULL, FILEDESC_SBUF_SIZE, req); + sbuf_clear_flags(&sb, SBUF_INCLUDENUL); error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p); if (error != 0) { sbuf_delete(&sb); @@ -3490,6 +3491,7 @@ sysctl_kern_proc_cwd(SYSCTL_HANDLER_ARGS) name = (int *)arg1; sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_file), req); + sbuf_clear_flags(&sb, SBUF_INCLUDENUL); error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p); if (error != 0) { sbuf_delete(&sb); diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index 9e29030fb6f0..aef1e4e23d31 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -918,6 +918,7 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) if (error != 0) return (error); sbuf_new_for_sysctl(&sbuf, NULL, 128, req); + sbuf_clear_flags(&sbuf, SBUF_INCLUDENUL); mtx_lock(&malloc_mtx); /* diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 2aa5c4a3d4cc..a607d7b191b0 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1273,6 +1273,7 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int flags, pid = p->p_pid; sbuf_new_for_sysctl(&sb, (char *)&ki, sizeof(ki), req); + sbuf_clear_flags(&sb, SBUF_INCLUDENUL); error = kern_proc_out(p, &sb, flags); error2 = sbuf_finish(&sb); sbuf_delete(&sb); @@ -1934,6 +1935,7 @@ sysctl_kern_proc_auxv(SYSCTL_HANDLER_ARGS) return (0); } sbuf_new_for_sysctl(&sb, NULL, GET_PS_STRINGS_CHUNK_SZ, req); + sbuf_clear_flags(&sb, SBUF_INCLUDENUL); error = proc_getauxv(curthread, p, &sb); error2 = sbuf_finish(&sb); PRELE(p); @@ -2421,6 +2423,7 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS) name = (int *)arg1; sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_vmentry), req); + sbuf_clear_flags(&sb, SBUF_INCLUDENUL); error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p); if (error != 0) { sbuf_delete(&sb); diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index f429a7bfdba7..97ee63428531 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1807,7 +1807,7 @@ sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req) { - s = sbuf_new(s, buf, length, SBUF_FIXEDLEN); + s = sbuf_new(s, buf, length, SBUF_FIXEDLEN | SBUF_INCLUDENUL); sbuf_set_drain(s, sbuf_sysctl_drain, req); return (s); } diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 5e8eb605229b..2bb6260c9049 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -3451,6 +3451,7 @@ sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS) if (error != 0) return (error); sbuf_new_for_sysctl(&sbuf, NULL, 128, req); + sbuf_clear_flags(&sbuf, SBUF_INCLUDENUL); count = 0; rw_rlock(&uma_rwlock); From 6be291e47aa3d99bc3b5912687a972811d675aa1 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sat, 14 Mar 2015 17:19:48 +0000 Subject: [PATCH 5/5] Amend r277940, by also disabling -Wcast-qual warnings for a few specific aesni files on i386. --- sys/conf/files.i386 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index d3e743baeade..5bd584b38d39 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -118,12 +118,12 @@ crypto/aesni/aeskeys_i386.S optional aesni crypto/aesni/aesni.c optional aesni aesni_ghash.o optional aesni \ dependency "$S/crypto/aesni/aesni_ghash.c" \ - compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -maes -mpclmul ${.IMPSRC}" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes -mpclmul ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_ghash.o" aesni_wrap.o optional aesni \ dependency "$S/crypto/aesni/aesni_wrap.c" \ - compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${PROF} -mmmx -msse -msse4 -maes ${.IMPSRC}" \ + compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_wrap.o" crypto/des/arch/i386/des_enc.S optional crypto | ipsec | netsmb