From eb28afe4221409a70cd8a064f77fe88af86da2e2 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Thu, 18 Dec 2014 18:10:39 +0000 Subject: [PATCH 001/207] Setgid before running a command as a specified user. Previously only initgroups(3) was called, what isn't quite enough. This brings jail(8) in line with jexec(8), which was already doing the right thing. PR: 195984 MFC after: 1 week --- usr.sbin/jail/command.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/usr.sbin/jail/command.c b/usr.sbin/jail/command.c index 6101e078bc2..6fefe414be6 100644 --- a/usr.sbin/jail/command.c +++ b/usr.sbin/jail/command.c @@ -667,6 +667,11 @@ run_command(struct cfjail *j) if (term != NULL) setenv("TERM", term, 1); } + if (setgid(pwd->pw_gid) < 0) { + jail_warnx(j, "setgid %d: %s", pwd->pw_gid, + strerror(errno)); + exit(1); + } if (setusercontext(lcap, pwd, pwd->pw_uid, username ? LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN : LOGIN_SETPATH | LOGIN_SETENV) < 0) { From f703589ef4b4d0afd59b54c0482aaa1445a8e06e Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Thu, 18 Dec 2014 18:16:00 +0000 Subject: [PATCH 002/207] Fix building/installing tests when TESTSBASE != /usr/tests The work in r258233 hardcoded the assumption that tests was the last component of the tests tree by pushing tests as an explicit prefix for the paths in BSD.tests.dist and /usr was the prefix for all tests, per BSD.usr.dist and all of the mtree calls used in Makefile.inc1. This assumption breaks if/when one provides a custom TESTSBASE "prefix", e.g. TESTSBASE=/mytests . One thing that r258233 did properly though was remove "/usr/tests" creation from BSD.usr.dist -- that should have not been there in the first place. That was an "oops" on my part for the work that was originally committed in r241823 MFC after: 2 weeks Phabric: D1301 Reviewed by: imp Sponsored by: EMC / Isilon Storage Division --- Makefile.inc1 | 9 +- etc/Makefile | 4 +- etc/mtree/BSD.include.dist | 4 + etc/mtree/BSD.tests.dist | 726 +++++++++++------------ etc/mtree/BSD.usr.dist | 6 + tools/build/mk/OptionalObsoleteFiles.inc | 6 +- 6 files changed, 376 insertions(+), 379 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 86294fef1b8..2bcb45e54f2 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -526,8 +526,9 @@ _worldtmp: -p ${WORLDTMP}/usr/lib >/dev/null .endif .if ${MK_TESTS} != "no" + mkdir -p ${WORLDTMP}${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ - -p ${WORLDTMP}/usr >/dev/null + -p ${WORLDTMP}${TESTSBASE} >/dev/null .endif .for _mtree in ${LOCAL_MTREE} mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null @@ -866,8 +867,9 @@ distributeworld installworld: _installcheck_world -p ${DESTDIR}/${DISTDIR}/${dist}/usr/lib >/dev/null .endif .if ${MK_TESTS} != "no" && ${dist} == "tests" + -mkdir -p ${DESTDIR}/${DISTDIR}/${dist}${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ - -p ${DESTDIR}/${DISTDIR}/${dist}/usr >/dev/null + -p ${DESTDIR}/${DISTDIR}/${dist}${TESTSBASE} >/dev/null .endif .if defined(NO_ROOT) ${IMAKEENV} mtree -C -f ${.CURDIR}/etc/mtree/BSD.root.dist | \ @@ -2085,8 +2087,9 @@ _xi-mtree: mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${XDDESTDIR}/usr/include >/dev/null .if ${MK_TESTS} != "no" + mkdir -p ${XDDESTDIR}${TESTSBASE} mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \ - -p ${XDDESTDIR}/usr >/dev/null + -p ${XDDESTDIR}${TESTSBASE} >/dev/null .endif .ORDER: xdev-build _xi-mtree _xi-cross-tools _xi-includes _xi-libraries diff --git a/etc/Makefile b/etc/Makefile index ff70cc12ad0..76db02a0cb2 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -333,7 +333,7 @@ MTREES+= mtree/BSD.debug.dist /usr/lib MTREES+= mtree/BSD.groff.dist /usr .endif .if ${MK_TESTS} != "no" -MTREES+= mtree/BSD.tests.dist /usr +MTREES+= mtree/BSD.tests.dist ${TESTSBASE} .endif .if ${MK_SENDMAIL} != "no" MTREES+= mtree/BSD.sendmail.dist / @@ -349,6 +349,7 @@ distrib-dirs: ${MTREES:N/*} shift; \ d=${DESTDIR}$$1; \ shift; \ + test -d $$d || mkdir -p $$d; \ ${ECHO} ${MTREE_CMD} -deU ${MTREE_FOLLOWS_SYMLINKS} \ -f $$m -p $$d; \ ${MTREE_CMD} -deU ${MTREE_FOLLOWS_SYMLINKS} -f $$m -p $$d; \ @@ -362,6 +363,7 @@ distrib-dirs: ${MTREES:N/*} test "$$d" == "/" && d=""; \ d=${DISTBASE}$$d; \ shift; \ + test -d $$d || mkdir -p $$d; \ ${ECHO} "${MTREE_CMD:N-W} -C -f $$m -K uname,gname | " \ "sed s#^\.#.$$d# | ${METALOG.add}" ; \ ${MTREE_CMD:N-W} -C -f $$m -K uname,gname | sed s#^\.#.$$d# | \ diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index fd543870cd7..c01429e4f42 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -9,6 +9,10 @@ .. arpa .. + atf-c + .. + atf-c++ + .. bsm .. bsnmp diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 5285fe3c3f2..2708568bc78 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -5,410 +5,392 @@ /set type=dir uname=root gname=wheel mode=0755 . - include - atf-c + bin + chown .. - atf-c++ + date + .. + mv + .. + pax + .. + pkill + .. + sh + builtins + .. + errors + .. + execution + .. + expansion + .. + parameters + .. + parser + .. + set-e + .. + .. + sleep + .. + test + .. + .. + cddl + lib + .. + sbin + .. + usr.bin + .. + usr.sbin + .. + .. + etc + .. + games + .. + gnu + lib + .. + usr.bin + diff + .. + .. + .. + lib + atf + libatf-c + detail + .. + .. + libatf-c++ + detail + .. + .. + test-programs + .. + .. + libc + c063 + .. + db + .. + gen + execve + .. + posix_spawn + .. + .. + hash + data + .. + .. + inet + .. + locale + .. + net + getaddrinfo + data + .. + .. + .. + regex + data + .. + .. + ssp + .. + stdio + .. + stdlib + .. + string + .. + sys + .. + time + .. + tls + dso + .. + .. + termios + .. + ttyio + .. + .. + libcrypt + .. + libmp + .. + libnv + .. + libpam + .. + libproc + .. + librt + .. + libthr + dlopen + .. + .. + libutil + .. + msun + .. + .. + libexec + atf + atf-check + .. + atf-sh + .. + .. + rtld-elf + .. + .. + sbin + dhclient + .. + devd + .. + growfs + .. + mdconfig + .. + .. + secure + lib + .. + libexec + .. + usr.bin + .. + usr.sbin .. .. share - atf - .. - doc - atf - .. - pjdfstest + examples + tests + atf + .. + plain + .. .. .. .. - tests - bin + sys + kern + .. + netinet + .. + opencrypto + .. + pjdfstest + chflags + .. + chmod + .. chown .. - date + ftruncate .. - mv + granular .. - pax + link .. - pkill + mkdir .. - sh - builtins - .. - errors - .. - execution - .. - expansion - .. - parameters - .. - parser - .. - set-e - .. + mkfifo .. - sleep + mknod .. - test + open .. - .. - cddl - lib + rename .. - sbin + rmdir .. - usr.bin - .. - usr.sbin - .. - .. - etc - .. - games - .. - gnu - lib - .. - usr.bin - diff - .. - .. - .. - lib - atf - libatf-c - detail - .. - .. - libatf-c++ - detail - .. - .. - test-programs - .. - .. - libc - c063 - .. - db - .. - gen - execve - .. - posix_spawn - .. - .. - hash - data - .. - .. - inet - .. - locale - .. - net - getaddrinfo - data - .. - .. - .. - regex - data - .. - .. - ssp - .. - stdio - .. - stdlib - .. - string - .. - sys - .. - time - .. - tls - dso - .. - .. - termios - .. - ttyio - .. - .. - libcrypt - .. - libmp - .. - libnv - .. - libpam - .. - libproc - .. - librt - .. - libthr - dlopen - .. - .. - libutil - .. - msun - .. - .. - libexec - atf - atf-check - .. - atf-sh - .. - .. - rtld-elf - .. - .. - sbin - dhclient - .. - devd - .. - growfs - .. - mdconfig - .. - .. - secure - lib - .. - libexec - .. - usr.bin - .. - usr.sbin - .. - .. - share - examples - tests - atf - .. - plain - .. - .. - .. - .. - sys - kern - .. - netinet - .. - opencrypto - .. - pjdfstest - chflags - .. - chmod - .. - chown - .. - ftruncate - .. - granular - .. - link - .. - mkdir - .. - mkfifo - .. - mknod - .. - open - .. - rename - .. - rmdir - .. - symlink - .. - truncate - .. - unlink - .. - .. - .. - usr.bin - apply - .. - basename - .. - bmake - archives - fmt_44bsd - .. - fmt_44bsd_mod - .. - fmt_oldbsd - .. - .. - basic - t0 - .. - t1 - .. - t2 - .. - t3 - .. - .. - execution - ellipsis - .. - empty - .. - joberr - .. - plus - .. - .. - shell - builtin - .. - meta - .. - path - .. - path_select - .. - replace - .. - select - .. - .. - suffixes - basic - .. - src_wild1 - .. - src_wild2 - .. - .. - syntax - directive-t0 - .. - enl - .. - funny-targets - .. - semi - .. - .. - sysmk - t0 - 2 - 1 - .. - .. - mk - .. - .. - t1 - 2 - 1 - .. - .. - mk - .. - .. - t2 - 2 - 1 - .. - .. - mk - .. - .. - .. - variables - modifier_M - .. - modifier_t - .. - opt_V - .. - t0 - .. - .. - .. - calendar - .. - cmp - .. - comm - .. - cut - .. - dirname - .. - file2c - .. - grep - .. - gzip - .. - join - .. - jot - .. - lastcomm - .. - m4 - .. - mkimg - .. - ncal - .. - printf - .. - sed - regress.multitest.out - .. - .. - timeout - .. - tr + symlink .. truncate .. - units + unlink .. - uudecode + .. + .. + usr.bin + apply + .. + basename + .. + bmake + archives + fmt_44bsd + .. + fmt_44bsd_mod + .. + fmt_oldbsd + .. .. - uuencode + basic + t0 + .. + t1 + .. + t2 + .. + t3 + .. .. - xargs + execution + ellipsis + .. + empty + .. + joberr + .. + plus + .. .. - yacc - yacc + shell + builtin + .. + meta + .. + path + .. + path_select + .. + replace + .. + select + .. + .. + suffixes + basic + .. + src_wild1 + .. + src_wild2 + .. + .. + syntax + directive-t0 + .. + enl + .. + funny-targets + .. + semi + .. + .. + sysmk + t0 + 2 + 1 + .. + .. + mk + .. + .. + t1 + 2 + 1 + .. + .. + mk + .. + .. + t2 + 2 + 1 + .. + .. + mk + .. + .. + .. + variables + modifier_M + .. + modifier_t + .. + opt_V + .. + t0 .. .. .. - usr.sbin - etcupdate + calendar + .. + cmp + .. + comm + .. + cut + .. + dirname + .. + file2c + .. + grep + .. + gzip + .. + join + .. + jot + .. + lastcomm + .. + m4 + .. + mkimg + .. + ncal + .. + printf + .. + sed + regress.multitest.out .. - newsyslog - .. - nmtree - .. - pw - .. - sa + .. + timeout + .. + tr + .. + truncate + .. + units + .. + uudecode + .. + uuencode + .. + xargs + .. + yacc + yacc .. .. .. + usr.sbin + etcupdate + .. + newsyslog + .. + nmtree + .. + pw + .. + sa + .. + .. .. # vim: set expandtab ts=4 sw=4: diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 977cf754d45..c24d5c4e606 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -126,6 +126,8 @@ sbin .. share + atf + .. bsdconfig media .. @@ -169,6 +171,8 @@ doc IPv6 .. + atf + .. atm .. legal @@ -189,6 +193,8 @@ .. papers .. + pjdfstest + .. psd 01.cacm .. diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 0f72659f766..c3c7a282110 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -4663,10 +4663,10 @@ OLD_FILES+=usr/share/man/man4/atf-test-case.4.gz OLD_FILES+=usr/share/mk/atf.test.mk # Test suite. -. if(exists(${DESTDIR}/usr/tests/)) -TESTS_DIRS!=find ${DESTDIR}/usr/tests -type d | sed -e 's,^${DESTDIR}/,,'; echo +. if exists(${DESTDIR}${TESTSBASE}) +TESTS_DIRS!=find ${DESTDIR}${TESTSBASE} -type d | sed -e 's,^${DESTDIR}/,,'; echo OLD_DIRS+=${TESTS_DIRS} -TESTS_FILES!=find ${DESTDIR}/usr/tests \! -type d | sed -e 's,^${DESTDIR}/,,'; echo +TESTS_FILES!=find ${DESTDIR}${TESTSBASE} \! -type d | sed -e 's,^${DESTDIR}/,,'; echo OLD_FILES+=${TESTS_FILES} . endif .endif # Test suite. From 3547290f1d2e491f2be45811331f670445f17886 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Thu, 18 Dec 2014 18:20:33 +0000 Subject: [PATCH 003/207] Document STRIP_CMD in build(7) and note its importance with LOCAL_ITOOLS MFC after: 1 week Phabric: D1335 Reviewed by: brueffer Sponsored by: EMC / Isilon Storage Division --- share/man/man7/build.7 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/share/man/man7/build.7 b/share/man/man7/build.7 index a2172ed3316..f634b59bb7f 100644 --- a/share/man/man7/build.7 +++ b/share/man/man7/build.7 @@ -445,6 +445,21 @@ process. .Bd -literal -offset indent make PORTS_MODULES=emulators/kqemu-kmod kernel .Ed +.It Va STRIP_CMD +Command to use at install time when stripping binaries. +Be sure to add any additional tools required to run +.Va STRIP_CMD +to the +.Va LOCAL_ITOOLS +.Xr make 1 +variable before running the +.Cm distributeworld +or +.Cm installworld +targets. +See +.Xr install 1 +for more details. .It Va SUBDIR_OVERRIDE Override the default list of sub-directories and only build the sub-directory named in this variable. From c8ed1da7c38dff021057530b14ee2f98e72a9b92 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Thu, 18 Dec 2014 18:26:10 +0000 Subject: [PATCH 004/207] Don't build full clang toolchain or clang extras in stages 1-3 of buildworld MFC after: 1 week Reviewed by: dim (as part of a "larger" diff) Phabric: D1336 Sponsored by: EMC / Isilon Storage Division --- Makefile.inc1 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 2bcb45e54f2..e9c1aca4961 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -263,7 +263,8 @@ BMAKE= MAKEOBJDIRPREFIX=${WORLDTMP} \ MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ - MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no + MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ + MK_LLDB=no MK_TESTS=no # build-tools stage TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ @@ -273,7 +274,9 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \ BOOTSTRAPPING=${OSRELDATE} \ SSP_CFLAGS= \ -DNO_LINT \ - -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no MK_CLANG_FULL=no MK_LLDB=no MK_TESTS=no + -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ + MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ + MK_LLDB=no MK_TESTS=no # cross-tools stage XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \ @@ -1478,7 +1481,8 @@ NXBMAKE= ${NXBENV} ${MAKE} \ MK_HTML=no MK_INFO=no NO_LINT=yes MK_MAN=no \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ - MK_CLANG_FULL=no MK_LLDB=no + MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ + MK_DEBUG_FILES=no MK_LLDB=no native-xtools: .MAKE mkdir -p ${OBJTREE}/nxb-bin/bin From 9e7d291e9a1d160255ab3af4cab5dfd295a401e7 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Thu, 18 Dec 2014 18:30:33 +0000 Subject: [PATCH 005/207] Fix accidental MK_DEBUG_FILES=no addition to NXBMAKE in r275909 X-MFC with: r275909 Sponsored by: EMC / Isilon Storage Division --- Makefile.inc1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index e9c1aca4961..9b036f43106 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1482,7 +1482,7 @@ NXBMAKE= ${NXBENV} ${MAKE} \ -DNO_PIC MK_PROFILE=no -DNO_SHARED \ -DNO_CPU_CFLAGS MK_WARNS=no MK_CTF=no \ MK_CLANG_EXTRAS=no MK_CLANG_FULL=no \ - MK_DEBUG_FILES=no MK_LLDB=no + MK_LLDB=no native-xtools: .MAKE mkdir -p ${OBJTREE}/nxb-bin/bin From cce363922b765605d6b67ae68b5e4edce951d76b Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 18 Dec 2014 18:59:26 +0000 Subject: [PATCH 006/207] 5422 preserve AVL invariants in dn_dbufs Reviewed by: Matthew Ahrens Reviewed by: Paul Dagnelie Reviewed by: Josef 'Jeff' Sipek Reviewed by: Albert Lee Approved by: Dan McDonald Author: Alex Reece illumos/illumos-gate@a846f19d279fdfb0e0d63f78ccaf0205a88274d2 --- uts/common/fs/zfs/dnode.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/uts/common/fs/zfs/dnode.c b/uts/common/fs/zfs/dnode.c index 250dd9f9415..3303ee709ed 100644 --- a/uts/common/fs/zfs/dnode.c +++ b/uts/common/fs/zfs/dnode.c @@ -79,16 +79,14 @@ dbuf_compare(const void *x1, const void *x2) return (1); } - if (d1->db_state < d2->db_state) { + if (d1->db_state == DB_SEARCH) { + ASSERT3S(d2->db_state, !=, DB_SEARCH); return (-1); - } - if (d1->db_state > d2->db_state) { + } else if (d2->db_state == DB_SEARCH) { + ASSERT3S(d1->db_state, !=, DB_SEARCH); return (1); } - ASSERT3S(d1->db_state, !=, DB_SEARCH); - ASSERT3S(d2->db_state, !=, DB_SEARCH); - if ((uintptr_t)d1 < (uintptr_t)d2) { return (-1); } From 17eee5222e64e25d7416ff691dcfb76c40148bc5 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 18 Dec 2014 19:09:59 +0000 Subject: [PATCH 007/207] Include section name in strip warning message --- contrib/elftoolchain/elfcopy/sections.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c index d01659a935e..1704a6b3355 100644 --- a/contrib/elftoolchain/elfcopy/sections.c +++ b/contrib/elftoolchain/elfcopy/sections.c @@ -762,8 +762,8 @@ resync_sections(struct elfcopy *ecp) s->off = roundup(off, s->align); } else { if (s->loadable) - warnx("moving loadable section," - "is this intentional?"); + warnx("moving loadable section %s, " + "is this intentional?", s->name); s->off = roundup(off, s->align); } From bf855dd34270918725184b9f4bf866f211f2211f Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 18 Dec 2014 20:23:19 +0000 Subject: [PATCH 008/207] Sync with NetBSD, mainly address NetBSD bug #43355: Fix valid_format() to be more careful about allowing only valid printf formats. Obtained from: NetBSD MFC after: 2 weeks --- usr.bin/seq/seq.1 | 9 ++++-- usr.bin/seq/seq.c | 75 +++++++++++++++++++++++++++++------------------ 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/usr.bin/seq/seq.1 b/usr.bin/seq/seq.1 index 1ac977e8d90..12dd1841982 100644 --- a/usr.bin/seq/seq.1 +++ b/usr.bin/seq/seq.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: seq.1,v 1.6 2008/11/26 15:03:47 ginsbach Exp $ +.\" $NetBSD: seq.1,v 1.8 2013/04/07 17:37:45 jdf Exp $ .\" .\" Copyright (c) 2005 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 19, 2010 +.Dd September 10, 2013 .Dt SEQ 1 .Os .Sh NAME @@ -59,7 +59,7 @@ as possible, in increments of When .Ar first is larger than -.Ar last +.Ar last , the default .Ar incr is -1. @@ -79,8 +79,11 @@ style .Ar format to print each number. Only the +.Cm A , +.Cm a , .Cm E , .Cm e , +.Cm F , .Cm f , .Cm G , .Cm g , diff --git a/usr.bin/seq/seq.c b/usr.bin/seq/seq.c index e0777431e80..6d715e1d42a 100644 --- a/usr.bin/seq/seq.c +++ b/usr.bin/seq/seq.c @@ -1,4 +1,4 @@ -/* $NetBSD: seq.c,v 1.5 2008/07/21 14:19:26 lukem Exp $ */ +/* $NetBSD: seq.c,v 1.7 2010/05/27 08:40:19 dholland Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation, Inc. * All rights reserved. @@ -158,6 +158,8 @@ main(int argc, char *argv[]) if (!valid_format(fmt)) errx(1, "invalid format string: `%s'", fmt); fmt = unescape(fmt); + if (!valid_format(fmt)) + errx(1, "invalid format string"); /* * XXX to be bug for bug compatible with Plan 9 add a * newline if none found at the end of the format string. @@ -225,39 +227,56 @@ numeric(const char *s) static int valid_format(const char *fmt) { - int conversions = 0; + unsigned conversions = 0; while (*fmt != '\0') { /* scan for conversions */ - if (*fmt != '\0' && *fmt != '%') { - do { - fmt++; - } while (*fmt != '\0' && *fmt != '%'); + if (*fmt != '%') { + fmt++; + continue; } - /* scan a conversion */ - if (*fmt != '\0') { - do { + fmt++; + + /* allow %% but not things like %10% */ + if (*fmt == '%') { + fmt++; + continue; + } + + /* flags */ + while (*fmt != '\0' && strchr("#0- +'", *fmt)) { + fmt++; + } + + /* field width */ + while (*fmt != '\0' && strchr("0123456789", *fmt)) { + fmt++; + } + + /* precision */ + if (*fmt == '.') { + fmt++; + while (*fmt != '\0' && strchr("0123456789", *fmt)) { fmt++; + } + } - /* ok %% */ - if (*fmt == '%') { - fmt++; - break; - } - /* valid conversions */ - if (strchr("eEfgG", *fmt) && - conversions++ < 1) { - fmt++; - break; - } - /* flags, width and precision */ - if (isdigit((unsigned char)*fmt) || - strchr("+- 0#.", *fmt)) - continue; - - /* oops! bad conversion format! */ - return (0); - } while (*fmt != '\0'); + /* conversion */ + switch (*fmt) { + case 'A': + case 'a': + case 'E': + case 'e': + case 'F': + case 'f': + case 'G': + case 'g': + /* floating point formats are accepted */ + conversions++; + break; + default: + /* anything else is not */ + return 0; } } From cb8727e23a4b2c2ab61032946ba99ae63d75b05e Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 18 Dec 2014 22:32:22 +0000 Subject: [PATCH 009/207] Pass real optimal transfer size supported by backend. For files and ZVOLs that is 1MB now, not 128K. MFC after: 1 week --- sys/cam/ctl/ctl.c | 2 +- sys/cam/ctl/ctl_backend.h | 9 ++++++++- sys/cam/ctl/ctl_backend_block.c | 30 ++++++++++++++++++++---------- sys/cam/ctl/ctl_backend_ramdisk.c | 1 + 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 8fccd02f47b..f7aff89ebea 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -10142,7 +10142,7 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) scsi_ulto4b(0xffffffff, bl_ptr->max_txfer_len); if (lun != NULL) { bs = lun->be_lun->blocksize; - scsi_ulto4b(MAXPHYS / bs, bl_ptr->opt_txfer_len); + scsi_ulto4b(lun->be_lun->opttxferlen, bl_ptr->opt_txfer_len); if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt); scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt); diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h index 5e0af5cc302..93a530cf7c0 100644 --- a/sys/cam/ctl/ctl_backend.h +++ b/sys/cam/ctl/ctl_backend.h @@ -146,10 +146,16 @@ typedef void (*be_lun_config_t)(void *be_lun, * * pblockexp is the log2() of number of LBAs on the LUN per physical sector. * - * pblockoff is the lowest LBA on the LUN aligned ot physical sector. + * pblockoff is the lowest LBA on the LUN aligned to physical sector. + * + * ublockexp is the log2() of number of LBAs on the LUN per UNMAP block. + * + * ublockoff is the lowest LBA on the LUN aligned to UNMAP block. * * atomicblock is the number of blocks that can be written atomically. * + * opttxferlen is the number of blocks that can be written in one operation. + * * req_lun_id is the requested LUN ID. CTL only pays attention to this * field if the CTL_LUN_FLAG_ID_REQ flag is set. If the requested LUN ID is * not available, the LUN addition will fail. If a particular LUN ID isn't @@ -197,6 +203,7 @@ struct ctl_be_lun { uint16_t ublockexp; /* passed to CTL */ uint16_t ublockoff; /* passed to CTL */ uint32_t atomicblock; /* passed to CTL */ + uint32_t opttxferlen; /* passed to CTL */ uint32_t req_lun_id; /* passed to CTL */ uint32_t lun_id; /* returned from CTL */ uint8_t serial_num[CTL_SN_LEN]; /* passed to CTL */ diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index 9c3e8fd686d..56b41a99c8e 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -175,6 +175,8 @@ struct ctl_be_block_lun { uint16_t pblockoff; uint16_t ublockexp; uint16_t ublockoff; + uint32_t atomicblock; + uint32_t opttxferlen; struct ctl_be_block_softc *softc; struct devstat *disk_stats; ctl_be_block_lun_flags flags; @@ -1845,6 +1847,8 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) "file %s size %ju < block size %u", be_lun->dev_path, (uintmax_t)be_lun->size_bytes, be_lun->blocksize); } + + be_lun->opttxferlen = CTLBLK_MAX_IO_SIZE / be_lun->blocksize; return (error); } @@ -1856,7 +1860,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) struct cdev *dev; struct cdevsw *devsw; char *value; - int error; + int error, atomic, maxio; off_t ps, pss, po, pos, us, uss, uo, uos; params = &be_lun->params; @@ -1870,8 +1874,16 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) if (strcmp(be_lun->backend.dev.csw->d_name, "zvol") == 0) { be_lun->dispatch = ctl_be_block_dispatch_zvol; be_lun->get_lba_status = ctl_be_block_gls_zvol; - } else + atomic = maxio = CTLBLK_MAX_IO_SIZE; + } else { be_lun->dispatch = ctl_be_block_dispatch_dev; + atomic = 0; + maxio = be_lun->backend.dev.cdev->si_iosize_max; + if (maxio <= 0) + maxio = DFLTPHYS; + if (maxio > CTLBLK_MAX_IO_SIZE) + maxio = CTLBLK_MAX_IO_SIZE; + } be_lun->lun_flush = ctl_be_block_flush_dev; be_lun->unmap = ctl_be_block_unmap_dev; be_lun->getattr = ctl_be_block_getattr_dev; @@ -2002,6 +2014,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req) be_lun->ublockoff = (uss - uos) % uss; } + be_lun->atomicblock = atomic / be_lun->blocksize; + be_lun->opttxferlen = maxio / be_lun->blocksize; return (0); } @@ -2268,10 +2282,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff; be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp; be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff; - if (be_lun->dispatch == ctl_be_block_dispatch_zvol && - be_lun->blocksize != 0) - be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE / - be_lun->blocksize; + be_lun->ctl_be_lun.atomicblock = be_lun->atomicblock; + be_lun->ctl_be_lun.opttxferlen = be_lun->opttxferlen; /* Tell the user the blocksize we ended up using */ params->lun_size_bytes = be_lun->size_bytes; params->blocksize_bytes = be_lun->blocksize; @@ -2649,10 +2661,8 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff; be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp; be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff; - if (be_lun->dispatch == ctl_be_block_dispatch_zvol && - be_lun->blocksize != 0) - be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE / - be_lun->blocksize; + be_lun->ctl_be_lun.atomicblock = be_lun->atomicblock; + be_lun->ctl_be_lun.opttxferlen = be_lun->opttxferlen; ctl_lun_capacity_changed(&be_lun->ctl_be_lun); if (oldsize == 0 && be_lun->size_blocks != 0) ctl_lun_online(&be_lun->ctl_be_lun); diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index adace4f7909..b18994fa482 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -597,6 +597,7 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, if (unmap) be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP; be_lun->ctl_be_lun.atomicblock = UINT32_MAX; + be_lun->ctl_be_lun.opttxferlen = softc->rd_size / blocksize; be_lun->ctl_be_lun.be_lun = be_lun; if (params->flags & CTL_LUN_FLAG_ID_REQ) { From 62722f7d5b333a239a83f42106a830c9481faa02 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 19 Dec 2014 00:20:29 +0000 Subject: [PATCH 010/207] Add missing continue: we can't proceed further if the kernel does not panic with zfs_panic_recover. Illumos issue: 5438 zfs_blkptr_verify should continue after zfs_panic_recover Reported by: Coverity CID: 1232014 --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 3925e90c0e8..afda3e464f6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -704,18 +704,20 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp) zfs_panic_recover("blkptr at %p DVA %u has invalid " "VDEV %llu", bp, i, (longlong_t)vdevid); + continue; } vdev_t *vd = spa->spa_root_vdev->vdev_child[vdevid]; if (vd == NULL) { zfs_panic_recover("blkptr at %p DVA %u has invalid " "VDEV %llu", bp, i, (longlong_t)vdevid); + continue; } if (vd->vdev_ops == &vdev_hole_ops) { zfs_panic_recover("blkptr at %p DVA %u has hole " "VDEV %llu", bp, i, (longlong_t)vdevid); - + continue; } if (vd->vdev_ops == &vdev_missing_ops) { /* From 3f9e1172b736400f343c4521ebeac1923a7f541b Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Dec 2014 01:12:22 +0000 Subject: [PATCH 011/207] Slightly polish iSCSI parameters negotiation. MFC after: 1 week --- sys/dev/iscsi/iscsi.c | 4 ++++ usr.sbin/ctld/login.c | 2 +- usr.sbin/iscsid/login.c | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index f9edc8246c3..0d762aadb83 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -2157,6 +2157,10 @@ iscsi_action_scsiio(struct iscsi_session *is, union ccb *ccb) ISCSI_SESSION_DEBUG(is, "len %zd -> %zd", len, is->is_first_burst_length); len = is->is_first_burst_length; } + if (len > is->is_max_data_segment_length) { + ISCSI_SESSION_DEBUG(is, "len %zd -> %zd", len, is->is_max_data_segment_length); + len = is->is_max_data_segment_length; + } error = icl_pdu_append_data(request, csio->data_ptr, len, M_NOWAIT); if (error != 0) { diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index 7add09b5d9b..5358e4b979a 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -558,7 +558,7 @@ login_negotiate_key(struct pdu *request, const char *name, tmp = MAX_DATA_SEGMENT_LENGTH; } conn->conn_max_data_segment_length = tmp; - keys_add_int(response_keys, name, tmp); + keys_add_int(response_keys, name, MAX_DATA_SEGMENT_LENGTH); } else if (strcmp(name, "MaxBurstLength") == 0) { tmp = strtoul(value, NULL, 10); if (tmp <= 0) { diff --git a/usr.sbin/iscsid/login.c b/usr.sbin/iscsid/login.c index 360b0ef186a..1338970a036 100644 --- a/usr.sbin/iscsid/login.c +++ b/usr.sbin/iscsid/login.c @@ -388,6 +388,11 @@ login_negotiate_key(struct connection *conn, const char *name, if (tmp <= 0) log_errx(1, "received invalid " "MaxRecvDataSegmentLength"); + if (tmp > ISCSI_MAX_DATA_SEGMENT_LENGTH) { + log_debugx("capping MaxRecvDataSegmentLength " + "from %d to %d", tmp, ISCSI_MAX_DATA_SEGMENT_LENGTH); + tmp = ISCSI_MAX_DATA_SEGMENT_LENGTH; + } conn->conn_max_data_segment_length = tmp; } else if (strcmp(name, "MaxBurstLength") == 0) { if (conn->conn_immediate_data) { @@ -451,10 +456,11 @@ login_negotiate(struct connection *conn) keys_add(request_keys, "ImmediateData", "Yes"); keys_add_int(request_keys, "MaxBurstLength", - ISCSI_MAX_DATA_SEGMENT_LENGTH); + 2 * ISCSI_MAX_DATA_SEGMENT_LENGTH); keys_add_int(request_keys, "FirstBurstLength", ISCSI_MAX_DATA_SEGMENT_LENGTH); keys_add(request_keys, "InitialR2T", "Yes"); + keys_add(request_keys, "MaxOutstandingR2T", "1"); } else { keys_add(request_keys, "HeaderDigest", "None"); keys_add(request_keys, "DataDigest", "None"); @@ -465,7 +471,6 @@ login_negotiate(struct connection *conn) keys_add(request_keys, "DefaultTime2Wait", "0"); keys_add(request_keys, "DefaultTime2Retain", "0"); keys_add(request_keys, "ErrorRecoveryLevel", "0"); - keys_add(request_keys, "MaxOutstandingR2T", "1"); keys_save(request_keys, request); keys_delete(request_keys); request_keys = NULL; From de981aecde243071d03ba845e43a98c35b0b3688 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 19 Dec 2014 01:39:58 +0000 Subject: [PATCH 012/207] Make ieee80211_add_ssid() public. Some drivers use private copies of this. PR: kern/196116 Submitted by: Andriy Voskoboinyk --- sys/net80211/ieee80211_output.c | 2 +- sys/net80211/ieee80211_proto.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index a8d92f97628..8cb1f51ac77 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -1702,7 +1702,7 @@ ieee80211_add_xrates(uint8_t *frm, const struct ieee80211_rateset *rs) /* * Add an ssid element to a frame. */ -static uint8_t * +uint8_t * ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len) { *frm++ = IEEE80211_ELEMID_SSID; diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 8df51163e4e..3b46ac4b1ec 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -149,6 +149,7 @@ struct mbuf *ieee80211_alloc_cts(struct ieee80211com *, uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *); uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *); +uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int); uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap *); uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap *); uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node *); From bbd01a41002e32b1198e5a73d3d439c7bd8818e5 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 19 Dec 2014 01:41:51 +0000 Subject: [PATCH 013/207] Remove a private copy of ieee80211_add_ssid(). PR: kern/196116 Submitted by: Andriy Voskoboinyk --- sys/dev/iwn/if_iwn.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index bf8c98d96f8..b287c6c5e69 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -279,7 +279,6 @@ static int iwn_send_btcoex(struct iwn_softc *); static int iwn_send_advanced_btcoex(struct iwn_softc *); static int iwn5000_runtime_calib(struct iwn_softc *); static int iwn_config(struct iwn_softc *); -static uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int); static int iwn_scan(struct iwn_softc *, struct ieee80211vap *, struct ieee80211_scan_state *, struct ieee80211_channel *); static int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap); @@ -6527,18 +6526,6 @@ iwn_config(struct iwn_softc *sc) return 0; } -/* - * Add an ssid element to a frame. - */ -static uint8_t * -ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len) -{ - *frm++ = IEEE80211_ELEMID_SSID; - *frm++ = len; - memcpy(frm, ssid, len); - return frm + len; -} - static uint16_t iwn_get_active_dwell_time(struct iwn_softc *sc, struct ieee80211_channel *c, uint8_t n_probes) From cfbebadc603ad85459bd6f189c192d3ad44f6b43 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 19 Dec 2014 06:48:47 +0000 Subject: [PATCH 014/207] Plug a memory leak. Obtained from: DragonFlyBSD (commit 5119ece) MFC after: 2 weeks --- lib/libc/regex/regcomp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c index a01bb95931b..2ecb88c54a9 100644 --- a/lib/libc/regex/regcomp.c +++ b/lib/libc/regex/regcomp.c @@ -1716,8 +1716,10 @@ computematchjumps(struct parse *p, struct re_guts *g) } g->matchjump = (int*) malloc(g->mlen * sizeof(unsigned int)); - if (g->matchjump == NULL) /* Not a fatal error */ + if (g->matchjump == NULL) { /* Not a fatal error */ + free(pmatches); return; + } /* Set maximum possible jump for each character in the pattern */ for (mindex = 0; mindex < g->mlen; mindex++) From cf56c6b846ec96ae7e79afb9a581580f8b9390f9 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Fri, 19 Dec 2014 06:51:01 +0000 Subject: [PATCH 015/207] Fix `make depend` in sys/modules Differential Revision: https://reviews.freebsd.org/D1338 Reviewed by: delphij Approved by: delphij --- sys/modules/cryptodev/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/cryptodev/Makefile b/sys/modules/cryptodev/Makefile index a82517d5897..cc5ca1234e2 100644 --- a/sys/modules/cryptodev/Makefile +++ b/sys/modules/cryptodev/Makefile @@ -3,6 +3,6 @@ .PATH: ${.CURDIR}/../../opencrypto KMOD = cryptodev SRCS = cryptodev.c -SRCS += bus_if.h device_if.h opt_compat.h +SRCS += bus_if.h device_if.h opt_compat.h opt_kdtrace.h .include From ac4203e2abd8c718165307dc5bdc971e01371634 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Fri, 19 Dec 2014 12:09:29 +0000 Subject: [PATCH 016/207] Correct the end address of the memory regions. Pointed out by: ian --- sys/mips/beri/beri_machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/beri/beri_machdep.c b/sys/mips/beri/beri_machdep.c index 714ee3d583e..e3cca2846ca 100644 --- a/sys/mips/beri/beri_machdep.c +++ b/sys/mips/beri/beri_machdep.c @@ -117,13 +117,13 @@ mips_init(void) ("First region is not within FDT memory range")); /* Limit size of the first region */ - phys_avail[1] = MIN(mr[0].mr_size, ctob(realmem)); + phys_avail[1] = (mr[0].mr_start + MIN(mr[0].mr_size, ctob(realmem))); dump_avail[1] = phys_avail[1]; /* Add the rest of regions */ for (i = 1, j = 2; i < mr_cnt; i++, j+=2) { phys_avail[j] = mr[i].mr_start; - phys_avail[j+1] = mr[i].mr_size; + phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size); dump_avail[j] = phys_avail[j]; dump_avail[j+1] = phys_avail[j+1]; } From 30ef1a05c2ad21af934b35a54dadf703449bb030 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Fri, 19 Dec 2014 13:07:36 +0000 Subject: [PATCH 017/207] Add support for empty ranges properties within the tree, some vendor device trees have these, for example the ARM AArch64 Foundation Model. Sponsored by: The FreeBSD Foundation --- sys/dev/fdt/fdt_common.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c index d99fdf26dcd..f00519e5646 100644 --- a/sys/dev/fdt/fdt_common.c +++ b/sys/dev/fdt/fdt_common.c @@ -75,6 +75,12 @@ fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base, u_long bus_addr, par_bus_addr, pbase, psize; int err, i, len, tuple_size, tuples; + if (node == 0) { + *base = 0; + *size = ULONG_MAX; + return (0); + } + if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) return (ENXIO); /* @@ -91,9 +97,8 @@ fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base, if (len > sizeof(ranges)) return (ENOMEM); if (len == 0) { - *base = 0; - *size = ULONG_MAX; - return (0); + return (fdt_get_range_by_busaddr(OF_parent(node), addr, + base, size)); } if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0) From e808299c020f25d822a737dea9c2b4ea1b1d2c50 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 19 Dec 2014 18:45:52 +0000 Subject: [PATCH 018/207] Bump the largest record we can cope with from 1k to 8k. Other users of the hints file don't have any real limits, and longer records will need to be written shortly. --- usr.sbin/kldxref/kldxref.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c index 9144ba03056..73c60045c0f 100644 --- a/usr.sbin/kldxref/kldxref.c +++ b/usr.sbin/kldxref/kldxref.c @@ -53,7 +53,7 @@ #include "ef.h" -#define MAXRECSIZE 1024 +#define MAXRECSIZE 8192 #define check(val) if ((error = (val)) != 0) break static int dflag; /* do not create a hint file, only write on stdout */ From 6d659a5d9bf34dabb20d9c7d111f017bd1fb9230 Mon Sep 17 00:00:00 2001 From: Benno Rice Date: Fri, 19 Dec 2014 19:09:22 +0000 Subject: [PATCH 019/207] Adjust the test of a KASSERT to better match the intent. This assertion was added in r246213 as a guard against corrupted mbufs arriving from drivers, the key distinguishing factor of said mbufs being that they had a negative length. Given we're in a while loop specifically designed to skip over zero-length mbufs, panicking on a zero-length mbuf seems incorrect. No objection from: kib --- sys/fs/nfs/nfs_commonsubs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index d9f843611b3..0f6db328102 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -219,7 +219,8 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz) } mbufcp = NFSMTOD(mp, caddr_t); len = mbuf_len(mp); - KASSERT(len > 0, ("len %d", len)); + KASSERT(len >= 0, + ("len %d, corrupted mbuf?", len)); } xfer = (left > len) ? len : left; #ifdef notdef From 9602f4361653a4cb538c42592b3e11ddab8e79c1 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Dec 2014 20:35:06 +0000 Subject: [PATCH 020/207] Reduce number of places where global control_softc is used. At some point we may want to have several CTL instances, and that is not really impossible. MFC after: 2 weeks --- sys/cam/ctl/ctl.c | 347 +++++++++++++++--------------------- sys/cam/ctl/ctl_backend.c | 46 ++--- sys/cam/ctl/ctl_frontend.c | 84 ++++----- sys/cam/ctl/ctl_tpc.c | 49 ++--- sys/cam/ctl/ctl_tpc.h | 3 +- sys/cam/ctl/ctl_tpc_local.c | 5 +- sys/cam/ctl/scsi_ctl.c | 2 - 7 files changed, 245 insertions(+), 291 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index f7aff89ebea..6e4ea8b819e 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -398,8 +398,8 @@ static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num, struct ctl_ooa_entry *kern_entries); static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td); -static uint32_t ctl_map_lun(int port_num, uint32_t lun); -static uint32_t ctl_map_lun_back(int port_num, uint32_t lun); +static uint32_t ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun); +static uint32_t ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun); static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun, struct ctl_be_lun *be_lun, struct ctl_id target_id); static int ctl_free_lun(struct ctl_lun *lun); @@ -441,8 +441,7 @@ static ctl_action ctl_check_for_blockage(struct ctl_lun *lun, static ctl_action ctl_check_ooa(struct ctl_lun *lun, union ctl_io *pending_io, union ctl_io *starting_io); static int ctl_check_blocked(struct ctl_lun *lun); -static int ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, - struct ctl_lun *lun, +static int ctl_scsiio_lun_check(struct ctl_lun *lun, const struct ctl_cmd_entry *entry, struct ctl_scsiio *ctsio); //static int ctl_check_rtr(union ctl_io *pending_io, struct ctl_softc *softc); @@ -609,12 +608,12 @@ ctl_isc_handler_finish_ser_only(struct ctl_softc *ctl_softc, static void ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; union ctl_io *io; struct ctl_prio *presio; ctl_ha_status isc_status; - ctl_softc = control_softc; + softc = control_softc; io = NULL; @@ -640,7 +639,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) #if 0 printf("Serialize\n"); #endif - io = ctl_alloc_io_nowait(ctl_softc->othersc_pool); + io = ctl_alloc_io_nowait(softc->othersc_pool); if (io == NULL) { printf("ctl_isc_event_handler: can't allocate " "ctl_io!\n"); @@ -672,7 +671,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) * * XXX KDM add another flag that is more specific. */ - if (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY) + if (softc->ha_mode == CTL_HA_MODE_SER_ONLY) io->io_hdr.flags |= CTL_FLAG_INT_COPY; io->io_hdr.nexus = msg_info.hdr.nexus; #if 0 @@ -686,7 +685,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) io->scsiio.tag_type = msg_info.scsi.tag_type; memcpy(io->scsiio.cdb, msg_info.scsi.cdb, CTL_MAX_CDBLEN); - if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) { + if (softc->ha_mode == CTL_HA_MODE_XFER) { const struct ctl_cmd_entry *entry; entry = ctl_get_cmd_entry(&io->scsiio, NULL); @@ -852,11 +851,11 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) * mode */ case CTL_MSG_FINISH_IO: - if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) - ctl_isc_handler_finish_xfer(ctl_softc, + if (softc->ha_mode == CTL_HA_MODE_XFER) + ctl_isc_handler_finish_xfer(softc, &msg_info); else - ctl_isc_handler_finish_ser_only(ctl_softc, + ctl_isc_handler_finish_ser_only(softc, &msg_info); break; @@ -886,7 +885,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) case CTL_MSG_MANAGE_TASKS: { struct ctl_taskio *taskio; taskio = (struct ctl_taskio *)ctl_alloc_io_nowait( - ctl_softc->othersc_pool); + softc->othersc_pool); if (taskio == NULL) { printf("ctl_isc_event_handler: can't allocate " "ctl_io!\n"); @@ -915,7 +914,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param) /* Persistent Reserve action which needs attention */ case CTL_MSG_PERS_ACTION: presio = (struct ctl_prio *)ctl_alloc_io_nowait( - ctl_softc->othersc_pool); + softc->othersc_pool); if (presio == NULL) { printf("ctl_isc_event_handler: can't allocate " "ctl_io!\n"); @@ -1832,16 +1831,16 @@ bailout: static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; union ctl_ha_msg msg_info; struct ctl_lun *lun; int retval = 0; uint32_t targ_lun; - ctl_softc = control_softc; + softc = control_softc; targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; - lun = ctl_softc->ctl_luns[targ_lun]; + lun = softc->ctl_luns[targ_lun]; if (lun==NULL) { /* @@ -1886,7 +1885,7 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio) break; case CTL_ACTION_PASS: case CTL_ACTION_SKIP: - if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) { + if (softc->ha_mode == CTL_HA_MODE_XFER) { ctsio->io_hdr.flags |= CTL_FLAG_IS_WAS_ON_RTR; ctl_enqueue_rtr((union ctl_io *)ctsio); } else { @@ -3602,11 +3601,11 @@ ctl_port_idx(int port_num) } static uint32_t -ctl_map_lun(int port_num, uint32_t lun_id) +ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun_id) { struct ctl_port *port; - port = control_softc->ctl_ports[ctl_port_idx(port_num)]; + port = softc->ctl_ports[ctl_port_idx(port_num)]; if (port == NULL) return (UINT32_MAX); if (port->lun_map == NULL) @@ -3615,12 +3614,12 @@ ctl_map_lun(int port_num, uint32_t lun_id) } static uint32_t -ctl_map_lun_back(int port_num, uint32_t lun_id) +ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun_id) { struct ctl_port *port; uint32_t i; - port = control_softc->ctl_ports[ctl_port_idx(port_num)]; + port = softc->ctl_ports[ctl_port_idx(port_num)]; if (port->lun_map == NULL) return (lun_id); for (i = 0; i < CTL_MAX_LUNS; i++) { @@ -4777,25 +4776,25 @@ ctl_free_lun(struct ctl_lun *lun) static void ctl_create_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; - ctl_softc = control_softc; + softc = control_softc; /* * ctl_alloc_lun() should handle all potential failure cases. */ - ctl_alloc_lun(ctl_softc, NULL, be_lun, ctl_softc->target); + ctl_alloc_lun(softc, NULL, be_lun, softc->target); } int ctl_add_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc = control_softc; + struct ctl_softc *softc = control_softc; - mtx_lock(&ctl_softc->ctl_lock); - STAILQ_INSERT_TAIL(&ctl_softc->pending_lun_queue, be_lun, links); - mtx_unlock(&ctl_softc->ctl_lock); - wakeup(&ctl_softc->pending_lun_queue); + mtx_lock(&softc->ctl_lock); + STAILQ_INSERT_TAIL(&softc->pending_lun_queue, be_lun, links); + mtx_unlock(&softc->ctl_lock); + wakeup(&softc->pending_lun_queue); return (0); } @@ -4803,16 +4802,15 @@ ctl_add_lun(struct ctl_be_lun *be_lun) int ctl_enable_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_port *port, *nport; struct ctl_lun *lun; int retval; - ctl_softc = control_softc; - lun = (struct ctl_lun *)be_lun->ctl_lun; + softc = lun->ctl_softc; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); mtx_lock(&lun->lun_lock); if ((lun->flags & CTL_LUN_DISABLED) == 0) { /* @@ -4820,13 +4818,13 @@ ctl_enable_lun(struct ctl_be_lun *be_lun) * enabled? */ mtx_unlock(&lun->lun_lock); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (0); } lun->flags &= ~CTL_LUN_DISABLED; mtx_unlock(&lun->lun_lock); - for (port = STAILQ_FIRST(&ctl_softc->port_list); port != NULL; port = nport) { + for (port = STAILQ_FIRST(&softc->port_list); port != NULL; port = nport) { nport = STAILQ_NEXT(port, links); /* @@ -4834,9 +4832,9 @@ ctl_enable_lun(struct ctl_be_lun *be_lun) * This can lead to a callback into CTL (at least in the * case of the internal initiator frontend. */ - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); retval = port->lun_enable(port->targ_lun_arg, lun->target,lun->lun); - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); if (retval != 0) { printf("%s: FETD %s port %d returned error " "%d for lun_enable on target %ju lun %jd\n", @@ -4851,7 +4849,7 @@ ctl_enable_lun(struct ctl_be_lun *be_lun) #endif } - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (0); } @@ -4859,27 +4857,26 @@ ctl_enable_lun(struct ctl_be_lun *be_lun) int ctl_disable_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_port *port; struct ctl_lun *lun; int retval; - ctl_softc = control_softc; - lun = (struct ctl_lun *)be_lun->ctl_lun; + softc = lun->ctl_softc; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); mtx_lock(&lun->lun_lock); if (lun->flags & CTL_LUN_DISABLED) { mtx_unlock(&lun->lun_lock); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (0); } lun->flags |= CTL_LUN_DISABLED; mtx_unlock(&lun->lun_lock); - STAILQ_FOREACH(port, &ctl_softc->port_list, links) { - mtx_unlock(&ctl_softc->ctl_lock); + STAILQ_FOREACH(port, &softc->port_list, links) { + mtx_unlock(&softc->ctl_lock); /* * Drop the lock before we call the frontend's disable * routine, to avoid lock order reversals. @@ -4889,7 +4886,7 @@ ctl_disable_lun(struct ctl_be_lun *be_lun) */ retval = port->lun_disable(port->targ_lun_arg, lun->target, lun->lun); - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); if (retval != 0) { printf("ctl_alloc_lun: FETD %s port %d returned error " "%d for lun_disable on target %ju lun %jd\n", @@ -4898,7 +4895,7 @@ ctl_disable_lun(struct ctl_be_lun *be_lun) } } - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (0); } @@ -4906,80 +4903,55 @@ ctl_disable_lun(struct ctl_be_lun *be_lun) int ctl_start_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; - struct ctl_lun *lun; - - ctl_softc = control_softc; - - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); lun->flags &= ~CTL_LUN_STOPPED; mtx_unlock(&lun->lun_lock); - return (0); } int ctl_stop_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; - struct ctl_lun *lun; - - ctl_softc = control_softc; - - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); lun->flags |= CTL_LUN_STOPPED; mtx_unlock(&lun->lun_lock); - return (0); } int ctl_lun_offline(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; - struct ctl_lun *lun; - - ctl_softc = control_softc; - - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); lun->flags |= CTL_LUN_OFFLINE; mtx_unlock(&lun->lun_lock); - return (0); } int ctl_lun_online(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; - struct ctl_lun *lun; - - ctl_softc = control_softc; - - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); lun->flags &= ~CTL_LUN_OFFLINE; mtx_unlock(&lun->lun_lock); - return (0); } int ctl_invalidate_lun(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_lun *lun; - ctl_softc = control_softc; - lun = (struct ctl_lun *)be_lun->ctl_lun; + softc = lun->ctl_softc; mtx_lock(&lun->lun_lock); @@ -5002,9 +4974,9 @@ ctl_invalidate_lun(struct ctl_be_lun *be_lun) */ if (TAILQ_EMPTY(&lun->ooa_queue)) { mtx_unlock(&lun->lun_lock); - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); ctl_free_lun(lun); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); } else mtx_unlock(&lun->lun_lock); @@ -5014,32 +4986,22 @@ ctl_invalidate_lun(struct ctl_be_lun *be_lun) int ctl_lun_inoperable(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; - struct ctl_lun *lun; - - ctl_softc = control_softc; - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); lun->flags |= CTL_LUN_INOPERABLE; mtx_unlock(&lun->lun_lock); - return (0); } int ctl_lun_operable(struct ctl_be_lun *be_lun) { - struct ctl_softc *ctl_softc; - struct ctl_lun *lun; - - ctl_softc = control_softc; - lun = (struct ctl_lun *)be_lun->ctl_lun; + struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun; mtx_lock(&lun->lun_lock); lun->flags &= ~CTL_LUN_INOPERABLE; mtx_unlock(&lun->lun_lock); - return (0); } @@ -5225,7 +5187,6 @@ int ctl_scsi_release(struct ctl_scsiio *ctsio) { int length, longid, thirdparty_id, resv_id; - struct ctl_softc *ctl_softc; struct ctl_lun *lun; uint32_t residx; @@ -5236,7 +5197,6 @@ ctl_scsi_release(struct ctl_scsiio *ctsio) residx = ctl_get_resindex(&ctsio->io_hdr.nexus); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctl_softc = control_softc; switch (ctsio->cdb[0]) { case RELEASE_10: { @@ -5313,7 +5273,6 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) int extent, thirdparty, longid; int resv_id, length; uint64_t thirdparty_id; - struct ctl_softc *ctl_softc; struct ctl_lun *lun; uint32_t residx; @@ -5328,7 +5287,6 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio) residx = ctl_get_resindex(&ctsio->io_hdr.nexus); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctl_softc = control_softc; switch (ctsio->cdb[0]) { case RESERVE_10: { @@ -5402,13 +5360,11 @@ ctl_start_stop(struct ctl_scsiio *ctsio) { struct scsi_start_stop_unit *cdb; struct ctl_lun *lun; - struct ctl_softc *ctl_softc; int retval; CTL_DEBUG_PRINT(("ctl_start_stop\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctl_softc = control_softc; retval = 0; cdb = (struct scsi_start_stop_unit *)ctsio->cdb; @@ -5529,7 +5485,7 @@ int ctl_sync_cache(struct ctl_scsiio *ctsio) { struct ctl_lun *lun; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; uint64_t starting_lba; uint32_t block_count; int retval; @@ -5537,7 +5493,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_sync_cache\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctl_softc = control_softc; + softc = lun->ctl_softc; retval = 0; switch (ctsio->cdb[0]) { @@ -5590,7 +5546,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio) * CACHE command directly to the back end. */ mtx_lock(&lun->lun_lock); - if ((ctl_softc->flags & CTL_FLAG_REAL_SYNC) + if ((softc->flags & CTL_FLAG_REAL_SYNC) && (++(lun->sync_count) >= lun->sync_interval)) { lun->sync_count = 0; mtx_unlock(&lun->lun_lock); @@ -5611,13 +5567,11 @@ ctl_format(struct ctl_scsiio *ctsio) { struct scsi_format *cdb; struct ctl_lun *lun; - struct ctl_softc *ctl_softc; int length, defect_list_len; CTL_DEBUG_PRINT(("ctl_format\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - ctl_softc = control_softc; cdb = (struct scsi_format *)ctsio->cdb; @@ -6075,7 +6029,6 @@ ctl_control_page_handler(struct ctl_scsiio *ctsio, { struct scsi_control_page *current_cp, *saved_cp, *user_cp; struct ctl_lun *lun; - struct ctl_softc *softc; int set_ua; uint32_t initidx; @@ -6091,8 +6044,6 @@ ctl_control_page_handler(struct ctl_scsiio *ctsio, (page_index->page_data + (page_index->page_len * CTL_PAGE_SAVED)); - softc = control_softc; - mtx_lock(&lun->lun_lock); if (((current_cp->rlec & SCP_DSENSE) == 0) && ((user_cp->rlec & SCP_DSENSE) != 0)) { @@ -7358,8 +7309,8 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_report_tagret_port_groups\n")); cdb = (struct scsi_maintenance_in *)ctsio->cdb; - softc = control_softc; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + softc = lun->ctl_softc; retval = CTL_RETVAL_COMPLETE; @@ -7390,7 +7341,8 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) STAILQ_FOREACH(port, &softc->port_list, links) { if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; - if (ctl_map_lun_back(port->targ_port, lun->lun) >= CTL_MAX_LUNS) + if (ctl_map_lun_back(softc, port->targ_port, lun->lun) >= + CTL_MAX_LUNS) continue; num_target_ports++; } @@ -7463,8 +7415,8 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio) STAILQ_FOREACH(port, &softc->port_list, links) { if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; - if (ctl_map_lun_back(port->targ_port, lun->lun) >= - CTL_MAX_LUNS) + if (ctl_map_lun_back(softc, port->targ_port, lun->lun) + >= CTL_MAX_LUNS) continue; p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS; scsi_ulto2b(p, tpg_desc->descriptors[pc]. @@ -7756,13 +7708,12 @@ ctl_persistent_reserve_in(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_persistent_reserve_in\n")); - softc = control_softc; - cdb = (struct scsi_per_res_in *)ctsio->cdb; alloc_len = scsi_2btoul(cdb->length); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + softc = lun->ctl_softc; retry: mtx_lock(&lun->lun_lock); @@ -8385,10 +8336,9 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) retval = CTL_RETVAL_COMPLETE; - softc = control_softc; - cdb = (struct scsi_per_res_out *)ctsio->cdb; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + softc = lun->ctl_softc; /* * We only support whole-LUN scope. The scope & type are ignored for @@ -9304,6 +9254,7 @@ ctl_verify(struct ctl_scsiio *ctsio) int ctl_report_luns(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = control_softc; struct scsi_report_luns *cdb; struct scsi_report_luns_data *lun_data; struct ctl_lun *lun, *request_lun; @@ -9319,9 +9270,9 @@ ctl_report_luns(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_report_luns\n")); - mtx_lock(&control_softc->ctl_lock); - num_luns = control_softc->num_luns; - mtx_unlock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); + num_luns = softc->num_luns; + mtx_unlock(&softc->ctl_lock); switch (cdb->select_report) { case RPL_REPORT_DEFAULT: @@ -9373,12 +9324,13 @@ ctl_report_luns(struct ctl_scsiio *ctsio) initidx = ctl_get_initindex(&ctsio->io_hdr.nexus); - mtx_lock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) { - lun_id = ctl_map_lun(ctsio->io_hdr.nexus.targ_port, targ_lun_id); + lun_id = ctl_map_lun(softc, ctsio->io_hdr.nexus.targ_port, + targ_lun_id); if (lun_id >= CTL_MAX_LUNS) continue; - lun = control_softc->ctl_luns[lun_id]; + lun = softc->ctl_luns[lun_id]; if (lun == NULL) continue; @@ -9434,7 +9386,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio) mtx_unlock(&lun->lun_lock); } } - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); /* * It's quite possible that we've returned fewer LUNs than we allocated @@ -9869,15 +9821,15 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len) { struct scsi_vpd_device_id *devid_ptr; struct scsi_vpd_id_descriptor *desc; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_lun *lun; struct ctl_port *port; int data_len; uint8_t proto; - ctl_softc = control_softc; + softc = control_softc; - port = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; + port = softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; data_len = sizeof(struct scsi_vpd_device_id) + @@ -10011,7 +9963,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; if (lun != NULL && - ctl_map_lun_back(port->targ_port, lun->lun) >= + ctl_map_lun_back(softc, port->targ_port, lun->lun) >= CTL_MAX_LUNS) continue; num_target_ports++; @@ -10065,8 +10017,8 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) continue; if (lun != NULL && - ctl_map_lun_back(port->targ_port, lun->lun) >= - CTL_MAX_LUNS) + ctl_map_lun_back(softc, port->targ_port, lun->lun) + >= CTL_MAX_LUNS) continue; p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS; scsi_ulto2b(p, pd->relative_port_id); @@ -10342,20 +10294,20 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) { struct scsi_inquiry_data *inq_ptr; struct scsi_inquiry *cdb; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_lun *lun; char *val; uint32_t alloc_len, data_len; ctl_port_type port_type; - ctl_softc = control_softc; + softc = control_softc; /* * Figure out whether we're talking to a Fibre Channel port or not. * We treat the ioctl front end, and any SCSI adapters, as packetized * SCSI front ends. */ - port_type = ctl_softc->ctl_ports[ + port_type = softc->ctl_ports[ ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]->port_type; if (port_type == CTL_PORT_IOCTL || port_type == CTL_PORT_INTERNAL) port_type = CTL_PORT_SCSI; @@ -10432,7 +10384,7 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio) if (lun != NULL) inq_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | lun->be_lun->lun_type; - else if (ctl_softc->inquiry_pq_no_lun == 0) + else if (softc->inquiry_pq_no_lun == 0) inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; else inq_ptr->device = (SID_QUAL_BAD_LU << 5) | T_NODEVICE; @@ -11065,7 +11017,6 @@ ctl_check_blocked(struct ctl_lun *lun) break; case CTL_ACTION_PASS: case CTL_ACTION_SKIP: { - struct ctl_softc *softc; const struct ctl_cmd_entry *entry; int isc_retval; @@ -11104,7 +11055,6 @@ ctl_check_blocked(struct ctl_lun *lun) break; } entry = ctl_get_cmd_entry(&cur_blocked->scsiio, NULL); - softc = control_softc; /* * Check this I/O for LUN state changes that may @@ -11114,7 +11064,7 @@ ctl_check_blocked(struct ctl_lun *lun) * for any states that can be caused by SCSI * commands. */ - if (ctl_scsiio_lun_check(softc, lun, entry, + if (ctl_scsiio_lun_check(lun, entry, &cur_blocked->scsiio) == 0) { cur_blocked->io_hdr.flags |= CTL_FLAG_IS_WAS_ON_RTR; @@ -11148,9 +11098,10 @@ ctl_check_blocked(struct ctl_lun *lun) * careful attention to the placement of any new checks. */ static int -ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun, +ctl_scsiio_lun_check(struct ctl_lun *lun, const struct ctl_cmd_entry *entry, struct ctl_scsiio *ctsio) { + struct ctl_softc *softc = lun->ctl_softc; int retval; uint32_t residx; @@ -11162,7 +11113,7 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun, * If this shelf is a secondary shelf controller, we have to reject * any media access commands. */ - if ((ctl_softc->flags & CTL_FLAG_ACTIVE_SHELF) == 0 && + if ((softc->flags & CTL_FLAG_ACTIVE_SHELF) == 0 && (entry->flags & CTL_CMD_FLAG_OK_ON_SECONDARY) == 0) { ctl_set_lun_standby(ctsio); retval = 1; @@ -11268,14 +11219,14 @@ static void ctl_failover(void) { struct ctl_lun *lun; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; union ctl_io *next_io, *pending_io; union ctl_io *io; int lun_idx; - ctl_softc = control_softc; + softc = control_softc; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); /* * Remove any cmds from the other SC from the rtr queue. These * will obviously only be for LUNs for which we're the primary. @@ -11285,19 +11236,19 @@ ctl_failover(void) * which HA mode we're in. */ #ifdef notyet - mtx_lock(&ctl_softc->queue_lock); - for (io = (union ctl_io *)STAILQ_FIRST(&ctl_softc->rtr_queue); + mtx_lock(&softc->queue_lock); + for (io = (union ctl_io *)STAILQ_FIRST(&softc->rtr_queue); io != NULL; io = next_io) { next_io = (union ctl_io *)STAILQ_NEXT(&io->io_hdr, links); if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC) - STAILQ_REMOVE(&ctl_softc->rtr_queue, &io->io_hdr, + STAILQ_REMOVE(&softc->rtr_queue, &io->io_hdr, ctl_io_hdr, links); } - mtx_unlock(&ctl_softc->queue_lock); + mtx_unlock(&softc->queue_lock); #endif - for (lun_idx=0; lun_idx < ctl_softc->num_luns; lun_idx++) { - lun = ctl_softc->ctl_luns[lun_idx]; + for (lun_idx=0; lun_idx < softc->num_luns; lun_idx++) { + lun = softc->ctl_luns[lun_idx]; if (lun==NULL) continue; @@ -11309,7 +11260,7 @@ ctl_failover(void) continue; if ((lun->flags & CTL_LUN_PRIMARY_SC) - && (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY)) { + && (softc->ha_mode == CTL_HA_MODE_SER_ONLY)) { printf("FAILOVER: primary lun %d\n", lun_idx); /* * Remove all commands from the other SC. First from the @@ -11351,7 +11302,7 @@ ctl_failover(void) } ctl_check_blocked(lun); } else if ((lun->flags & CTL_LUN_PRIMARY_SC) - && (ctl_softc->ha_mode == CTL_HA_MODE_XFER)) { + && (softc->ha_mode == CTL_HA_MODE_XFER)) { printf("FAILOVER: primary lun %d\n", lun_idx); /* @@ -11369,7 +11320,7 @@ ctl_failover(void) io->io_hdr.flags |= CTL_FLAG_ABORT; } } else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0) - && (ctl_softc->ha_mode == CTL_HA_MODE_XFER)) { + && (softc->ha_mode == CTL_HA_MODE_XFER)) { printf("FAILOVER: secondary lun %d\n", lun_idx); @@ -11408,7 +11359,7 @@ ctl_failover(void) ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE); } else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0) - && (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY)) { + && (softc->ha_mode == CTL_HA_MODE_SER_ONLY)) { printf("FAILOVER: secondary lun %d\n", lun_idx); /* * if the first io on the OOA is not on the RtR queue @@ -11498,15 +11449,15 @@ ctl_failover(void) ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE); } else { panic("Unhandled HA mode failover, LUN flags = %#x, " - "ha_mode = #%x", lun->flags, ctl_softc->ha_mode); + "ha_mode = #%x", lun->flags, softc->ha_mode); } } ctl_pause_rtr = 0; - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); } static int -ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio) +ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio) { struct ctl_lun *lun; const struct ctl_cmd_entry *entry; @@ -11519,7 +11470,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio) targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun; if ((targ_lun < CTL_MAX_LUNS) - && ((lun = ctl_softc->ctl_luns[targ_lun]) != NULL)) { + && ((lun = softc->ctl_luns[targ_lun]) != NULL)) { /* * If the LUN is invalid, pretend that it doesn't exist. * It will go away as soon as all pending I/O has been @@ -11651,7 +11602,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio) } - if (ctl_scsiio_lun_check(ctl_softc, lun, entry, ctsio) != 0) { + if (ctl_scsiio_lun_check(lun, entry, ctsio) != 0) { mtx_unlock(&lun->lun_lock); ctl_done((union ctl_io *)ctsio); return (retval); @@ -11859,13 +11810,13 @@ bailout: * our single target. */ static int -ctl_bus_reset(struct ctl_softc *ctl_softc, union ctl_io *io) +ctl_bus_reset(struct ctl_softc *softc, union ctl_io *io) { - return(ctl_target_reset(ctl_softc, io, CTL_UA_BUS_RESET)); + return(ctl_target_reset(softc, io, CTL_UA_BUS_RESET)); } static int -ctl_target_reset(struct ctl_softc *ctl_softc, union ctl_io *io, +ctl_target_reset(struct ctl_softc *softc, union ctl_io *io, ctl_ua_type ua_type) { struct ctl_lun *lun; @@ -11889,10 +11840,10 @@ ctl_target_reset(struct ctl_softc *ctl_softc, union ctl_io *io, } retval = 0; - mtx_lock(&ctl_softc->ctl_lock); - STAILQ_FOREACH(lun, &ctl_softc->lun_list, links) + mtx_lock(&softc->ctl_lock); + STAILQ_FOREACH(lun, &softc->lun_list, links) retval += ctl_lun_reset(lun, io, ua_type); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (retval); } @@ -12078,7 +12029,7 @@ ctl_abort_task(union ctl_io *io) { union ctl_io *xio; struct ctl_lun *lun; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; #if 0 struct sbuf sb; char printbuf[128]; @@ -12086,19 +12037,19 @@ ctl_abort_task(union ctl_io *io) int found; uint32_t targ_lun; - ctl_softc = control_softc; + softc = control_softc; found = 0; /* * Look up the LUN. */ targ_lun = io->io_hdr.nexus.targ_mapped_lun; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); if ((targ_lun < CTL_MAX_LUNS) - && (ctl_softc->ctl_luns[targ_lun] != NULL)) - lun = ctl_softc->ctl_luns[targ_lun]; + && (softc->ctl_luns[targ_lun] != NULL)) + lun = softc->ctl_luns[targ_lun]; else { - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (1); } @@ -12108,7 +12059,7 @@ ctl_abort_task(union ctl_io *io) #endif mtx_lock(&lun->lun_lock); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); /* * Run through the OOA queue and attempt to find the given I/O. * The target port, initiator ID, tag type and tag number have to @@ -12224,7 +12175,7 @@ ctl_abort_task(union ctl_io *io) static void ctl_run_task(union ctl_io *io) { - struct ctl_softc *ctl_softc = control_softc; + struct ctl_softc *softc = control_softc; int retval = 1; const char *task_desc; @@ -12279,12 +12230,12 @@ ctl_run_task(union ctl_io *io) uint32_t targ_lun; targ_lun = io->io_hdr.nexus.targ_mapped_lun; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); if ((targ_lun < CTL_MAX_LUNS) - && (ctl_softc->ctl_luns[targ_lun] != NULL)) - lun = ctl_softc->ctl_luns[targ_lun]; + && (softc->ctl_luns[targ_lun] != NULL)) + lun = softc->ctl_luns[targ_lun]; else { - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); retval = 1; break; } @@ -12311,14 +12262,14 @@ ctl_run_task(union ctl_io *io) retval = ctl_lun_reset(lun, io, CTL_UA_LUN_RESET); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); break; } case CTL_TASK_TARGET_RESET: - retval = ctl_target_reset(ctl_softc, io, CTL_UA_TARG_RESET); + retval = ctl_target_reset(softc, io, CTL_UA_TARG_RESET); break; case CTL_TASK_BUS_RESET: - retval = ctl_bus_reset(ctl_softc, io); + retval = ctl_bus_reset(softc, io); break; case CTL_TASK_PORT_LOGIN: break; @@ -12345,13 +12296,13 @@ ctl_handle_isc(union ctl_io *io) { int free_io; struct ctl_lun *lun; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; uint32_t targ_lun; - ctl_softc = control_softc; + softc = control_softc; targ_lun = io->io_hdr.nexus.targ_mapped_lun; - lun = ctl_softc->ctl_luns[targ_lun]; + lun = softc->ctl_luns[targ_lun]; switch (io->io_hdr.msg_type) { case CTL_MSG_SERIALIZE: @@ -12366,7 +12317,7 @@ ctl_handle_isc(union ctl_io *io) free_io = 0; entry = ctl_get_cmd_entry(&io->scsiio, NULL); mtx_lock(&lun->lun_lock); - if (ctl_scsiio_lun_check(ctl_softc, lun, + if (ctl_scsiio_lun_check(lun, entry, (struct ctl_scsiio *)io) != 0) { mtx_unlock(&lun->lun_lock); ctl_done(io); @@ -12378,7 +12329,7 @@ ctl_handle_isc(union ctl_io *io) break; } case CTL_MSG_FINISH_IO: - if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) { + if (softc->ha_mode == CTL_HA_MODE_XFER) { free_io = 0; ctl_done(io); } else { @@ -13477,14 +13428,13 @@ static int ctl_process_done(union ctl_io *io) { struct ctl_lun *lun; - struct ctl_softc *ctl_softc = control_softc; + struct ctl_softc *softc = control_softc; void (*fe_done)(union ctl_io *io); uint32_t targ_port = ctl_port_idx(io->io_hdr.nexus.targ_port); CTL_DEBUG_PRINT(("ctl_process_done\n")); - fe_done = - control_softc->ctl_ports[targ_port]->fe_done; + fe_done = softc->ctl_ports[targ_port]->fe_done; #ifdef CTL_TIME_IO if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) { @@ -13611,9 +13561,9 @@ ctl_process_done(union ctl_io *io) if ((lun->flags & CTL_LUN_INVALID) && TAILQ_EMPTY(&lun->ooa_queue)) { mtx_unlock(&lun->lun_lock); - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); ctl_free_lun(lun); - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); } else mtx_unlock(&lun->lun_lock); @@ -13665,7 +13615,7 @@ bailout: * if the frontend comes back in in this context to queue * something. */ - if ((ctl_softc->ha_mode == CTL_HA_MODE_XFER) + if ((softc->ha_mode == CTL_HA_MODE_XFER) && (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)) { union ctl_ha_msg msg; @@ -13713,10 +13663,10 @@ int ctl_queue_sense(union ctl_io *io) { struct ctl_lun *lun; - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; uint32_t initidx, targ_lun; - ctl_softc = control_softc; + softc = control_softc; CTL_DEBUG_PRINT(("ctl_queue_sense\n")); @@ -13727,17 +13677,17 @@ ctl_queue_sense(union ctl_io *io) * things like an INQUIRY to a LUN that we don't have enabled. We * can't deal with that right now. */ - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); /* * If we don't have a LUN for this, just toss the sense * information. */ targ_lun = io->io_hdr.nexus.targ_lun; - targ_lun = ctl_map_lun(io->io_hdr.nexus.targ_port, targ_lun); + targ_lun = ctl_map_lun(softc, io->io_hdr.nexus.targ_port, targ_lun); if ((targ_lun < CTL_MAX_LUNS) - && (ctl_softc->ctl_luns[targ_lun] != NULL)) - lun = ctl_softc->ctl_luns[targ_lun]; + && (softc->ctl_luns[targ_lun] != NULL)) + lun = softc->ctl_luns[targ_lun]; else goto bailout; @@ -13759,7 +13709,7 @@ ctl_queue_sense(union ctl_io *io) mtx_unlock(&lun->lun_lock); bailout: - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); ctl_free_io(io); @@ -13774,12 +13724,9 @@ bailout: int ctl_queue(union ctl_io *io) { - struct ctl_softc *ctl_softc; CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0])); - ctl_softc = control_softc; - #ifdef CTL_TIME_IO io->io_hdr.start_time = time_uptime; getbintime(&io->io_hdr.start_bt); @@ -13787,7 +13734,8 @@ ctl_queue(union ctl_io *io) /* Map FE-specific LUN ID into global one. */ io->io_hdr.nexus.targ_mapped_lun = - ctl_map_lun(io->io_hdr.nexus.targ_port, io->io_hdr.nexus.targ_lun); + ctl_map_lun(control_softc, io->io_hdr.nexus.targ_port, + io->io_hdr.nexus.targ_lun); switch (io->io_hdr.io_type) { case CTL_IO_SCSI: @@ -13818,9 +13766,6 @@ ctl_done_timer_wakeup(void *arg) void ctl_done(union ctl_io *io) { - struct ctl_softc *ctl_softc; - - ctl_softc = control_softc; /* * Enable this to catch duplicate completion issues. diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c index 0e1a76c5d97..cabecb710ca 100644 --- a/sys/cam/ctl/ctl_backend.c +++ b/sys/cam/ctl/ctl_backend.c @@ -66,33 +66,33 @@ extern struct ctl_softc *control_softc; int ctl_backend_register(struct ctl_backend_driver *be) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_backend_driver *be_tmp; - ctl_softc = control_softc; + softc = control_softc; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); /* * Sanity check, make sure this isn't a duplicate registration. */ - STAILQ_FOREACH(be_tmp, &ctl_softc->be_list, links) { + STAILQ_FOREACH(be_tmp, &softc->be_list, links) { if (strcmp(be_tmp->name, be->name) == 0) { - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (-1); } } - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); /* * Call the backend's initialization routine. */ be->init(); - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); - STAILQ_INSERT_TAIL(&ctl_softc->be_list, be, links); + STAILQ_INSERT_TAIL(&softc->be_list, be, links); - ctl_softc->num_backends++; + softc->num_backends++; /* * Don't want to increment the usage count for internal consumers, @@ -113,7 +113,7 @@ ctl_backend_register(struct ctl_backend_driver *be) atomic_set(&be->num_luns, 0); #endif - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (0); } @@ -121,24 +121,24 @@ ctl_backend_register(struct ctl_backend_driver *be) int ctl_backend_deregister(struct ctl_backend_driver *be) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; - ctl_softc = control_softc; + softc = control_softc; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); #if 0 if (atomic_read(&be->num_luns) != 0) { #endif /* XXX KDM fix this! */ if (be->num_luns != 0) { - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (-1); } - STAILQ_REMOVE(&ctl_softc->be_list, be, ctl_backend_driver, links); + STAILQ_REMOVE(&softc->be_list, be, ctl_backend_driver, links); - ctl_softc->num_backends--; + softc->num_backends--; /* XXX KDM find a substitute for this? */ #if 0 @@ -146,7 +146,7 @@ ctl_backend_deregister(struct ctl_backend_driver *be) MOD_DEC_USE_COUNT; #endif - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (0); } @@ -154,21 +154,21 @@ ctl_backend_deregister(struct ctl_backend_driver *be) struct ctl_backend_driver * ctl_backend_find(char *backend_name) { - struct ctl_softc *ctl_softc; + struct ctl_softc *softc; struct ctl_backend_driver *be_tmp; - ctl_softc = control_softc; + softc = control_softc; - mtx_lock(&ctl_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); - STAILQ_FOREACH(be_tmp, &ctl_softc->be_list, links) { + STAILQ_FOREACH(be_tmp, &softc->be_list, links) { if (strcmp(be_tmp->name, backend_name) == 0) { - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (be_tmp); } } - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (NULL); } diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c index 52dc31c55ea..982675e8feb 100644 --- a/sys/cam/ctl/ctl_frontend.c +++ b/sys/cam/ctl/ctl_frontend.c @@ -68,21 +68,22 @@ extern struct ctl_softc *control_softc; int ctl_frontend_register(struct ctl_frontend *fe) { + struct ctl_softc *softc = control_softc; struct ctl_frontend *fe_tmp; - KASSERT(control_softc != NULL, ("CTL is not initialized")); + KASSERT(softc != NULL, ("CTL is not initialized")); /* * Sanity check, make sure this isn't a duplicate registration. */ - mtx_lock(&control_softc->ctl_lock); - STAILQ_FOREACH(fe_tmp, &control_softc->fe_list, links) { + mtx_lock(&softc->ctl_lock); + STAILQ_FOREACH(fe_tmp, &softc->fe_list, links) { if (strcmp(fe_tmp->name, fe->name) == 0) { - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (-1); } } - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); STAILQ_INIT(&fe->port_list); /* @@ -91,24 +92,25 @@ ctl_frontend_register(struct ctl_frontend *fe) if (fe->init != NULL) fe->init(); - mtx_lock(&control_softc->ctl_lock); - control_softc->num_frontends++; - STAILQ_INSERT_TAIL(&control_softc->fe_list, fe, links); - mtx_unlock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); + softc->num_frontends++; + STAILQ_INSERT_TAIL(&softc->fe_list, fe, links); + mtx_unlock(&softc->ctl_lock); return (0); } int ctl_frontend_deregister(struct ctl_frontend *fe) { + struct ctl_softc *softc = control_softc; if (!STAILQ_EMPTY(&fe->port_list)) return (-1); - mtx_lock(&control_softc->ctl_lock); - STAILQ_REMOVE(&control_softc->fe_list, fe, ctl_frontend, links); - control_softc->num_frontends--; - mtx_unlock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); + STAILQ_REMOVE(&softc->fe_list, fe, ctl_frontend, links); + softc->num_frontends--; + mtx_unlock(&softc->ctl_lock); /* * Call the frontend's shutdown routine. @@ -121,41 +123,42 @@ ctl_frontend_deregister(struct ctl_frontend *fe) struct ctl_frontend * ctl_frontend_find(char *frontend_name) { - struct ctl_softc *ctl_softc = control_softc; + struct ctl_softc *softc = control_softc; struct ctl_frontend *fe; - mtx_lock(&ctl_softc->ctl_lock); - STAILQ_FOREACH(fe, &ctl_softc->fe_list, links) { + mtx_lock(&softc->ctl_lock); + STAILQ_FOREACH(fe, &softc->fe_list, links) { if (strcmp(fe->name, frontend_name) == 0) { - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (fe); } } - mtx_unlock(&ctl_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (NULL); } int ctl_port_register(struct ctl_port *port) { + struct ctl_softc *softc = control_softc; void *pool; int port_num; int retval; retval = 0; - KASSERT(control_softc != NULL, ("CTL is not initialized")); + KASSERT(softc != NULL, ("CTL is not initialized")); - mtx_lock(&control_softc->ctl_lock); - port_num = ctl_ffz(control_softc->ctl_port_mask, CTL_MAX_PORTS); + mtx_lock(&softc->ctl_lock); + port_num = ctl_ffz(softc->ctl_port_mask, CTL_MAX_PORTS); if ((port_num == -1) - || (ctl_set_mask(control_softc->ctl_port_mask, port_num) == -1)) { + || (ctl_set_mask(softc->ctl_port_mask, port_num) == -1)) { port->targ_port = -1; - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); return (1); } - control_softc->num_ports++; - mtx_unlock(&control_softc->ctl_lock); + softc->num_ports++; + mtx_unlock(&softc->ctl_lock); /* * Initialize the initiator and portname mappings @@ -176,15 +179,15 @@ ctl_port_register(struct ctl_port *port) * pending sense queue on the next command, whether or not it is * a REQUEST SENSE. */ - retval = ctl_pool_create(control_softc, port->port_name, + retval = ctl_pool_create(softc, port->port_name, port->num_requested_ctl_io + 20, &pool); if (retval != 0) { free(port->wwpn_iid, M_CTL); error: port->targ_port = -1; - mtx_lock(&control_softc->ctl_lock); - ctl_clear_mask(control_softc->ctl_port_mask, port_num); - mtx_unlock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); + ctl_clear_mask(softc->ctl_port_mask, port_num); + mtx_unlock(&softc->ctl_lock); return (retval); } port->ctl_pool_ref = pool; @@ -192,12 +195,12 @@ error: if (port->options.stqh_first == NULL) STAILQ_INIT(&port->options); - mtx_lock(&control_softc->ctl_lock); - port->targ_port = port_num + control_softc->port_offset; + mtx_lock(&softc->ctl_lock); + port->targ_port = port_num + softc->port_offset; STAILQ_INSERT_TAIL(&port->frontend->port_list, port, fe_links); - STAILQ_INSERT_TAIL(&control_softc->port_list, port, links); - control_softc->ctl_ports[port_num] = port; - mtx_unlock(&control_softc->ctl_lock); + STAILQ_INSERT_TAIL(&softc->port_list, port, links); + softc->ctl_ports[port_num] = port; + mtx_unlock(&softc->ctl_lock); return (retval); } @@ -205,6 +208,7 @@ error: int ctl_port_deregister(struct ctl_port *port) { + struct ctl_softc *softc = control_softc; struct ctl_io_pool *pool; int port_num, retval, i; @@ -217,15 +221,15 @@ ctl_port_deregister(struct ctl_port *port) goto bailout; } - mtx_lock(&control_softc->ctl_lock); - STAILQ_REMOVE(&control_softc->port_list, port, ctl_port, links); + mtx_lock(&softc->ctl_lock); + STAILQ_REMOVE(&softc->port_list, port, ctl_port, links); STAILQ_REMOVE(&port->frontend->port_list, port, ctl_port, fe_links); - control_softc->num_ports--; + softc->num_ports--; port_num = (port->targ_port < CTL_MAX_PORTS) ? port->targ_port : port->targ_port - CTL_MAX_PORTS; - ctl_clear_mask(control_softc->ctl_port_mask, port_num); - control_softc->ctl_ports[port_num] = NULL; - mtx_unlock(&control_softc->ctl_lock); + ctl_clear_mask(softc->ctl_port_mask, port_num); + softc->ctl_ports[port_num] = NULL; + mtx_unlock(&softc->ctl_lock); ctl_pool_free(pool); ctl_free_opts(&port->options); diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c index 90a31ae59e0..4e67ce14d32 100644 --- a/sys/cam/ctl/ctl_tpc.c +++ b/sys/cam/ctl/ctl_tpc.c @@ -145,8 +145,6 @@ struct tpc_list { TAILQ_ENTRY(tpc_list) links; }; -extern struct ctl_softc *control_softc; - static void tpc_timeout(void *arg) { @@ -216,6 +214,7 @@ ctl_tpc_lun_init(struct ctl_lun *lun) void ctl_tpc_lun_shutdown(struct ctl_lun *lun) { + struct ctl_softc *softc = lun->ctl_softc; struct tpc_list *list; struct tpc_token *token, *ttoken; @@ -228,11 +227,11 @@ ctl_tpc_lun_shutdown(struct ctl_lun *lun) } /* Free ROD tokens for this LUN. */ - mtx_assert(&control_softc->ctl_lock, MA_OWNED); - TAILQ_FOREACH_SAFE(token, &control_softc->tpc_tokens, links, ttoken) { + mtx_assert(&softc->ctl_lock, MA_OWNED); + TAILQ_FOREACH_SAFE(token, &softc->tpc_tokens, links, ttoken) { if (token->lun != lun->lun || token->active) continue; - TAILQ_REMOVE(&control_softc->tpc_tokens, token, links); + TAILQ_REMOVE(&softc->tpc_tokens, token, links); free(token->params, M_CTL); free(token, M_CTL); } @@ -796,7 +795,8 @@ tpc_resolve(struct tpc_list *list, uint16_t idx, uint32_t *ss) } if (idx >= list->ncscd) return (UINT64_MAX); - return (tpcl_resolve(list->init_port, &list->cscd[idx], ss)); + return (tpcl_resolve(list->lun->ctl_softc, + list->init_port, &list->cscd[idx], ss)); } static int @@ -1296,6 +1296,7 @@ static void tpc_process(struct tpc_list *list) { struct ctl_lun *lun = list->lun; + struct ctl_softc *softc = lun->ctl_softc; struct scsi_ec_segment *seg; struct ctl_scsiio *ctsio = list->ctsio; int retval = CTL_RETVAL_COMPLETE; @@ -1349,10 +1350,10 @@ done: free(list->params, M_CTL); list->params = NULL; if (list->token) { - mtx_lock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); if (--list->token->active == 0) list->token->last_active = time_uptime; - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); list->token = NULL; } mtx_lock(&lun->lun_lock); @@ -1831,6 +1832,7 @@ ctl_populate_token(struct ctl_scsiio *ctsio) { struct scsi_populate_token *cdb; struct scsi_populate_token_data *data; + struct ctl_softc *softc; struct ctl_lun *lun; struct ctl_port *port; struct tpc_list *list, *tlist; @@ -1840,7 +1842,8 @@ ctl_populate_token(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_populate_token\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; - port = control_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; + softc = lun->ctl_softc; + port = softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; cdb = (struct scsi_populate_token *)ctsio->cdb; len = scsi_4btoul(cdb->length); @@ -1944,9 +1947,9 @@ ctl_populate_token(struct ctl_scsiio *ctsio) list->curseg = 0; list->completed = 1; list->last_active = time_uptime; - mtx_lock(&control_softc->ctl_lock); - TAILQ_INSERT_TAIL(&control_softc->tpc_tokens, token, links); - mtx_unlock(&control_softc->ctl_lock); + mtx_lock(&softc->ctl_lock); + TAILQ_INSERT_TAIL(&softc->tpc_tokens, token, links); + mtx_unlock(&softc->ctl_lock); ctl_set_success(ctsio); ctl_done((union ctl_io *)ctsio); return (CTL_RETVAL_COMPLETE); @@ -1965,6 +1968,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio) { struct scsi_write_using_token *cdb; struct scsi_write_using_token_data *data; + struct ctl_softc *softc; struct ctl_lun *lun; struct tpc_list *list, *tlist; struct tpc_token *token; @@ -1973,6 +1977,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio) CTL_DEBUG_PRINT(("ctl_write_using_token\n")); lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + softc = lun->ctl_softc; cdb = (struct scsi_write_using_token *)ctsio->cdb; len = scsi_4btoul(cdb->length); @@ -2051,8 +2056,8 @@ ctl_write_using_token(struct ctl_scsiio *ctsio) return (CTL_RETVAL_COMPLETE); } - mtx_lock(&control_softc->ctl_lock); - TAILQ_FOREACH(token, &control_softc->tpc_tokens, links) { + mtx_lock(&softc->ctl_lock); + TAILQ_FOREACH(token, &softc->tpc_tokens, links) { if (memcmp(token->token, data->rod_token, sizeof(data->rod_token)) == 0) break; @@ -2063,7 +2068,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio) if (data->flags & EC_WUT_DEL_TKN) token->timeout = 0; } - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); if (token == NULL) { mtx_lock(&lun->lun_lock); TAILQ_REMOVE(&lun->tpc_lists, list, links); @@ -2188,6 +2193,7 @@ ctl_receive_rod_token_information(struct ctl_scsiio *ctsio) int ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio) { + struct ctl_softc *softc; struct ctl_lun *lun; struct scsi_report_all_rod_tokens *cdb; struct scsi_report_all_rod_tokens_data *data; @@ -2199,14 +2205,15 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio) cdb = (struct scsi_report_all_rod_tokens *)ctsio->cdb; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + softc = lun->ctl_softc; retval = CTL_RETVAL_COMPLETE; tokens = 0; - mtx_lock(&control_softc->ctl_lock); - TAILQ_FOREACH(token, &control_softc->tpc_tokens, links) + mtx_lock(&softc->ctl_lock); + TAILQ_FOREACH(token, &softc->tpc_tokens, links) tokens++; - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); if (tokens > 512) tokens = 512; @@ -2231,15 +2238,15 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio) data = (struct scsi_report_all_rod_tokens_data *)ctsio->kern_data_ptr; i = 0; - mtx_lock(&control_softc->ctl_lock); - TAILQ_FOREACH(token, &control_softc->tpc_tokens, links) { + mtx_lock(&softc->ctl_lock); + TAILQ_FOREACH(token, &softc->tpc_tokens, links) { if (i >= tokens) break; memcpy(&data->rod_management_token_list[i * 96], token->token, 96); i++; } - mtx_unlock(&control_softc->ctl_lock); + mtx_unlock(&softc->ctl_lock); scsi_ulto4b(sizeof(*data) - 4 + i * 96, data->available_data); /* printf("RART tokens=%d\n", i); diff --git a/sys/cam/ctl/ctl_tpc.h b/sys/cam/ctl/ctl_tpc.h index ecbaec105d3..ffdab5a44b9 100644 --- a/sys/cam/ctl/ctl_tpc.h +++ b/sys/cam/ctl/ctl_tpc.h @@ -31,7 +31,8 @@ void tpc_done(union ctl_io *io); -uint64_t tpcl_resolve(int init_port, struct scsi_ec_cscd *cscd, uint32_t *ss); +uint64_t tpcl_resolve(struct ctl_softc *softc, int init_port, + struct scsi_ec_cscd *cscd, uint32_t *ss); union ctl_io * tpcl_alloc_io(void); int tpcl_queue(union ctl_io *io, uint64_t lun); diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c index 97a5f984e26..63360fe75ae 100644 --- a/sys/cam/ctl/ctl_tpc_local.c +++ b/sys/cam/ctl/ctl_tpc_local.c @@ -63,7 +63,6 @@ struct tpcl_softc { int cur_tag_num; }; -extern struct ctl_softc *control_softc; static struct tpcl_softc tpcl_softc; static int tpcl_init(void); @@ -309,9 +308,9 @@ tpcl_done(union ctl_io *io) } uint64_t -tpcl_resolve(int init_port, struct scsi_ec_cscd *cscd, uint32_t *ss) +tpcl_resolve(struct ctl_softc *softc, int init_port, + struct scsi_ec_cscd *cscd, uint32_t *ss) { - struct ctl_softc *softc = control_softc; struct scsi_ec_cscd_id *cscdid; struct ctl_port *port; struct ctl_lun *lun; diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c index a1f39d287da..b1dba8c0895 100644 --- a/sys/cam/ctl/scsi_ctl.c +++ b/sys/cam/ctl/scsi_ctl.c @@ -228,8 +228,6 @@ static struct ctl_frontend ctlfe_frontend = }; CTL_FRONTEND_DECLARE(ctlfe, ctlfe_frontend); -extern struct ctl_softc *control_softc; - void ctlfeshutdown(void) { From 0664680536a15c666673ab650d3237986694508d Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 19 Dec 2014 20:51:54 +0000 Subject: [PATCH 021/207] Constify some static data. MFC after: 2 weeks --- sys/cam/ctl/ctl.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 6e4ea8b819e..8cd2d39334c 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -111,7 +111,7 @@ struct ctl_softc *control_softc = NULL; * Note that these are default values only. The actual values will be * filled in when the user does a mode sense. */ -static struct copan_debugconf_subpage debugconf_page_default = { +const static struct copan_debugconf_subpage debugconf_page_default = { DBGCNF_PAGE_CODE | SMPH_SPF, /* page_code */ DBGCNF_SUBPAGE_CODE, /* subpage */ {(sizeof(struct copan_debugconf_subpage) - 4) >> 8, @@ -121,7 +121,7 @@ static struct copan_debugconf_subpage debugconf_page_default = { CTL_TIME_IO_DEFAULT_SECS>>0}, /* ctl_time_io_secs */ }; -static struct copan_debugconf_subpage debugconf_page_changeable = { +const static struct copan_debugconf_subpage debugconf_page_changeable = { DBGCNF_PAGE_CODE | SMPH_SPF, /* page_code */ DBGCNF_SUBPAGE_CODE, /* subpage */ {(sizeof(struct copan_debugconf_subpage) - 4) >> 8, @@ -130,7 +130,7 @@ static struct copan_debugconf_subpage debugconf_page_changeable = { {0xff,0xff}, /* ctl_time_io_secs */ }; -static struct scsi_da_rw_recovery_page rw_er_page_default = { +const static struct scsi_da_rw_recovery_page rw_er_page_default = { /*page_code*/SMS_RW_ERROR_RECOVERY_PAGE, /*page_length*/sizeof(struct scsi_da_rw_recovery_page) - 2, /*byte3*/SMS_RWER_AWRE|SMS_RWER_ARRE, @@ -144,7 +144,7 @@ static struct scsi_da_rw_recovery_page rw_er_page_default = { /*recovery_time_limit*/{0, 0}, }; -static struct scsi_da_rw_recovery_page rw_er_page_changeable = { +const static struct scsi_da_rw_recovery_page rw_er_page_changeable = { /*page_code*/SMS_RW_ERROR_RECOVERY_PAGE, /*page_length*/sizeof(struct scsi_da_rw_recovery_page) - 2, /*byte3*/0, @@ -158,7 +158,7 @@ static struct scsi_da_rw_recovery_page rw_er_page_changeable = { /*recovery_time_limit*/{0, 0}, }; -static struct scsi_format_page format_page_default = { +const static struct scsi_format_page format_page_default = { /*page_code*/SMS_FORMAT_DEVICE_PAGE, /*page_length*/sizeof(struct scsi_format_page) - 2, /*tracks_per_zone*/ {0, 0}, @@ -175,7 +175,7 @@ static struct scsi_format_page format_page_default = { /*reserved*/ {0, 0, 0} }; -static struct scsi_format_page format_page_changeable = { +const static struct scsi_format_page format_page_changeable = { /*page_code*/SMS_FORMAT_DEVICE_PAGE, /*page_length*/sizeof(struct scsi_format_page) - 2, /*tracks_per_zone*/ {0, 0}, @@ -191,7 +191,7 @@ static struct scsi_format_page format_page_changeable = { /*reserved*/ {0, 0, 0} }; -static struct scsi_rigid_disk_page rigid_disk_page_default = { +const static struct scsi_rigid_disk_page rigid_disk_page_default = { /*page_code*/SMS_RIGID_DISK_PAGE, /*page_length*/sizeof(struct scsi_rigid_disk_page) - 2, /*cylinders*/ {0, 0, 0}, @@ -208,7 +208,7 @@ static struct scsi_rigid_disk_page rigid_disk_page_default = { /*reserved2*/ {0, 0} }; -static struct scsi_rigid_disk_page rigid_disk_page_changeable = { +const static struct scsi_rigid_disk_page rigid_disk_page_changeable = { /*page_code*/SMS_RIGID_DISK_PAGE, /*page_length*/sizeof(struct scsi_rigid_disk_page) - 2, /*cylinders*/ {0, 0, 0}, @@ -224,7 +224,7 @@ static struct scsi_rigid_disk_page rigid_disk_page_changeable = { /*reserved2*/ {0, 0} }; -static struct scsi_caching_page caching_page_default = { +const static struct scsi_caching_page caching_page_default = { /*page_code*/SMS_CACHING_PAGE, /*page_length*/sizeof(struct scsi_caching_page) - 2, /*flags1*/ SCP_DISC | SCP_WCE, @@ -240,7 +240,7 @@ static struct scsi_caching_page caching_page_default = { /*non_cache_seg_size*/ {0, 0, 0} }; -static struct scsi_caching_page caching_page_changeable = { +const static struct scsi_caching_page caching_page_changeable = { /*page_code*/SMS_CACHING_PAGE, /*page_length*/sizeof(struct scsi_caching_page) - 2, /*flags1*/ SCP_WCE | SCP_RCD, @@ -256,7 +256,7 @@ static struct scsi_caching_page caching_page_changeable = { /*non_cache_seg_size*/ {0, 0, 0} }; -static struct scsi_control_page control_page_default = { +const static struct scsi_control_page control_page_default = { /*page_code*/SMS_CONTROL_MODE_PAGE, /*page_length*/sizeof(struct scsi_control_page) - 2, /*rlec*/0, @@ -268,7 +268,7 @@ static struct scsi_control_page control_page_default = { /*extended_selftest_completion_time*/{0, 0} }; -static struct scsi_control_page control_page_changeable = { +const static struct scsi_control_page control_page_changeable = { /*page_code*/SMS_CONTROL_MODE_PAGE, /*page_length*/sizeof(struct scsi_control_page) - 2, /*rlec*/SCP_DSENSE, @@ -280,7 +280,7 @@ static struct scsi_control_page control_page_changeable = { /*extended_selftest_completion_time*/{0, 0} }; -static struct scsi_info_exceptions_page ie_page_default = { +const static struct scsi_info_exceptions_page ie_page_default = { /*page_code*/SMS_INFO_EXCEPTIONS_PAGE, /*page_length*/sizeof(struct scsi_info_exceptions_page) - 2, /*info_flags*/SIEP_FLAGS_DEXCPT, @@ -289,7 +289,7 @@ static struct scsi_info_exceptions_page ie_page_default = { /*report_count*/{0, 0, 0, 0} }; -static struct scsi_info_exceptions_page ie_page_changeable = { +const static struct scsi_info_exceptions_page ie_page_changeable = { /*page_code*/SMS_INFO_EXCEPTIONS_PAGE, /*page_length*/sizeof(struct scsi_info_exceptions_page) - 2, /*info_flags*/0, @@ -300,7 +300,7 @@ static struct scsi_info_exceptions_page ie_page_changeable = { #define CTL_LBPM_LEN (sizeof(struct ctl_logical_block_provisioning_page) - 4) -static struct ctl_logical_block_provisioning_page lbp_page_default = {{ +const static struct ctl_logical_block_provisioning_page lbp_page_default = {{ /*page_code*/SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF, /*subpage_code*/0x02, /*page_length*/{CTL_LBPM_LEN >> 8, CTL_LBPM_LEN}, @@ -326,7 +326,7 @@ static struct ctl_logical_block_provisioning_page lbp_page_default = {{ } }; -static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{ +const static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{ /*page_code*/SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF, /*subpage_code*/0x02, /*page_length*/{CTL_LBPM_LEN >> 8, CTL_LBPM_LEN}, From 7a8f993664db453d058508919e8c6161fa2d8de0 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Fri, 19 Dec 2014 23:13:46 +0000 Subject: [PATCH 022/207] Add code to set and reset open-drain mode on the bus when requested. Submitted by: Michal Meloun --- sys/arm/ti/ti_sdhci.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c index 024c830ad9d..a56f3840df9 100644 --- a/sys/arm/ti/ti_sdhci.c +++ b/sys/arm/ti/ti_sdhci.c @@ -112,6 +112,7 @@ static struct ofw_compat_data compat_data[] = { #define MMCHS_CON 0x02C #define MMCHS_CON_DW8 (1 << 5) #define MMCHS_CON_DVAL_8_4MS (3 << 9) +#define MMCHS_CON_OD (1 << 0) #define MMCHS_SYSCTL 0x12C #define MMCHS_SYSCTL_CLKD_MASK 0x3FF #define MMCHS_SYSCTL_CLKD_SHIFT 6 @@ -327,7 +328,7 @@ ti_sdhci_update_ios(device_t brdev, device_t reqdev) struct ti_sdhci_softc *sc = device_get_softc(brdev); struct sdhci_slot *slot; struct mmc_ios *ios; - uint32_t val32; + uint32_t val32, newval32; slot = device_get_ivars(reqdev); ios = &slot->host.ios; @@ -339,10 +340,20 @@ ti_sdhci_update_ios(device_t brdev, device_t reqdev) * requested, then let the standard driver handle everything else. */ val32 = ti_mmchs_read_4(sc, MMCHS_CON); + newval32 = val32; + if (ios->bus_width == bus_width_8) - ti_mmchs_write_4(sc, MMCHS_CON, val32 | MMCHS_CON_DW8); + newval32 |= MMCHS_CON_DW8; else - ti_mmchs_write_4(sc, MMCHS_CON, val32 & ~MMCHS_CON_DW8); + newval32 &= ~MMCHS_CON_DW8; + + if (ios->bus_mode == opendrain) + newval32 |= MMCHS_CON_OD; + else /* if (ios->bus_mode == pushpull) */ + newval32 &= ~MMCHS_CON_OD; + + if (newval32 != val32) + ti_mmchs_write_4(sc, MMCHS_CON, newval32); return (sdhci_generic_update_ios(brdev, reqdev)); } From a5d3a7fba9341421f684667f6d9eceb5d0390a5e Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Fri, 19 Dec 2014 23:24:54 +0000 Subject: [PATCH 023/207] Rewrap long lines; no functional changes. Submitted by: Michal Meloun --- sys/arm/ti/ti_sdhci.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c index a56f3840df9..6db13c3be06 100644 --- a/sys/arm/ti/ti_sdhci.c +++ b/sys/arm/ti/ti_sdhci.c @@ -403,9 +403,11 @@ ti_sdhci_hw_init(device_t dev) /* Issue a softreset to the controller */ ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, MMCHS_SYSCONFIG_RESET); timeout = 1000; - while (!(ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) & MMCHS_SYSSTATUS_RESETDONE)) { + while (!(ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) & + MMCHS_SYSSTATUS_RESETDONE)) { if (--timeout == 0) { - device_printf(dev, "Error: Controller reset operation timed out\n"); + device_printf(dev, + "Error: Controller reset operation timed out\n"); break; } DELAY(100); @@ -414,9 +416,11 @@ ti_sdhci_hw_init(device_t dev) /* Reset both the command and data state machines */ ti_sdhci_write_1(dev, NULL, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL); timeout = 1000; - while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL)) { + while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) & + SDHCI_RESET_ALL)) { if (--timeout == 0) { - device_printf(dev, "Error: Software reset operation timed out\n"); + device_printf(dev, + "Error: Software reset operation timed out\n"); break; } DELAY(100); From 0acf08d985eab5704b19cac57c3829d4879cf8dd Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 20 Dec 2014 00:04:01 +0000 Subject: [PATCH 024/207] Remove support for FreeBSD 7 and really old FreeBSD 8. The classifiers have been in the base for a while, so the gymnastics here aren't needed. In addition, the bugs in subr_disk.c have been fixed since 2009, so there's no need for an identical copy of it in the tree anymore. There's really no need to binary patch g_io_request, so let's get rid of the code (not compiled in anymore) lest others think it is a good idea. --- sys/geom/sched/README | 26 +- sys/geom/sched/g_sched.c | 170 +------------ sys/geom/sched/g_sched.h | 13 - sys/geom/sched/gs_rr.c | 12 +- sys/geom/sched/subr_disk.c | 226 ------------------ sys/modules/geom/geom_sched/gs_sched/Makefile | 2 +- 6 files changed, 13 insertions(+), 436 deletions(-) delete mode 100644 sys/geom/sched/subr_disk.c diff --git a/sys/geom/sched/README b/sys/geom/sched/README index 1b52d901162..b62d4688932 100644 --- a/sys/geom/sched/README +++ b/sys/geom/sched/README @@ -39,37 +39,17 @@ with cvs, and lets cvs progress when competing with a writer. To try it out: -1. USERS OF FREEBSD 7, PLEASE READ CAREFULLY THE FOLLOWING: - - On loading, this module patches one kernel function (g_io_request()) - so that I/O requests ("bio's") carry a classification tag, useful - for scheduling purposes. - - ON FREEBSD 7, the tag is stored in an existing (though rarely used) - field of the "struct bio", a solution which makes this module - incompatible with other modules using it, such as ZFS and gjournal. - Additionally, g_io_request() is patched in-memory to add a call - to the function that initializes this field (i386/amd64 only; - for other architectures you need to manually patch sys/geom/geom_io.c). - See details in the file g_sched.c. - - On FreeBSD 8.0 and above, the above trick is not necessary, - as the struct bio contains dedicated fields for the classifier, - and hooks for request classifiers. - - If you don't like the above, don't run this code. - -2. PLEASE MAKE SURE THAT THE DISK THAT YOU WILL BE USING FOR TESTS +1. PLEASE MAKE SURE THAT THE DISK THAT YOU WILL BE USING FOR TESTS DOES NOT CONTAIN PRECIOUS DATA. This is experimental code, so we make no guarantees, though I am routinely using it on my desktop and laptop. -3. EXTRACT AND BUILD THE PROGRAMS +2. EXTRACT AND BUILD THE PROGRAMS A 'make install' in the directory should work (with root privs), or you can even try the binary modules. If you want to build the modules yourself, look at the Makefile. -4. LOAD THE MODULE, CREATE A GEOM NODE, RUN TESTS +3. LOAD THE MODULE, CREATE A GEOM NODE, RUN TESTS The scheduler's module must be loaded first: diff --git a/sys/geom/sched/g_sched.c b/sys/geom/sched/g_sched.c index 009a58cedee..f1c9a3db7e7 100644 --- a/sys/geom/sched/g_sched.c +++ b/sys/geom/sched/g_sched.c @@ -346,17 +346,8 @@ static inline u_long g_sched_classify(struct bio *bp) { -#if __FreeBSD_version > 800098 /* we have classifier fields in the struct bio */ -#define HAVE_BIO_CLASSIFIER return ((u_long)bp->bio_classifier1); -#else -#warning old version!!! - while (bp->bio_parent != NULL) - bp = bp->bio_parent; - - return ((u_long)bp->bio_caller1); -#endif } /* Return the hash chain for the given key. */ @@ -705,7 +696,7 @@ g_gsched_global_init(void) G_SCHED_DEBUG(0, "Initializing global data."); mtx_init(&me.gs_mtx, "gsched", NULL, MTX_DEF); LIST_INIT(&me.gs_scheds); - gs_bioq_init(&me.gs_pending); + bioq_init(&me.gs_pending); me.gs_initialized = 1; } } @@ -914,7 +905,7 @@ g_sched_temporary_start(struct bio *bio) mtx_lock(&me.gs_mtx); me.gs_npending++; - gs_bioq_disksort(&me.gs_pending, bio); + bioq_disksort(&me.gs_pending, bio); mtx_unlock(&me.gs_mtx); } @@ -923,7 +914,7 @@ g_sched_flush_pending(g_start_t *start) { struct bio *bp; - while ((bp = gs_bioq_takefirst(&me.gs_pending))) + while ((bp = bioq_takefirst(&me.gs_pending))) start(bp); } @@ -1365,162 +1356,8 @@ g_sched_destroy_geom(struct gctl_req *req, struct g_class *mp, * to the issuer of a request in bp->bio_classifier1 as soon * as the bio is posted to the geom queue (and not later, because * requests are managed by the g_down thread afterwards). - * - * On older versions of the system (but this code is not used - * in any existing release), we [ab]use the caller1 field in the - * root element of the bio tree to store the classification info. - * The marking is done at the beginning of g_io_request() - * and only if we find that the field is NULL. - * - * To avoid rebuilding the kernel, this module will patch the - * initial part of g_io_request() so it jumps to some hand-coded - * assembly that does the marking and then executes the original - * body of g_io_request(). - * - * fake_ioreq[] is architecture-specific machine code - * that implements the above. CODE_SIZE, STORE_SIZE etc. - * are constants used in the patching routine. Look at the - * code in g_ioreq_patch() for the details. */ -#ifndef HAVE_BIO_CLASSIFIER -/* - * Support for old FreeBSD versions - */ -#if defined(__i386__) -#define CODE_SIZE 29 -#define STORE_SIZE 5 -#define EPILOGUE 5 -#define SIZE (CODE_SIZE + STORE_SIZE + EPILOGUE) - -static u_char fake_ioreq[SIZE] = { - 0x8b, 0x44, 0x24, 0x04, /* mov bp, %eax */ - /* 1: */ - 0x89, 0xc2, /* mov %eax, %edx # edx = bp */ - 0x8b, 0x40, 0x64, /* mov bp->bio_parent, %eax */ - 0x85, 0xc0, /* test %eax, %eax */ - 0x75, 0xf7, /* jne 1b */ - 0x8b, 0x42, 0x30, /* mov bp->bp_caller1, %eax */ - 0x85, 0xc0, /* test %eax, %eax */ - 0x75, 0x09, /* jne 2f */ - 0x64, 0xa1, 0x00, 0x00, /* mov %fs:0, %eax */ - 0x00, 0x00, - 0x89, 0x42, 0x30, /* mov %eax, bp->bio_caller1 */ - /* 2: */ - 0x55, 0x89, 0xe5, 0x57, 0x56, - 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp back... */ -}; -#elif defined(__amd64) -#define CODE_SIZE 38 -#define STORE_SIZE 6 -#define EPILOGUE 5 -#define SIZE (CODE_SIZE + STORE_SIZE + EPILOGUE) - -static u_char fake_ioreq[SIZE] = { - 0x48, 0x89, 0xf8, /* mov bp, %rax */ - /* 1: */ - 0x48, 0x89, 0xc2, /* mov %rax, %rdx # rdx = bp */ - 0x48, 0x8b, 0x82, 0xa8, /* mov bp->bio_parent, %rax */ - 0x00, 0x00, 0x00, - 0x48, 0x85, 0xc0, /* test %rax, %rax */ - 0x75, 0xf1, /* jne 1b */ - 0x48, 0x83, 0x7a, 0x58, /* cmp $0, bp->bp_caller1 */ - 0x00, - 0x75, 0x0d, /* jne 2f */ - 0x65, 0x48, 0x8b, 0x04, /* mov %gs:0, %rax */ - 0x25, 0x00, 0x00, 0x00, - 0x00, - 0x48, 0x89, 0x42, 0x58, /* mov %rax, bp->bio_caller1 */ - /* 2: */ - 0x55, 0x48, 0x89, 0xe5, 0x41, 0x56, - 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp back... */ -}; -#else /* neither x86 nor amd64 */ -static void -g_new_io_request(struct bio *bp, struct g_consumer *cp) -{ - struct bio *top = bp; - - /* - * bio classification: if bio_caller1 is available in the - * root of the 'struct bio' tree, store there the thread id - * of the thread that originated the request. - * More sophisticated classification schemes can be used. - */ - while (top->bio_parent) - top = top->bio_parent; - - if (top->bio_caller1 == NULL) - top->bio_caller1 = curthread; -} - -#error please add the code above in g_new_io_request() to the beginning of \ - /sys/geom/geom_io.c::g_io_request(), and remove this line. -#endif /* end of arch-specific code */ - -static int -g_ioreq_patch(void) -{ - u_char *original; - u_long ofs; - int found; - - if (me.gs_patched) - return (-1); - - original = (u_char *)g_io_request; - - found = !bcmp(original, fake_ioreq + CODE_SIZE, STORE_SIZE); - if (!found) - return (-1); - - /* Jump back to the original + STORE_SIZE. */ - ofs = (original + STORE_SIZE) - (fake_ioreq + SIZE); - bcopy(&ofs, fake_ioreq + CODE_SIZE + STORE_SIZE + 1, 4); - - /* Patch the original address with a jump to the trampoline. */ - *original = 0xe9; /* jump opcode */ - ofs = fake_ioreq - (original + 5); - bcopy(&ofs, original + 1, 4); - - me.gs_patched = 1; - - return (0); -} - -/* - * Restore the original code, this is easy. - */ -static void -g_ioreq_restore(void) -{ - u_char *original; - - if (me.gs_patched) { - original = (u_char *)g_io_request; - bcopy(fake_ioreq + CODE_SIZE, original, STORE_SIZE); - me.gs_patched = 0; - } -} - -static inline void -g_classifier_ini(void) -{ - - g_ioreq_patch(); -} - -static inline void -g_classifier_fini(void) -{ - - g_ioreq_restore(); -} - -/*--- end of support code for older FreeBSD versions */ - -#else /* HAVE_BIO_CLASSIFIER */ - /* * Classifier support for recent FreeBSD versions: we use * a very simple classifier, only use curthread to tag a request. @@ -1552,7 +1389,6 @@ g_classifier_fini(void) g_unregister_classifier(&g_sched_classifier); } -#endif /* HAVE_BIO_CLASSIFIER */ static void g_sched_init(struct g_class *mp) diff --git a/sys/geom/sched/g_sched.h b/sys/geom/sched/g_sched.h index 3a34e2922b1..9fdadc4e300 100644 --- a/sys/geom/sched/g_sched.h +++ b/sys/geom/sched/g_sched.h @@ -120,19 +120,6 @@ struct g_sched_softc { #define G_SCHED_PROXYING 1 #define G_SCHED_FLUSHING 2 -/* - * Temporary- our own version of the disksort, because the - * version in 7.x and 8.x before march 2009 is buggy. - */ -void gs_bioq_init(struct bio_queue_head *); -void gs_bioq_remove(struct bio_queue_head *, struct bio *); -void gs_bioq_flush(struct bio_queue_head *, struct devstat *, int); -void gs_bioq_insert_head(struct bio_queue_head *, struct bio *); -void gs_bioq_insert_tail(struct bio_queue_head *, struct bio *); -struct bio *gs_bioq_first(struct bio_queue_head *); -struct bio *gs_bioq_takefirst(struct bio_queue_head *); -void gs_bioq_disksort(struct bio_queue_head *, struct bio *); - #endif /* _KERNEL */ #endif /* _G_SCHED_H_ */ diff --git a/sys/geom/sched/gs_rr.c b/sys/geom/sched/gs_rr.c index 6f268798c0a..b9d5d1b4e22 100644 --- a/sys/geom/sched/gs_rr.c +++ b/sys/geom/sched/gs_rr.c @@ -315,7 +315,7 @@ g_rr_init_class(void *data, void *priv) struct g_rr_softc *sc = data; struct g_rr_queue *qp = priv; - gs_bioq_init(&qp->q_bioq); + bioq_init(&qp->q_bioq); /* * Set the initial parameters for the client: @@ -350,7 +350,7 @@ g_rr_fini_class(void *data, void *priv) { struct g_rr_queue *qp = priv; - KASSERT(gs_bioq_first(&qp->q_bioq) == NULL, + KASSERT(bioq_first(&qp->q_bioq) == NULL, ("released nonempty queue")); qp->q_sc->sc_nqueues--; me.queues--; @@ -438,7 +438,7 @@ g_rr_next(void *data, int force) qp->q_flags &= ~G_FLAG_COMPLETED; } - bp = gs_bioq_takefirst(&qp->q_bioq); /* surely not NULL */ + bp = bioq_takefirst(&qp->q_bioq); /* surely not NULL */ qp->q_service += bp->bio_length; /* charge the service */ /* @@ -456,7 +456,7 @@ g_rr_next(void *data, int force) * on read or writes (e.g., anticipate only on reads). */ expired = g_rr_queue_expired(qp); /* are we expired ? */ - next = gs_bioq_first(&qp->q_bioq); /* do we have one more ? */ + next = bioq_first(&qp->q_bioq); /* do we have one more ? */ if (expired) { sc->sc_active = NULL; /* Either requeue or release reference. */ @@ -538,7 +538,7 @@ g_rr_start(void *data, struct bio *bp) if (qp == NULL) return (-1); /* allocation failed, tell upstream */ - if (gs_bioq_first(&qp->q_bioq) == NULL) { + if (bioq_first(&qp->q_bioq) == NULL) { /* * We are inserting into an empty queue. * Reset its state if it is sc_active, @@ -560,7 +560,7 @@ g_rr_start(void *data, struct bio *bp) /* Inherit the reference returned by g_rr_queue_get(). */ bp->bio_caller1 = qp; - gs_bioq_disksort(&qp->q_bioq, bp); + bioq_disksort(&qp->q_bioq, bp); return (0); } diff --git a/sys/geom/sched/subr_disk.c b/sys/geom/sched/subr_disk.c deleted file mode 100644 index db2a9ef11f8..00000000000 --- a/sys/geom/sched/subr_disk.c +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * The bioq_disksort() (and the specification of the bioq API) - * have been written by Luigi Rizzo and Fabio Checconi under the same - * license as above. - */ - -#include -__FBSDID("$FreeBSD$"); - -//#include "opt_geom.h" - -#include -#include -#include -#include -#include -#include -#include "g_sched.h" - -/* - * BIO queue implementation - * - * Please read carefully the description below before making any change - * to the code, or you might change the behaviour of the data structure - * in undesirable ways. - * - * A bioq stores disk I/O request (bio), normally sorted according to - * the distance of the requested position (bio->bio_offset) from the - * current head position (bioq->last_offset) in the scan direction, i.e. - * - * (uoff_t)(bio_offset - last_offset) - * - * Note that the cast to unsigned (uoff_t) is fundamental to insure - * that the distance is computed in the scan direction. - * - * The main methods for manipulating the bioq are: - * - * bioq_disksort() performs an ordered insertion; - * - * bioq_first() return the head of the queue, without removing; - * - * bioq_takefirst() return and remove the head of the queue, - * updating the 'current head position' as - * bioq->last_offset = bio->bio_offset + bio->bio_length; - * - * When updating the 'current head position', we assume that the result of - * bioq_takefirst() is dispatched to the device, so bioq->last_offset - * represents the head position once the request is complete. - * - * If the bioq is manipulated using only the above calls, it starts - * with a sorted sequence of requests with bio_offset >= last_offset, - * possibly followed by another sorted sequence of requests with - * 0 <= bio_offset < bioq->last_offset - * - * NOTE: historical behaviour was to ignore bio->bio_length in the - * update, but its use tracks the head position in a better way. - * Historical behaviour was also to update the head position when - * the request under service is complete, rather than when the - * request is extracted from the queue. However, the current API - * has no method to update the head position; secondly, once - * a request has been submitted to the disk, we have no idea of - * the actual head position, so the final one is our best guess. - * - * --- Direct queue manipulation --- - * - * A bioq uses an underlying TAILQ to store requests, so we also - * export methods to manipulate the TAILQ, in particular: - * - * bioq_insert_tail() insert an entry at the end. - * It also creates a 'barrier' so all subsequent - * insertions through bioq_disksort() will end up - * after this entry; - * - * bioq_insert_head() insert an entry at the head, update - * bioq->last_offset = bio->bio_offset so that - * all subsequent insertions through bioq_disksort() - * will end up after this entry; - * - * bioq_remove() remove a generic element from the queue, act as - * bioq_takefirst() if invoked on the head of the queue. - * - * The semantic of these methods is the same as the operations - * on the underlying TAILQ, but with additional guarantees on - * subsequent bioq_disksort() calls. E.g. bioq_insert_tail() - * can be useful for making sure that all previous ops are flushed - * to disk before continuing. - * - * Updating bioq->last_offset on a bioq_insert_head() guarantees - * that the bio inserted with the last bioq_insert_head() will stay - * at the head of the queue even after subsequent bioq_disksort(). - * - * Note that when the direct queue manipulation functions are used, - * the queue may contain multiple inversion points (i.e. more than - * two sorted sequences of requests). - * - */ - -void -gs_bioq_init(struct bio_queue_head *head) -{ - - TAILQ_INIT(&head->queue); - head->last_offset = 0; - head->insert_point = NULL; -} - -void -gs_bioq_remove(struct bio_queue_head *head, struct bio *bp) -{ - - if (head->insert_point == NULL) { - if (bp == TAILQ_FIRST(&head->queue)) - head->last_offset = bp->bio_offset + bp->bio_length; - } else if (bp == head->insert_point) - head->insert_point = NULL; - - TAILQ_REMOVE(&head->queue, bp, bio_queue); -} - -void -gs_bioq_flush(struct bio_queue_head *head, struct devstat *stp, int error) -{ - struct bio *bp; - - while ((bp = gs_bioq_takefirst(head)) != NULL) - biofinish(bp, stp, error); -} - -void -gs_bioq_insert_head(struct bio_queue_head *head, struct bio *bp) -{ - - if (head->insert_point == NULL) - head->last_offset = bp->bio_offset; - TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue); -} - -void -gs_bioq_insert_tail(struct bio_queue_head *head, struct bio *bp) -{ - - TAILQ_INSERT_TAIL(&head->queue, bp, bio_queue); - head->insert_point = bp; - head->last_offset = bp->bio_offset; -} - -struct bio * -gs_bioq_first(struct bio_queue_head *head) -{ - - return (TAILQ_FIRST(&head->queue)); -} - -struct bio * -gs_bioq_takefirst(struct bio_queue_head *head) -{ - struct bio *bp; - - bp = TAILQ_FIRST(&head->queue); - if (bp != NULL) - gs_bioq_remove(head, bp); - return (bp); -} - -/* - * Compute the sorting key. The cast to unsigned is - * fundamental for correctness, see the description - * near the beginning of the file. - */ -static inline uoff_t -gs_bioq_bio_key(struct bio_queue_head *head, struct bio *bp) -{ - - return ((uoff_t)(bp->bio_offset - head->last_offset)); -} - -/* - * Seek sort for disks. - * - * Sort all requests in a single queue while keeping - * track of the current position of the disk with last_offset. - * See above for details. - */ -void -gs_bioq_disksort(struct bio_queue_head *head, struct bio *bp) -{ - struct bio *cur, *prev; - uoff_t key; - - if ((bp->bio_flags & BIO_ORDERED) != 0) { - /* - * Ordered transactions can only be dispatched - * after any currently queued transactions. They - * also have barrier semantics - no transactions - * queued in the future can pass them. - */ - gs_bioq_insert_tail(head, bp); - return; - } - - prev = NULL; - key = gs_bioq_bio_key(head, bp); - cur = TAILQ_FIRST(&head->queue); - - if (head->insert_point) { - prev = head->insert_point; - cur = TAILQ_NEXT(head->insert_point, bio_queue); - } - - while (cur != NULL && key >= gs_bioq_bio_key(head, cur)) { - prev = cur; - cur = TAILQ_NEXT(cur, bio_queue); - } - - if (prev == NULL) - TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue); - else - TAILQ_INSERT_AFTER(&head->queue, prev, bp, bio_queue); -} diff --git a/sys/modules/geom/geom_sched/gs_sched/Makefile b/sys/modules/geom/geom_sched/gs_sched/Makefile index 5739365a380..13bb91bc99f 100644 --- a/sys/modules/geom/geom_sched/gs_sched/Makefile +++ b/sys/modules/geom/geom_sched/gs_sched/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ KMOD= geom_sched -SRCS= g_sched.c subr_disk.c +SRCS= g_sched.c # ../Makefile.inc automatically included .include From cf26c003517e880e16d7e0618646f56bfc7ac481 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 20 Dec 2014 00:07:53 +0000 Subject: [PATCH 025/207] Remove comments relevant to 6.x only. --- sys/modules/geom/geom_sched/gsched_rr/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/modules/geom/geom_sched/gsched_rr/Makefile b/sys/modules/geom/geom_sched/gsched_rr/Makefile index 42092771f8c..44cc56605a3 100644 --- a/sys/modules/geom/geom_sched/gsched_rr/Makefile +++ b/sys/modules/geom/geom_sched/gsched_rr/Makefile @@ -2,8 +2,6 @@ KMOD= gsched_rr SRCS= gs_rr.c -# hash.h on 6.x has a (char *) cast on a const pointer -#CWARNFLAGS= # ../Makefile.inc automatically included .include From 7e5866432f26970abe14f6d2fd8b671c4455bb68 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 20 Dec 2014 00:37:56 +0000 Subject: [PATCH 026/207] When command and data interrupts have been aggregated together, don't do the data-completed processing if a command-error interrupt is also asserted. Reviewed by: Michal Meloun --- sys/dev/sdhci/sdhci.c | 8 +++++++- sys/dev/sdhci/sdhci.h | 5 ++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index f92d42b94af..0b1f6162f26 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -713,9 +713,13 @@ sdhci_timeout(void *arg) struct sdhci_slot *slot = arg; if (slot->curcmd != NULL) { + slot_printf(slot, " Controller timeout\n"); + sdhci_dumpregs(slot); sdhci_reset(slot, SDHCI_RESET_CMD|SDHCI_RESET_DATA); slot->curcmd->error = MMC_ERR_TIMEOUT; sdhci_req_done(slot); + } else { + slot_printf(slot, " Spurious timeout - no active command\n"); } } @@ -1274,7 +1278,9 @@ sdhci_generic_intr(struct sdhci_slot *slot) /* Handle data interrupts. */ if (intmask & SDHCI_INT_DATA_MASK) { WR4(slot, SDHCI_INT_STATUS, intmask & SDHCI_INT_DATA_MASK); - sdhci_data_irq(slot, intmask & SDHCI_INT_DATA_MASK); + /* Dont call data_irq in case of errored command */ + if ((intmask & SDHCI_INT_CMD_ERROR_MASK) == 0) + sdhci_data_irq(slot, intmask & SDHCI_INT_DATA_MASK); } /* Handle AutoCMD12 error interrupt. */ if (intmask & SDHCI_INT_ACMD12ERR) { diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index 5cde2b0539c..f2679fce096 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -182,8 +182,11 @@ #define SDHCI_INT_NORMAL_MASK 0x00007FFF #define SDHCI_INT_ERROR_MASK 0xFFFF8000 -#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \ +#define SDHCI_INT_CMD_ERROR_MASK (SDHCI_INT_TIMEOUT | \ SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX) + +#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_CMD_ERROR_MASK) + #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \ SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \ SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \ From 61bc42f7824d5eb89ec14467400daf50d5ccf862 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 20 Dec 2014 01:13:13 +0000 Subject: [PATCH 027/207] Add a new sdhci quirk, SDHCI_QUIRK_WAITFOR_RESET_ASSERTED, to work around TI OMAP controllers which will return the reset-in-progress bit as zero if you read the status register too fast after setting the reset bit. The zero is apparently from a stale snapshot of the internal state presented in the interface register, and leads to a false indication that the reset is complete when it either hasn't started yet or is in-progress. The workaround is to first loop until the bit is seen as asserted, then do the normal loop waiting to see it de-asserted. Submitted by: Michal Meloun --- sys/arm/ti/ti_sdhci.c | 28 ++++++++++++++++++++++++++-- sys/dev/sdhci/sdhci.c | 36 ++++++++++++++++++++++++++---------- sys/dev/sdhci/sdhci.h | 2 ++ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c index 6db13c3be06..380a40eed49 100644 --- a/sys/arm/ti/ti_sdhci.c +++ b/sys/arm/ti/ti_sdhci.c @@ -413,9 +413,27 @@ ti_sdhci_hw_init(device_t dev) DELAY(100); } - /* Reset both the command and data state machines */ + /* + * Reset the command and data state machines and also other aspects of + * the controller such as bus clock and power. + * + * If we read the software reset register too fast after writing it we + * can get back a zero that means the reset hasn't started yet rather + * than that the reset is complete. Per TI recommendations, work around + * it by reading until we see the reset bit asserted, then read until + * it's clear. We also set the SDHCI_QUIRK_WAITFOR_RESET_ASSERTED quirk + * so that the main sdhci driver uses this same logic in its resets. + */ ti_sdhci_write_1(dev, NULL, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL); - timeout = 1000; + timeout = 10000; + while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) & + SDHCI_RESET_ALL) != SDHCI_RESET_ALL) { + if (--timeout == 0) { + break; + } + DELAY(1); + } + timeout = 10000; while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL)) { if (--timeout == 0) { @@ -582,6 +600,12 @@ ti_sdhci_attach(device_t dev) */ sc->slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE; + /* + * Reset bits are broken, have to wait to see the bits asserted + * before waiting to see them de-asserted. + */ + sc->slot.quirks |= SDHCI_QUIRK_WAITFOR_RESET_ASSERTED; + /* * DMA is not really broken, I just haven't implemented it yet. */ diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c index 0b1f6162f26..98861ab611c 100644 --- a/sys/dev/sdhci/sdhci.c +++ b/sys/dev/sdhci/sdhci.c @@ -149,7 +149,6 @@ static void sdhci_reset(struct sdhci_slot *slot, uint8_t mask) { int timeout; - uint8_t res; if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { if (!(RD4(slot, SDHCI_PRESENT_STATE) & @@ -168,26 +167,43 @@ sdhci_reset(struct sdhci_slot *slot, uint8_t mask) sdhci_set_clock(slot, clock); } - WR1(slot, SDHCI_SOFTWARE_RESET, mask); - if (mask & SDHCI_RESET_ALL) { slot->clock = 0; slot->power = 0; } + WR1(slot, SDHCI_SOFTWARE_RESET, mask); + + if (slot->quirks & SDHCI_QUIRK_WAITFOR_RESET_ASSERTED) { + /* + * Resets on TI OMAPs and AM335x are incompatible with SDHCI + * specification. The reset bit has internal propagation delay, + * so a fast read after write returns 0 even if reset process is + * in progress. The workaround is to poll for 1 before polling + * for 0. In the worst case, if we miss seeing it asserted the + * time we spent waiting is enough to ensure the reset finishes. + */ + timeout = 10000; + while ((RD1(slot, SDHCI_SOFTWARE_RESET) & mask) != mask) { + if (timeout <= 0) + break; + timeout--; + DELAY(1); + } + } + /* Wait max 100 ms */ - timeout = 100; + timeout = 10000; /* Controller clears the bits when it's done */ - while ((res = RD1(slot, SDHCI_SOFTWARE_RESET)) & mask) { - if (timeout == 0) { - slot_printf(slot, - "Reset 0x%x never completed - 0x%x.\n", - (int)mask, (int)res); + while (RD1(slot, SDHCI_SOFTWARE_RESET) & mask) { + if (timeout <= 0) { + slot_printf(slot, "Reset 0x%x never completed.\n", + mask); sdhci_dumpregs(slot); return; } timeout--; - DELAY(1000); + DELAY(10); } } diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h index f2679fce096..ff1576e296b 100644 --- a/sys/dev/sdhci/sdhci.h +++ b/sys/dev/sdhci/sdhci.h @@ -59,6 +59,8 @@ #define SDHCI_QUIRK_MISSING_CAPS (1<<12) /* Hardware shifts the 136-bit response, don't do it in software. */ #define SDHCI_QUIRK_DONT_SHIFT_RESPONSE (1<<13) +/* Wait to see reset bit asserted before waiting for de-asserted */ +#define SDHCI_QUIRK_WAITFOR_RESET_ASSERTED (1<<14) /* * Controller registers From dc47198f507931c81d672e1e9cc023d6d45cfcbf Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sat, 20 Dec 2014 04:24:40 +0000 Subject: [PATCH 028/207] Log mmc and sd command failures. Reporting of routine expected errors, such as timeouts while probing a bus or testing for a feature, is squelched. Also, error reporting is limited to 5 events per second, because when an sdcard goes bad on a low-end embedded board, flooding the console at high speed isn't helpful. Original logging code contributed by Michal Meloun, but then I fancied it up with squelching and ppsratecheck. --- sys/dev/mmc/mmc.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index a3b9744b99b..4d6c2db6a28 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -76,8 +77,13 @@ struct mmc_softc { struct intr_config_hook config_intrhook; device_t owner; uint32_t last_rca; + int squelched; /* suppress reporting of (expected) errors */ + int log_count; + struct timeval log_time; }; +#define LOG_PPS 5 /* Log no more than 5 errors per second. */ + /* * Per-card data */ @@ -426,6 +432,13 @@ mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries) err = cmd->error; } while (err != MMC_ERR_NONE && retries-- > 0); + if (err != MMC_ERR_NONE && sc->squelched == 0) { + if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) { + device_printf(sc->dev, "CMD%d failed, RESULT: %d\n", + cmd->opcode, err); + } + } + return (err); } @@ -436,6 +449,8 @@ mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, struct mmc_command appcmd; int err; + /* Squelch error reporting at lower levels, we report below. */ + sc->squelched++; do { memset(&appcmd, 0, sizeof(appcmd)); appcmd.opcode = MMC_APP_CMD; @@ -455,6 +470,14 @@ mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca, err = cmd->error; } } while (err != MMC_ERR_NONE && retries-- > 0); + sc->squelched--; + + if (err != MMC_ERR_NONE && sc->squelched == 0) { + if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) { + device_printf(sc->dev, "ACMD%d failed, RESULT: %d\n", + cmd->opcode, err); + } + } return (err); } @@ -760,6 +783,7 @@ mmc_test_bus_width(struct mmc_softc *sc) mmcbr_set_bus_width(sc->dev, bus_width_8); mmcbr_update_ios(sc->dev); + sc->squelched++; /* Errors are expected, squelch reporting. */ memset(&cmd, 0, sizeof(cmd)); memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_W; @@ -783,6 +807,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.len = 8; data.flags = MMC_DATA_READ; err = mmc_wait_for_cmd(sc, &cmd, 0); + sc->squelched--; mmcbr_set_bus_width(sc->dev, bus_width_1); mmcbr_update_ios(sc->dev); @@ -795,6 +820,7 @@ mmc_test_bus_width(struct mmc_softc *sc) mmcbr_set_bus_width(sc->dev, bus_width_4); mmcbr_update_ios(sc->dev); + sc->squelched++; /* Errors are expected, squelch reporting. */ memset(&cmd, 0, sizeof(cmd)); memset(&data, 0, sizeof(data)); cmd.opcode = MMC_BUSTEST_W; @@ -818,6 +844,7 @@ mmc_test_bus_width(struct mmc_softc *sc) data.len = 4; data.flags = MMC_DATA_READ; err = mmc_wait_for_cmd(sc, &cmd, 0); + sc->squelched--; mmcbr_set_bus_width(sc->dev, bus_width_1); mmcbr_update_ios(sc->dev); @@ -1270,7 +1297,9 @@ mmc_discover_cards(struct mmc_softc *sc) if (bootverbose || mmc_debug) device_printf(sc->dev, "Probing cards\n"); while (1) { + sc->squelched++; /* Errors are expected, squelch reporting. */ err = mmc_all_send_cid(sc, raw_cid); + sc->squelched--; if (err == MMC_ERR_TIMEOUT) break; if (err != MMC_ERR_NONE) { @@ -1536,6 +1565,7 @@ mmc_go_discovery(struct mmc_softc *sc) /* * First, try SD modes */ + sc->squelched++; /* Errors are expected, squelch reporting. */ mmcbr_set_mode(dev, mode_sd); mmc_power_up(sc); mmcbr_set_bus_mode(dev, pushpull); @@ -1561,6 +1591,7 @@ mmc_go_discovery(struct mmc_softc *sc) "MMC probe: OK (OCR: 0x%08x)\n", ocr); } else if (bootverbose || mmc_debug) device_printf(sc->dev, "SD probe: OK (OCR: 0x%08x)\n", ocr); + sc->squelched--; mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr)); if (mmcbr_get_ocr(dev) != 0) From ac721e53ec30c700a00f49ab4f63e8ee851f538c Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Sat, 20 Dec 2014 04:57:45 +0000 Subject: [PATCH 029/207] Various 8259 device model improvements: - implement 8259 "polled" mode. - set 'atpic->sfn' if bit 4 in ICW4 is set during master initialization. - report error if guest tries to enable the "special mask" mode. Differential Revision: https://reviews.freebsd.org/D1328 Reviewed by: tychon Reported by: grehan Tested by: grehan MFC after: 1 week --- sys/amd64/vmm/io/vatpic.c | 41 +++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c index c6d4590e893..74a70279eb2 100644 --- a/sys/amd64/vmm/io/vatpic.c +++ b/sys/amd64/vmm/io/vatpic.c @@ -112,6 +112,16 @@ struct vatpic { static void vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate); +static __inline bool +master_atpic(struct vatpic *vatpic, struct atpic *atpic) +{ + + if (atpic == &vatpic->atpic[0]) + return (true); + else + return (false); +} + static __inline int vatpic_get_highest_isrpin(struct atpic *atpic) { @@ -250,6 +260,7 @@ vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) atpic->mask = 0; atpic->lowprio = 7; atpic->rd_cmd_reg = 0; + atpic->poll = 0; if ((val & ICW1_SNGL) != 0) { VATPIC_CTR0(vatpic, "vatpic cascade mode required"); @@ -301,6 +312,15 @@ vatpic_icw4(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) if ((val & ICW4_AEOI) != 0) atpic->aeoi = true; + if ((val & ICW4_SFNM) != 0) { + if (master_atpic(vatpic, atpic)) { + atpic->sfn = true; + } else { + VATPIC_CTR1(vatpic, "Ignoring special fully nested " + "mode on slave atpic: %#x", val); + } + } + atpic->icw_num = 0; atpic->ready = true; @@ -354,11 +374,17 @@ vatpic_ocw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val) { VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val); - atpic->poll = ((val & OCW3_P) != 0); + if (val & OCW3_ESMM) { + VATPIC_CTR0(vatpic, "atpic special mask mode not implemented"); + return (-1); + } if (val & OCW3_RR) { /* read register command */ atpic->rd_cmd_reg = val & OCW3_RIS; + + /* Polling mode */ + atpic->poll = ((val & OCW3_P) != 0); } return (0); @@ -578,12 +604,19 @@ static int vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port, int bytes, uint32_t *eax) { + int pin; + VATPIC_LOCK(vatpic); if (atpic->poll) { - VATPIC_CTR0(vatpic, "vatpic polled mode not supported"); - VATPIC_UNLOCK(vatpic); - return (-1); + atpic->poll = 0; + pin = vatpic_get_highest_irrpin(atpic); + if (pin >= 0) { + vatpic_pin_accepted(atpic, pin); + *eax = 0x80 | pin; + } else { + *eax = 0; + } } else { if (port & ICU_IMR_OFFSET) { /* read interrrupt mask register */ From e7038eb747853c6d534016bfdfbf2d8793acff16 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 20 Dec 2014 13:33:31 +0000 Subject: [PATCH 030/207] Replace ctl_min() macro with MIN(). MFC after: 1 week --- sys/cam/ctl/ctl.c | 32 ++++++++++++++--------------- sys/cam/ctl/ctl.h | 1 - sys/cam/ctl/ctl_backend_block.c | 14 ++++++------- sys/cam/ctl/ctl_backend_ramdisk.c | 23 ++++++++++----------- sys/cam/ctl/ctl_frontend_cam_sim.c | 4 ++-- sys/cam/ctl/ctl_frontend_internal.c | 8 ++++---- 6 files changed, 40 insertions(+), 42 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 8cd2d39334c..cafb4d2cb1c 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -1743,8 +1743,8 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio) i < ext_sg_entries && j < kern_sg_entries;) { uint8_t *ext_ptr, *kern_ptr; - len_to_copy = ctl_min(ext_sglist[i].len - ext_watermark, - kern_sglist[j].len - kern_watermark); + len_to_copy = MIN(ext_sglist[i].len - ext_watermark, + kern_sglist[j].len - kern_watermark); ext_ptr = (uint8_t *)ext_sglist[i].addr; ext_ptr = ext_ptr + ext_watermark; @@ -2834,8 +2834,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, bbr_info->scsi_status = metatask->taskinfo.bbrread.scsi_status; memcpy(&bbr_info->sense_data, &metatask->taskinfo.bbrread.sense_data, - ctl_min(sizeof(bbr_info->sense_data), - sizeof(metatask->taskinfo.bbrread.sense_data))); + MIN(sizeof(bbr_info->sense_data), + sizeof(metatask->taskinfo.bbrread.sense_data))); cfi_free_metatask(metatask); @@ -3642,7 +3642,7 @@ ctl_ffz(uint32_t *mask, uint32_t size) num_chunks = (size >> 5); if (num_chunks == 0) num_chunks++; - num_pieces = ctl_min((sizeof(uint32_t) * 8), size); + num_pieces = MIN((sizeof(uint32_t) * 8), size); for (i = 0; i < num_chunks; i++) { for (j = 0; j < num_pieces; j++) { @@ -3889,7 +3889,7 @@ ctl_copy_io(union ctl_io *src, union ctl_io *dest) */ pool_ref = dest->io_hdr.pool; - memcpy(dest, src, ctl_min(sizeof(*src), sizeof(*dest))); + memcpy(dest, src, MIN(sizeof(*src), sizeof(*dest))); dest->io_hdr.pool = pool_ref; /* @@ -6752,7 +6752,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) header = (struct scsi_mode_hdr_6 *)ctsio->kern_data_ptr; - header->datalen = ctl_min(total_len - 1, 254); + header->datalen = MIN(total_len - 1, 254); if (control_dev == 0) { header->dev_specific = 0x10; /* DPOFUA */ if ((lun->flags & CTL_LUN_READONLY) || @@ -6774,7 +6774,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio) header = (struct scsi_mode_hdr_10 *)ctsio->kern_data_ptr; - datalen = ctl_min(total_len - 2, 65533); + datalen = MIN(total_len - 2, 65533); scsi_ulto2b(datalen, header->datalen); if (control_dev == 0) { header->dev_specific = 0x10; /* DPOFUA */ @@ -9515,7 +9515,7 @@ ctl_request_sense(struct ctl_scsiio *ctsio) (struct scsi_sense_data_fixed *)sense_ptr); else memcpy(sense_ptr, &lun->pending_sense[initidx], - ctl_min(sizeof(*sense_ptr), + MIN(sizeof(*sense_ptr), sizeof(lun->pending_sense[initidx]))); ctl_clear_mask(lun->have_ca, initidx); @@ -12474,8 +12474,8 @@ ctl_inject_error(struct ctl_lun *lun, union ctl_io *io) * checks. */ bcopy(&desc->custom_sense, &io->scsiio.sense_data, - ctl_min(sizeof(desc->custom_sense), - sizeof(io->scsiio.sense_data))); + MIN(sizeof(desc->custom_sense), + sizeof(io->scsiio.sense_data))); io->scsiio.scsi_status = SCSI_STATUS_CHECK_COND; io->scsiio.sense_len = SSD_FULL_SIZE; io->io_hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE; @@ -12704,7 +12704,7 @@ ctl_datamove(union ctl_io *io) */ for (sg_entries_sent = 0; sg_entries_sent < msg.dt.kern_sg_entries; msg.dt.sg_sequence++) { - msg.dt.cur_sg_entries = ctl_min((sizeof(msg.dt.sg_list)/ + msg.dt.cur_sg_entries = MIN((sizeof(msg.dt.sg_list)/ sizeof(msg.dt.sg_list[0])), msg.dt.kern_sg_entries - sg_entries_sent); @@ -13067,7 +13067,7 @@ ctl_datamove_remote_sgl_setup(union ctl_io *io) for (i = 0; (i < sizeof(io->io_hdr.remote_sglist) / sizeof(io->io_hdr.remote_sglist[0])) && (len_to_go > 0); i++) { - local_sglist[i].len = ctl_min(len_to_go, 131072); + local_sglist[i].len = MIN(len_to_go, 131072); CTL_SIZE_8B(local_dma_sglist[i].len, local_sglist[i].len); local_sglist[i].addr = @@ -13203,8 +13203,8 @@ ctl_datamove_remote_xfer(union ctl_io *io, unsigned command, * also have enough slack left over at the end, though, * to round up to the next 8 byte boundary. */ - cur_len = ctl_min(local_sglist[i].len - local_used, - remote_sglist[j].len - remote_used); + cur_len = MIN(local_sglist[i].len - local_used, + remote_sglist[j].len - remote_used); /* * In this case, we have a size issue and need to decrease @@ -13703,7 +13703,7 @@ ctl_queue_sense(union ctl_io *io) } memcpy(&lun->pending_sense[initidx], &io->scsiio.sense_data, - ctl_min(sizeof(lun->pending_sense[initidx]), + MIN(sizeof(lun->pending_sense[initidx]), sizeof(io->scsiio.sense_data))); ctl_set_mask(lun->have_ca, initidx); mtx_unlock(&lun->lun_lock); diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h index ae6c5835f87..9cf967c3987 100644 --- a/sys/cam/ctl/ctl.h +++ b/sys/cam/ctl/ctl.h @@ -40,7 +40,6 @@ #ifndef _CTL_H_ #define _CTL_H_ -#define ctl_min(x,y) (((x) < (y)) ? (x) : (y)) #define CTL_RETVAL_COMPLETE 0 #define CTL_RETVAL_QUEUED 1 #define CTL_RETVAL_ALLOCATED 2 diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c index 56b41a99c8e..a5e45024541 100644 --- a/sys/cam/ctl/ctl_backend_block.c +++ b/sys/cam/ctl/ctl_backend_block.c @@ -2302,32 +2302,32 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req) snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d", softc->num_luns); strncpy((char *)be_lun->ctl_be_lun.serial_num, tmpstr, - ctl_min(sizeof(be_lun->ctl_be_lun.serial_num), + MIN(sizeof(be_lun->ctl_be_lun.serial_num), sizeof(tmpstr))); /* Tell the user what we used for a serial number */ strncpy((char *)params->serial_num, tmpstr, - ctl_min(sizeof(params->serial_num), sizeof(tmpstr))); + MIN(sizeof(params->serial_num), sizeof(tmpstr))); } else { strncpy((char *)be_lun->ctl_be_lun.serial_num, params->serial_num, - ctl_min(sizeof(be_lun->ctl_be_lun.serial_num), + MIN(sizeof(be_lun->ctl_be_lun.serial_num), sizeof(params->serial_num))); } if ((params->flags & CTL_LUN_FLAG_DEVID) == 0) { snprintf(tmpstr, sizeof(tmpstr), "MYDEVID%4d", softc->num_luns); strncpy((char *)be_lun->ctl_be_lun.device_id, tmpstr, - ctl_min(sizeof(be_lun->ctl_be_lun.device_id), + MIN(sizeof(be_lun->ctl_be_lun.device_id), sizeof(tmpstr))); /* Tell the user what we used for a device ID */ strncpy((char *)params->device_id, tmpstr, - ctl_min(sizeof(params->device_id), sizeof(tmpstr))); + MIN(sizeof(params->device_id), sizeof(tmpstr))); } else { strncpy((char *)be_lun->ctl_be_lun.device_id, params->device_id, - ctl_min(sizeof(be_lun->ctl_be_lun.device_id), - sizeof(params->device_id))); + MIN(sizeof(be_lun->ctl_be_lun.device_id), + sizeof(params->device_id))); } TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_be_block_worker, be_lun); diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index b18994fa482..6c62b4bdc2d 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -313,8 +313,7 @@ ctl_backend_ramdisk_continue(union ctl_io *io) sg_entries = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr; for (i = 0, len_filled = 0; i < sg_filled; i++) { sg_entries[i].addr = softc->ramdisk_pages[i]; - sg_entries[i].len = ctl_min(PAGE_SIZE, - len - len_filled); + sg_entries[i].len = MIN(PAGE_SIZE, len - len_filled); len_filled += sg_entries[i].len; } io->io_hdr.flags |= CTL_FLAG_KDPTR_SGLIST; @@ -614,32 +613,32 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d", softc->num_luns); strncpy((char *)be_lun->ctl_be_lun.serial_num, tmpstr, - ctl_min(sizeof(be_lun->ctl_be_lun.serial_num), - sizeof(tmpstr))); + MIN(sizeof(be_lun->ctl_be_lun.serial_num), + sizeof(tmpstr))); /* Tell the user what we used for a serial number */ strncpy((char *)params->serial_num, tmpstr, - ctl_min(sizeof(params->serial_num), sizeof(tmpstr))); + MIN(sizeof(params->serial_num), sizeof(tmpstr))); } else { strncpy((char *)be_lun->ctl_be_lun.serial_num, params->serial_num, - ctl_min(sizeof(be_lun->ctl_be_lun.serial_num), - sizeof(params->serial_num))); + MIN(sizeof(be_lun->ctl_be_lun.serial_num), + sizeof(params->serial_num))); } if ((params->flags & CTL_LUN_FLAG_DEVID) == 0) { snprintf(tmpstr, sizeof(tmpstr), "MYDEVID%4d", softc->num_luns); strncpy((char *)be_lun->ctl_be_lun.device_id, tmpstr, - ctl_min(sizeof(be_lun->ctl_be_lun.device_id), - sizeof(tmpstr))); + MIN(sizeof(be_lun->ctl_be_lun.device_id), + sizeof(tmpstr))); /* Tell the user what we used for a device ID */ strncpy((char *)params->device_id, tmpstr, - ctl_min(sizeof(params->device_id), sizeof(tmpstr))); + MIN(sizeof(params->device_id), sizeof(tmpstr))); } else { strncpy((char *)be_lun->ctl_be_lun.device_id, params->device_id, - ctl_min(sizeof(be_lun->ctl_be_lun.device_id), - sizeof(params->device_id))); + MIN(sizeof(be_lun->ctl_be_lun.device_id), + sizeof(params->device_id))); } STAILQ_INIT(&be_lun->cont_queue); diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c index cb17aec502e..e779e48f600 100644 --- a/sys/cam/ctl/ctl_frontend_cam_sim.c +++ b/sys/cam/ctl/ctl_frontend_cam_sim.c @@ -401,8 +401,8 @@ cfcs_datamove(union ctl_io *io) i < cam_sg_count && j < ctl_sg_count;) { uint8_t *cam_ptr, *ctl_ptr; - len_to_copy = ctl_min(cam_sglist[i].ds_len - cam_watermark, - ctl_sglist[j].len - ctl_watermark); + len_to_copy = MIN(cam_sglist[i].ds_len - cam_watermark, + ctl_sglist[j].len - ctl_watermark); cam_ptr = (uint8_t *)cam_sglist[i].ds_addr; cam_ptr = cam_ptr + cam_watermark; diff --git a/sys/cam/ctl/ctl_frontend_internal.c b/sys/cam/ctl/ctl_frontend_internal.c index 7e7adda35c3..23bd0cfcc00 100644 --- a/sys/cam/ctl/ctl_frontend_internal.c +++ b/sys/cam/ctl/ctl_frontend_internal.c @@ -499,8 +499,8 @@ cfi_datamove(union ctl_io *io) i < ext_sg_entries && j < kern_sg_entries;) { uint8_t *ext_ptr, *kern_ptr; - len_to_copy = ctl_min(ext_sglist[i].len - ext_watermark, - kern_sglist[j].len - kern_watermark); + len_to_copy = MIN(ext_sglist[i].len - ext_watermark, + kern_sglist[j].len - kern_watermark); ext_ptr = (uint8_t *)ext_sglist[i].addr; ext_ptr = ext_ptr + ext_watermark; @@ -1103,8 +1103,8 @@ cfi_metatask_bbr_errorparse(struct cfi_metatask *metatask, union ctl_io *io) metatask->taskinfo.bbrread.scsi_status = io->scsiio.scsi_status; memcpy(&metatask->taskinfo.bbrread.sense_data, &io->scsiio.sense_data, - ctl_min(sizeof(metatask->taskinfo.bbrread.sense_data), - sizeof(io->scsiio.sense_data))); + MIN(sizeof(metatask->taskinfo.bbrread.sense_data), + sizeof(io->scsiio.sense_data))); if (io->scsiio.scsi_status == SCSI_STATUS_RESERV_CONFLICT) { metatask->status = CFI_MT_ERROR; From ca10a8d94450254aa3cc0f343cc3fa2234f22efa Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 20 Dec 2014 13:47:38 +0000 Subject: [PATCH 031/207] Cleanup the code. Reported by: Coverity CID: 1232003 --- sys/netinet/sctp_usrreq.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 617e48014d3..1feed33b613 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -3643,12 +3643,6 @@ flags_out: (sid < stcb->asoc.streamoutcnt) && ((policy == SCTP_PR_SCTP_ALL) || (PR_SCTP_VALID_POLICY(policy)))) { -#else - if ((stcb != NULL) && - (policy != SCTP_PR_SCTP_NONE) && - (sid < stcb->asoc.streamoutcnt) && - (policy == SCTP_PR_SCTP_ALL)) { -#endif if (policy == SCTP_PR_SCTP_ALL) { sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; @@ -3656,6 +3650,13 @@ flags_out: sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy]; sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy]; } +#else + if ((stcb != NULL) && + (policy == SCTP_PR_SCTP_ALL) && + (sid < stcb->asoc.streamoutcnt)) { + sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; + sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; +#endif SCTP_TCB_UNLOCK(stcb); *optsize = sizeof(struct sctp_prstatus); } else { From b7413232f63ba15f195c0cc2739517338d2bdd87 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Sat, 20 Dec 2014 14:19:46 +0000 Subject: [PATCH 032/207] Add to sbappendstream_locked() a check against NULL mbuf, like it is done in sbappend_locked() and sbappendrecord_locked(). This is a quick fix to the panic introduced by r274712. A proper solution should be to make sosend_generic() avoid calling pru_send() with NULL mbuf for the protocols that do not understand control messages. Those protocols that understand control messages, should be able to receive NULL mbuf, if control is non-NULL. --- sys/kern/uipc_sockbuf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 537f9c867bf..8ca522c7ebd 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -640,6 +640,9 @@ sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags) { SOCKBUF_LOCK_ASSERT(sb); + if (m == NULL) + return; + KASSERT(m->m_nextpkt == NULL,("sbappendstream 0")); KASSERT(sb->sb_mb == sb->sb_lastrecord,("sbappendstream 1")); From fcb263a5fc417cbc914ae573cccde6d2873d5353 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 20 Dec 2014 16:13:31 +0000 Subject: [PATCH 033/207] Report XML parsing errors. MFC after: 3 days --- usr.sbin/ctladm/ctladm.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c index 03f46c9f2cc..646cfbfa82f 100644 --- a/usr.sbin/ctladm/ctladm.c +++ b/usr.sbin/ctladm/ctladm.c @@ -3643,11 +3643,14 @@ retry: XML_SetCharacterDataHandler(parser, cctl_islist_char_handler); retval = XML_Parse(parser, conn_str, strlen(conn_str), 1); - XML_ParserFree(parser); if (retval != 1) { + warnx("%s: Unable to parse XML: Error %d", __func__, + XML_GetErrorCode(parser)); + XML_ParserFree(parser); retval = 1; goto bailout; } + XML_ParserFree(parser); if (verbose != 0) { STAILQ_FOREACH(conn, &islist.conn_list, links) { @@ -4058,11 +4061,14 @@ retry: XML_SetCharacterDataHandler(parser, cctl_char_handler); retval = XML_Parse(parser, lun_str, strlen(lun_str), 1); - XML_ParserFree(parser); if (retval != 1) { + warnx("%s: Unable to parse XML: Error %d", __func__, + XML_GetErrorCode(parser)); + XML_ParserFree(parser); retval = 1; goto bailout; } + XML_ParserFree(parser); printf("LUN Backend %18s %4s %-16s %-16s\n", "Size (Blocks)", "BS", "Serial Number", "Device ID"); @@ -4336,11 +4342,14 @@ retry: XML_SetCharacterDataHandler(parser, cctl_char_phandler); retval = XML_Parse(parser, port_str, strlen(port_str), 1); - XML_ParserFree(parser); if (retval != 1) { + warnx("%s: Unable to parse XML: Error %d", __func__, + XML_GetErrorCode(parser)); + XML_ParserFree(parser); retval = 1; goto bailout; } + XML_ParserFree(parser); if (quiet == 0) printf("Port Online Frontend Name pp vp\n"); From 83c25ce791f5232215233112ebb80216e5b0a961 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 20 Dec 2014 16:39:56 +0000 Subject: [PATCH 034/207] Report initiator id in portlist XML in more formalized way. MFC after: 3 days --- sys/cam/ctl/ctl.c | 4 ++-- usr.sbin/ctladm/ctladm.c | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index cafb4d2cb1c..0c2524b02f9 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -3497,11 +3497,11 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, if (port->wwpn_iid[j].name != NULL) retval = sbuf_printf(sb, - "\t%u %s\n", + "\t%s\n", j, port->wwpn_iid[j].name); else retval = sbuf_printf(sb, - "\t%u naa.%08jx\n", + "\tnaa.%08jx\n", j, port->wwpn_iid[j].wwpn); if (retval != 0) break; diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c index 646cfbfa82f..9f72c83a00c 100644 --- a/usr.sbin/ctladm/ctladm.c +++ b/usr.sbin/ctladm/ctladm.c @@ -4117,6 +4117,7 @@ struct cctl_portlist_data { STAILQ_HEAD(,cctl_port) port_list; struct cctl_port *cur_port; int level; + uint64_t cur_id; struct sbuf *cur_sb[32]; }; @@ -4139,6 +4140,14 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr) if (portlist->cur_sb[portlist->level] == NULL) err(1, "%s: Unable to allocate sbuf", __func__); + portlist->cur_id = 0; + for (i = 0; attr[i] != NULL; i += 2) { + if (strcmp(attr[i], "id") == 0) { + portlist->cur_id = strtoull(attr[i+1], NULL, 0); + break; + } + } + if (strcmp(name, "targ_port") == 0) { if (cur_port != NULL) errx(1, "%s: improper port element nesting", __func__); @@ -4153,16 +4162,8 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr) STAILQ_INIT(&cur_port->init_list); STAILQ_INIT(&cur_port->attr_list); + cur_port->port_id = portlist->cur_id; STAILQ_INSERT_TAIL(&portlist->port_list, cur_port, links); - - for (i = 0; attr[i] != NULL; i += 2) { - if (strcmp(attr[i], "id") == 0) { - cur_port->port_id = strtoull(attr[i+1], NULL, 0); - } else { - errx(1, "%s: invalid LUN attribute %s = %s", - __func__, attr[i], attr[i+1]); - } - } } } @@ -4231,7 +4232,10 @@ cctl_end_pelement(void *user_data, const char *name) err(1, "%s: can't allocate %zd bytes for nv pair", __func__, sizeof(*nv)); - nv->name = strdup(name); + if (strcmp(name, "initiator") == 0) + asprintf(&nv->name, "%ju", portlist->cur_id); + else + nv->name = strdup(name); if (nv->name == NULL) err(1, "%s: can't allocated %zd bytes for string", __func__, strlen(name)); @@ -4372,7 +4376,8 @@ retry: if (port->target) printf(" Target: %s\n", port->target); STAILQ_FOREACH(nv, &port->init_list, links) { - printf(" Initiator: %s\n", nv->value); + printf(" Initiator %s: %s\n", + nv->name, nv->value); } } From 77b14d8df1aa55e8240c06ee5eebd035728e0c13 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 20 Dec 2014 16:40:49 +0000 Subject: [PATCH 035/207] Increase allowed size of the microcode blob to 32KB. Some Intel CPU's updates weight 28KB. PR: 179523 MFC after: 1 week --- sys/dev/cpuctl/cpuctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c index 96ceb0daacb..ec41a2e55f8 100644 --- a/sys/dev/cpuctl/cpuctl.c +++ b/sys/dev/cpuctl/cpuctl.c @@ -63,7 +63,7 @@ static d_ioctl_t cpuctl_ioctl; # define DPRINTF(...) #endif -#define UCODE_SIZE_MAX (16 * 1024) +#define UCODE_SIZE_MAX (32 * 1024) static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd, struct thread *td); From d943b9a337a3492084413ae8d9c838a74e9352c4 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 20 Dec 2014 18:15:23 +0000 Subject: [PATCH 036/207] Clean up to use the standard style of "options \t" and "device\t\t" --- sys/arm/conf/IMX6 | 190 +++++++++++++++++++++++----------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 007862bc6d1..35e6053b4a8 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -21,139 +21,139 @@ ident IMX6 include "../freescale/imx/std.imx6" options HZ=500 # Scheduling quantum is 2 milliseconds. -options SCHED_ULE # ULE scheduler -options PREEMPTION # Enable kernel thread preemption -options INET # InterNETworking -options INET6 # IPv6 communications protocols -options SCTP # Stream Control Transmission Protocol -options FFS # Berkeley Fast Filesystem -options SOFTUPDATES # Enable FFS soft updates support -options UFS_ACL # Support for access control lists -options UFS_DIRHASH # Improve performance on big directories -options UFS_GJOURNAL # Enable gjournal-based UFS journaling -#options MD_ROOT # MD is a potential root device -options NFSCL # New Network Filesystem Client -#options NFSD # New Network Filesystem Server -options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCL +options SCHED_ULE # ULE scheduler +options PREEMPTION # Enable kernel thread preemption +options INET # InterNETworking +options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol +options FFS # Berkeley Fast Filesystem +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +#options MD_ROOT # MD is a potential root device +options NFSCL # New Network Filesystem Client +#options NFSD # New Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options TMPFS # Efficient memory filesystem -options MSDOSFS # MSDOS Filesystem -options CD9660 # ISO 9660 Filesystem -#options PROCFS # Process filesystem (requires PSEUDOFS) -options PSEUDOFS # Pseudo-filesystem framework +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +#options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID Partition Tables. -options GEOM_LABEL # Provides labelization -options KTRACE # ktrace(1) support -options SYSVSHM # SYSV-style shared memory -options SYSVMSG # SYSV-style message queues -options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions -options INCLUDE_CONFIG_FILE # Include this file in kernel +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_LABEL # Provides labelization +options KTRACE # ktrace(1) support +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options INCLUDE_CONFIG_FILE # Include this file in kernel # Debugging support. Always need this: -options KDB # Enable kernel debugger support. +options KDB # Enable kernel debugger support. # For minimum debugger support use KDB_TRACE, for interactive use DDB. -#options KDB_TRACE # Print a stack trace for a panic. -options DDB # Support DDB. +#options KDB_TRACE # Print a stack trace for a panic. +options DDB # Support DDB. # For full debugger support use this instead: -#options GDB # Support remote GDB. +#options GDB # Support remote GDB. # Other debugging options... makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols -options ALT_BREAK_TO_DEBUGGER # Use to enter debugger. -#options DEBUG -#options DEADLKRES # Enable the deadlock resolver -#options INVARIANTS # Enable calls of extra sanity checking -#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS # Enable checks to detect deadlocks and cycles +options ALT_BREAK_TO_DEBUGGER # Use to enter debugger. +#options DEBUG +#options DEADLKRES # Enable the deadlock resolver +#options INVARIANTS # Enable calls of extra sanity checking +#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS # Enable checks to detect deadlocks and cycles # Pseudo devices. -device loop # Network loopback -device random # Entropy device -device vlan # 802.1Q VLAN support -device tun # Packet tunnel. -device md # Memory "disks" -#device gif # IPv6 and IPv4 tunneling -#device firmware # firmware assist module -device ether # Ethernet support -device miibus # Required for ethernet -device bpf # Berkeley packet filter (required for DHCP) +device loop # Network loopback +device random # Entropy device +device vlan # 802.1Q VLAN support +device tun # Packet tunnel. +device md # Memory "disks" +#device gif # IPv6 and IPv4 tunneling +#device firmware # firmware assist module +device ether # Ethernet support +device miibus # Required for ethernet +device bpf # Berkeley packet filter (required for DHCP) # General-purpose input/output device gpio # Serial (COM) ports -device uart # Multi-uart driver +device uart # Multi-uart driver # SDCard -device sdhci # SD controller -device mmc # SD/MMC protocol -device mmcsd # SDCard disk device +device sdhci # SD controller +device mmc # SD/MMC protocol +device mmcsd # SDCard disk device # SCSI peripherals -device scbus # SCSI bus (required for ATA/SCSI) -device da # Direct Access (disks) -device cd # CD -device pass # Passthrough device (direct ATA/SCSI access) +device scbus # SCSI bus (required for ATA/SCSI) +device da # Direct Access (disks) +device cd # CD +device pass # Passthrough device (direct ATA/SCSI access) # USB support -#options USB_DEBUG # enable debug msgs -device ehci # OHCI USB interface -device usb # USB Bus (required) -device umass # Disks/Mass storage - Requires scbus and da -device uhid # "Human Interface Devices" -device u3g # USB modems -#device ukbd # Allow keyboard like HIDs to control console -#device ums # USB mouse +#options USB_DEBUG # enable debug msgs +device ehci # OHCI USB interface +device usb # USB Bus (required) +device umass # Disks/Mass storage - Requires scbus and da +device uhid # "Human Interface Devices" +device u3g # USB modems +#device ukbd # Allow keyboard like HIDs to control console +#device ums # USB mouse # USB Ethernet, requires miibus -#device aue # ADMtek USB Ethernet -#device axe # ASIX Electronics USB Ethernet -#device cdce # Generic USB over Ethernet -#device cue # CATC USB Ethernet -#device kue # Kawasaki LSI USB Ethernet -#device rue # RealTek RTL8150 USB Ethernet -#device udav # Davicom DM9601E USB +#device aue # ADMtek USB Ethernet +#device axe # ASIX Electronics USB Ethernet +#device cdce # Generic USB over Ethernet +#device cue # CATC USB Ethernet +#device kue # Kawasaki LSI USB Ethernet +#device rue # RealTek RTL8150 USB Ethernet +#device udav # Davicom DM9601E USB # USB Wireless -#device rum # Ralink Technology RT2501USB wireless NICs +#device rum # Ralink Technology RT2501USB wireless NICs # Wireless NIC cards -#device wlan # 802.11 support -#device wlan_wep # 802.11 WEP support -#device wlan_ccmp # 802.11 CCMP support -#device wlan_tkip # 802.11 TKIP support -#device wlan_amrr # AMRR transmit rate control algorithm +#device wlan # 802.11 support +#device wlan_wep # 802.11 WEP support +#device wlan_ccmp # 802.11 CCMP support +#device wlan_tkip # 802.11 TKIP support +#device wlan_amrr # AMRR transmit rate control algorithm # NOTE: serial console will be disabled if syscons enabled # Uncomment following lines for framebuffer/syscons support # Wandboard has no video console support yet. -#device sc -#device kbdmux -#options SC_DFLT_FONT # compile font in -#makeoptions SC_DFLT_FONT=cp437 +#device sc +#device kbdmux +#options SC_DFLT_FONT # compile font in +#makeoptions SC_DFLT_FONT=cp437 # required for netbooting -#options BOOTP -#options BOOTP_COMPAT -#options BOOTP_NFSROOT -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ffec0 +#options BOOTP +#options BOOTP_COMPAT +#options BOOTP_NFSROOT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ffec0 # U-Boot stuff lives on slice 1, FreeBSD on slice 2. -options ROOTDEVNAME=\"ufs:mmcsd0s2a\" +options ROOTDEVNAME=\"ufs:mmcsd0s2a\" # ARM and SoC-specific options -options FDT # Configure using FDT/DTB data. -options SMP # Enable multiple cores -options VFP # Enable floating point hardware support -options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options FDT # Configure using FDT/DTB data. +options SMP # Enable multiple cores +options VFP # Enable floating point hardware support +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) # SoC-specific devices -device ffec # Freescale Fast Ethernet Controller -device fsliic # Freescale i2c/iic -device iic # iic protocol -device iicbus # iic bus -#device imxwdt # Watchdog. WARNING: can't be disabled!!! +device ffec # Freescale Fast Ethernet Controller +device fsliic # Freescale i2c/iic +device iic # iic protocol +device iicbus # iic bus +#device imxwdt # Watchdog. WARNING: can't be disabled!!! From 9b2655e094cfe1eb6ec988d41a3de7a5d61f0fd0 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sat, 20 Dec 2014 18:42:20 +0000 Subject: [PATCH 037/207] Clean up the style of the CUBIEBOARD2 config file --- sys/arm/conf/CUBIEBOARD2 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2 index 1c5184c431d..e971e8d6b53 100644 --- a/sys/arm/conf/CUBIEBOARD2 +++ b/sys/arm/conf/CUBIEBOARD2 @@ -20,7 +20,7 @@ ident CUBIEBOARD2 -include "../allwinner/a20/std.a20" +include "../allwinner/a20/std.a20" makeoptions MODULES_OVERRIDE="" makeoptions WITHOUT_MODULES="ahc" @@ -34,18 +34,18 @@ options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support -options UFS_ACL # Support for access control lists +options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -options MSDOSFS # MSDOS Filesystem +options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support -options SYSVSHM # SYSV-style shared memory -options SYSVMSG # SYSV-style message queues -options SYSVSEM # SYSV-style semaphores +options SYSVSHM # SYSV-style shared memory +options SYSVMSG # SYSV-style message queues +options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev options PREEMPTION @@ -60,7 +60,7 @@ options KDB options DDB # Enable the kernel debugger options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -options WITNESS # Enable checks to detect deadlocks and cycles +options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC @@ -78,15 +78,15 @@ options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options BOOTP_WIRED_TO=cpsw0 # MMC/SD/SDIO card slot support -#device mmc # mmc/sd bus -#device mmcsd # mmc/sd flash cards +#device mmc # mmc/sd bus +#device mmcsd # mmc/sd flash cards # Boot device is 2nd slice on MMC/SD card options ROOTDEVNAME=\"ufs:/dev/da0s2\" # ATA controllers -#device ahci # AHCI-compatible SATA controllers -#device ata # Legacy ATA/SATA controllers +#device ahci # AHCI-compatible SATA controllers +#device ata # Legacy ATA/SATA controllers #options ATA_STATIC_ID # Static device numbering # Console and misc @@ -98,8 +98,8 @@ device md device random # Entropy device # I2C support -#device iicbus -#device iic +#device iicbus +#device iic # GPIO device gpio @@ -114,8 +114,8 @@ device usb options USB_DEBUG #options USB_REQ_DEBUG #options USB_VERBOSE -#device uhci -#device ohci +#device uhci +#device ohci device ehci device umass @@ -125,7 +125,7 @@ device loop device ether device mii device smscphy -#device cpsw +#device cpsw device bpf device emac From b9450e431d9c06392031a8b6636ad212db2101c7 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 20 Dec 2014 19:15:10 +0000 Subject: [PATCH 038/207] Driver for CPU frequency/voltage control on the Raspberry Pi. Differential Revision: https://reviews.freebsd.org/D1025 Submitted by: Daisuke Aoyama aoyama@peach.ne.jp Reviewed by: ian (earlier version), rpaulo MFC after: 1 month Relnotes: yes --- sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c | 1818 ++++++++++++++++++ sys/arm/broadcom/bcm2835/bcm2835_mbox.c | 33 +- sys/arm/broadcom/bcm2835/bcm2835_mbox.h | 3 +- sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h | 273 +++ sys/arm/broadcom/bcm2835/files.bcm2835 | 2 + sys/boot/fdt/dts/arm/rpi.dts | 11 + 6 files changed, 2125 insertions(+), 15 deletions(-) create mode 100644 sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c create mode 100644 sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h diff --git a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c new file mode 100644 index 00000000000..7ea95a2fa12 --- /dev/null +++ b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c @@ -0,0 +1,1818 @@ +/*- + * Copyright (C) 2013-2014 Daisuke Aoyama + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "cpufreq_if.h" +#include "mbox_if.h" + +#ifdef DEBUG +#define DPRINTF(fmt, ...) do { \ + printf("%s:%u: ", __func__, __LINE__); \ + printf(fmt, ##__VA_ARGS__); \ +} while (0) +#else +#define DPRINTF(fmt, ...) +#endif + +#define HZ2MHZ(freq) ((freq) / (1000 * 1000)) +#define MHZ2HZ(freq) ((freq) * (1000 * 1000)) +#define OFFSET2MVOLT(val) (1200 + ((val) * 25)) +#define MVOLT2OFFSET(val) (((val) - 1200) / 25) +#define RAW2K(temp) (((temp) + 273150) / 1000) +#define K2RAW(temp) (((temp) * 1000) - 273150) + +#define DEFAULT_ARM_FREQUENCY 700 +#define DEFAULT_CORE_FREQUENCY 250 +#define DEFAULT_SDRAM_FREQUENCY 400 +#define DEFAULT_LOWEST_FREQ 300 +#define TRANSITION_LATENCY 1000 +#define MIN_OVER_VOLTAGE -16 +#define MAX_OVER_VOLTAGE 6 +#define MSG_ERROR -999999999 +#define MHZSTEP 100 +#define HZSTEP (MHZ2HZ(MHZSTEP)) + +#define VC_LOCK(sc) do { \ + sema_wait(&vc_sema); \ + } while (0) +#define VC_UNLOCK(sc) do { \ + sema_post(&vc_sema); \ + } while (0) + +/* ARM->VC mailbox property semaphore */ +static struct sema vc_sema; + +static struct sysctl_ctx_list bcm2835_sysctl_ctx; + +struct bcm2835_cpufreq_softc { + device_t dev; + int arm_max_freq; + int arm_min_freq; + int core_max_freq; + int core_min_freq; + int sdram_max_freq; + int sdram_min_freq; + int max_voltage_core; + int min_voltage_core; + + /* the values written in mbox */ + int voltage_core; + int voltage_sdram; + int voltage_sdram_c; + int voltage_sdram_i; + int voltage_sdram_p; + int turbo_mode; + + /* mbox buffer (physical address) */ + bus_dma_tag_t dma_tag; + bus_dmamap_t dma_map; + bus_size_t dma_size; + void *dma_buf; + bus_addr_t dma_phys; + + /* initial hook for waiting mbox intr */ + struct intr_config_hook init_hook; +}; + +static int cpufreq_verbose = 0; +TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose); +static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ; +TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq); + +#ifdef DEBUG +static void +bcm2835_dump(const void *data, int len) +{ + const uint8_t *p = (const uint8_t*)data; + int i; + + printf("dump @ %p:\n", data); + for (i = 0; i < len; i++) { + printf("%2.2x ", p[i]); + if ((i % 4) == 3) + printf(" "); + if ((i % 16) == 15) + printf("\n"); + } + printf("\n"); +} +#endif + +static int +bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc) +{ + struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf; + struct bcm2835_mbox_tag_hdr *tag, *last; + uint8_t *up; + device_t mbox; + size_t hdr_size; + int idx; + int err; + + /* + * For multiple calls, locking is not here. The caller must have + * VC semaphore. + */ + + /* get mbox device */ + mbox = devclass_get_device(devclass_find("mbox"), 0); + if (mbox == NULL) { + device_printf(sc->dev, "can't find mbox\n"); + return (-1); + } + + /* go mailbox property */ +#ifdef PROP_DEBUG + bcm2835_dump(msg, 64); +#endif + bus_dmamap_sync(sc->dma_tag, sc->dma_map, + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)sc->dma_phys); + MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &err); + bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD); +#ifdef PROP_DEBUG + bcm2835_dump(msg, 64); +#endif + + /* check response code */ + if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) { + device_printf(sc->dev, "mbox response error\n"); + return (-1); + } + + /* tag = first tag */ + up = (uint8_t *)msg; + hdr_size = sizeof(struct bcm2835_mbox_hdr); + tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size); + /* last = end of buffer specified by header */ + last = (struct bcm2835_mbox_tag_hdr *)(up + msg->buf_size); + + /* loop unitl end tag (=0x0) */ + hdr_size = sizeof(struct bcm2835_mbox_tag_hdr); + for (idx = 0; tag->tag != 0; idx++) { + if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) { + device_printf(sc->dev, "tag%d response error\n", idx); + return (-1); + } + /* clear response bit */ + tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE; + + /* get next tag */ + up = (uint8_t *)tag; + tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size + + tag->val_buf_size); + + /* check buffer size of header */ + if (tag > last) { + device_printf(sc->dev, "mbox buffer size error\n"); + return (-1); + } + } + + return (0); +} + +static int +bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc, + uint32_t clock_id) +{ + struct msg_get_clock_rate *msg; + int rate; + int err; + + /* + * Get clock rate + * Tag: 0x00030002 + * Request: + * Length: 4 + * Value: + * u32: clock id + * Response: + * Length: 8 + * Value: + * u32: clock id + * u32: rate (in Hz) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_clock_rate *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.clock_id = clock_id; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get clock rate (id=%u)\n", + clock_id); + return (MSG_ERROR); + } + + /* result (Hz) */ + rate = (int)msg->body.resp.rate_hz; + DPRINTF("clock = %d(Hz)\n", rate); + return (rate); +} + +static int +bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc, + uint32_t clock_id) +{ + struct msg_get_max_clock_rate *msg; + int rate; + int err; + + /* + * Get max clock rate + * Tag: 0x00030004 + * Request: + * Length: 4 + * Value: + * u32: clock id + * Response: + * Length: 8 + * Value: + * u32: clock id + * u32: rate (in Hz) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_max_clock_rate *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.clock_id = clock_id; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get max clock rate (id=%u)\n", + clock_id); + return (MSG_ERROR); + } + + /* result (Hz) */ + rate = (int)msg->body.resp.rate_hz; + DPRINTF("clock = %d(Hz)\n", rate); + return (rate); +} + +static int +bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc, + uint32_t clock_id) +{ + struct msg_get_min_clock_rate *msg; + int rate; + int err; + + /* + * Get min clock rate + * Tag: 0x00030007 + * Request: + * Length: 4 + * Value: + * u32: clock id + * Response: + * Length: 8 + * Value: + * u32: clock id + * u32: rate (in Hz) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_min_clock_rate *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.clock_id = clock_id; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get min clock rate (id=%u)\n", + clock_id); + return (MSG_ERROR); + } + + /* result (Hz) */ + rate = (int)msg->body.resp.rate_hz; + DPRINTF("clock = %d(Hz)\n", rate); + return (rate); +} + +static int +bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc, + uint32_t clock_id, uint32_t rate_hz) +{ + struct msg_set_clock_rate *msg; + int rate; + int err; + + /* + * Set clock rate + * Tag: 0x00038002 + * Request: + * Length: 8 + * Value: + * u32: clock id + * u32: rate (in Hz) + * Response: + * Length: 8 + * Value: + * u32: clock id + * u32: rate (in Hz) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_set_clock_rate *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.clock_id = clock_id; + msg->body.req.rate_hz = rate_hz; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't set clock rate (id=%u)\n", + clock_id); + return (MSG_ERROR); + } + + /* workaround for core clock */ + if (clock_id == BCM2835_MBOX_CLOCK_ID_CORE) { + /* for safety (may change voltage without changing clock) */ + DELAY(TRANSITION_LATENCY); + + /* + * XXX: the core clock is unable to change at once, + * to change certainly, write it twice now. + */ + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.clock_id = clock_id; + msg->body.req.rate_hz = rate_hz; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, + "can't set clock rate (id=%u)\n", clock_id); + return (MSG_ERROR); + } + } + + /* result (Hz) */ + rate = (int)msg->body.resp.rate_hz; + DPRINTF("clock = %d(Hz)\n", rate); + return (rate); +} + +static int +bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc) +{ + struct msg_get_turbo *msg; + int level; + int err; + + /* + * Get turbo + * Tag: 0x00030009 + * Request: + * Length: 4 + * Value: + * u32: id + * Response: + * Length: 8 + * Value: + * u32: id + * u32: level + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_turbo *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.id = 0; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get turbo\n"); + return (MSG_ERROR); + } + + /* result 0=non-turbo, 1=turbo */ + level = (int)msg->body.resp.level; + DPRINTF("level = %d\n", level); + return (level); +} + +static int +bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level) +{ + struct msg_set_turbo *msg; + int value; + int err; + + /* + * Set turbo + * Tag: 0x00038009 + * Request: + * Length: 8 + * Value: + * u32: id + * u32: level + * Response: + * Length: 8 + * Value: + * u32: id + * u32: level + */ + + /* using DMA buffer for VC */ + msg = (struct msg_set_turbo *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* replace unknown value to OFF */ + if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF) + level = BCM2835_MBOX_TURBO_OFF; + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.id = 0; + msg->body.req.level = level; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't set turbo\n"); + return (MSG_ERROR); + } + + /* result 0=non-turbo, 1=turbo */ + value = (int)msg->body.resp.level; + DPRINTF("level = %d\n", value); + return (value); +} + +static int +bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc, + uint32_t voltage_id) +{ + struct msg_get_voltage *msg; + int value; + int err; + + /* + * Get voltage + * Tag: 0x00030003 + * Request: + * Length: 4 + * Value: + * u32: voltage id + * Response: + * Length: 8 + * Value: + * u32: voltage id + * u32: value (offset from 1.2V in units of 0.025V) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_voltage *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.voltage_id = voltage_id; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get voltage\n"); + return (MSG_ERROR); + } + + /* result (offset from 1.2V) */ + value = (int)msg->body.resp.value; + DPRINTF("value = %d\n", value); + return (value); +} + +static int +bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc, + uint32_t voltage_id) +{ + struct msg_get_max_voltage *msg; + int value; + int err; + + /* + * Get voltage + * Tag: 0x00030005 + * Request: + * Length: 4 + * Value: + * u32: voltage id + * Response: + * Length: 8 + * Value: + * u32: voltage id + * u32: value (offset from 1.2V in units of 0.025V) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_max_voltage *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.voltage_id = voltage_id; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get max voltage\n"); + return (MSG_ERROR); + } + + /* result (offset from 1.2V) */ + value = (int)msg->body.resp.value; + DPRINTF("value = %d\n", value); + return (value); +} +static int +bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc, + uint32_t voltage_id) +{ + struct msg_get_min_voltage *msg; + int value; + int err; + + /* + * Get voltage + * Tag: 0x00030008 + * Request: + * Length: 4 + * Value: + * u32: voltage id + * Response: + * Length: 8 + * Value: + * u32: voltage id + * u32: value (offset from 1.2V in units of 0.025V) + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_min_voltage *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.voltage_id = voltage_id; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get min voltage\n"); + return (MSG_ERROR); + } + + /* result (offset from 1.2V) */ + value = (int)msg->body.resp.value; + DPRINTF("value = %d\n", value); + return (value); +} + +static int +bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc, + uint32_t voltage_id, int32_t value) +{ + struct msg_set_voltage *msg; + int err; + + /* + * Set voltage + * Tag: 0x00038003 + * Request: + * Length: 4 + * Value: + * u32: voltage id + * u32: value (offset from 1.2V in units of 0.025V) + * Response: + * Length: 8 + * Value: + * u32: voltage id + * u32: value (offset from 1.2V in units of 0.025V) + */ + + /* + * over_voltage: + * 0 (1.2 V). Values above 6 are only allowed when force_turbo or + * current_limit_override are specified (which set the warranty bit). + */ + if (value > MAX_OVER_VOLTAGE || value < MIN_OVER_VOLTAGE) { + /* currently not supported */ + device_printf(sc->dev, "not supported voltage: %d\n", value); + return (MSG_ERROR); + } + + /* using DMA buffer for VC */ + msg = (struct msg_set_voltage *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.voltage_id = voltage_id; + msg->body.req.value = (uint32_t)value; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't set voltage\n"); + return (MSG_ERROR); + } + + /* result (offset from 1.2V) */ + value = (int)msg->body.resp.value; + DPRINTF("value = %d\n", value); + return (value); +} + +static int +bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc) +{ + struct msg_get_temperature *msg; + int value; + int err; + + /* + * Get temperature + * Tag: 0x00030006 + * Request: + * Length: 4 + * Value: + * u32: temperature id + * Response: + * Length: 8 + * Value: + * u32: temperature id + * u32: value + */ + + /* using DMA buffer for VC */ + msg = (struct msg_get_temperature *)sc->dma_buf; + if (sizeof(*msg) > sc->dma_size) { + device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n", + sizeof(*msg), sc->dma_size); + return (MSG_ERROR); + } + + /* setup single tag buffer */ + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.temperature_id = 0; + msg->end_tag = 0; + + /* call mailbox property */ + err = bcm2835_mbox_call_prop(sc); + if (err) { + device_printf(sc->dev, "can't get temperature\n"); + return (MSG_ERROR); + } + + /* result (temperature of degree C) */ + value = (int)msg->body.resp.value; + DPRINTF("value = %d\n", value); + return (value); +} + + + +static int +sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + VC_LOCK(sc); + err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM, + val); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set clock arm_freq error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + VC_LOCK(sc); + err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE, + val); + if (err == MSG_ERROR) { + VC_UNLOCK(sc); + device_printf(sc->dev, "set clock core_freq error\n"); + return (EIO); + } + VC_UNLOCK(sc); + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + VC_LOCK(sc); + err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM, + val); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set clock sdram_freq error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_turbo(sc); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + if (val > 0) + sc->turbo_mode = BCM2835_MBOX_TURBO_ON; + else + sc->turbo_mode = BCM2835_MBOX_TURBO_OFF; + + VC_LOCK(sc); + err = bcm2835_cpufreq_set_turbo(sc, sc->turbo_mode); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set turbo error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) + return (EINVAL); + sc->voltage_core = val; + + VC_LOCK(sc); + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE, + sc->voltage_core); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set voltage core error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) + return (EINVAL); + sc->voltage_sdram_c = val; + + VC_LOCK(sc); + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C, + sc->voltage_sdram_c); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set voltage sdram_c error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) + return (EINVAL); + sc->voltage_sdram_i = val; + + VC_LOCK(sc); + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I, + sc->voltage_sdram_i); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set voltage sdram_i error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) + return (EINVAL); + sc->voltage_sdram_p = val; + + VC_LOCK(sc); + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P, + sc->voltage_sdram_p); + VC_UNLOCK(sc); + if (err == MSG_ERROR) { + device_printf(sc->dev, "set voltage sdram_p error\n"); + return (EIO); + } + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* multiple write only */ + if (!req->newptr) + return (EINVAL); + val = 0; + err = sysctl_handle_int(oidp, &val, 0, req); + if (err) + return (err); + + /* write request */ + if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE) + return (EINVAL); + sc->voltage_sdram = val; + + VC_LOCK(sc); + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C, + val); + if (err == MSG_ERROR) { + VC_UNLOCK(sc); + device_printf(sc->dev, "set voltage sdram_c error\n"); + return (EIO); + } + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I, + val); + if (err == MSG_ERROR) { + VC_UNLOCK(sc); + device_printf(sc->dev, "set voltage sdram_i error\n"); + return (EIO); + } + err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P, + val); + if (err == MSG_ERROR) { + VC_UNLOCK(sc); + device_printf(sc->dev, "set voltage sdram_p error\n"); + return (EIO); + } + VC_UNLOCK(sc); + DELAY(TRANSITION_LATENCY); + + return (0); +} + +static int +sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_temperature(sc); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + return (EINVAL); +} + +static int +sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS) +{ + struct bcm2835_cpufreq_softc *sc = arg1; + int val; + int err; + + /* get realtime value */ + VC_LOCK(sc); + val = bcm2835_cpufreq_get_temperature(sc); + VC_UNLOCK(sc); + if (val == MSG_ERROR) + return (EIO); + + /* 1/1000 celsius (raw) to 1/10 kelvin */ + val = RAW2K(val) * 10; + + err = sysctl_handle_int(oidp, &val, 0, req); + if (err || !req->newptr) /* error || read request */ + return (err); + + /* write request */ + return (EINVAL); +} + + +static void +bcm2835_cpufreq_init(void *arg) +{ + struct bcm2835_cpufreq_softc *sc = arg; + struct sysctl_ctx_list *ctx; + device_t cpu; + int arm_freq, core_freq, sdram_freq; + int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq; + int sdram_max_freq, sdram_min_freq; + int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p; + int max_voltage_core, min_voltage_core; + int max_voltage_sdram_c, min_voltage_sdram_c; + int max_voltage_sdram_i, min_voltage_sdram_i; + int max_voltage_sdram_p, min_voltage_sdram_p; + int turbo, temperature; + + VC_LOCK(sc); + + /* current clock */ + arm_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM); + core_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE); + sdram_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM); + + /* max/min clock */ + arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM); + arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM); + core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE); + core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE); + sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM); + sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM); + + /* turbo mode */ + turbo = bcm2835_cpufreq_get_turbo(sc); + if (turbo > 0) + sc->turbo_mode = BCM2835_MBOX_TURBO_ON; + else + sc->turbo_mode = BCM2835_MBOX_TURBO_OFF; + + /* voltage */ + voltage_core = bcm2835_cpufreq_get_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_CORE); + voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_C); + voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_I); + voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_P); + + /* current values (offset from 1.2V) */ + sc->voltage_core = voltage_core; + sc->voltage_sdram = voltage_sdram_c; + sc->voltage_sdram_c = voltage_sdram_c; + sc->voltage_sdram_i = voltage_sdram_i; + sc->voltage_sdram_p = voltage_sdram_p; + + /* max/min voltage */ + max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_CORE); + min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_CORE); + max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_C); + max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_I); + max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_P); + min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_C); + min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_I); + min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_SDRAM_P); + + /* temperature */ + temperature = bcm2835_cpufreq_get_temperature(sc); + + /* show result */ + if (cpufreq_verbose || bootverbose) { + device_printf(sc->dev, "Boot settings:\n"); + device_printf(sc->dev, + "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n", + HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq), + (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF"); + + device_printf(sc->dev, + "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n", + HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq), + HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq), + HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq)); + + device_printf(sc->dev, + "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, " + "SDRAM_P %dmV\n", + OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c), + OFFSET2MVOLT(voltage_sdram_i), + OFFSET2MVOLT(voltage_sdram_p)); + + device_printf(sc->dev, + "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, " + "SDRAM_P %d/%dmV\n", + OFFSET2MVOLT(max_voltage_core), + OFFSET2MVOLT(min_voltage_core), + OFFSET2MVOLT(max_voltage_sdram_c), + OFFSET2MVOLT(min_voltage_sdram_c), + OFFSET2MVOLT(max_voltage_sdram_i), + OFFSET2MVOLT(min_voltage_sdram_i), + OFFSET2MVOLT(max_voltage_sdram_p), + OFFSET2MVOLT(min_voltage_sdram_p)); + + device_printf(sc->dev, + "Temperature %d.%dC\n", (temperature / 1000), + (temperature % 1000) / 100); + } else { /* !cpufreq_verbose && !bootverbose */ + device_printf(sc->dev, + "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n", + HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq), + (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF"); + } + + /* keep in softc (MHz/mV) */ + sc->arm_max_freq = HZ2MHZ(arm_max_freq); + sc->arm_min_freq = HZ2MHZ(arm_min_freq); + sc->core_max_freq = HZ2MHZ(core_max_freq); + sc->core_min_freq = HZ2MHZ(core_min_freq); + sc->sdram_max_freq = HZ2MHZ(sdram_max_freq); + sc->sdram_min_freq = HZ2MHZ(sdram_min_freq); + sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core); + sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core); + + /* if turbo is on, set to max values */ + if (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) { + bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM, + arm_max_freq); + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE, + core_max_freq); + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq); + DELAY(TRANSITION_LATENCY); + } else { + bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM, + arm_min_freq); + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE, + core_min_freq); + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq); + DELAY(TRANSITION_LATENCY); + } + + VC_UNLOCK(sc); + + /* add human readable temperature to dev.cpu node */ + cpu = device_get_parent(sc->dev); + if (cpu != NULL) { + ctx = device_get_sysctl_ctx(cpu); + SYSCTL_ADD_PROC(ctx, + SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO, + "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0, + sysctl_bcm2835_devcpu_temperature, "IK", + "Current SoC temperature"); + } + + /* release this hook (continue boot) */ + config_intrhook_disestablish(&sc->init_hook); +} + +static void +bcm2835_cpufreq_identify(driver_t *driver, device_t parent) +{ + + DPRINTF("driver=%p, parent=%p\n", driver, parent); + if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL) + return; + if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL) + device_printf(parent, "add child failed\n"); +} + +static int +bcm2835_cpufreq_probe(device_t dev) +{ + + device_set_desc(dev, "CPU Frequency Control"); + return (0); +} + +static void +bcm2835_cpufreq_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err) +{ + bus_addr_t *addr; + + if (err) + return; + addr = (bus_addr_t *)arg; + *addr = PHYS_TO_VCBUS(segs[0].ds_addr); +} + +static int +bcm2835_cpufreq_attach(device_t dev) +{ + struct bcm2835_cpufreq_softc *sc; + struct sysctl_oid *oid; + int err; + + /* set self dev */ + sc = device_get_softc(dev); + sc->dev = dev; + + /* initial values */ + sc->arm_max_freq = -1; + sc->arm_min_freq = -1; + sc->core_max_freq = -1; + sc->core_min_freq = -1; + sc->sdram_max_freq = -1; + sc->sdram_min_freq = -1; + sc->max_voltage_core = 0; + sc->min_voltage_core = 0; + + /* create VC mbox buffer */ + sc->dma_size = PAGE_SIZE; + err = bus_dma_tag_create( + bus_get_dma_tag(sc->dev), + PAGE_SIZE, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + sc->dma_size, 1, /* maxsize, nsegments */ + sc->dma_size, 0, /* maxsegsize, flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->dma_tag); + if (err) { + device_printf(dev, "can't create DMA tag\n"); + return (ENXIO); + } + + err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0, + &sc->dma_map); + if (err) { + bus_dma_tag_destroy(sc->dma_tag); + device_printf(dev, "can't allocate dmamem\n"); + return (ENXIO); + } + + err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf, + sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0); + if (err) { + bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map); + bus_dma_tag_destroy(sc->dma_tag); + device_printf(dev, "can't load DMA map\n"); + return (ENXIO); + } + /* OK, ready to use VC buffer */ + + /* setup sysctl at first device */ + if (device_get_unit(dev) == 0) { + sysctl_ctx_init(&bcm2835_sysctl_ctx); + /* create node for hw.cpufreq */ + oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq", + CTLFLAG_RD, NULL, ""); + + /* Frequency (Hz) */ + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + sysctl_bcm2835_cpufreq_arm_freq, "IU", + "ARM frequency (Hz)"); + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + sysctl_bcm2835_cpufreq_core_freq, "IU", + "Core frequency (Hz)"); + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + sysctl_bcm2835_cpufreq_sdram_freq, "IU", + "SDRAM frequency (Hz)"); + + /* Turbo state */ + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + sysctl_bcm2835_cpufreq_turbo, "IU", + "Disables dynamic clocking"); + + /* Voltage (offset from 1.2V in units of 0.025V) */ + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0, + sysctl_bcm2835_cpufreq_voltage_core, "I", + "ARM/GPU core voltage" + "(offset from 1.2V in units of 0.025V)"); + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc, + 0, sysctl_bcm2835_cpufreq_voltage_sdram, "I", + "SDRAM voltage (offset from 1.2V in units of 0.025V)"); + + /* Voltage individual SDRAM */ + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc, + 0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I", + "SDRAM controller voltage" + "(offset from 1.2V in units of 0.025V)"); + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc, + 0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I", + "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)"); + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc, + 0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I", + "SDRAM phy voltage (offset from 1.2V in units of 0.025V)"); + + /* Temperature */ + SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid), + OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0, + sysctl_bcm2835_cpufreq_temperature, "I", + "SoC temperature (thousandths of a degree C)"); + } + + /* ARM->VC lock */ + sema_init(&vc_sema, 1, "vcsema"); + + /* register callback for using mbox when interrupts are enabled */ + sc->init_hook.ich_func = bcm2835_cpufreq_init; + sc->init_hook.ich_arg = sc; + + if (config_intrhook_establish(&sc->init_hook) != 0) { + bus_dmamap_unload(sc->dma_tag, sc->dma_map); + bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map); + bus_dma_tag_destroy(sc->dma_tag); + device_printf(dev, "config_intrhook_establish failed\n"); + return (ENOMEM); + } + + /* this device is controlled by cpufreq(4) */ + cpufreq_register(dev); + + return (0); +} + +static int +bcm2835_cpufreq_detach(device_t dev) +{ + struct bcm2835_cpufreq_softc *sc; + + sc = device_get_softc(dev); + + sema_destroy(&vc_sema); + + if (sc->dma_phys != 0) + bus_dmamap_unload(sc->dma_tag, sc->dma_map); + if (sc->dma_buf != NULL) + bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map); + if (sc->dma_tag != NULL) + bus_dma_tag_destroy(sc->dma_tag); + + return (cpufreq_unregister(dev)); +} + +static int +bcm2835_cpufreq_set(device_t dev, const struct cf_setting *cf) +{ + struct bcm2835_cpufreq_softc *sc; + uint32_t rate_hz, rem; + int cur_freq, resp_freq, arm_freq, min_freq, core_freq; + + if (cf == NULL || cf->freq < 0) + return (EINVAL); + + sc = device_get_softc(dev); + + /* setting clock (Hz) */ + rate_hz = (uint32_t)MHZ2HZ(cf->freq); + rem = rate_hz % HZSTEP; + rate_hz -= rem; + if (rate_hz == 0) + return (EINVAL); + + /* adjust min freq */ + min_freq = sc->arm_min_freq; + if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) + if (min_freq > cpufreq_lowest_freq) + min_freq = cpufreq_lowest_freq; + + if (rate_hz < MHZ2HZ(min_freq) || rate_hz > MHZ2HZ(sc->arm_max_freq)) + return (EINVAL); + + /* set new value and verify it */ + VC_LOCK(sc); + cur_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM); + resp_freq = bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM, rate_hz); + DELAY(TRANSITION_LATENCY); + arm_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM); + + /* + * if non-turbo and lower than or equal min_freq, + * clock down core and sdram to default first. + */ + if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) { + core_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE); + if (rate_hz > MHZ2HZ(sc->arm_min_freq)) { + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE, + MHZ2HZ(sc->core_max_freq)); + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM, + MHZ2HZ(sc->sdram_max_freq)); + DELAY(TRANSITION_LATENCY); + } else { + if (sc->core_min_freq < DEFAULT_CORE_FREQUENCY && + core_freq > DEFAULT_CORE_FREQUENCY) { + /* first, down to 250, then down to min */ + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE, + MHZ2HZ(DEFAULT_CORE_FREQUENCY)); + DELAY(TRANSITION_LATENCY); + /* reset core voltage */ + bcm2835_cpufreq_set_voltage(sc, + BCM2835_MBOX_VOLTAGE_ID_CORE, 0); + DELAY(TRANSITION_LATENCY); + } + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_CORE, + MHZ2HZ(sc->core_min_freq)); + DELAY(TRANSITION_LATENCY); + bcm2835_cpufreq_set_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_SDRAM, + MHZ2HZ(sc->sdram_min_freq)); + DELAY(TRANSITION_LATENCY); + } + } + + VC_UNLOCK(sc); + + if (resp_freq < 0 || arm_freq < 0 || resp_freq != arm_freq) { + device_printf(dev, "wrong freq\n"); + return (EIO); + } + DPRINTF("cpufreq: %d -> %d\n", cur_freq, arm_freq); + + return (0); +} + +static int +bcm2835_cpufreq_get(device_t dev, struct cf_setting *cf) +{ + struct bcm2835_cpufreq_softc *sc; + int arm_freq; + + if (cf == NULL) + return (EINVAL); + + sc = device_get_softc(dev); + memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf)); + cf->dev = NULL; + + /* get cuurent value */ + VC_LOCK(sc); + arm_freq = bcm2835_cpufreq_get_clock_rate(sc, + BCM2835_MBOX_CLOCK_ID_ARM); + VC_UNLOCK(sc); + if (arm_freq < 0) { + device_printf(dev, "can't get clock\n"); + return (EINVAL); + } + + /* CPU clock in MHz or 100ths of a percent. */ + cf->freq = HZ2MHZ(arm_freq); + /* Voltage in mV. */ + cf->volts = CPUFREQ_VAL_UNKNOWN; + /* Power consumed in mW. */ + cf->power = CPUFREQ_VAL_UNKNOWN; + /* Transition latency in us. */ + cf->lat = TRANSITION_LATENCY; + /* Driver providing this setting. */ + cf->dev = dev; + + return (0); +} + +static int +bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets, + int *count) +{ + struct bcm2835_cpufreq_softc *sc; + int freq, min_freq, volts, rem; + int idx; + + sc = device_get_softc(dev); + freq = sc->arm_max_freq; + min_freq = sc->arm_min_freq; + + /* adjust head freq to STEP */ + rem = freq % MHZSTEP; + freq -= rem; + if (freq < min_freq) + freq = min_freq; + + /* if non-turbo, add extra low freq */ + if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) + if (min_freq > cpufreq_lowest_freq) + min_freq = cpufreq_lowest_freq; + + /* from freq to min_freq */ + for (idx = 0; idx < *count && freq >= min_freq; idx++) { + if (freq > sc->arm_min_freq) + volts = sc->max_voltage_core; + else + volts = sc->min_voltage_core; + sets[idx].freq = freq; + sets[idx].volts = volts; + sets[idx].lat = TRANSITION_LATENCY; + sets[idx].dev = dev; + freq -= MHZSTEP; + } + *count = ++idx; + + return (0); +} + +static int +bcm2835_cpufreq_settings(device_t dev, struct cf_setting *sets, int *count) +{ + struct bcm2835_cpufreq_softc *sc; + + if (sets == NULL || count == NULL) + return (EINVAL); + + sc = device_get_softc(dev); + if (sc->arm_min_freq < 0 || sc->arm_max_freq < 0) { + printf("device is not configured\n"); + return (EINVAL); + } + + /* fill data with unknown value */ + memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * (*count)); + /* create new array up to count */ + bcm2835_cpufreq_make_freq_list(dev, sets, count); + + return (0); +} + +static int +bcm2835_cpufreq_type(device_t dev, int *type) +{ + + if (type == NULL) + return (EINVAL); + *type = CPUFREQ_TYPE_ABSOLUTE; + + return (0); +} + +static device_method_t bcm2835_cpufreq_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, bcm2835_cpufreq_identify), + DEVMETHOD(device_probe, bcm2835_cpufreq_probe), + DEVMETHOD(device_attach, bcm2835_cpufreq_attach), + DEVMETHOD(device_detach, bcm2835_cpufreq_detach), + + /* cpufreq interface */ + DEVMETHOD(cpufreq_drv_set, bcm2835_cpufreq_set), + DEVMETHOD(cpufreq_drv_get, bcm2835_cpufreq_get), + DEVMETHOD(cpufreq_drv_settings, bcm2835_cpufreq_settings), + DEVMETHOD(cpufreq_drv_type, bcm2835_cpufreq_type), + + DEVMETHOD_END +}; + +static devclass_t bcm2835_cpufreq_devclass; +static driver_t bcm2835_cpufreq_driver = { + "bcm2835_cpufreq", + bcm2835_cpufreq_methods, + sizeof(struct bcm2835_cpufreq_softc), +}; + +DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver, + bcm2835_cpufreq_devclass, 0, 0); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c index 7628eb60338..4c647fddaca 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -88,8 +89,8 @@ struct bcm_mbox_softc { void* intr_hl; bus_space_tag_t bst; bus_space_handle_t bsh; - int valid[BCM2835_MBOX_CHANS]; int msg[BCM2835_MBOX_CHANS]; + struct sema sema[BCM2835_MBOX_CHANS]; }; #define mbox_read_4(sc, reg) \ @@ -105,23 +106,19 @@ bcm_mbox_intr(void *arg) uint32_t data; uint32_t msg; - MBOX_LOCK(sc); while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY)) { msg = mbox_read_4(sc, REG_READ); dprintf("bcm_mbox_intr: raw data %08x\n", msg); chan = MBOX_CHAN(msg); data = MBOX_DATA(msg); - if (sc->valid[chan]) { + if (sc->msg[chan]) { printf("bcm_mbox_intr: channel %d oveflow\n", chan); continue; } dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data); - sc->msg[chan] = data; - sc->valid[chan] = 1; - wakeup(&sc->msg[chan]); - + sc->msg[chan] = MBOX_MSG(data, 0xf); + sema_post(&sc->sema[chan]); } - MBOX_UNLOCK(sc); } static int @@ -172,8 +169,8 @@ bcm_mbox_attach(device_t dev) mtx_init(&sc->lock, "vcio mbox", NULL, MTX_DEF); for (i = 0; i < BCM2835_MBOX_CHANS; i++) { - sc->valid[0] = 0; - sc->msg[0] = 0; + sc->msg[i] = 0; + sema_init(&sc->sema[i], 0, "mbox"); } /* Read all pending messages */ @@ -219,10 +216,18 @@ bcm_mbox_read(device_t dev, int chan, uint32_t *data) dprintf("bcm_mbox_read: chan %d\n", chan); MBOX_LOCK(sc); - while (!sc->valid[chan]) - msleep(&sc->msg[chan], &sc->lock, PZERO, "vcio mbox read", 0); - *data = sc->msg[chan]; - sc->valid[chan] = 0; + while (sema_trywait(&sc->sema[chan]) == 0) { + /* do not unlock sc while waiting for the mbox */ + if (sema_timedwait(&sc->sema[chan], 10*hz) == 0) + break; + printf("timeout sema for chan %d\n", chan); + } + /* + * get data from intr handler, the same channel is never coming + * because of holding sc lock. + */ + *data = MBOX_DATA(sc->msg[chan]); + sc->msg[chan] = 0; MBOX_UNLOCK(sc); dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox.h index 52f48e47920..17e59eb7adc 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.h +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.h @@ -36,6 +36,7 @@ #define BCM2835_MBOX_CHAN_LEDS 4 #define BCM2835_MBOX_CHAN_BUTTONS 5 #define BCM2835_MBOX_CHAN_TS 6 -#define BCM2835_MBOX_CHANS 7 +#define BCM2835_MBOX_CHAN_PROP 8 +#define BCM2835_MBOX_CHANS 9 #endif /* _BCM2835_MBOX_H_ */ diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h new file mode 100644 index 00000000000..a2e212e518c --- /dev/null +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h @@ -0,0 +1,273 @@ +/*- + * Copyright (C) 2013-2014 Daisuke Aoyama + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _BCM2835_MBOX_PROP_H_ +#define _BCM2835_MBOX_PROP_H_ + +#include +#include + +/* + * Mailbox property interface: + * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface + */ +#define BCM2835_MBOX_CODE_REQ 0 +#define BCM2835_MBOX_CODE_RESP_SUCCESS 0x80000000 +#define BCM2835_MBOX_CODE_RESP_ERROR 0x80000001 +#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000 + +struct bcm2835_mbox_hdr { + uint32_t buf_size; + uint32_t code; +}; + +struct bcm2835_mbox_tag_hdr { + uint32_t tag; + uint32_t val_buf_size; + uint32_t val_len; +}; + +#define BCM2835_MBOX_CLOCK_ID_EMMC 0x00000001 +#define BCM2835_MBOX_CLOCK_ID_UART 0x00000002 +#define BCM2835_MBOX_CLOCK_ID_ARM 0x00000003 +#define BCM2835_MBOX_CLOCK_ID_CORE 0x00000004 +#define BCM2835_MBOX_CLOCK_ID_V3D 0x00000005 +#define BCM2835_MBOX_CLOCK_ID_H264 0x00000006 +#define BCM2835_MBOX_CLOCK_ID_ISP 0x00000007 +#define BCM2835_MBOX_CLOCK_ID_SDRAM 0x00000008 +#define BCM2835_MBOX_CLOCK_ID_PIXEL 0x00000009 +#define BCM2835_MBOX_CLOCK_ID_PWM 0x0000000a + +#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002 +#define BCM2835_MBOX_TAG_SET_CLOCK_RATE 0x00038002 +#define BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE 0x00030004 +#define BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE 0x00030007 + +struct msg_get_clock_rate { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t clock_id; + } req; + struct { + uint32_t clock_id; + uint32_t rate_hz; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_set_clock_rate { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t clock_id; + uint32_t rate_hz; + } req; + struct { + uint32_t clock_id; + uint32_t rate_hz; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_get_max_clock_rate { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t clock_id; + } req; + struct { + uint32_t clock_id; + uint32_t rate_hz; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_get_min_clock_rate { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t clock_id; + } req; + struct { + uint32_t clock_id; + uint32_t rate_hz; + } resp; + } body; + uint32_t end_tag; +}; + +#define BCM2835_MBOX_TURBO_ON 1 +#define BCM2835_MBOX_TURBO_OFF 0 + +#define BCM2835_MBOX_TAG_GET_TURBO 0x00030009 +#define BCM2835_MBOX_TAG_SET_TURBO 0x00038009 + +struct msg_get_turbo { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t id; + } req; + struct { + uint32_t id; + uint32_t level; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_set_turbo { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t id; + uint32_t level; + } req; + struct { + uint32_t id; + uint32_t level; + } resp; + } body; + uint32_t end_tag; +}; + +#define BCM2835_MBOX_VOLTAGE_ID_CORE 0x00000001 +#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_C 0x00000002 +#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_P 0x00000003 +#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_I 0x00000004 + +#define BCM2835_MBOX_TAG_GET_VOLTAGE 0x00030003 +#define BCM2835_MBOX_TAG_SET_VOLTAGE 0x00038003 +#define BCM2835_MBOX_TAG_GET_MAX_VOLTAGE 0x00030005 +#define BCM2835_MBOX_TAG_GET_MIN_VOLTAGE 0x00030008 + +struct msg_get_voltage { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t voltage_id; + } req; + struct { + uint32_t voltage_id; + uint32_t value; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_set_voltage { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t voltage_id; + uint32_t value; + } req; + struct { + uint32_t voltage_id; + uint32_t value; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_get_max_voltage { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t voltage_id; + } req; + struct { + uint32_t voltage_id; + uint32_t value; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_get_min_voltage { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t voltage_id; + } req; + struct { + uint32_t voltage_id; + uint32_t value; + } resp; + } body; + uint32_t end_tag; +}; + +#define BCM2835_MBOX_TAG_GET_TEMPERATURE 0x00030006 +#define BCM2835_MBOX_TAG_GET_MAX_TEMPERATURE 0x0003000a + +struct msg_get_temperature { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t temperature_id; + } req; + struct { + uint32_t temperature_id; + uint32_t value; + } resp; + } body; + uint32_t end_tag; +}; + +struct msg_get_max_temperature { + struct bcm2835_mbox_hdr hdr; + struct bcm2835_mbox_tag_hdr tag_hdr; + union { + struct { + uint32_t temperature_id; + } req; + struct { + uint32_t temperature_id; + uint32_t value; + } resp; + } body; + uint32_t end_tag; +}; + +#endif /* _BCM2835_MBOX_PROP_H_ */ diff --git a/sys/arm/broadcom/bcm2835/files.bcm2835 b/sys/arm/broadcom/bcm2835/files.bcm2835 index 865f2d02b5b..11158cb822a 100644 --- a/sys/arm/broadcom/bcm2835/files.bcm2835 +++ b/sys/arm/broadcom/bcm2835/files.bcm2835 @@ -2,6 +2,7 @@ arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc arm/broadcom/bcm2835/bcm2835_common.c optional fdt +arm/broadcom/bcm2835/bcm2835_cpufreq.c standard arm/broadcom/bcm2835/bcm2835_dma.c standard arm/broadcom/bcm2835/bcm2835_fb.c optional sc arm/broadcom/bcm2835/bcm2835_fbd.c optional vt @@ -25,3 +26,4 @@ arm/arm/cpufunc_asm_armv6.S standard kern/kern_clocksource.c standard dev/mbox/mbox_if.m standard +dev/ofw/ofw_cpu.c standard diff --git a/sys/boot/fdt/dts/arm/rpi.dts b/sys/boot/fdt/dts/arm/rpi.dts index 58ceaa42dcf..08d9d24bb4e 100644 --- a/sys/boot/fdt/dts/arm/rpi.dts +++ b/sys/boot/fdt/dts/arm/rpi.dts @@ -35,6 +35,17 @@ memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */ + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + compatible = "arm,1176jzf-s"; + device_type = "cpu"; + reg = <0>; /* CPU ID=0 */ + clock-frequency = <700000000>; /* 700MHz */ + }; + }; + memory { device_type = "memory"; reg = <0 0x8000000>; /* 128MB, Set by VideoCore */ From 92c59ab94fc51bf1e3a03db7a4f08cce26ea7c05 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 20 Dec 2014 19:41:31 +0000 Subject: [PATCH 039/207] Document where in scan_task the scan state can change, and potentially deal/log a warning if the scan flags change during one of those race windows. It's highly likely that I need to actually sit down and replace this scan infrastructure at some point. It has some other side effects too - the scan task is a blocking task scheduled in the net80211 taskqueue; so drivers that use this taskqueue have other things not run. Eek. If you see this printf happen then please let me know! --- sys/net80211/ieee80211_scan.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index 66e843097cc..eae048061dd 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -882,6 +882,9 @@ scan_task(void *arg, int pending) } scanend = ticks + SCAN_PRIVATE(ss)->ss_duration; + + /* XXX scan state can change! Re-validate scan state! */ + IEEE80211_UNLOCK(ic); ic->ic_scan_start(ic); /* notify driver */ IEEE80211_LOCK(ic); @@ -944,6 +947,8 @@ scan_task(void *arg, int pending) ic->ic_scan_curchan(ss, maxdwell); IEEE80211_LOCK(ic); + /* XXX scan state can change! Re-validate scan state! */ + SCAN_PRIVATE(ss)->ss_chanmindwell = ticks + ss->ss_mindwell; /* clear mindwell lock and initial channel change flush */ SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_REP; @@ -960,6 +965,7 @@ scan_task(void *arg, int pending) IEEE80211_UNLOCK(ic); ic->ic_scan_end(ic); /* notify driver */ IEEE80211_LOCK(ic); + /* XXX scan state can change! Re-validate scan state! */ /* * Since a cancellation may have occured during one of the @@ -969,10 +975,10 @@ scan_task(void *arg, int pending) ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0)) { /* XXX printf? */ if_printf(vap->iv_ifp, - "%s: OOPS! scan cancelled during driver call!\n", + "%s: OOPS! scan cancelled during driver call (1)!\n", __func__); + scandone = 1; } - scandone |= ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0); /* * Record scan complete time. Note that we also do @@ -1031,6 +1037,19 @@ scan_task(void *arg, int pending) __func__, scandone ? "done" : "stopped", ticks, ss->ss_mindwell, scanend); + /* + * Since a cancellation may have occured during one of the + * driver calls (whilst unlocked), update scandone. + */ + if (scandone == 0 && + ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0)) { + /* XXX printf? */ + if_printf(vap->iv_ifp, + "%s: OOPS! scan cancelled during driver call (2)!\n", + __func__); + scandone = 1; + } + /* * Clear the SCAN bit first in case frames are * pending on the station power save queue. If From d66bcddce497ee37152fbe5e8c41d637d55dcfe4 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Sat, 20 Dec 2014 19:47:51 +0000 Subject: [PATCH 040/207] Emulate writes to the IA32_MISC_ENABLE MSR. PR: 196093 Reported by: db Tested by: db Discussed with: grehan MFC after: 1 week --- sys/amd64/vmm/intel/vmx_msr.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c index 746ca7358e4..f6bbf2aed7d 100644 --- a/sys/amd64/vmm/intel/vmx_msr.c +++ b/sys/amd64/vmm/intel/vmx_msr.c @@ -376,9 +376,31 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu) int vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu) { - int error = 0; - + uint64_t changed; + int error; + + error = 0; switch (num) { + case MSR_IA32_MISC_ENABLE: + changed = val ^ misc_enable; + /* + * If the host has disabled the NX feature then the guest + * also cannot use it. However, a Linux guest will try to + * enable the NX feature by writing to the MISC_ENABLE MSR. + * + * This can be safely ignored because the memory management + * code looks at CPUID.80000001H:EDX.NX to check if the + * functionality is actually enabled. + */ + changed &= ~(1UL << 34); + + /* + * Punt to userspace if any other bits are being modified. + */ + if (changed) + error = EINVAL; + + break; default: error = EINVAL; break; From e54c8bda3e4f3fcb46a8e354975b28594736b600 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 20 Dec 2014 20:07:48 +0000 Subject: [PATCH 041/207] Remove some hard-coded IE assembly over to use net80211 methods. PR: kern/196069 Submitted by: Andriy Voskoboinyk --- sys/dev/wpi/if_wpi.c | 30 ++++++------------------------ sys/dev/wpi/if_wpireg.h | 2 +- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index e94fa740424..accb46c34bf 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -2564,7 +2564,7 @@ wpi_scan(struct wpi_softc *sc) struct ieee80211_channel *c; enum ieee80211_phymode mode; uint8_t *frm; - int nrates, pktlen, error, i, nssid; + int pktlen, error, i, nssid; bus_addr_t physaddr; desc = &ring->desc[ring->cur]; @@ -2613,7 +2613,7 @@ wpi_scan(struct wpi_softc *sc) nssid = MIN(ss->ss_nssid, WPI_SCAN_MAX_ESSIDS); for (i = 0; i < nssid; i++) { hdr->scan_essids[i].id = IEEE80211_ELEMID_SSID; - hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, 32); + hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN); memcpy(hdr->scan_essids[i].essid, ss->ss_ssid[i].ssid, hdr->scan_essids[i].esslen); #ifdef WPI_DEBUG @@ -2630,7 +2630,7 @@ wpi_scan(struct wpi_softc *sc) * Build a probe request frame. Most of the following code is a * copy & paste of what is done in net80211. */ - wh = (struct ieee80211_frame *)&hdr->scan_essids[4]; + wh = (struct ieee80211_frame *)&hdr->scan_essids[WPI_SCAN_MAX_ESSIDS]; wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ; wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; @@ -2642,30 +2642,12 @@ wpi_scan(struct wpi_softc *sc) frm = (uint8_t *)(wh + 1); - /* add essid IE, the hardware will fill this in for us */ - *frm++ = IEEE80211_ELEMID_SSID; - *frm++ = 0; - mode = ieee80211_chan2mode(ic->ic_curchan); rs = &ic->ic_sup_rates[mode]; - /* add supported rates IE */ - *frm++ = IEEE80211_ELEMID_RATES; - nrates = rs->rs_nrates; - if (nrates > IEEE80211_RATE_SIZE) - nrates = IEEE80211_RATE_SIZE; - *frm++ = nrates; - memcpy(frm, rs->rs_rates, nrates); - frm += nrates; - - /* add supported xrates IE */ - if (rs->rs_nrates > IEEE80211_RATE_SIZE) { - nrates = rs->rs_nrates - IEEE80211_RATE_SIZE; - *frm++ = IEEE80211_ELEMID_XRATES; - *frm++ = nrates; - memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates); - frm += nrates; - } + frm = ieee80211_add_ssid(frm, NULL, 0); + frm = ieee80211_add_rates(frm, rs); + frm = ieee80211_add_xrates(frm, rs); /* setup length of probe request */ hdr->tx.len = htole16(frm - (uint8_t *)wh); diff --git a/sys/dev/wpi/if_wpireg.h b/sys/dev/wpi/if_wpireg.h index df71b3d3965..60d183a6736 100644 --- a/sys/dev/wpi/if_wpireg.h +++ b/sys/dev/wpi/if_wpireg.h @@ -511,7 +511,7 @@ struct { struct { uint8_t id; uint8_t esslen; - uint8_t essid[32]; + uint8_t essid[IEEE80211_NWID_LEN]; }scan_essids[WPI_SCAN_MAX_ESSIDS]; /* followed by probe request body */ /* followed by nchan x wpi_scan_chan */ From b03b5d729a76ff61932e492b0ed83496df280111 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 20 Dec 2014 21:17:28 +0000 Subject: [PATCH 042/207] Fix and harmonize the validation of PR-SCTP policies. Reported by: Coverity CID: 1232044 MFC after: 3 days --- sys/netinet/sctp_usrreq.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 1feed33b613..95955dedcb9 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -3639,10 +3639,10 @@ flags_out: policy = sprstat->sprstat_policy; #if defined(SCTP_DETAILED_STR_STATS) if ((stcb != NULL) && - (policy != SCTP_PR_SCTP_NONE) && (sid < stcb->asoc.streamoutcnt) && - ((policy == SCTP_PR_SCTP_ALL) || - (PR_SCTP_VALID_POLICY(policy)))) { + (policy != SCTP_PR_SCTP_NONE) && + ((policy <= SCTP_PR_SCTP_MAX) || + (policy == SCTP_PR_SCTP_ALL))) { if (policy == SCTP_PR_SCTP_ALL) { sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; @@ -3652,8 +3652,8 @@ flags_out: } #else if ((stcb != NULL) && - (policy == SCTP_PR_SCTP_ALL) && - (sid < stcb->asoc.streamoutcnt)) { + (sid < stcb->asoc.streamoutcnt) && + (policy == SCTP_PR_SCTP_ALL)) { sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; #endif @@ -3676,8 +3676,8 @@ flags_out: policy = sprstat->sprstat_policy; if ((stcb != NULL) && (policy != SCTP_PR_SCTP_NONE) && - ((policy == SCTP_PR_SCTP_ALL) || - (PR_SCTP_VALID_POLICY(policy)))) { + ((policy <= SCTP_PR_SCTP_MAX) || + (policy == SCTP_PR_SCTP_ALL))) { if (policy == SCTP_PR_SCTP_ALL) { sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0]; sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0]; @@ -6038,7 +6038,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize); SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id); - if (PR_SCTP_INVALID_POLICY(info->pr_policy)) { + if (info->pr_policy > SCTP_PR_SCTP_MAX) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); error = EINVAL; break; From e834a8402623dfe04667768f876143416cc139d4 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Sat, 20 Dec 2014 22:12:04 +0000 Subject: [PATCH 043/207] Revert r274494, r274712, r275955 and provide extra comments explaining why there could appear a zero-sized mbufs in socket buffers. A proper fix would be to divorce record socket buffers and stream socket buffers, and divorce pru_send that accepts normal data from pru_send that accepts control data. --- sys/kern/uipc_sockbuf.c | 18 +++++++++++++++--- sys/kern/uipc_socket.c | 9 ++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index 8ca522c7ebd..acbccc9176e 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -640,9 +640,6 @@ sbappendstream_locked(struct sockbuf *sb, struct mbuf *m, int flags) { SOCKBUF_LOCK_ASSERT(sb); - if (m == NULL) - return; - KASSERT(m->m_nextpkt == NULL,("sbappendstream 0")); KASSERT(sb->sb_mb == sb->sb_lastrecord,("sbappendstream 1")); @@ -1065,6 +1062,21 @@ sbcut_internal(struct sockbuf *sb, int len) m = n; } } + /* + * Free any zero-length mbufs from the buffer. + * For SOCK_DGRAM sockets such mbufs represent empty records. + * XXX: For SOCK_STREAM sockets such mbufs can appear in the buffer, + * when sosend_generic() needs to send only control data. + */ + while (m && m->m_len == 0) { + struct mbuf *n; + + sbfree(sb, m); + n = m->m_next; + m->m_next = mfree; + mfree = m; + m = n; + } if (m) { sb->sb_mb = m; m->m_nextpkt = next; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index f08036d6336..189a30f053f 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1310,11 +1310,14 @@ restart: resid = 0; if (flags & MSG_EOR) top->m_flags |= M_EOR; - } else if (resid > 0) { + } else { /* * Copy the data from userland into a mbuf - * chain. If no data is to be copied in, - * a single empty mbuf is returned. + * chain. If resid is 0, which can happen + * only if we have control to send, then + * a single empty mbuf is returned. This + * is a workaround to prevent protocol send + * methods to panic. */ top = m_uiotombuf(uio, M_WAITOK, space, (atomic ? max_hdr : 0), From f13a4d33ef2344c859f1a49a34d8cb0abbe238d8 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 20 Dec 2014 23:41:37 +0000 Subject: [PATCH 044/207] Add some more debugging to the scan cancel methods - I'd like to see what situations would cause the scan cancel's to not complete. --- sys/net80211/ieee80211_scan.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index eae048061dd..d93645724d1 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -698,6 +698,13 @@ ieee80211_cancel_scan(struct ieee80211vap *vap) SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL; /* wake up the scan task */ scan_signal(ss); + } else { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n", + __func__, + !! (ic->ic_flags & IEEE80211_F_SCAN), + (ss->ss_vap == vap ? "match" : "nomatch"), + !! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL)); } IEEE80211_UNLOCK(ic); } @@ -724,6 +731,13 @@ ieee80211_cancel_anyscan(struct ieee80211vap *vap) SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL; /* wake up the scan task */ scan_signal(ss); + } else { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n", + __func__, + !! (ic->ic_flags & IEEE80211_F_SCAN), + (ss->ss_vap == vap ? "match" : "nomatch"), + !! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL)); } IEEE80211_UNLOCK(ic); } From 2c6179401bb2f09c9b9a581795581fc9ca013a45 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 21 Dec 2014 01:15:55 +0000 Subject: [PATCH 045/207] Add more debugging to try and track down this scan hang nonsense. --- sys/net80211/ieee80211_scan.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index d93645724d1..d81ba7c9fbb 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -752,6 +752,8 @@ ieee80211_scan_next(struct ieee80211vap *vap) struct ieee80211com *ic = vap->iv_ic; struct ieee80211_scan_state *ss = ic->ic_scan; + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); + /* wake up the scan task */ IEEE80211_LOCK(ic); scan_signal(ss); @@ -768,6 +770,8 @@ ieee80211_scan_done(struct ieee80211vap *vap) struct ieee80211com *ic = vap->iv_ic; struct ieee80211_scan_state *ss; + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); + IEEE80211_LOCK(ic); ss = ic->ic_scan; ss->ss_next = ss->ss_last; /* all channels are complete */ @@ -821,6 +825,10 @@ scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { struct ieee80211vap *vap = ss->ss_vap; + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: calling; maxdwell=%lu\n", + __func__, + maxdwell); IEEE80211_LOCK(vap->iv_ic); if (ss->ss_flags & IEEE80211_SCAN_ACTIVE) ieee80211_probe_curchan(vap, 0); @@ -835,7 +843,6 @@ scan_signal(void *arg) struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg; IEEE80211_LOCK_ASSERT(ss->ss_ic); - cv_signal(&SCAN_PRIVATE(ss)->ss_scan_cv); } @@ -848,6 +855,8 @@ scan_mindwell(struct ieee80211_scan_state *ss) { struct ieee80211com *ic = ss->ss_ic; + IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__); + IEEE80211_LOCK(ic); scan_signal(ss); IEEE80211_UNLOCK(ic); @@ -904,8 +913,15 @@ scan_task(void *arg, int pending) IEEE80211_LOCK(ic); for (;;) { + scandone = (ss->ss_next >= ss->ss_last) || (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0; + + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: loop start; scandone=%d\n", + __func__, + scandone); + if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) || (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) || time_after(ticks + ss->ss_mindwell, scanend)) @@ -970,9 +986,13 @@ scan_task(void *arg, int pending) if ((SCAN_PRIVATE(ss)->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT))) continue; + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: waiting\n", __func__); /* Wait to be signalled to scan the next channel */ cv_wait(&SCAN_PRIVATE(ss)->ss_scan_cv, IEEE80211_LOCK_OBJ(ic)); } + + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: out\n", __func__); + if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) goto done; From 3b00b9a60a022e9e81ddc5f1eea7cbc802f7c48b Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 21 Dec 2014 04:48:54 +0000 Subject: [PATCH 046/207] Break out the unicast/multicast TIM bit setting into "set something that indicates we have traffic" bit and a "do something if we have traffic bit." I'm going to be fleshing out this stuff more over time and it'll make more sense to have it broken out into two pieces here. --- sys/net80211/ieee80211_sta.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 89ed85627d6..c3c2bc92b59 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -1405,6 +1405,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int ix = aid / NBBY; int min = tim->tim_bitctl &~ 1; int max = tim->tim_len + min - 4; + int tim_ucast = 0, tim_mcast = 0; /* * Only do this for unicast traffic in the TIM @@ -1414,20 +1415,42 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, */ if (min <= ix && ix <= max && isset(tim->tim_bitmap - min, aid)) { - ieee80211_sta_tim_notify(vap, 1); - ic->ic_lastdata = ticks; + tim_ucast = 1; } /* - * XXX TODO: do a separate notification + * Do a separate notification * for the multicast bit being set. */ -#if 0 if (tim->tim_bitctl & 1) { + tim_mcast = 1; + } + + /* + * If the TIM indicates there's traffic for + * us then get us out of STA mode powersave. + */ + if (tim_ucast == 1) { + + /* + * Wake us out of SLEEP state if we're + * in it; and if we're doing bgscan + * then wake us out of STA powersave. + */ ieee80211_sta_tim_notify(vap, 1); + + /* + * This is preventing us from + * continuing a bgscan; because it + * tricks the contbgscan() + * routine to think there's always + * traffic for us. + * + * I think we need both an RX and + * TX ic_lastdata field. + */ ic->ic_lastdata = ticks; } -#endif ni->ni_dtim_count = tim->tim_count; ni->ni_dtim_period = tim->tim_period; From 1de34f860ea81d7f677941a7341156b06434b574 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 21 Dec 2014 04:58:45 +0000 Subject: [PATCH 047/207] Update ieee80211_sta_tim_notify() to do double duty - handle STA sleep to awake transition as well as handle waking up a VAP in STA powersave mode if it's in bgscan. This was a reasonably hairy bug to try and figure out and it became more obvious because of stuff I've done. Specifically: * a NIC would go into bgscan mode - either because of a bgscan timer or wpa_supplicant asked it to; * the AP would indicate there's traffic for the STA by setting the TIM bitmap bit for it; * mindwell would be met during scan, so it'd wake up and break out of the scan loop in scan_task(), but * because the scan wasn't completed, it wouldn't bring the VAP out of STA mode powersave (so it wouldn't tell the AP about it and it would block VAP TX); * .. but because we kept seeing the TIM bit set, ic->ic_lastdata was being constantly updated, and .. * bgscancont() would thus never say "yes we can continue a bgscan" so the bgscan would hang and never make progress. Now, I do see this particular state occur on iwn(4) - /however/ - this NIC has the firmware call ieee80211_scan_next() once the firmware scan for that channel has completed. This has the effect of moving the scan along to the next channel. I do see the debug that I'm adding where we see a beacon with a TIM bit set whilst we're in bgscan, so the condition about waking up to receive traffic is triggering. It just won't cause a hang. For other NICs - all of the USB ones and at least ath(4) - ieee80211_scan_next() / ieee80211_scan_done() isn't called. So it relies upon the mindwell timer, the beacon receive and the beacon / probe response -> ieee80211_add_scan() to move along the scan state. In the above case, mindwell triggered, there's no beacons triggering the scan_add code to move things along, and we weren't waking things up when seeing the TIM set for us. So it just hung until the interface was dropped. So, the short-term fix here is to do what the comment in scan_task() says - if we are in bgscan mode and we see our TIM bit set, just wake up the VAP. If it's already awake then it's a nop. If we're awake then we transition to awake and handle the traffic. Once there's no TX or RX traffic going on, ic->ic_lastdata won't be updated anymore and bgscancont() will continue. This was triggered more often after my initial SLEEP state handling for software sleep states - because now I update ic->ic_lastdata upon seeing a TIM bit set, not just the RX of the subsequent traffic. That's needed so the thing doesn't ping-pong up and down between seeing the TIM bit set, sending the "I'm awake" NULL data frame, and starting to receive data from the AP. I'd like to subsequently split ic_lastdata into two - one for TX and one for RX - so it becomes easier to use the correct one (or both!) when making decisions like whether to scan, go to sleep, etc. I'd appreciate this getting some further testing. Tested: * rsu(4), STA mode, bgscan on * iwn(4), STA mode, bgscan on --- sys/net80211/ieee80211_power.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c index 04b3c3ad547..812cd7053ce 100644 --- a/sys/net80211/ieee80211_power.c +++ b/sys/net80211/ieee80211_power.c @@ -560,10 +560,15 @@ ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable) * Handle being notified that we have data available for us in a TIM/ATIM. * * This may schedule a transition from _SLEEP -> _RUN if it's appropriate. + * + * In STA mode, we may have put to sleep during scan and need to be dragged + * back out of powersave mode. */ void ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set) { + struct ieee80211com *ic = vap->iv_ic; + /* * Schedule the driver state change. It'll happen at some point soon. * Since the hardware shouldn't know that we're running just yet @@ -574,10 +579,24 @@ ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set) * XXX TODO: verify that the transition to RUN will wake up the * BSS node! */ - IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, "%s: TIM=%d\n", __func__, set); IEEE80211_LOCK(vap->iv_ic); if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) { ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0); + IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, + "%s: TIM=%d; wakeup\n", __func__, set); + } else if ((set == 1) && (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)) { + /* + * XXX only do this if we're in RUN state? + */ + IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, + "%s: wake up from bgscan vap sleep\n", + __func__); + /* + * We may be in BGSCAN mode - this means the VAP is is in STA + * mode powersave. If it is, we need to wake it up so we + * can process outbound traffic. + */ + vap->iv_sta_ps(vap, 0); } IEEE80211_UNLOCK(vap->iv_ic); } From 61f26cae7d4b9c6e239329a0d4cecada3c457802 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 21 Dec 2014 05:07:11 +0000 Subject: [PATCH 048/207] Where appropriate, use the modern terms for the one true time base (UTC) rather than the archaic (GMT) in comments. Except where the comments are making fun of people doing this (and pedants who insist on the new terms). --- sys/i386/xen/clock.c | 2 +- sys/kern/subr_fattime.c | 2 +- sys/netinet/in_systm.h | 7 +++++-- sys/netinet/ip_icmp.c | 2 +- sys/netinet/ip_icmp.h | 2 +- sys/sys/sem.h | 4 ++-- sys/sys/time.h | 2 +- 7 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c index 0f5b0e516cf..26fafee64f0 100644 --- a/sys/i386/xen/clock.c +++ b/sys/i386/xen/clock.c @@ -118,7 +118,7 @@ struct mtx clock_lock; #define RTC_UNLOCK mtx_unlock_spin(&clock_lock) #define NS_PER_TICK (1000000000ULL/hz) -int adjkerntz; /* local offset from GMT in seconds */ +int adjkerntz; /* local offset from UTC in seconds */ int clkintr_pending; int pscnt = 1; int psdiv = 1; diff --git a/sys/kern/subr_fattime.c b/sys/kern/subr_fattime.c index e2a2195a707..099479c9c6c 100644 --- a/sys/kern/subr_fattime.c +++ b/sys/kern/subr_fattime.c @@ -45,7 +45,7 @@ * Later on again, in Windows NT, timestamps were defined relative to GMT. * * Purists will point out that UTC replaced GMT for such uses around - * a century ago, already then. Ironically "NT" was an abbreviation of + * half a century ago, already then. Ironically "NT" was an abbreviation of * "New Technology". Anyway... * * The 'utc' argument determines if the resulting FATTIME timestamp diff --git a/sys/netinet/in_systm.h b/sys/netinet/in_systm.h index 4b34aa00f76..acd2e62a2e5 100644 --- a/sys/netinet/in_systm.h +++ b/sys/netinet/in_systm.h @@ -44,12 +44,15 @@ * Internally the system keeps counters in the headers with the bytes * swapped so that VAX instructions will work on them. It reverses * the bytes before transmission at each protocol level. The n_ types - * represent the types with the bytes in ``high-ender'' order. + * represent the types with the bytes in ``high-ender'' order. Network + * byte order is usually referered to as big-endian these days rather + * than high-ender, which sadly invokes an Orson Scott Card novel, or + * worse, the movie. */ typedef u_int16_t n_short; /* short as received from the net */ typedef u_int32_t n_long; /* long as received from the net */ -typedef u_int32_t n_time; /* ms since 00:00 GMT, byte rev */ +typedef u_int32_t n_time; /* ms since 00:00 UTC, byte rev */ #ifdef _KERNEL uint32_t iptime(void); diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index d134a2ec3bd..b6b967f6d59 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -861,7 +861,7 @@ icmp_send(struct mbuf *m, struct mbuf *opts) } /* - * Return milliseconds since 00:00 GMT in network format. + * Return milliseconds since 00:00 UTC in network format. */ uint32_t iptime(void) diff --git a/sys/netinet/ip_icmp.h b/sys/netinet/ip_icmp.h index ca1e963abaa..38d44d78617 100644 --- a/sys/netinet/ip_icmp.h +++ b/sys/netinet/ip_icmp.h @@ -99,7 +99,7 @@ struct icmp { struct id_ts { /* ICMP Timestamp */ /* * The next 3 fields are in network format, - * milliseconds since 00:00 GMT + * milliseconds since 00:00 UTC */ uint32_t its_otime; /* Originate */ uint32_t its_rtime; /* Receive */ diff --git a/sys/sys/sem.h b/sys/sys/sem.h index f52bc0c9506..0ea259bd9ab 100644 --- a/sys/sys/sem.h +++ b/sys/sys/sem.h @@ -37,7 +37,7 @@ struct semid_ds_old { long sem_pad1; /* SVABI/386 says I need this here */ time_t sem_ctime; /* last change time */ /* Times measured in secs since */ - /* 00:00:00 GMT, Jan. 1, 1970 */ + /* 00:00:00 UTC, Jan. 1, 1970, without leap seconds */ long sem_pad2; /* SVABI/386 says I need this here */ long sem_pad3[4]; /* SVABI/386 says I need this here */ }; @@ -50,7 +50,7 @@ struct semid_ds { time_t sem_otime; /* last operation time */ time_t sem_ctime; /* last change time */ /* Times measured in secs since */ - /* 00:00:00 GMT, Jan. 1, 1970 */ + /* 00:00:00 UTC, Jan. 1, 1970, without leap seconds */ }; /* diff --git a/sys/sys/time.h b/sys/sys/time.h index 1f0a5301e61..395e8886a6e 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -398,7 +398,7 @@ extern sbintime_t sbt_tickthreshold; * Functions containing "up" returns time relative to boot and * should be used for calculating time intervals. * - * Functions without "up" returns GMT time. + * Functions without "up" returns UTC time. * * Functions with the "get" prefix returns a less precise result * much faster than the functions without "get" prefix and should From 0b3504fd3bde5e45a37b23962e6b1ec0cd32db6a Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 21 Dec 2014 09:53:29 +0000 Subject: [PATCH 049/207] Fix various mdoc issues. Found with: mandoc -Tlint --- share/man/man4/aout.4 | 2 +- share/man/man4/ath_ahb.4 | 2 +- share/man/man4/ath_pci.4 | 2 +- share/man/man4/carp.4 | 2 +- share/man/man4/crypto.4 | 1 - share/man/man4/ip.4 | 4 ++-- share/man/man4/ipheth.4 | 2 +- share/man/man4/iscsi_initiator.4 | 3 ++- share/man/man4/isp.4 | 4 +++- share/man/man4/ispfw.4 | 3 ++- share/man/man4/iwi.4 | 2 +- share/man/man4/multicast.4 | 8 ++++---- share/man/man4/net80211.4 | 4 ++-- share/man/man4/netmap.4 | 10 +--------- share/man/man4/nfe.4 | 4 ++-- share/man/man4/ng_ether_echo.4 | 2 +- share/man/man4/ng_netflow.4 | 2 +- share/man/man4/nvram2env.4 | 2 +- share/man/man4/pass.4 | 2 +- share/man/man4/pccbb.4 | 4 ++-- share/man/man4/pflog.4 | 2 +- share/man/man4/pfsync.4 | 2 +- share/man/man4/pts.4 | 2 +- share/man/man4/sa.4 | 4 ++-- share/man/man4/send.4 | 6 +++--- share/man/man4/sfxge.4 | 2 +- share/man/man4/snd_hda.4 | 2 +- share/man/man4/snd_ich.4 | 4 ++-- share/man/man4/ural.4 | 4 ++-- share/man/man4/usfs.4 | 2 +- share/man/man4/virtio_console.4 | 2 +- share/man/man4/virtio_random.4 | 2 +- share/man/man4/vxlan.4 | 4 ++-- share/man/man4/wpi.4 | 2 +- 34 files changed, 50 insertions(+), 55 deletions(-) diff --git a/share/man/man4/aout.4 b/share/man/man4/aout.4 index 8e7b02b886f..960ae25dd0b 100644 --- a/share/man/man4/aout.4 +++ b/share/man/man4/aout.4 @@ -123,7 +123,7 @@ non-executable mappings. .Xr execve 2 , .Xr a.out 5 , .Xr elf 5 , -.Xr sysctl 8 . +.Xr sysctl 8 .Sh HISTORY The .Xr a.out 5 diff --git a/share/man/man4/ath_ahb.4 b/share/man/man4/ath_ahb.4 index 6688dc27468..52aceb76065 100644 --- a/share/man/man4/ath_ahb.4 +++ b/share/man/man4/ath_ahb.4 @@ -47,7 +47,7 @@ drivers. This is only relevant for embedded System-on-Chip (SoC) devices such as the Atheros AR913x series, which include an Atheros wireless MAC on-die. .Sh SEE ALSO -.Xr ath 4 +.Xr ath 4 , .Xr ath_hal 4 .Sh HISTORY The diff --git a/share/man/man4/ath_pci.4 b/share/man/man4/ath_pci.4 index 814e5353c34..0cc36d7268f 100644 --- a/share/man/man4/ath_pci.4 +++ b/share/man/man4/ath_pci.4 @@ -44,7 +44,7 @@ and .Xr ath_hal 4 drivers. .Sh SEE ALSO -.Xr ath 4 +.Xr ath 4 , .Xr ath_hal 4 .Sh HISTORY The diff --git a/share/man/man4/carp.4 b/share/man/man4/carp.4 index ca52ba2f7b8..56335980f8e 100644 --- a/share/man/man4/carp.4 +++ b/share/man/man4/carp.4 @@ -306,7 +306,7 @@ tcpdump -npi vlan0 -T carp .Xr rc.conf 5 , .Xr devd.conf 5 , .Xr ifconfig 8 , -.Xr sysctl 8 +.Xr sysctl 8 , .Xr tcpdump 8 .Sh HISTORY The diff --git a/share/man/man4/crypto.4 b/share/man/man4/crypto.4 index ef35e030019..a488d9c240f 100644 --- a/share/man/man4/crypto.4 +++ b/share/man/man4/crypto.4 @@ -114,7 +114,6 @@ The two modes are described separately below. .Sh THEORY OF OPERATION Regardless of whether symmetric-key or asymmetric-key operations are to be performed, use of the device requires a basic series of steps: -.Pp .Bl -enum .It Open a file descriptor for the device. diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4 index 68b817d6fad..101993f0804 100644 --- a/share/man/man4/ip.4 +++ b/share/man/man4/ip.4 @@ -857,12 +857,12 @@ field was not equal to the length of the datagram written to the socket. .Xr recv 2 , .Xr send 2 , .Xr byteorder 3 , +.Xr sourcefilter 3 , .Xr icmp 4 , .Xr igmp 4 , .Xr inet 4 , .Xr intro 4 , -.Xr multicast 4 , -.Xr sourcefilter 3 +.Xr multicast 4 .Rs .%A D. Thaler .%A B. Fenner diff --git a/share/man/man4/ipheth.4 b/share/man/man4/ipheth.4 index 85801f2cf5e..a237524b379 100644 --- a/share/man/man4/ipheth.4 +++ b/share/man/man4/ipheth.4 @@ -80,7 +80,7 @@ Apple iPad tethering (all models) .Xr netintro 4 , .Xr urndis 4 , .Xr usb 4 , -.Xr ifconfig 8 +.Xr ifconfig 8 , .Xr usbconfig 8 .Sh HISTORY The diff --git a/share/man/man4/iscsi_initiator.4 b/share/man/man4/iscsi_initiator.4 index a391e086d6c..704365c8b7e 100644 --- a/share/man/man4/iscsi_initiator.4 +++ b/share/man/man4/iscsi_initiator.4 @@ -112,6 +112,7 @@ for each new session. iSCSI RFC 3720 .\" .Sh HISTORY .Sh AUTHORS -This software was written by Daniel Braniss +This software was written by +.An Daniel Braniss Aq Mt danny@cs.huji.ac.il .Sh BUGS The lun discovery method is old-fashioned. diff --git a/share/man/man4/isp.4 b/share/man/man4/isp.4 index cf1fa12d9b0..6d3a49a3f1b 100644 --- a/share/man/man4/isp.4 +++ b/share/man/man4/isp.4 @@ -230,7 +230,9 @@ This is the readonly World Wide Port Name value for this port. .Sh AUTHORS The .Nm -driver was written by Matthew Jacob originally for NetBSD at +driver was written by +.An Matthew Jacob +originally for NetBSD at NASA/Ames Research Center. .Sh BUGS The driver currently ignores some NVRAM settings. diff --git a/share/man/man4/ispfw.4 b/share/man/man4/ispfw.4 index 5755501f3bf..119b67587ec 100644 --- a/share/man/man4/ispfw.4 +++ b/share/man/man4/ispfw.4 @@ -56,4 +56,5 @@ This will kick the f/w into getting unstuck. .Sh SEE ALSO .Xr isp 4 .Sh AUTHORS -This driver was written by Matthew Jacob. +This driver was written by +.An Matthew Jacob . diff --git a/share/man/man4/iwi.4 b/share/man/man4/iwi.4 index 683f49655eb..911e54ce525 100644 --- a/share/man/man4/iwi.4 +++ b/share/man/man4/iwi.4 @@ -152,7 +152,7 @@ This should not happen. .Xr wlan_tkip 4 , .Xr wlan_wep 4 , .Xr ifconfig 8 , -.Xr wpa_supplicant 8 . +.Xr wpa_supplicant 8 .Sh AUTHORS The original .Nm diff --git a/share/man/man4/multicast.4 b/share/man/man4/multicast.4 index 81d6c778d45..2a22e578f0b 100644 --- a/share/man/man4/multicast.4 +++ b/share/man/man4/multicast.4 @@ -945,16 +945,16 @@ signal, but the next upcall will be triggered no earlier than after the previous upcall. .\" .Sh SEE ALSO -.Xr altq 4 , -.Xr dummynet 4 , .Xr getsockopt 2 , -.Xr gif 4 , -.Xr gre 4 , .Xr recvfrom 2 , .Xr recvmsg 2 , .Xr setsockopt 2 , .Xr socket 2 , .Xr sourcefilter 3 , +.Xr altq 4 , +.Xr dummynet 4 , +.Xr gif 4 , +.Xr gre 4 , .Xr icmp6 4 , .Xr igmp 4 , .Xr inet 4 , diff --git a/share/man/man4/net80211.4 b/share/man/man4/net80211.4 index 3773b989879..650bbf48272 100644 --- a/share/man/man4/net80211.4 +++ b/share/man/man4/net80211.4 @@ -1313,6 +1313,6 @@ Set whether or not Wi-FI Protected Setup (WPS) is enabled using the value in .Xr wlan 4 , .Xr wlan_acl 4 , .Xr wlan_xauth 4 , -.Xr ifconfig 8 , .Xr hostapd 8 , -.Xr wpa_supplicant 8 . +.Xr ifconfig 8 , +.Xr wpa_supplicant 8 diff --git a/share/man/man4/netmap.4 b/share/man/man4/netmap.4 index 9d985610d84..595deb39b32 100644 --- a/share/man/man4/netmap.4 +++ b/share/man/man4/netmap.4 @@ -104,7 +104,6 @@ various aspects of the and .Nm VALE architecture, features and usage. -.Pp .Sh ARCHITECTURE .Nm supports raw packet I/O through a @@ -141,7 +140,6 @@ and ports by default use separate memory regions, but can be independently configured to share memory. -.Pp .Sh ENTERING AND EXITING NETMAP MODE The following section describes the system calls to create and control @@ -210,7 +208,6 @@ A on the file descriptor removes the binding, and returns the NIC to normal mode (reconnecting the data path to the host stack), or destroys the virtual port. -.Pp .Sh DATA STRUCTURES The data structures in the mmapped memory region are detailed in .Xr sys/net/netmap.h , @@ -403,7 +400,6 @@ A transmit ring with pending transmissions has The function .Va int nm_tx_pending(ring) implements this test. -.Pp .Ss RECEIVE RINGS On receive rings, after a .Nm @@ -447,7 +443,6 @@ Below is an example of the evolution of an RX ring: v v v RX [.......hhhRRRRRRRRRRRR....] .Ed -.Pp .Sh SLOTS AND PACKET BUFFERS Normally, packets should be stored in the netmap-allocated buffers assigned to slots when ports are bound to a file descriptor. @@ -749,7 +744,6 @@ of the packet is successful, or 0 on error; similar to pcap_dispatch(), applies a callback to incoming packets .It Va u_char * nm_nextpkt(struct nm_desc *d, struct nm_pkthdr *hdr) similar to pcap_next(), fetches the next packet -.Pp .El .Sh SUPPORTED DEVICES .Nm @@ -1037,10 +1031,8 @@ Other .Nm clients attached to the same switch can now communicate with the network card or the host. -.Pp .Sh SEE ALSO -.Pp -http://info.iet.unipi.it/~luigi/netmap/ +.Pa http://info.iet.unipi.it/~luigi/netmap/ .Pp Luigi Rizzo, Revisiting network I/O APIs: the netmap framework, Communications of the ACM, 55 (3), pp.45-51, March 2012 diff --git a/share/man/man4/nfe.4 b/share/man/man4/nfe.4 index 29342111079..b9f91a20aa8 100644 --- a/share/man/man4/nfe.4 +++ b/share/man/man4/nfe.4 @@ -175,8 +175,8 @@ before a change takes effect. .Xr pci 4 , .Xr polling 4 , .Xr rgephy 4 , -.Xr sysctl 8 , -.Xr ifconfig 8 +.Xr ifconfig 8 , +.Xr sysctl 8 .Sh HISTORY The .Nm diff --git a/share/man/man4/ng_ether_echo.4 b/share/man/man4/ng_ether_echo.4 index e86c3a931e4..a62c55320cc 100644 --- a/share/man/man4/ng_ether_echo.4 +++ b/share/man/man4/ng_ether_echo.4 @@ -64,9 +64,9 @@ This node shuts down upon receipt of a control message, or when all hooks have been disconnected. .Sh SEE ALSO .Xr netgraph 4 , -.Xr ng_hole 4 , .Xr ng_echo 4 , .Xr ng_ether 4 , +.Xr ng_hole 4 , .Xr ngctl 8 .Sh HISTORY The diff --git a/share/man/man4/ng_netflow.4 b/share/man/man4/ng_netflow.4 index fb7e1faafad..889c88ae145 100644 --- a/share/man/man4/ng_netflow.4 +++ b/share/man/man4/ng_netflow.4 @@ -315,8 +315,8 @@ we do not use tee, but send packets back to either node. SEQ .Ed .Sh SEE ALSO -.Xr netgraph 4 , .Xr setfib 2 , +.Xr netgraph 4 , .Xr ng_ether 4 , .Xr ng_iface 4 , .Xr ng_ksocket 4 , diff --git a/share/man/man4/nvram2env.4 b/share/man/man4/nvram2env.4 index b9b03115e98..36781600b49 100644 --- a/share/man/man4/nvram2env.4 +++ b/share/man/man4/nvram2env.4 @@ -107,7 +107,7 @@ hint.nvram.1.base=0x1cff8000 .Ed .Sh SEE ALSO .Xr kenv 1 , -.Xr kenv 2 . +.Xr kenv 2 .Sh HISTORY .Nm first appeared in diff --git a/share/man/man4/pass.4 b/share/man/man4/pass.4 index 7280de1a2df..6b4fb1e7c7b 100644 --- a/share/man/man4/pass.4 +++ b/share/man/man4/pass.4 @@ -104,8 +104,8 @@ CAM subsystem. None. .Sh SEE ALSO .Xr cam 3 , -.Xr cam 4 , .Xr cam_cdbparse 3 , +.Xr cam 4 , .Xr xpt 4 , .Xr camcontrol 8 .Sh HISTORY diff --git a/share/man/man4/pccbb.4 b/share/man/man4/pccbb.4 index d8d955e5538..6018bec7b64 100644 --- a/share/man/man4/pccbb.4 +++ b/share/man/man4/pccbb.4 @@ -179,5 +179,5 @@ debugging problems with the bridge chipset. .El .Sh SEE ALSO .Xr cardbus 4 , -.Xr pccard 4 , -.Xr exca 4 +.Xr exca 4 , +.Xr pccard 4 diff --git a/share/man/man4/pflog.4 b/share/man/man4/pflog.4 index c1039a3ed14..803f1fdee5a 100644 --- a/share/man/man4/pflog.4 +++ b/share/man/man4/pflog.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 31 2007 +.Dd May 31, 2007 .Dt PFLOG 4 .Os .Sh NAME diff --git a/share/man/man4/pfsync.4 b/share/man/man4/pfsync.4 index b00bf9d0fc7..0529b71e24c 100644 --- a/share/man/man4/pfsync.4 +++ b/share/man/man4/pfsync.4 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 20 2011 +.Dd December 20, 2011 .Dt PFSYNC 4 .Os .Sh NAME diff --git a/share/man/man4/pts.4 b/share/man/man4/pts.4 index e9aaaaa052f..c142c500bbc 100644 --- a/share/man/man4/pts.4 +++ b/share/man/man4/pts.4 @@ -142,8 +142,8 @@ Pseudo-terminal slave devices. .Sh DIAGNOSTICS None. .Sh SEE ALSO -.Xr grantpt 3 , .Xr posix_openpt 2 , +.Xr grantpt 3 , .Xr ptsname 3 , .Xr pty 4 , .Xr tty 4 diff --git a/share/man/man4/sa.4 b/share/man/man4/sa.4 index aa72f68ec18..f5984aa18dd 100644 --- a/share/man/man4/sa.4 +++ b/share/man/man4/sa.4 @@ -264,8 +264,8 @@ accessing the device, e.g.). .Sh DIAGNOSTICS None. .Sh SEE ALSO -.Xr cam 4 , -.Xr mt 1 +.Xr mt 1 , +.Xr cam 4 .Sh AUTHORS .An -nosplit The diff --git a/share/man/man4/send.4 b/share/man/man4/send.4 index 4af510aa729..e69e6e35ca4 100644 --- a/share/man/man4/send.4 +++ b/share/man/man4/send.4 @@ -196,9 +196,9 @@ Occurs if interface output routines fail to send the packet out of the interface. .El .Sh SEE ALSO -.Xr recvfrom 2 -.Xr sendto 2 -.Xr socket 2 +.Xr recvfrom 2 , +.Xr sendto 2 , +.Xr socket 2 , .Xr loader.conf 5 .Sh HISTORY The diff --git a/share/man/man4/sfxge.4 b/share/man/man4/sfxge.4 index 7930fcf6e1e..e6fe6a42d49 100644 --- a/share/man/man4/sfxge.4 +++ b/share/man/man4/sfxge.4 @@ -114,11 +114,11 @@ For general information and support, go to the Solarflare support website at: .Pa https://support.solarflare.com . .Sh SEE ALSO +.Xr cpuset 1 , .Xr arp 4 , .Xr netintro 4 , .Xr ng_ether 4 , .Xr vlan 4 , -.Xr cpuset 1 , .Xr ifconfig 8 .Sh AUTHORS The diff --git a/share/man/man4/snd_hda.4 b/share/man/man4/snd_hda.4 index cdb2a620dbc..40a8862ca42 100644 --- a/share/man/man4/snd_hda.4 +++ b/share/man/man4/snd_hda.4 @@ -590,8 +590,8 @@ driver supports more than two hundred different controllers and CODECs. There is no sense to list all of them here, as in most cases specific CODEC configuration and wiring are more important then type of the CODEC itself. .Sh SEE ALSO -.Xr sound 4 , .Xr snd_ich 4 , +.Xr sound 4 , .Xr device.hints 5 , .Xr loader.conf 5 , .Xr sysctl 8 diff --git a/share/man/man4/snd_ich.4 b/share/man/man4/snd_ich.4 index 528d28cb52e..b03a0fd5569 100644 --- a/share/man/man4/snd_ich.4 +++ b/share/man/man4/snd_ich.4 @@ -99,8 +99,8 @@ NVIDIA nForce4 SiS 7012 .El .Sh SEE ALSO -.Xr sound 4 , -.Xr snd_hda 4 +.Xr snd_hda 4 , +.Xr sound 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/ural.4 b/share/man/man4/ural.4 index 1563fde2096..4b412f57905 100644 --- a/share/man/man4/ural.4 +++ b/share/man/man4/ural.4 @@ -142,9 +142,9 @@ This should not happen. .Xr wlan_tkip 4 , .Xr wlan_wep 4 , .Xr wlan_xauth 4 , -.Xr ifconfig 8 , .Xr hostapd 8 , -.Xr wpa_supplicant 8 . +.Xr ifconfig 8 , +.Xr wpa_supplicant 8 .Rs .%T "Ralink Technology" .%U http://www.ralinktech.com/ diff --git a/share/man/man4/usfs.4 b/share/man/man4/usfs.4 index 215d31e8cff..a72a8d8435b 100644 --- a/share/man/man4/usfs.4 +++ b/share/man/man4/usfs.4 @@ -54,7 +54,7 @@ the USB stack is activated in USB device side mode. .Pp Upon attach the driver creates a RAM disk which can be read and written. .Sh SEE ALSO -.Xr umass 4 +.Xr umass 4 , .Xr usb 4 .Sh HISTORY The diff --git a/share/man/man4/virtio_console.4 b/share/man/man4/virtio_console.4 index b855f1388da..542c8458c03 100644 --- a/share/man/man4/virtio_console.4 +++ b/share/man/man4/virtio_console.4 @@ -58,7 +58,7 @@ each port is accessible through .It Pa /dev/ttyV?.?? .El .Sh SEE ALSO -.Xr tty 4 +.Xr tty 4 , .Xr virtio 4 .Sh HISTORY The diff --git a/share/man/man4/virtio_random.4 b/share/man/man4/virtio_random.4 index 5ce7d17ffb0..d44b08d482f 100644 --- a/share/man/man4/virtio_random.4 +++ b/share/man/man4/virtio_random.4 @@ -52,7 +52,7 @@ device driver provides support for VirtIO entropy devices. The entropy device supplies high-quality randomness from the hypervisor to the guest. .Sh SEE ALSO -.Xr random 4 +.Xr random 4 , .Xr virtio 4 .Sh HISTORY The diff --git a/share/man/man4/vxlan.4 b/share/man/man4/vxlan.4 index ec95db1d9cf..167d5b0f2ae 100644 --- a/share/man/man4/vxlan.4 +++ b/share/man/man4/vxlan.4 @@ -215,9 +215,9 @@ Once created, the interface can be configured with .Xr ifconfig 8 . .Sh SEE ALSO -.Xr ifconfig 8 , .Xr inet 4 , -.Xr inet 6 , +.Xr inet6 4 , +.Xr ifconfig 8 , .Xr sysctl 8 , .Xr vlan 8 .Rs diff --git a/share/man/man4/wpi.4 b/share/man/man4/wpi.4 index f2d4251e5e1..4cf33c410e7 100644 --- a/share/man/man4/wpi.4 +++ b/share/man/man4/wpi.4 @@ -117,12 +117,12 @@ The hardware switch controlling the radio is currently turned off. Data transmission is not possible in this state. .El .Sh SEE ALSO -.Xr wpifw 4 , .Xr pci 4 , .Xr wlan 4 , .Xr wlan_ccmp 4 , .Xr wlan_tkip 4 , .Xr wlan_wep 4 , +.Xr wpifw 4 , .Xr ifconfig 8 , .Xr wpa_supplicant 8 .Sh AUTHORS From 05a1e019f38f9165df58d24a34297f11ea1d1b8a Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 21 Dec 2014 10:04:26 +0000 Subject: [PATCH 050/207] Remove EOL whitespace. Found with: mandoc -Tlint --- share/man/man4/altera_atse.4 | 2 +- share/man/man4/gpioled.4 | 4 +- share/man/man4/iicbus.4 | 8 ++-- share/man/man4/iscsi_initiator.4 | 2 +- share/man/man4/mpr.4 | 2 +- share/man/man4/mrsas.4 | 78 ++++++++++++++++---------------- share/man/man4/netmap.4 | 2 +- share/man/man4/tap.4 | 2 +- share/man/man4/tun.4 | 2 +- share/man/man4/umass.4 | 2 +- share/man/man4/wsp.4 | 2 +- 11 files changed, 53 insertions(+), 53 deletions(-) diff --git a/share/man/man4/altera_atse.4 b/share/man/man4/altera_atse.4 index 10835cf01cd..1cff0d05482 100644 --- a/share/man/man4/altera_atse.4 +++ b/share/man/man4/altera_atse.4 @@ -80,7 +80,7 @@ Only a single MAC address may be stored in flash. If the address begins with the Altera prefix 00:07:ed and ends in 00 then up to 16 addresses will be derived from it by adding the unit number of the interface to the stored address. -For other prefixes, the address will be assigned to atse0 and random +For other prefixes, the address will be assigned to atse0 and random addresses will be used for other interfaces. If the stored address is invalid, for example all zero's, multicast, or the default address shipped on all DE4 boards (00:07:ed:ff:ed:15) then a random diff --git a/share/man/man4/gpioled.4 b/share/man/man4/gpioled.4 index 6d1b41ec396..3e305959809 100644 --- a/share/man/man4/gpioled.4 +++ b/share/man/man4/gpioled.4 @@ -52,8 +52,8 @@ The GPIO pin can then be controlled by writing to this device as described in .Xr led 4 . .Pp -On a -.Xr device.hints 5 +On a +.Xr device.hints 5 based system, like .Li MIPS , these values are configurable for diff --git a/share/man/man4/iicbus.4 b/share/man/man4/iicbus.4 index ce9d586506c..c89bfaf7068 100644 --- a/share/man/man4/iicbus.4 +++ b/share/man/man4/iicbus.4 @@ -106,11 +106,11 @@ Some I2C interfaces are available: .Sh BUS FREQUENCY CONFIGURATION The operating frequency of an I2C bus may be fixed or configurable. The bus may be used as part of some larger standard interface, and that -interface specification may require a fixed frequency. -The driver for that hardware would not honor an attempt to configure a +interface specification may require a fixed frequency. +The driver for that hardware would not honor an attempt to configure a different speed. A general purpose I2C bus, such as those found in many embedded systems, -will often support multiple bus frequencies. +will often support multiple bus frequencies. .Pp When a system supports multiple I2C busses, a different frequency can be configured for each bus by number, represented by the @@ -145,7 +145,7 @@ The same variable can be changed at any time with Reset the bus using .Xr i2c 8 or the -.Xr iic 4 +.Xr iic 4 .Va I2CRSTCARD ioctl to make the change take effect. .Sh SEE ALSO diff --git a/share/man/man4/iscsi_initiator.4 b/share/man/man4/iscsi_initiator.4 index 704365c8b7e..df03e6a0058 100644 --- a/share/man/man4/iscsi_initiator.4 +++ b/share/man/man4/iscsi_initiator.4 @@ -47,7 +47,7 @@ iscsi_initiator_load="YES" .Sh DESCRIPTION .Bf -symbolic This driver, along with its userspace counterpart -.Xr iscontrol 8 , +.Xr iscontrol 8 , is obsolete. Users are advised to use .Xr iscsi 4 diff --git a/share/man/man4/mpr.4 b/share/man/man4/mpr.4 index c85be675838..1780a95b8c1 100644 --- a/share/man/man4/mpr.4 +++ b/share/man/man4/mpr.4 @@ -59,7 +59,7 @@ mpr_load="YES" .Ed .Sh DESCRIPTION The -.Nm +.Nm driver provides support for LSI Fusion-MPT 3 IT/IR .Tn SAS controllers. diff --git a/share/man/man4/mrsas.4 b/share/man/man4/mrsas.4 index 70cafca9bf5..2ed2c84cf73 100644 --- a/share/man/man4/mrsas.4 +++ b/share/man/man4/mrsas.4 @@ -27,7 +27,7 @@ .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. -.\" +.\" .\" The views and conclusions contained in the software and documentation .\" are those of the authors and should not be interpreted as representing .\" official policies, either expressed or implied, of the FreeBSD Project. @@ -57,15 +57,15 @@ mrsas_load="YES" .Ed .Sh DESCRIPTION The -.Nm +.Nm driver will detect LSI's next generation (6Gb/s and 12Gb/s) PCI Express SAS/SATA RAID controllers. See the .Nm HARDWARE section for the supported devices list. -A disk (virtual disk/physical disk) attached to the +A disk (virtual disk/physical disk) attached to the .Nm -driver will be visible to the user through +driver will be visible to the user through .Xr camcontrol 8 as .Pa /dev/da? @@ -79,11 +79,11 @@ The name is derived from the phrase "MegaRAID SAS HBA", which is substantially different than the old "MegaRAID" Driver .Xr mfi 4 -which does not connect targets -to the +which does not connect targets +to the +.Xr cam 4 +layer and thus requires a new driver which attaches targets to the .Xr cam 4 -layer and thus requires a new driver which attaches targets to the -.Xr cam 4 layer. Older MegaRAID controllers are supported by .Xr mfi 4 @@ -91,7 +91,7 @@ and will not work with .Nm , but both the .Xr mfi 4 -and +and .Nm drivers can detect and manage the LSI MegaRAID SAS 2208/2308/3008/3108 series of controllers. @@ -104,8 +104,8 @@ driver's behavior for LSI MegaRAID SAS 2208/2308/3008/3108 controllers. By default, the .Xr mfi 4 driver will detect these controllers. -See the -.Nm PRIORITY +See the +.Nm PRIORITY section to know more about driver priority for MR-Fusion devices. .Pp .Nm @@ -164,16 +164,16 @@ DELL PERC H330 .Sh CONFIGURATION To disable Online Controller Reset(OCR) for a specific .Nm -driver instance, set the +driver instance, set the following tunable value in .Xr loader.conf 5 : .Bd -literal -offset indent -dev.mrsas.X.disable_ocr=1 +dev.mrsas.X.disable_ocr=1 .Ed .Pp where X is the adapter number. .Pp -To change the I/O timeout value for a specific +To change the I/O timeout value for a specific .Nm driver instance, set the following tunable value in .Xr loader.conf 5 : @@ -230,12 +230,12 @@ and .Dv BUS_PROBE_LOW_PRIORITY ) . MR-Fusion Controllers include all cards with the Device IDs - -0x005B, +0x005B, 0x005D, 0x005F. .Pp The -.Xr mfi 4 +.Xr mfi 4 driver will set a priority of either .Dv BUS_PROBE_DEFAULT or @@ -254,13 +254,13 @@ for the .Nm driver to detect a MR-Fusion card instead of the .Xr mfi 4 -driver. +driver. .Bd -ragged -offset indent .Cd hw.mfi.mrsas_enable="1" .Ed .Pp At boot time, the -.Xr mfi 4 +.Xr mfi 4 driver will get priority to detect MR-Fusion controllers by default. Before changing this default driver selection policy, LSI advises users to understand @@ -273,9 +273,9 @@ driver to detect MR-Fusion cards, but allow for the ability to choose the driver to detect MR-Fusion cards. .Pp LSI recommends setting hw.mfi.mrsas_enable="0" for customers who are using the -older -.Xr mfi 4 -driver and do not want to switch to +older +.Xr mfi 4 +driver and do not want to switch to .Nm . For those customers who are using a MR-Fusion controller for the first time, LSI recommends using the @@ -286,8 +286,8 @@ Changing the default behavior is well tested under most conditions, but unexpected behavior may pop up if more complex and unrealistic operations are executed by switching between the .Xr mfi 4 -and -.Nm +and +.Nm drivers for MR-Fusion. Switching drivers is designed to happen only one time. Although multiple @@ -296,16 +296,16 @@ The user should decide from .Nm Start of Day which driver they want to use for the MR-Fusion card. .Pp -The user may see different device names when switching from -.Xr mfi 4 -to +The user may see different device names when switching from +.Xr mfi 4 +to .Nm . This behavior is .Nm Functions As Designed and the user needs to change the .Xr fstab 5 -entry manually if they are doing any experiments with -.Xr mfi 4 +entry manually if they are doing any experiments with +.Xr mfi 4 and .Nm interoperability. @@ -342,7 +342,7 @@ is the new driver reworked by LSI which supports Thunderbolt and onward products. The SAS+SATA RAID controller with device id 0x005b is referred to as the Thunderbolt controller throughout this man page. -.Ed +.Ed .Bd -ragged .Nm cam aware HBA drivers: .Fx @@ -351,12 +351,12 @@ has a layer which attaches storage devices and provides a common access mechanism to storage controllers and attached devices. The -.Nm +.Nm driver is .Xr cam 4 -aware and devices associated with -.Nm -can be seen using +aware and devices associated with +.Nm +can be seen using .Xr camcontrol 8 . The .Xr mfi 4 @@ -364,13 +364,13 @@ driver does not understand the .Xr cam 4 layer and it directly associates storage disks to the block layer. .Pp -.Nm Thunderbolt Controller: +.Nm Thunderbolt Controller: This is the 6Gb/s MegaRAID HBA card which has device id 0x005B. .Pp -.Nm Invader Controller: +.Nm Invader Controller: This is 12Gb/s MegaRAID HBA card which has device id 0x005D. .Pp -.Nm Fury Controller: +.Nm Fury Controller: This is the 12Gb/s MegaRAID HBA card which has device id 0x005F. .Ed .Sh AUTHORS @@ -387,11 +387,11 @@ switches between two drivers and does not want to edit manually). .Pp The -.Nm +.Nm driver exposes devices as .Pa /dev/da? , -whereas -.Xr mfi 4 +whereas +.Xr mfi 4 exposes devices as .Pa /dev/mfid? . .Pp diff --git a/share/man/man4/netmap.4 b/share/man/man4/netmap.4 index 595deb39b32..f6ca70b01f6 100644 --- a/share/man/man4/netmap.4 +++ b/share/man/man4/netmap.4 @@ -143,7 +143,7 @@ but can be independently configured to share memory. .Sh ENTERING AND EXITING NETMAP MODE The following section describes the system calls to create and control -.Nm netmap +.Nm netmap ports (including .Nm VALE and diff --git a/share/man/man4/tap.4 b/share/man/man4/tap.4 index 229de6028eb..6e4299609c7 100644 --- a/share/man/man4/tap.4 +++ b/share/man/man4/tap.4 @@ -34,7 +34,7 @@ or a terminal for and a character-special device .Dq control interface. -A client program transfers Ethernet frames to or from the +A client program transfers Ethernet frames to or from the .Nm .Dq control interface. diff --git a/share/man/man4/tun.4 b/share/man/man4/tun.4 index 0b88b7213b0..9a2171175c4 100644 --- a/share/man/man4/tun.4 +++ b/share/man/man4/tun.4 @@ -35,7 +35,7 @@ or a terminal for and a character-special device .Dq control interface. -A client program transfers IP (by default) packets to or from the +A client program transfers IP (by default) packets to or from the .Nm .Dq control interface. diff --git a/share/man/man4/umass.4 b/share/man/man4/umass.4 index b4c08d72170..4b0d0e417c8 100644 --- a/share/man/man4/umass.4 +++ b/share/man/man4/umass.4 @@ -62,7 +62,7 @@ or .Xr ohci 4 or .Xr ehci 4 -or +or .Xr xhci 4 must be configured in the kernel. Additionally, since diff --git a/share/man/man4/wsp.4 b/share/man/man4/wsp.4 index 24c9b77efb1..32ec7980467 100644 --- a/share/man/man4/wsp.4 +++ b/share/man/man4/wsp.4 @@ -52,7 +52,7 @@ device found in many Apple laptops. .Pp The driver simulates a three-button mouse using multi-finger tap detection. -A single-finger press generates a left button click. +A single-finger press generates a left button click. A two-finger tap maps to the right button; whereas a three-finger tap gets treated as a middle button click. .Pp From 1e9469d188355e00de1c3811dd2f983d2f5a47d9 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 21 Dec 2014 10:57:42 +0000 Subject: [PATCH 051/207] Fix various mdoc issues and some EOL whitespace. Found with: mandoc -Tlint --- share/man/man9/BUF_ISLOCKED.9 | 4 ++-- share/man/man9/BUS_BIND_INTR.9 | 2 +- share/man/man9/BUS_DESCRIBE_INTR.9 | 2 +- share/man/man9/DB_COMMAND.9 | 2 +- share/man/man9/EVENTHANDLER.9 | 2 +- share/man/man9/VFS.9 | 4 ++-- share/man/man9/VFS_CHECKEXP.9 | 4 ++-- share/man/man9/VFS_FHTOVP.9 | 4 ++-- share/man/man9/VFS_SET.9 | 4 ++-- share/man/man9/VOP_LOCK.9 | 5 +++-- share/man/man9/VOP_VPTOCNP.9 | 4 ++-- share/man/man9/accf_data.9 | 2 +- share/man/man9/accf_dns.9 | 2 +- share/man/man9/acl.9 | 2 +- share/man/man9/alq.9 | 2 +- share/man/man9/devfs_set_cdevpriv.9 | 2 +- share/man/man9/eventtimers.9 | 4 ++-- share/man/man9/ieee80211_crypto.9 | 4 ++-- share/man/man9/ifnet.9 | 5 +++-- share/man/man9/kqueue.9 | 5 +++-- share/man/man9/lock.9 | 4 ++-- share/man/man9/locking.9 | 6 +++--- share/man/man9/mbuf.9 | 6 ++++-- share/man/man9/refcount.9 | 2 +- share/man/man9/usbdi.9 | 4 ++-- share/man/man9/vm_page_busy.9 | 4 ++-- share/man/man9/vnet.9 | 15 +++++---------- share/man/man9/vnode.9 | 4 ++-- share/man/man9/zone.9 | 2 +- 29 files changed, 56 insertions(+), 56 deletions(-) diff --git a/share/man/man9/BUF_ISLOCKED.9 b/share/man/man9/BUF_ISLOCKED.9 index 2471db978d9..8616ff5d65a 100644 --- a/share/man/man9/BUF_ISLOCKED.9 +++ b/share/man/man9/BUF_ISLOCKED.9 @@ -59,11 +59,11 @@ A shared lock is held. The lock is not held by anyone. .El .Sh SEE ALSO -.Xr lockstatus 9 , .Xr buf 9 , .Xr BUF_LOCK 9 , .Xr BUF_UNLOCK 9 , -.Xr lockmgr 9 +.Xr lockmgr 9 , +.Xr lockstatus 9 .Sh AUTHORS This manual page was written by .An Attilio Rao Aq Mt attilio@FreeBSD.org . diff --git a/share/man/man9/BUS_BIND_INTR.9 b/share/man/man9/BUS_BIND_INTR.9 index 2e22dea9ae1..1c97897e51d 100644 --- a/share/man/man9/BUS_BIND_INTR.9 +++ b/share/man/man9/BUS_BIND_INTR.9 @@ -86,8 +86,8 @@ The most recent binding request is the one that will be in effect. .Sh RETURN VALUES Zero is returned on success, otherwise an appropriate error is returned. .Sh SEE ALSO -.Xr BUS_SETUP_INTR 9 , .Xr cpuset 2 , +.Xr BUS_SETUP_INTR 9 , .Xr device 9 .Sh HISTORY The diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9 index b7f137b5b20..10004551e76 100644 --- a/share/man/man9/BUS_DESCRIBE_INTR.9 +++ b/share/man/man9/BUS_DESCRIBE_INTR.9 @@ -87,9 +87,9 @@ the interrupt handler name. .Sh RETURN VALUES Zero is returned on success, otherwise an appropriate error is returned. .Sh SEE ALSO -.Xr BUS_SETUP_INTR 9 , .Xr systat 1 , .Xr vmstat 8 , +.Xr BUS_SETUP_INTR 9 , .Xr device 9 , .Xr printf 9 .Sh HISTORY diff --git a/share/man/man9/DB_COMMAND.9 b/share/man/man9/DB_COMMAND.9 index bf3faea6926..34d7b50e0cd 100644 --- a/share/man/man9/DB_COMMAND.9 +++ b/share/man/man9/DB_COMMAND.9 @@ -68,7 +68,7 @@ command, respectively. .Pp The general command syntax: .Cm command Ns Op Li \&/ Ns Ar modifier -.Ar address Ns Op Li , Ns Ar count , +.Ar address Ns Op , Ns Ar count , translates into the following parameters for .Fa command_function : .Bl -tag -width Fa -offset indent diff --git a/share/man/man9/EVENTHANDLER.9 b/share/man/man9/EVENTHANDLER.9 index 711c6efaa44..c8f3002239a 100644 --- a/share/man/man9/EVENTHANDLER.9 +++ b/share/man/man9/EVENTHANDLER.9 @@ -261,7 +261,7 @@ operation. Callbacks invoked when a process exits. .It Vt process_fini Callback invoked when a process memory is destroyed. -This is never called. +This is never called. .It Vt process_fork Callbacks invoked when a process forks a child. .It Vt process_init diff --git a/share/man/man9/VFS.9 b/share/man/man9/VFS.9 index cf5189e67a0..86852ce9caa 100644 --- a/share/man/man9/VFS.9 +++ b/share/man/man9/VFS.9 @@ -54,8 +54,8 @@ rather than implementing empty functions or casting to .Xr VFS_SYNC 9 , .Xr VFS_UNMOUNT 9 , .Xr VFS_VGET 9 , -.Xr VOP_VPTOFH 9 , -.Xr vnode 9 +.Xr vnode 9 , +.Xr VOP_VPTOFH 9 .Sh AUTHORS This manual page was written by .An Doug Rabson . diff --git a/share/man/man9/VFS_CHECKEXP.9 b/share/man/man9/VFS_CHECKEXP.9 index 62d545c753e..42aeeb6833c 100644 --- a/share/man/man9/VFS_CHECKEXP.9 +++ b/share/man/man9/VFS_CHECKEXP.9 @@ -81,8 +81,8 @@ and .Sh SEE ALSO .Xr VFS 9 , .Xr VFS_FHTOVP 9 , -.Xr VOP_VPTOFH 9 , -.Xr vnode 9 +.Xr vnode 9 , +.Xr VOP_VPTOFH 9 .Sh AUTHORS This manual page was written by .An Alfred Perlstein . diff --git a/share/man/man9/VFS_FHTOVP.9 b/share/man/man9/VFS_FHTOVP.9 index 39a6168f51b..cdc03e139a4 100644 --- a/share/man/man9/VFS_FHTOVP.9 +++ b/share/man/man9/VFS_FHTOVP.9 @@ -76,8 +76,8 @@ The locked vnode for the file will be returned in .Sh SEE ALSO .Xr VFS 9 , .Xr VFS_CHECKEXP 9 , -.Xr VOP_VPTOFH 9 , -.Xr vnode 9 +.Xr vnode 9 , +.Xr VOP_VPTOFH 9 .Sh AUTHORS This manual page was written by .An Doug Rabson . diff --git a/share/man/man9/VFS_SET.9 b/share/man/man9/VFS_SET.9 index c35935e6c47..e0388fd18ab 100644 --- a/share/man/man9/VFS_SET.9 +++ b/share/man/man9/VFS_SET.9 @@ -104,8 +104,8 @@ VFS_SET(myfs_vfsops, myfs, 0); .Xr jail 2 , .Xr jail 8 , .Xr DECLARE_MODULE 9 , -.Xr vfsconf 9 , -.Xr vfs_modevent 9 +.Xr vfs_modevent 9 , +.Xr vfsconf 9 .Sh AUTHORS This manual page was written by .An Chad David Aq Mt davidc@acns.ab.ca . diff --git a/share/man/man9/VOP_LOCK.9 b/share/man/man9/VOP_LOCK.9 index b4fdc7ac72b..db4608037ad 100644 --- a/share/man/man9/VOP_LOCK.9 +++ b/share/man/man9/VOP_LOCK.9 @@ -100,8 +100,9 @@ with these control flags: .Bl -tag -width ".Dv LK_CANRECURSE" -offset indent -compact .It Dv LK_INTERLOCK Specify when the caller already has a simple lock -.Fn ( VOP_LOCK -will unlock the simple lock after getting the lock). +.Po Fn VOP_LOCK +will unlock the simple lock after getting the lock +.Pc . .It Dv LK_RETRY Retry until locked. .El diff --git a/share/man/man9/VOP_VPTOCNP.9 b/share/man/man9/VOP_VPTOCNP.9 index f2d5ddc7755..74042601810 100644 --- a/share/man/man9/VOP_VPTOCNP.9 +++ b/share/man/man9/VOP_VPTOCNP.9 @@ -78,8 +78,8 @@ The buffer was not large enough to hold the vnode's component name. The vnode was not found on the file system. .El .Sh SEE ALSO -.Xr VOP_LOOKUP 9 , -.Xr vnode 9 +.Xr vnode 9 , +.Xr VOP_LOOKUP 9 .Sh NOTES This interface is a work in progress. .Sh HISTORY diff --git a/share/man/man9/accf_data.9 b/share/man/man9/accf_data.9 index 2d3b7a24d69..9caeba9b002 100644 --- a/share/man/man9/accf_data.9 +++ b/share/man/man9/accf_data.9 @@ -67,7 +67,7 @@ on the socket .Sh SEE ALSO .Xr setsockopt 2 , .Xr accept_filter 9 , -.Xr accf_dns 9 +.Xr accf_dns 9 , .Xr accf_http 9 .Sh HISTORY The accept filter mechanism and the diff --git a/share/man/man9/accf_dns.9 b/share/man/man9/accf_dns.9 index 4a2dad25066..0ea4bf46b19 100644 --- a/share/man/man9/accf_dns.9 +++ b/share/man/man9/accf_dns.9 @@ -69,8 +69,8 @@ on a socket .Sh SEE ALSO .Xr setsockopt 2 , .Xr accept_filter 9 , +.Xr accf_data 9 , .Xr accf_http 9 -.Xr accf_data 9 .Sh HISTORY The accept filter mechanism was introduced in .Fx 4.0 . diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9 index c6c71591801..a4ee9cd2450 100644 --- a/share/man/man9/acl.9 +++ b/share/man/man9/acl.9 @@ -207,10 +207,10 @@ The following values are valid: .El .Sh SEE ALSO .Xr acl 3 , +.Xr vaccess 9 , .Xr vaccess_acl_nfs4 9 , .Xr vaccess_acl_posix1e 9 , .Xr VFS 9 , -.Xr vaccess 9 , .Xr VOP_ACLCHECK 9 , .Xr VOP_GETACL 9 , .Xr VOP_SETACL 9 diff --git a/share/man/man9/alq.9 b/share/man/man9/alq.9 index b8b0c237b06..b13e73d16b9 100644 --- a/share/man/man9/alq.9 +++ b/share/man/man9/alq.9 @@ -417,10 +417,10 @@ and either the queue is full or the system is shutting down. NOTE: invalid arguments to non-void functions will result in undefined behaviour. .Sh SEE ALSO +.Xr syslog 3 , .Xr kproc 9 , .Xr ktr 9 , .Xr msleep_spin 9 , -.Xr syslog 3 , .Xr vnode 9 .Sh HISTORY The diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9 index 736a007c1ed..85df4f3079a 100644 --- a/share/man/man9/devfs_set_cdevpriv.9 +++ b/share/man/man9/devfs_set_cdevpriv.9 @@ -114,8 +114,8 @@ filedescriptor, or was called. .El .Sh SEE ALSO -.Xr open 2 , .Xr close 2 , +.Xr open 2 , .Xr devfs 5 , .Xr kern_openat 9 .Sh HISTORY diff --git a/share/man/man9/eventtimers.9 b/share/man/man9/eventtimers.9 index 09cd8b3e661..686f63c0ddf 100644 --- a/share/man/man9/eventtimers.9 +++ b/share/man/man9/eventtimers.9 @@ -179,13 +179,13 @@ methods control timers associated with the current CPU. Driver may deregister its functionality by calling .Fn et_deregister . .Pp -If the frequency of the clock hardware can change while it is +If the frequency of the clock hardware can change while it is running (for example, during power-saving modes), the driver must call .Fn et_change_frequency on each change. If the given event timer is the active timer, .Fn et_change_frequency -stops the timer on all CPUs, updates +stops the timer on all CPUs, updates .Va et->frequency , then restarts the timer on all CPUs so that all current events are rescheduled using the new frequency. diff --git a/share/man/man9/ieee80211_crypto.9 b/share/man/man9/ieee80211_crypto.9 index c82b8766319..1335551ad9f 100644 --- a/share/man/man9/ieee80211_crypto.9 +++ b/share/man/man9/ieee80211_crypto.9 @@ -253,8 +253,8 @@ and These calls also synchronize hardware key state update when receive traffic is active. .Sh SEE ALSO -.Xr ieee80211 9 , .Xr ioctl 2 , .Xr wlan_ccmp 4 , .Xr wlan_tkip 4 , -.Xr wlan_wep 4 +.Xr wlan_wep 4 , +.Xr ieee80211 9 diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9 index 7aef4def517..0e55850beba 100644 --- a/share/man/man9/ifnet.9 +++ b/share/man/man9/ifnet.9 @@ -418,7 +418,7 @@ lock used to protect interface-related address lists. .Xr queue 3 macro glue for the list of clonable network interfaces. .It Va if_groups -.Pq Fn TAILQ_HEAD ", ifg_list" +.Pq Fn TAILQ_HEAD "" "ifg_list" The head of the .Xr queue 3 .Li TAILQ @@ -1410,7 +1410,8 @@ address whose remote address is if one is found. If .Fa ignore_ptp -is true, skip point-to-point interface addresses. The +is true, skip point-to-point interface addresses. +The .Fa fib parameter is handled the same way as by .Fn ifa_ifwithdstaddr . diff --git a/share/man/man9/kqueue.9 b/share/man/man9/kqueue.9 index 28aadee776b..a8137bdfe61 100644 --- a/share/man/man9/kqueue.9 +++ b/share/man/man9/kqueue.9 @@ -395,8 +395,9 @@ There must be no .Vt knotes associated with the .Vt knlist -.Fn ( knlist_empty -returns true) +.Po Fn knlist_empty +returns true +.Pc and no more .Vt knotes may be attached to the object. diff --git a/share/man/man9/lock.9 b/share/man/man9/lock.9 index 2c874f28f43..69afdc4e90f 100644 --- a/share/man/man9/lock.9 +++ b/share/man/man9/lock.9 @@ -411,12 +411,12 @@ will be the result of trying. .Sh SEE ALSO .Xr condvar 9 , .Xr locking 9 , +.Xr mtx_assert 9 , .Xr mutex 9 , +.Xr panic 9 , .Xr rwlock 9 , .Xr sleep 9 , .Xr sx 9 , -.Xr mtx_assert 9 , -.Xr panic 9 , .Xr VOP_PRINT 9 .Sh AUTHORS This manual page was written by diff --git a/share/man/man9/locking.9 b/share/man/man9/locking.9 index f8ac5f2d27b..76ce70b9054 100644 --- a/share/man/man9/locking.9 +++ b/share/man/man9/locking.9 @@ -391,17 +391,17 @@ At this time this is a rather easy to remember table. .El .Sh SEE ALSO .Xr witness 4 , +.Xr BUS_SETUP_INTR 9 , .Xr condvar 9 , .Xr lock 9 , +.Xr LOCK_PROFILING 9 , .Xr mtx_pool 9 , .Xr mutex 9 , .Xr rmlock 9 , .Xr rwlock 9 , .Xr sema 9 , .Xr sleep 9 , -.Xr sx 9 , -.Xr BUS_SETUP_INTR 9 , -.Xr LOCK_PROFILING 9 +.Xr sx 9 .Sh HISTORY These functions appeared in diff --git a/share/man/man9/mbuf.9 b/share/man/man9/mbuf.9 index 6edbf444076..2bde56d37f8 100644 --- a/share/man/man9/mbuf.9 +++ b/share/man/man9/mbuf.9 @@ -1183,8 +1183,10 @@ slab allocation. .Sh AUTHORS The original .Nm -manual page was written by Yar Tikhiy. +manual page was written by +.An Yar Tikhiy . The .Xr uma 9 .Vt mbuf -allocator was written by Bosko Milekic. +allocator was written by +.An Bosko Milekic . diff --git a/share/man/man9/refcount.9 b/share/man/man9/refcount.9 index e7702a22661..b3c8d7f61d3 100644 --- a/share/man/man9/refcount.9 +++ b/share/man/man9/refcount.9 @@ -39,7 +39,7 @@ .In sys/param.h .In sys/refcount.h .Ft void -.Fn refcount_init "volatile u_int *count, u_int value" +.Fn refcount_init "volatile u_int *count" "u_int value" .Ft void .Fn refcount_acquire "volatile u_int *count" .Ft int diff --git a/share/man/man9/usbdi.9 b/share/man/man9/usbdi.9 index 283cda05d7e..a42626a7ccf 100644 --- a/share/man/man9/usbdi.9 +++ b/share/man/man9/usbdi.9 @@ -199,7 +199,7 @@ callback. . .Fn usbd_transfer_start This function will start the USB transfer pointed to by -.Fa xfer, +.Fa xfer , if not already started. . This function is always non-blocking and must be called with the @@ -212,7 +212,7 @@ pointer. . .Fn usbd_transfer_stop This function will stop the USB transfer pointed to by -.Fa xfer, +.Fa xfer , if not already stopped. . This function is always non-blocking and must be called with the diff --git a/share/man/man9/vm_page_busy.9 b/share/man/man9/vm_page_busy.9 index 9503dacbe8a..f4e922a8319 100644 --- a/share/man/man9/vm_page_busy.9 +++ b/share/man/man9/vm_page_busy.9 @@ -205,7 +205,6 @@ function panics if .Fa m is not exclusive busied. .Sh SEE ALSO -.Xr VOP_GETPAGES 9 , .Xr vm_page_aflag 9 , .Xr vm_page_alloc 9 , .Xr vm_page_deactivate 9 , @@ -213,4 +212,5 @@ is not exclusive busied. .Xr vm_page_grab 9 , .Xr vm_page_insert 9 , .Xr vm_page_lookup 9 , -.Xr vm_page_rename 9 +.Xr vm_page_rename 9 , +.Xr VOP_GETPAGES 9 diff --git a/share/man/man9/vnet.9 b/share/man/man9/vnet.9 index 68689eeeb84..cf7ea469783 100644 --- a/share/man/man9/vnet.9 +++ b/share/man/man9/vnet.9 @@ -100,8 +100,7 @@ .Fa "struct vnet *" .Fc .\" -.Fo CURVNET_RESTORE -.Fc +.Fn CURVNET_RESTORE .\" .Fo VNET_ITERATOR_DECL .Fa "struct vnet *" @@ -113,14 +112,10 @@ .\" ------------------------------------------------------------ .Ss "Locking" .\" -.Fo VNET_LIST_RLOCK -.Fc -.Fo VNET_LIST_RUNLOCK -.Fc -.Fo VNET_LIST_RLOCK_NOSLEEP -.Fc -.Fo VNET_LIST_RUNLOCK_NOSLEEP -.Fc +.Fn VNET_LIST_RLOCK +.Fn VNET_LIST_RUNLOCK +.Fn VNET_LIST_RLOCK_NOSLEEP +.Fn VNET_LIST_RUNLOCK_NOSLEEP .\" ------------------------------------------------------------ .Ss "Startup and Teardown Functions" .\" diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9 index 074d8ecfd8e..666db1e6501 100644 --- a/share/man/man9/vnode.9 +++ b/share/man/man9/vnode.9 @@ -158,6 +158,7 @@ interlock, will cause a LOR (Lock Order Reversal) due to the intertwining of VM Objects and Vnodes. .Sh SEE ALSO .Xr malloc 9 , +.Xr VFS 9 , .Xr VOP_ACCESS 9 , .Xr VOP_ACLCHECK 9 , .Xr VOP_ADVISE 9 , @@ -190,8 +191,7 @@ intertwining of VM Objects and Vnodes. .Xr VOP_SETEXTATTR 9 , .Xr VOP_STRATEGY 9 , .Xr VOP_VPTOCNP 9 , -.Xr VOP_VPTOFH 9 , -.Xr VFS 9 +.Xr VOP_VPTOFH 9 .Sh AUTHORS This manual page was written by .An Doug Rabson . diff --git a/share/man/man9/zone.9 b/share/man/man9/zone.9 index ed5939b0f31..2df14b022ee 100644 --- a/share/man/man9/zone.9 +++ b/share/man/man9/zone.9 @@ -337,7 +337,7 @@ macro declares a static read only oid that exports the approximate current occupancy of the zone. The .Fa zone -argument should be a pointer to +argument should be a pointer to .Vt uma_zone_t . A read of the oid returns value obtained through .Fn uma_zone_get_cur . From 0c08f785212f7afc61c2179c079c012012e9fbf4 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 11:37:00 +0000 Subject: [PATCH 052/207] tart to clean up the armv6 kernel configs by reducing the diff between them in the first sections and the later FDT support. Differential Revision: https://reviews.freebsd.org/D1346 Reviewed by: rpaulo (earlier version) --- sys/arm/conf/ARMADAXP | 94 ++++++++++++++++++++++++------------- sys/arm/conf/BEAGLEBONE | 52 +++++++++++--------- sys/arm/conf/CUBIEBOARD | 53 +++++++++++---------- sys/arm/conf/CUBIEBOARD2 | 55 ++++++++++++---------- sys/arm/conf/EFIKA_MX | 60 ++++++++++++----------- sys/arm/conf/EXYNOS5.common | 67 +++++++++++++------------- sys/arm/conf/IMX53 | 47 ++++++++++--------- sys/arm/conf/IMX6 | 57 +++++++++++----------- sys/arm/conf/PANDABOARD | 50 +++++++++++--------- sys/arm/conf/RK3188 | 63 ++++++++++++++----------- sys/arm/conf/RPI-B | 85 +++++++++++++++++++-------------- sys/arm/conf/SOCKIT | 59 ++++++++++++----------- sys/arm/conf/SOCKIT-BERI | 59 ++++++++++++----------- sys/arm/conf/VERSATILEPB | 62 ++++++++++++++---------- sys/arm/conf/VYBRID | 90 ++++++++++++++++++----------------- sys/arm/conf/ZEDBOARD | 87 +++++++++++++++++++--------------- 16 files changed, 582 insertions(+), 458 deletions(-) diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP index edfe75cc03c..ce0f0d4724e 100644 --- a/sys/arm/conf/ARMADAXP +++ b/sys/arm/conf/ARMADAXP @@ -1,8 +1,22 @@ # # Custom kernel for Marvell Armada XP # -# $FreeBSD$ +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # +# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html +# +# The handbook is also available locally in /usr/share/doc/handbook +# if you've installed the doc distribution, otherwise always see the +# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the +# latest information. +# +# An exhaustive list of options and more detailed explanations of the +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first +# in NOTES. +# +# $FreeBSD$ ident MV-88F78XX0 include "../mv/armadaxp/std.mv78x60" @@ -10,58 +24,75 @@ include "../mv/armadaxp/std.mv78x60" options SOC_MV_ARMADAXP makeoptions MODULES_OVERRIDE="" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WERROR="-Werror" +options HZ=1000 #options SCHED_ULE # ULE scheduler options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem -options NFSCL # Network Filesystem Client +options SOFTUPDATES # Enable FFS soft updates support +options UFS_ACL # Support for access control lists +options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCLIENT -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=mge0 - +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT -options ROOTDEVNAME=\"ufs:/dev/da0p1\" - +options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions -options MUTEX_NOINLINE -options RWLOCK_NOINLINE -options NO_FFS_SNAPSHOT -options NO_SWAPPING -options VFP +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -options SMP - -# Debugging -#options VERBOSE_SYSINIT +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +#options VERBOSE_SYSINIT # Enable verbose sysinit messages options ALT_BREAK_TO_DEBUGGER -options DDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger options GDB -#options DIAGNOSTIC #options INVARIANTS # Enable calls of extra sanity checking #options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -options KDB -options KDB_TRACE +#options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options WITNESS_KDB +#options DIAGNOSTIC #options KTR #options KTR_VERBOSE=0 #options KTR_ENTRIES=16384 #options KTR_MASK=(KTR_SPARE2) #options KTR_COMPILE=KTR_ALL -#options WITNESS # Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed -#options WITNESS_KDB + +# NFS root from boopt/dhcp +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=mge0 + +options ROOTDEVNAME=\"ufs:/dev/da0p1\" + +options MUTEX_NOINLINE +options RWLOCK_NOINLINE +options NO_FFS_SNAPSHOT +options NO_SWAPPING # Pseudo devices device random @@ -94,14 +125,13 @@ device mge # Marvell Gigabit Ethernet controller device mii device e1000phy device bpf -options HZ=1000 options DEVICE_POLLING device vlan #PCI/PCIE device pci -#FDT -options FDT +# Flattened Device Tree +options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=db78460.dts diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE index 03632748068..b9f2f393ced 100644 --- a/sys/arm/conf/BEAGLEBONE +++ b/sys/arm/conf/BEAGLEBONE @@ -1,10 +1,11 @@ +# # BEAGLEBONE -- Custom configuration for the BeagleBone ARM development # platforms, check out http://www.beagleboard.org/bone and # http://www.beagleboard.org/black. This kernel config file is used for the # original BeagleBone and the BeagleBone Black. # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -28,37 +29,47 @@ makeoptions WITHOUT_MODULES="ahc" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options PREEMPTION options PLATFORM -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support # Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER #options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS @@ -66,19 +77,19 @@ options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -options NFSCL +# NFS server support #options NFSD -options NFSLOCKD -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCL +# NFS root from boopt/dhcp +#options BOOTP #options BOOTP_NFSROOT #options BOOTP_COMPAT -#options BOOTP #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=cpsw0 +# Boot device is 2nd slice on MMC/SD card +options ROOTDEVNAME=\"ufs:mmcsd0s2\" + # MMC/SD/SDIO Card slot support device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards @@ -90,9 +101,6 @@ device iic device ti_i2c device am335x_pmic # AM335x Power Management IC (TPC65217) -# Boot device is 2nd slice on MMC/SD card -options ROOTDEVNAME=\"ufs:mmcsd0s2\" - # Console and misc device uart device uart_ns8250 @@ -148,6 +156,6 @@ device usb_template # Control of the gadget device usfs # Flattened Device Tree -options FDT -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=beaglebone.dts +options FDT # Configure using FDT/DTB data +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=beaglebone.dts diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD index a0b318eaf0b..9d2ca725daf 100644 --- a/sys/arm/conf/CUBIEBOARD +++ b/sys/arm/conf/CUBIEBOARD @@ -1,8 +1,9 @@ +# # CUBIEBOARD -- Custom configuration for the CUBIEBOARD ARM development # platform, check out http://www.cubieboard.org # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -27,36 +28,46 @@ makeoptions WITHOUT_MODULES="ahc" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options PREEMPTION -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER #options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS @@ -64,26 +75,20 @@ options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -#options NFSCL -#options NFSSERVER # Network Filesystem Server -#options NFSCLIENT # Network Filesystem Client - -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCLIENT +# NFS root from boopt/dhcp +#options BOOTP #options BOOTP_NFSROOT #options BOOTP_COMPAT -#options BOOTP #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=cpsw0 -# MMC/SD/SDIO card slot support -#device mmc # mmc/sd bus -#device mmcsd # mmc/sd flash cards - # Boot device is 2nd slice on MMC/SD card options ROOTDEVNAME=\"ufs:/dev/da0s2\" +# MMC/SD/SDIO Card slot support +#device mmc # mmc/sd bus +#device mmcsd # mmc/sd flash cards + # ATA controllers #device ahci # AHCI-compatible SATA controllers #device ata # Legacy ATA/SATA controllers @@ -134,7 +139,7 @@ device emac device miibus # Flattened Device Tree -options FDT +options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=cubieboard.dts diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2 index e971e8d6b53..e429f8cfef9 100644 --- a/sys/arm/conf/CUBIEBOARD2 +++ b/sys/arm/conf/CUBIEBOARD2 @@ -1,8 +1,9 @@ +# # CUBIEBOARD2 -- Custom configuration for the CUBIEBOARD2 ARM development # platform, check out http://www.cubieboard.org # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -27,36 +28,47 @@ makeoptions WITHOUT_MODULES="ahc" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options PREEMPTION -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER #options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS @@ -64,26 +76,20 @@ options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -#options NFSCL -#options NFSSERVER # Network Filesystem Server -#options NFSCLIENT # Network Filesystem Client - -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCLIENT +# NFS root from boopt/dhcp +#options BOOTP #options BOOTP_NFSROOT #options BOOTP_COMPAT -#options BOOTP #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=cpsw0 -# MMC/SD/SDIO card slot support -#device mmc # mmc/sd bus -#device mmcsd # mmc/sd flash cards - # Boot device is 2nd slice on MMC/SD card options ROOTDEVNAME=\"ufs:/dev/da0s2\" +# MMC/SD/SDIO Card slot support +#device mmc # mmc/sd bus +#device mmcsd # mmc/sd flash cards + # ATA controllers #device ahci # AHCI-compatible SATA controllers #device ata # Legacy ATA/SATA controllers @@ -134,8 +140,7 @@ device emac device miibus # Flattened Device Tree -options FDT +options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=cubieboard2.dts -options SMP # Enable multiple cores diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index 677d73d9edc..f4531f25019 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -1,3 +1,4 @@ +# # Kernel configuration for Efika MX Smarttop/Smartbook boards # # For more information on this file, please read the config(5) manual page, @@ -23,32 +24,30 @@ include "../freescale/imx/std.imx51" makeoptions WITHOUT_MODULES="ahc" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols -#options DEBUG - options SCHED_4BSD # 4BSD scheduler -#options PREEMPTION # Enable kernel thread preemption +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking -#options INET6 # IPv6 communications protocols -#options SCTP # Stream Control Transmission Protocol +options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS #options MD_ROOT # MD is a potential root device options NFSCL # New Network Filesystem Client #options NFSD # New Network Filesystem Server options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL -options TMPFS # Efficient memory filesystem options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem -#options PROCFS # Process filesystem (requires PSEUDOFS) +options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID Partition Tables. options GEOM_LABEL # Provides labelization #options COMPAT_FREEBSD5 # Compatible with FreeBSD5 #options COMPAT_FREEBSD6 # Compatible with FreeBSD6 @@ -59,16 +58,33 @@ options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev options INCLUDE_CONFIG_FILE # Include this file in kernel -options VFP # vfp/neon +options VFP # Enable floating point hardware support -# required for netbooting +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options BREAK_TO_DEBUGGER +#options VERBOSE_SYSINIT # Enable verbose sysinit messages +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger +#options GDB # Support remote GDB +options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed + +# NFS root from boopt/dhcp #options BOOTP -#options BOOTP_COMPAT #options BOOTP_NFSROOT +#options BOOTP_COMPAT #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=ue0 -# + options ROOTDEVNAME=\"ufs:ada0s2a\" @@ -79,18 +95,6 @@ options ROOTDEVNAME=\"ufs:ada0s2a\" #options NO_SYSCTL_DESCR #options RWLOCK_NOINLINE -# Debugging support. Always need this: -options KDB # Enable kernel debugger support. -# For minimum debugger support (stable branch) use: -#options KDB_TRACE # Print a stack trace for a panic. -# For full debugger support use this instead: -options DDB # Support DDB. -#options GDB # Support remote GDB. -options DEADLKRES # Enable the deadlock resolver -options INVARIANTS # Enable calls of extra sanity checking -options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -options WITNESS # Enable checks to detect deadlocks and cycles - # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! # Note that 'bpf' is required for DHCP. @@ -162,9 +166,9 @@ device wlan_tkip # 802.11 TKIP support device wlan_amrr # AMRR transmit rate control algorithm # Flattened Device Tree -options FDT -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=efikamx.dts +options FDT # Configure using FDT/DTB data +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=efikamx.dts # NOTE: serial console will be disabled if syscons enabled # Uncomment following lines for framebuffer/syscons support diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index 7cd577d02c6..f4cd3b50ee6 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -1,3 +1,4 @@ +# # Kernel configuration for Samsung Exynos 5 SoC. # # For more information on this file, please read the config(5) manual page, @@ -20,70 +21,72 @@ makeoptions MODULES_OVERRIDE="" makeoptions WITHOUT_MODULES="ahc" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WERROR="-Werror" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID partition tables -options TMPFS # Efficient memory filesystem +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem -options SOFTUPDATES +options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI -options KTRACE +options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions -options KBD_INSTALL_CDEV -options PREEMPTION -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -options SMP - -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER -#options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +#options VERBOSE_SYSINIT # Enable verbose sysinit messages +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger #options INVARIANTS # Enable calls of extra sanity checking #options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS # Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -options NFSCL # Network Filesystem Client -options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCLIENT +# NFS root from boopt/dhcp +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ue0 -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCL -#options BOOTP_NFSROOT -#options BOOTP_COMPAT -#options BOOTP -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ue0 +options ROOTDEVNAME=\"ufs:/dev/da0\" +# MMC/SD/SDIO Card slot support device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards device dwmmc -options ROOTDEVNAME=\"ufs:/dev/da0\" - # Pseudo devices device loop diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index 5fd56979fbf..9a3326cc6e2 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -1,3 +1,4 @@ +# # Kernel configuration for i.MX53 boards # # For more information on this file, please read the config(5) manual page, @@ -21,32 +22,29 @@ ident IMX53 include "../freescale/imx/std.imx53" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols -#options DEBUG - options SCHED_4BSD # 4BSD scheduler -#options PREEMPTION # Enable kernel thread preemption +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols -#options SCTP # Stream Control Transmission Protocol +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling -#options MD_ROOT # MD is a potential root device +options QUOTA # Enable disk quotas for UFS options NFSCL # New Network Filesystem Client #options NFSD # New Network Filesystem Server options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL -options TMPFS # Efficient memory filesystem options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem -#options PROCFS # Process filesystem (requires PSEUDOFS) +options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID Partition Tables. options GEOM_LABEL # Provides labelization #options COMPAT_FREEBSD5 # Compatible with FreeBSD5 #options COMPAT_FREEBSD6 # Compatible with FreeBSD6 @@ -57,8 +55,23 @@ options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev options INCLUDE_CONFIG_FILE # Include this file in kernel -options VFP # vfp/neon +options VFP # Enable floating point hardware support + +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger +#options GDB # Support remote GDB +options DEADLKRES # Enable the deadlock resolver +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed # kernel/memory size reduction #options MUTEX_NOINLINE @@ -67,18 +80,6 @@ options VFP # vfp/neon #options NO_SYSCTL_DESCR #options RWLOCK_NOINLINE -# Debugging support. Always need this: -options KDB # Enable kernel debugger support. -# For minimum debugger support (stable branch) use: -#options KDB_TRACE # Print a stack trace for a panic. -# For full debugger support use this instead: -options DDB # Support DDB. -#options GDB # Support remote GDB. -options DEADLKRES # Enable the deadlock resolver -options INVARIANTS # Enable calls of extra sanity checking -options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -options WITNESS # Enable checks to detect deadlocks and cycles - # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! # Note that 'bpf' is required for DHCP. @@ -161,7 +162,7 @@ device wlan_amrr # AMRR transmit rate control algorithm # Flattened Device Tree -options FDT +options FDT # Configure using FDT/DTB data # NOTE: serial console will be disabled if syscons enabled # Uncomment following lines for framebuffer/syscons support diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 35e6053b4a8..fe3dab398a0 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -1,3 +1,4 @@ +# # Kernel configuration for Freescale i.MX6 systems. # # For more information on this file, please read the config(5) manual page, @@ -20,7 +21,7 @@ ident IMX6 include "../freescale/imx/std.imx6" -options HZ=500 # Scheduling quantum is 2 milliseconds. +options HZ=500 # Scheduling quantum is 2 milliseconds. options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking @@ -31,42 +32,57 @@ options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories options UFS_GJOURNAL # Enable gjournal-based UFS journaling -#options MD_ROOT # MD is a potential root device +options QUOTA # Enable disk quotas for UFS options NFSCL # New Network Filesystem Client #options NFSD # New Network Filesystem Server options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL -options TMPFS # Efficient memory filesystem options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem -#options PROCFS # Process filesystem (requires PSEUDOFS) +options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID Partition Tables. options GEOM_LABEL # Provides labelization options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev options INCLUDE_CONFIG_FILE # Include this file in kernel +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -# Debugging support. Always need this: -options KDB # Enable kernel debugger support. -# For minimum debugger support use KDB_TRACE, for interactive use DDB. -#options KDB_TRACE # Print a stack trace for a panic. -options DDB # Support DDB. +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic # For full debugger support use this instead: +options DDB # Enable the kernel debugger #options GDB # Support remote GDB. # Other debugging options... -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options ALT_BREAK_TO_DEBUGGER # Use to enter debugger. -#options DEBUG #options DEADLKRES # Enable the deadlock resolver #options INVARIANTS # Enable calls of extra sanity checking #options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS #options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options DIAGNOSTIC + +# NFS root from boopt/dhcp +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ffec0 + +# U-Boot stuff lives on slice 1, FreeBSD on slice 2. +options ROOTDEVNAME=\"ufs:mmcsd0s2a\" # Pseudo devices. device loop # Network loopback @@ -134,21 +150,8 @@ device u3g # USB modems #options SC_DFLT_FONT # compile font in #makeoptions SC_DFLT_FONT=cp437 -# required for netbooting -#options BOOTP -#options BOOTP_COMPAT -#options BOOTP_NFSROOT -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ffec0 - -# U-Boot stuff lives on slice 1, FreeBSD on slice 2. -options ROOTDEVNAME=\"ufs:mmcsd0s2a\" - -# ARM and SoC-specific options -options FDT # Configure using FDT/DTB data. -options SMP # Enable multiple cores -options VFP # Enable floating point hardware support -options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +# Flattened Device Tree +options FDT # Configure using FDT/DTB data # SoC-specific devices device ffec # Freescale Fast Ethernet Controller diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD index cc345cb4580..7a71d12ff86 100644 --- a/sys/arm/conf/PANDABOARD +++ b/sys/arm/conf/PANDABOARD @@ -1,8 +1,9 @@ +# # PANDABOARD -- Custom configuration for the PandaBoard ARM development # platform, check out www.pandaboard.org # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -28,44 +29,53 @@ hints "PANDABOARD.hints" include "../ti/omap4/pandaboard/std.pandaboard" -#To statically compile in device wiring instead of /boot/device.hints makeoptions MODULES_OVERRIDE="" -makeoptions WITHOUT_MODULES="ahc" +makeoptions WITHOUT_MODULES="ahc" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options PREEMPTION options PLATFORM -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon -options SMP # Enable multiple cores +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores # Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER #options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger #options INVARIANTS # Enable calls of extra sanity checking #options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS @@ -73,14 +83,10 @@ options DDB # Enable the kernel debugger #options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -options NFSCL - -# NFS root -options NFS_ROOT # NFS usable as /, requires NFSCLIENT +# NFS root from boopt/dhcp +#options BOOTP #options BOOTP_NFSROOT #options BOOTP_COMPAT -#options BOOTP #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=ue0 @@ -146,6 +152,6 @@ device twl_vreg device twl_clks # Flattened Device Tree -options FDT -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=pandaboard.dts +options FDT # Configure using FDT/DTB data +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=pandaboard.dts diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188 index d6a26ddf196..cdf965f7ed2 100644 --- a/sys/arm/conf/RK3188 +++ b/sys/arm/conf/RK3188 @@ -1,7 +1,8 @@ +# # Kernel configuration for Rockchip RK3188 systems. # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -23,56 +24,61 @@ include "../rockchip/std.rk30xx" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options PREEMPTION -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon -options SMP # Enable multiple cores +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER -#options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +#options VERBOSE_SYSINIT # Enable verbose sysinit messages +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger -#options INVARIANTS # Enable calls of extra sanity checking -#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +#options INVARIANTS # Enable calls of extra sanity checking +#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed options DIAGNOSTIC -# NFS support -#options NFSCL -#options NFSSERVER # Network Filesystem Server -#options NFSCLIENT # Network Filesystem Client - -# MMC/SD/SDIO card slot support -#device mmc # mmc/sd bus -#device mmcsd # mmc/sd flash cards - # Boot device is 2nd slice on USB options ROOTDEVNAME=\"ufs:/dev/da0s2\" +# MMC/SD/SDIO Card slot support +#device mmc # mmc/sd bus +#device mmcsd # mmc/sd flash cards + # Console and misc device uart device uart_ns8250 @@ -96,8 +102,8 @@ device pass options USB_HOST_ALIGN=32 # Align usb buffers to cache line size. device usb options USB_DEBUG -#options USB_REQ_DEBUG -#options USB_VERBOSE +#options USB_REQ_DEBUG +#options USB_VERBOSE device dwcotg # DWC OTG controller device umass @@ -121,8 +127,9 @@ device urtwn device urtwnfw device firmware # Used by the above -# USB ethernet support, requires miibus +# USB Ethernet support, requires miibus device miibus device udav -options FDT # Configure using FDT/DTB data. +# Flattened Device Tree +options FDT # Configure using FDT/DTB data diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B index 322a4ecf83f..c1013d1fe5f 100644 --- a/sys/arm/conf/RPI-B +++ b/sys/arm/conf/RPI-B @@ -1,7 +1,8 @@ +# # RPI-B -- Custom configuration for the Raspberry Pi # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -11,8 +12,8 @@ # latest information. # # An exhaustive list of options and more detailed explanations of the -# device lines is also present in the ../../conf/NOTES and NOTES files. -# If you are in doubt as to the purpose or necessity of a line, check first +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ @@ -21,10 +22,9 @@ ident RPI-B include "../broadcom/bcm2835/std.rpi" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options HZ=100 - options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols options SCTP # Stream Control Transmission Protocol @@ -32,42 +32,62 @@ options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem -options MSDOSFS # MSDOS Filesystem -device snp - -options NFSCL # Network Filesystem Client - -#options NFS_ROOT # NFS usable as /, requires NFSCLIENT -#options BOOTP_NFSROOT -#options BOOTP_COMPAT -#options BOOTP -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ue0 - -options PSEUDOFS # Pseudo-filesystem framework options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -#options ROOTDEVNAME=\"ufs:mmcsd0s2\" - -options PREEMPTION options PLATFORM +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support + +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options BREAK_TO_DEBUGGER +#options VERBOSE_SYSINIT # Enable verbose sysinit messages +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options DIAGNOSTIC + +# NFS root from boopt/dhcp +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ue0 + +#options ROOTDEVNAME=\"ufs:mmcsd0s2\" device bpf device loop device ether device uart -device pl011 - device pty +device snp +device pl011 # Comment following lines for boot console on serial port device vt @@ -86,11 +106,6 @@ device iic device iicbus device bcm2835_bsc -options KDB -options DDB # Enable the kernel debugger -options INVARIANTS # Enable calls of extra sanity checking -options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS - device md device random # Entropy device @@ -114,10 +129,8 @@ device spibus device bcm2835_spi # Flattened Device Tree -options FDT +options FDT # Configure using FDT/DTB data # Note: DTB is normally loaded and modified by RPi boot loader, then # handed to kernel via U-Boot and ubldr. -#options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=rpi.dts - -options VFP # vfp/neon +#options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=rpi.dts diff --git a/sys/arm/conf/SOCKIT b/sys/arm/conf/SOCKIT index 5a9ade58d2c..744559af0c9 100644 --- a/sys/arm/conf/SOCKIT +++ b/sys/arm/conf/SOCKIT @@ -1,3 +1,4 @@ +# # Kernel configuration for Terasic SoCKit (Altera Cyclone V SoC). # # For more information on this file, please read the config(5) manual page, @@ -22,44 +23,51 @@ include "../altera/socfpga/std.socfpga" makeoptions MODULES_OVERRIDE="" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WERROR="-Werror" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID partition tables -options TMPFS # Efficient memory filesystem +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem -options SOFTUPDATES +options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI -options KTRACE +options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions -options KBD_INSTALL_CDEV -options PREEMPTION -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -options SMP - -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER #options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS @@ -67,25 +75,20 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require #options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -options NFSCL # Network Filesystem Client -options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCLIENT - -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCL +# NFS root from boopt/dhcp +#options BOOTP #options BOOTP_NFSROOT #options BOOTP_COMPAT -#options BOOTP #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=ue0 +options ROOTDEVNAME=\"ufs:/dev/da0\" + +# MMC/SD/SDIO Card slot support device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards device dwmmc -options ROOTDEVNAME=\"ufs:/dev/da0\" - # Pseudo devices device loop @@ -132,7 +135,7 @@ device miibus device axe # ASIX Electronics USB Ethernet device bpf # Berkeley packet filter -#FDT -options FDT +# Flattened Device Tree +options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=socfpga-sockit.dts diff --git a/sys/arm/conf/SOCKIT-BERI b/sys/arm/conf/SOCKIT-BERI index 76306def5d1..918da538c4f 100644 --- a/sys/arm/conf/SOCKIT-BERI +++ b/sys/arm/conf/SOCKIT-BERI @@ -1,3 +1,4 @@ +# # Kernel configuration for Terasic SoCKit (Altera Cyclone V SoC). # # For more information on this file, please read the config(5) manual page, @@ -22,44 +23,51 @@ include "../altera/socfpga/std.socfpga" makeoptions MODULES_OVERRIDE="" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WERROR="-Werror" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options GEOM_PART_GPT # GUID partition tables -options TMPFS # Efficient memory filesystem +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem -options SOFTUPDATES +options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI -options KTRACE +options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions -options KBD_INSTALL_CDEV -options PREEMPTION -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -options SMP - -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER #options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger options INVARIANTS # Enable calls of extra sanity checking options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS @@ -67,25 +75,20 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require #options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC -# NFS support -options NFSCL # Network Filesystem Client -options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCLIENT - -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCL +# NFS root from boopt/dhcp +#options BOOTP #options BOOTP_NFSROOT #options BOOTP_COMPAT -#options BOOTP #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=ue0 +options ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\" + +# MMC/SD/SDIO Card slot support device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards device dwmmc -options ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\" - # Pseudo devices device loop @@ -139,7 +142,7 @@ device miibus device axe # ASIX Electronics USB Ethernet device bpf # Berkeley packet filter -#FDT -options FDT +# Flattened Device Tree +options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=socfpga-sockit-beri.dts diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB index fb2087a83f6..8430133c206 100644 --- a/sys/arm/conf/VERSATILEPB +++ b/sys/arm/conf/VERSATILEPB @@ -1,7 +1,8 @@ +# # VERSATILEPB - Configuration for QEMU version of Versatile Platform Board # -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # @@ -11,8 +12,8 @@ # latest information. # # An exhaustive list of options and more detailed explanations of the -# device lines is also present in the ../../conf/NOTES and NOTES files. -# If you are in doubt as to the purpose or necessity of a line, check first +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ @@ -29,36 +30,53 @@ makeoptions KERNVIRTADDR=0xc0100000 options KERNPHYSADDR=0x00100000 makeoptions KERNPHYSADDR=0x00100000 options PHYSADDR=0x00000000 -options FREEBSD_BOOT_LOADER -options LINUX_BOOT_ABI -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options HZ=100 - options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking +options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -device snp - +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL +options MSDOSFS # MSDOS Filesystem +options CD9660 # ISO 9660 Filesystem +options PROCFS # Process filesystem (requires PSEUDOFS) +options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem -options PSEUDOFS # Pseudo-filesystem framework options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options ROOTDEVNAME=\"ufs:da0s1a\" -options VFP # vfp/neon +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options LINUX_BOOT_ABI # Process metadata passed from Linux boot loaders +options VFP # Enable floating point hardware support -options PREEMPTION +# Debugging for use in -current +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger +options INVARIANTS # Enable calls of extra sanity checking +options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS + +options ROOTDEVNAME=\"ufs:da0s1a\" device bpf device loop @@ -72,6 +90,7 @@ device pl011 device pl190 device pty +device snp device pci @@ -90,15 +109,10 @@ device kbdmux options SC_DFLT_FONT # compile font in makeoptions SC_DFLT_FONT=cp437 -options KDB -options DDB # Enable the kernel debugger -options INVARIANTS # Enable calls of extra sanity checking -options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS - device md device random # Entropy device # Flattened Device Tree -options FDT -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=versatilepb.dts +options FDT # Configure using FDT/DTB data +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=versatilepb.dts diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID index e2e1defa4ec..bf2c2c4bb38 100644 --- a/sys/arm/conf/VYBRID +++ b/sys/arm/conf/VYBRID @@ -1,3 +1,4 @@ +# # Kernel configuration for Vybrid Family boards. # # For more information on this file, please read the config(5) manual page, @@ -23,75 +24,79 @@ include "../freescale/vybrid/std.vybrid" makeoptions MODULES_OVERRIDE="" makeoptions WITHOUT_MODULES="ahc" -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols makeoptions WERROR="-Werror" options HZ=100 options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem -options SOFTUPDATES +options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem +#options NANDFS # NAND Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework -#options NANDFS # NAND Filesystem +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!] options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI -options KTRACE +options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions -options KBD_INSTALL_CDEV -options PREEMPTION -options FREEBSD_BOOT_LOADER -options MUTEX_NOINLINE -options RWLOCK_NOINLINE -options NO_FFS_SNAPSHOT -options NO_SWAPPING -options VFP # vfp/neon +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +#options SMP # Enable multiple cores -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER -#options VERBOSE_SYSINIT # Enable verbose sysinit messages -options KDB +#options VERBOSE_SYSINIT # Enable verbose sysinit messages +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: options DDB # Enable the kernel debugger -#options INVARIANTS # Enable calls of extra sanity checking -#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -#options WITNESS # Enable checks to detect deadlocks and cycles -#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed -#options DIAGNOSTIC +#options INVARIANTS # Enable calls of extra sanity checking +#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options DIAGNOSTIC -# NFS support -options NFSCL # Network Filesystem Client -options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCLIENT - -# Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCL -#options BOOTP_NFSROOT -#options BOOTP_COMPAT -#options BOOTP -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ffec0 - -device mmc # mmc/sd bus -device mmcsd # mmc/sd flash cards -device sdhci # generic sdhci +# NFS root from boopt/dhcp +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ffec0 #options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/cosmic\" #options ROOTDEVNAME=\"nandfs:/dev/gnand0s.root\" options ROOTDEVNAME=\"ufs:/dev/da0\" -#options SMP +options MUTEX_NOINLINE +options RWLOCK_NOINLINE +options NO_FFS_SNAPSHOT +options NO_SWAPPING + +# MMC/SD/SDIO Card slot support +device mmc # mmc/sd bus +device mmcsd # mmc/sd flash cards +device sdhci # generic sdhci # Pseudo devices @@ -150,4 +155,5 @@ device vt device kbdmux device ukbd -options FDT +# Flattened Device Tree +options FDT # Configure using FDT/DTB data diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD index 8ec0df1fe6a..e1200bfd5fc 100644 --- a/sys/arm/conf/ZEDBOARD +++ b/sys/arm/conf/ZEDBOARD @@ -1,73 +1,86 @@ +# # ZEDBOARD -- Custom configuration for the Xilinx Zynq-7000 based # ZedBoard (www.zedboard.org) -# -# For more information on this file, please read the handbook section on -# Kernel Configuration Files: -# +# +# For more information on this file, please read the config(5) manual page, +# and/or the handbook section on Kernel Configuration Files: +# # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html -# +# # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the # latest information. -# +# # An exhaustive list of options and more detailed explanations of the -# device lines is also present in the ../../conf/NOTES and NOTES files. -# If you are in doubt as to the purpose or necessity of a line, check first +# device lines is also present in the ../../conf/NOTES and NOTES files. +# If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. -# +# # $FreeBSD$ ident ZEDBOARD -include "../xilinx/zedboard/std.zedboard" +include "../xilinx/zedboard/std.zedboard" makeoptions MODULES_OVERRIDE="" makeoptions WITHOUT_MODULES="ahc" options SCHED_4BSD # 4BSD scheduler +options PREEMPTION # Enable kernel thread preemption options INET # InterNETworking options INET6 # IPv6 communications protocols +options SCTP # Stream Control Transmission Protocol options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options UFS_ACL # Support for access control lists options UFS_DIRHASH # Improve performance on big directories -# options ROOTDEVNAME=\"ufs:mmcsd0s2a\" - -options NFSCL # Network Filesystem Client -# options NFSSD # Network Filesystem Server -# options NFSLOCKD # Network Lock Manager -# options NFS_ROOT # NFS usable as /, requires NFSCL -# options BOOTP_NFSROOT -# options BOOTP - -options GEOM_PART_BSD # BSD partition scheme -options GEOM_PART_MBR # MBR partition scheme -options TMPFS # Efficient memory filesystem +options UFS_GJOURNAL # Enable gjournal-based UFS journaling +options QUOTA # Enable disk quotas for UFS +options NFSCL # New Network Filesystem Client +#options NFSSD # Network Filesystem Server +options NFSLOCKD # Network Lock Manager +options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework +options TMPFS # Efficient memory filesystem +options GEOM_PART_GPT # GUID Partition Tables +options GEOM_PART_BSD # BSD partition scheme +options GEOM_PART_MBR # MBR partition scheme options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support options SYSVSHM # SYSV-style shared memory options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores -options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions -options FREEBSD_BOOT_LOADER -options VFP # vfp/neon -options SMP # Symmetric MultiProcessor Kernel +options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions +options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) +options VFP # Enable floating point hardware support +options SMP # Enable multiple cores -# Debugging +# Debugging for use in -current makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols -options DDB -options KDB -# options BREAK_TO_DEBUGGER +#options BREAK_TO_DEBUGGER +options KDB # Enable kernel debugger support +# For minimum debugger support (stable branch) use: +#options KDB_TRACE # Print a stack trace for a panic +# For full debugger support use this instead: +options DDB # Enable the kernel debugger +#options INVARIANTS # Enable calls of extra sanity checking +#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS +#options WITNESS # Enable checks to detect deadlocks and cycles +#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options DIAGNOSTIC -# options INVARIANTS # Enable calls of extra sanity checking -# options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS -# options WITNESS # Enable checks to detect deadlocks and cycles -# options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +# NFS root from boopt/dhcp +#options BOOTP +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP_NFSV3 + +options ROOTDEVNAME=\"ufs:mmcsd0s2a\" device loop device random @@ -98,7 +111,7 @@ device axe # USB-Ethernet # Flattened Device Tree -options FDT -# options FDT_DTB_STATIC -# makeoptions FDT_DTS_FILE=zedboard.dts +options FDT # Configure using FDT/DTB data +#options FDT_DTB_STATIC +#makeoptions FDT_DTS_FILE=zedboard.dts From afa6f59ccad425012e288f5b23437efad91348e3 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 11:55:40 +0000 Subject: [PATCH 053/207] Fix the indentation to simplify comparing the ARM config files. --- sys/arm/conf/APALIS-IMX6 | 6 +- sys/arm/conf/BEAGLEBONE | 2 +- sys/arm/conf/CHROMEBOOK-PEACH-PIT | 18 +++--- sys/arm/conf/CNS11XXNAS | 6 +- sys/arm/conf/CUBIEBOARD | 2 +- sys/arm/conf/CUBIEBOARD2 | 2 +- sys/arm/conf/DIGI-CCWMX53 | 6 +- sys/arm/conf/DOCKSTAR | 92 ++++++++++++++--------------- sys/arm/conf/DREAMPLUG-1001 | 96 +++++++++++++++---------------- sys/arm/conf/EFIKA_MX | 6 +- sys/arm/conf/EXYNOS5.common | 4 +- sys/arm/conf/HL201 | 2 +- sys/arm/conf/IMX53 | 4 +- sys/arm/conf/IMX53-QSB | 4 +- sys/arm/conf/IMX6 | 2 +- sys/arm/conf/RK3188 | 8 +-- sys/arm/conf/SAM9260EK | 2 +- sys/arm/conf/VERSATILEPB | 4 +- sys/arm/conf/VYBRID | 4 +- sys/arm/conf/WANDBOARD-DUAL | 4 +- sys/arm/conf/WANDBOARD-QUAD | 4 +- sys/arm/conf/WANDBOARD-SOLO | 4 +- 22 files changed, 141 insertions(+), 141 deletions(-) diff --git a/sys/arm/conf/APALIS-IMX6 b/sys/arm/conf/APALIS-IMX6 index 137677f1b40..ceb21c7f4ab 100644 --- a/sys/arm/conf/APALIS-IMX6 +++ b/sys/arm/conf/APALIS-IMX6 @@ -26,6 +26,6 @@ makeoptions MODULES_OVERRIDE="" makeoptions WITHOUT_MODULES="ahc" # Flattened Device Tree -options FDT -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=apalis-imx6.dts +options FDT +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=apalis-imx6.dts diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE index b9f2f393ced..6f7e53e9c77 100644 --- a/sys/arm/conf/BEAGLEBONE +++ b/sys/arm/conf/BEAGLEBONE @@ -78,7 +78,7 @@ options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed #options DIAGNOSTIC # NFS server support -#options NFSD +#options NFSD # NFS root from boopt/dhcp #options BOOTP diff --git a/sys/arm/conf/CHROMEBOOK-PEACH-PIT b/sys/arm/conf/CHROMEBOOK-PEACH-PIT index 7bcfed7ed01..e01128c9977 100644 --- a/sys/arm/conf/CHROMEBOOK-PEACH-PIT +++ b/sys/arm/conf/CHROMEBOOK-PEACH-PIT @@ -33,15 +33,15 @@ device kbdmux device ukbd # Uncomment this for NFS root -#options NFS_ROOT # NFS usable as /, requires NFSCL -#options BOOTP_NFSROOT -#options BOOTP_COMPAT -#options BOOTP -#options BOOTP_NFSV3 -#options BOOTP_WIRED_TO=ue0 -#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/root\" +#options NFS_ROOT # NFS usable as /, requires NFSCL +#options BOOTP_NFSROOT +#options BOOTP_COMPAT +#options BOOTP +#options BOOTP_NFSV3 +#options BOOTP_WIRED_TO=ue0 +#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/root\" #FDT -options FDT -options FDT_DTB_STATIC +options FDT +options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=exynos5420-peach-pit.dts diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS index 53640ffe0ac..903fd0589fa 100644 --- a/sys/arm/conf/CNS11XXNAS +++ b/sys/arm/conf/CNS11XXNAS @@ -103,7 +103,7 @@ device bpf device loop device md -device random # Entropy device +device random # Entropy device device usb @@ -114,12 +114,12 @@ device umass device scbus # SCSI bus (required for ATA/SCSI) device da # Direct Access (disks) device pass -device cfi +device cfi #device udav # Davicom DM9601E USB device geom_label device geom_journal -device geom_part_bsd +device geom_part_bsd options ROOTDEVNAME=\"ufs:da0s1a\" diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD index 9d2ca725daf..40fe31305bd 100644 --- a/sys/arm/conf/CUBIEBOARD +++ b/sys/arm/conf/CUBIEBOARD @@ -92,7 +92,7 @@ options ROOTDEVNAME=\"ufs:/dev/da0s2\" # ATA controllers #device ahci # AHCI-compatible SATA controllers #device ata # Legacy ATA/SATA controllers -#options ATA_STATIC_ID # Static device numbering +#options ATA_STATIC_ID # Static device numbering # Console and misc device uart diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2 index e429f8cfef9..785364cad42 100644 --- a/sys/arm/conf/CUBIEBOARD2 +++ b/sys/arm/conf/CUBIEBOARD2 @@ -93,7 +93,7 @@ options ROOTDEVNAME=\"ufs:/dev/da0s2\" # ATA controllers #device ahci # AHCI-compatible SATA controllers #device ata # Legacy ATA/SATA controllers -#options ATA_STATIC_ID # Static device numbering +#options ATA_STATIC_ID # Static device numbering # Console and misc device uart diff --git a/sys/arm/conf/DIGI-CCWMX53 b/sys/arm/conf/DIGI-CCWMX53 index 77565588022..20dec9c0f53 100644 --- a/sys/arm/conf/DIGI-CCWMX53 +++ b/sys/arm/conf/DIGI-CCWMX53 @@ -22,7 +22,7 @@ include "IMX53" ident DIGI-CCWMX53 -makeoptions WITHOUT_MODULES="ahc" +makeoptions WITHOUT_MODULES="ahc" # required for netbooting #options BOOTP @@ -34,5 +34,5 @@ makeoptions WITHOUT_MODULES="ahc" #options ROOTDEVNAME=\"ufs:ada0s2a\" # Flattened Device Tree -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=digi-ccwmx53.dts +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=digi-ccwmx53.dts diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index a3c57a12177..73a0811f557 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -54,15 +54,15 @@ options FDT_DTB_STATIC # Misc pseudo devices device bpf # Required for DHCP -device firmware # firmware(9) required for USB wlan -device gif # IPv6 and IPv4 tunneling +device firmware # firmware(9) required for USB wlan +device gif # IPv6 and IPv4 tunneling device loop # Network loopback -device md # Memory/malloc disk +device md # Memory/malloc disk device pty # BSD-style compatibility pseudo ttys device random # Entropy device -device tun # Packet tunnel. +device tun # Packet tunnel. device ether # Required for all ethernet devices -device vlan # 802.1Q VLAN support +device vlan # 802.1Q VLAN support device wlan # 802.11 WLAN support # cam support for umass and ahci @@ -80,66 +80,66 @@ device e1000phy # USB options USB_HOST_ALIGN=32 # Align DMA to cacheline -#options USB_DEBUG # Compile in USB debug support -device usb # Basic usb support -device ehci # USB host controller -device umass # Mass storage -device uhid # Human-interface devices -device rum # Ralink Technology RT2501USB wireless NICs -device uath # Atheros AR5523 wireless NICs -device ural # Ralink Technology RT2500USB wireless NICs -device zyd # ZyDAS zb1211/zb1211b wireless NICs -device urtw # Realtek RTL8187B/L USB -device upgt # Conexant/Intersil PrismGT SoftMAC USB -device u3g # USB-based 3G modems (Option, Huawei, Sierra) +#options USB_DEBUG # Compile in USB debug support +device usb # Basic usb support +device ehci # USB host controller +device umass # Mass storage +device uhid # Human-interface devices +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs +device urtw # Realtek RTL8187B/L USB +device upgt # Conexant/Intersil PrismGT SoftMAC USB +device u3g # USB-based 3G modems (Option, Huawei, Sierra) # I2C (TWSI) device iic device iicbus # Sound -device sound -device snd_uaudio +device sound +device snd_uaudio #crypto -device cesa # Marvell security engine -device crypto -device cryptodev +device cesa # Marvell security engine +device crypto +device cryptodev # IPSec -device enc -options IPSEC -options IPSEC_NAT_T -options TCP_SIGNATURE # include support for RFC 2385 +device enc +options IPSEC +options IPSEC_NAT_T +options TCP_SIGNATURE # include support for RFC 2385 # IPFW -options IPFIREWALL -options IPFIREWALL_DEFAULT_TO_ACCEPT -options IPFIREWALL_VERBOSE -options IPFIREWALL_VERBOSE_LIMIT=100 -options IPFIREWALL_NAT -options LIBALIAS -options DUMMYNET -options IPDIVERT +options IPFIREWALL +options IPFIREWALL_DEFAULT_TO_ACCEPT +options IPFIREWALL_VERBOSE +options IPFIREWALL_VERBOSE_LIMIT=100 +options IPFIREWALL_NAT +options LIBALIAS +options DUMMYNET +options IPDIVERT #PF -device pf -device pflog -device pfsync +device pf +device pflog +device pfsync # ALTQ, required for PF -options ALTQ # Basic ALTQ support -options ALTQ_CBQ # Class Based Queueing -options ALTQ_RED # Random Early Detection -options ALTQ_RIO # RED In/Out -options ALTQ_HFSC # Hierarchical Packet Scheduler -options ALTQ_CDNR # Traffic conditioner -options ALTQ_PRIQ # Priority Queueing -options ALTQ_NOPCC # Required if the TSC is unusable +options ALTQ # Basic ALTQ support +options ALTQ_CBQ # Class Based Queueing +options ALTQ_RED # Random Early Detection +options ALTQ_RIO # RED In/Out +options ALTQ_HFSC # Hierarchical Packet Scheduler +options ALTQ_CDNR # Traffic conditioner +options ALTQ_PRIQ # Priority Queueing +options ALTQ_NOPCC # Required if the TSC is unusable #options ALTQ_DEBUG # Debugging -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER options ALT_BREAK_TO_DEBUGGER options DDB diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index 73695929947..5b5b002880f 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -57,22 +57,22 @@ options FDT_DTB_STATIC # Misc pseudo devices device bpf # Required for DHCP -device firmware # firmware(9) required for USB wlan -device gif # IPv6 and IPv4 tunneling +device firmware # firmware(9) required for USB wlan +device gif # IPv6 and IPv4 tunneling device loop # Network loopback -device md # Memory/malloc disk +device md # Memory/malloc disk device pty # BSD-style compatibility pseudo ttys device random # Entropy device -device tun # Packet tunnel. +device tun # Packet tunnel. device ether # Required for all ethernet devices -device vlan # 802.1Q VLAN support +device vlan # 802.1Q VLAN support device wlan # 802.11 WLAN support # cam support for umass and ahci device scbus device pass device da -device cd +device cd # Serial ports device uart @@ -84,18 +84,18 @@ device e1000phy # USB options USB_HOST_ALIGN=32 # Align DMA to cacheline -#options USB_DEBUG # Compile in USB debug support -device usb # Basic usb support -device ehci # USB host controller -device umass # Mass storage -device uhid # Human-interface devices -device rum # Ralink Technology RT2501USB wireless NICs -device uath # Atheros AR5523 wireless NICs -device ural # Ralink Technology RT2500USB wireless NICs -device zyd # ZyDAS zb1211/zb1211b wireless NICs -device urtw # Realtek RTL8187B/L USB -device upgt # Conexant/Intersil PrismGT SoftMAC USB -device u3g # USB-based 3G modems (Option, Huawei, Sierra) +#options USB_DEBUG # Compile in USB debug support +device usb # Basic usb support +device ehci # USB host controller +device umass # Mass storage +device uhid # Human-interface devices +device rum # Ralink Technology RT2501USB wireless NICs +device uath # Atheros AR5523 wireless NICs +device ural # Ralink Technology RT2500USB wireless NICs +device zyd # ZyDAS zb1211/zb1211b wireless NICs +device urtw # Realtek RTL8187B/L USB +device upgt # Conexant/Intersil PrismGT SoftMAC USB +device u3g # USB-based 3G modems (Option, Huawei, Sierra) # I2C (TWSI) device iic @@ -106,48 +106,48 @@ device mvs device ahci # Sound -device sound -device snd_uaudio +device sound +device snd_uaudio #crypto -device cesa # Marvell security engine -device crypto -device cryptodev +device cesa # Marvell security engine +device crypto +device cryptodev # IPSec -device enc -options IPSEC -options IPSEC_NAT_T -options TCP_SIGNATURE # include support for RFC 2385 +device enc +options IPSEC +options IPSEC_NAT_T +options TCP_SIGNATURE # include support for RFC 2385 # IPFW -options IPFIREWALL -options IPFIREWALL_DEFAULT_TO_ACCEPT -options IPFIREWALL_VERBOSE -options IPFIREWALL_VERBOSE_LIMIT=100 -options IPFIREWALL_NAT -options LIBALIAS -options DUMMYNET -options IPDIVERT +options IPFIREWALL +options IPFIREWALL_DEFAULT_TO_ACCEPT +options IPFIREWALL_VERBOSE +options IPFIREWALL_VERBOSE_LIMIT=100 +options IPFIREWALL_NAT +options LIBALIAS +options DUMMYNET +options IPDIVERT #PF -device pf -device pflog -device pfsync +device pf +device pflog +device pfsync # ALTQ, required for PF -options ALTQ # Basic ALTQ support -options ALTQ_CBQ # Class Based Queueing -options ALTQ_RED # Random Early Detection -options ALTQ_RIO # RED In/Out -options ALTQ_HFSC # Hierarchical Packet Scheduler -options ALTQ_CDNR # Traffic conditioner -options ALTQ_PRIQ # Priority Queueing -options ALTQ_NOPCC # Required if the TSC is unusable +options ALTQ # Basic ALTQ support +options ALTQ_CBQ # Class Based Queueing +options ALTQ_RED # Random Early Detection +options ALTQ_RIO # RED In/Out +options ALTQ_HFSC # Hierarchical Packet Scheduler +options ALTQ_CDNR # Traffic conditioner +options ALTQ_PRIQ # Priority Queueing +options ALTQ_NOPCC # Required if the TSC is unusable #options ALTQ_DEBUG # Debugging -makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols +makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols options BREAK_TO_DEBUGGER options ALT_BREAK_TO_DEBUGGER options DDB @@ -178,7 +178,7 @@ options ROOTDEVNAME=\"ufs:/dev/da1s1a\" # create a kernel config file that looks like this: # # include DREAMPLUG-1001 -# nomakeoptions FDT_DTS_FILE +# nomakeoptions FDT_DTS_FILE # makeoptions FDT_DTS_FILE=dreamplug-1001N.dts # device nand diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index f4531f25019..b6351c8edc7 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -22,7 +22,7 @@ ident EFIKA_MX include "../freescale/imx/std.imx51" -makeoptions WITHOUT_MODULES="ahc" +makeoptions WITHOUT_MODULES="ahc" options SCHED_4BSD # 4BSD scheduler options PREEMPTION # Enable kernel thread preemption @@ -174,7 +174,7 @@ makeoptions FDT_DTS_FILE=efikamx.dts # Uncomment following lines for framebuffer/syscons support device sc device kbdmux -options SC_DFLT_FONT # compile font in -makeoptions SC_DFLT_FONT=cp437 +options SC_DFLT_FONT # compile font in +makeoptions SC_DFLT_FONT=cp437 device ukbd # Allow keyboard like HIDs to control console device ums diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common index f4cd3b50ee6..0179d5b795b 100644 --- a/sys/arm/conf/EXYNOS5.common +++ b/sys/arm/conf/EXYNOS5.common @@ -99,8 +99,8 @@ device gpio options USB_HOST_ALIGN=64 # Align usb buffers to cache line size. device usb options USB_DEBUG -#options USB_REQ_DEBUG -#options USB_VERBOSE +#options USB_REQ_DEBUG +#options USB_VERBOSE #device musb device ehci #device ohci diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201 index efdea82f489..8a155440fbf 100644 --- a/sys/arm/conf/HL201 +++ b/sys/arm/conf/HL201 @@ -143,5 +143,5 @@ options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=hl201.dts options EARLY_PRINTF -options SOCDEV_PA=0xfc000000 +options SOCDEV_PA=0xfc000000 options SOCDEV_VA=0xdc000000 diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index 9a3326cc6e2..a2db13b60f8 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -169,5 +169,5 @@ options FDT # Configure using FDT/DTB data #device sc #device vt #device kbdmux -#options SC_DFLT_FONT # compile font in -#makeoptions SC_DFLT_FONT=cp437 +#options SC_DFLT_FONT # compile font in +#makeoptions SC_DFLT_FONT=cp437 diff --git a/sys/arm/conf/IMX53-QSB b/sys/arm/conf/IMX53-QSB index fdaa4ec0f40..fdde591b13b 100644 --- a/sys/arm/conf/IMX53-QSB +++ b/sys/arm/conf/IMX53-QSB @@ -34,5 +34,5 @@ options HZ=250 # 4ms scheduling quantum #options ROOTDEVNAME=\"ufs:ada0s2a\" # Flattened Device Tree -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=imx53-qsb.dts +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=imx53-qsb.dts diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index fe3dab398a0..32807847032 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -97,7 +97,7 @@ device miibus # Required for ethernet device bpf # Berkeley packet filter (required for DHCP) # General-purpose input/output -device gpio +device gpio # Serial (COM) ports device uart # Multi-uart driver diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188 index cdf965f7ed2..ab9d20aea49 100644 --- a/sys/arm/conf/RK3188 +++ b/sys/arm/conf/RK3188 @@ -115,10 +115,10 @@ device mii device bpf # Wireless NIC cards -options IEEE80211_DEBUG -options IEEE80211_AMPDU_AGE -options IEEE80211_SUPPORT_MESH -options IEEE80211_SUPPORT_TDMA +options IEEE80211_DEBUG +options IEEE80211_AMPDU_AGE +options IEEE80211_SUPPORT_MESH +options IEEE80211_SUPPORT_TDMA device wlan # 802.11 support device wlan_wep # 802.11 WEP support device wlan_ccmp # 802.11 CCMP support diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK index c3cba33f8b7..dd0d52e2591 100644 --- a/sys/arm/conf/SAM9260EK +++ b/sys/arm/conf/SAM9260EK @@ -180,5 +180,5 @@ device nand # NAND interface on CS3 #makeoptions FDT_DTS_FILE=sam9260ek.dts options EARLY_PRINTF -options SOCDEV_PA=0xfc000000 +options SOCDEV_PA=0xfc000000 options SOCDEV_VA=0xdc000000 diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB index 8430133c206..2132389454f 100644 --- a/sys/arm/conf/VERSATILEPB +++ b/sys/arm/conf/VERSATILEPB @@ -106,8 +106,8 @@ device pass # Passthrough device (direct ATA/SCSI access) # Comment following lines for headless setup device sc device kbdmux -options SC_DFLT_FONT # compile font in -makeoptions SC_DFLT_FONT=cp437 +options SC_DFLT_FONT # compile font in +makeoptions SC_DFLT_FONT=cp437 device md device random # Entropy device diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID index bf2c2c4bb38..7ff206eedfb 100644 --- a/sys/arm/conf/VYBRID +++ b/sys/arm/conf/VYBRID @@ -110,8 +110,8 @@ device gpio options USB_HOST_ALIGN=32 # Align usb buffers to cache line size. device usb options USB_DEBUG -#options USB_REQ_DEBUG -#options USB_VERBOSE +#options USB_REQ_DEBUG +#options USB_VERBOSE #device musb device ehci #device ohci diff --git a/sys/arm/conf/WANDBOARD-DUAL b/sys/arm/conf/WANDBOARD-DUAL index 1e690c91957..66e2535a4b2 100644 --- a/sys/arm/conf/WANDBOARD-DUAL +++ b/sys/arm/conf/WANDBOARD-DUAL @@ -23,6 +23,6 @@ include "IMX6" ident WANDBOARD-DUAL # Flattened Device Tree -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=wandboard-dual.dts +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=wandboard-dual.dts diff --git a/sys/arm/conf/WANDBOARD-QUAD b/sys/arm/conf/WANDBOARD-QUAD index 121e712d9c7..830a445fc99 100644 --- a/sys/arm/conf/WANDBOARD-QUAD +++ b/sys/arm/conf/WANDBOARD-QUAD @@ -23,6 +23,6 @@ include "IMX6" ident WANDBOARD-QUAD # Flattened Device Tree -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=wandboard-quad.dts +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=wandboard-quad.dts diff --git a/sys/arm/conf/WANDBOARD-SOLO b/sys/arm/conf/WANDBOARD-SOLO index 424bc5f1d6f..39a0c7c7308 100644 --- a/sys/arm/conf/WANDBOARD-SOLO +++ b/sys/arm/conf/WANDBOARD-SOLO @@ -23,6 +23,6 @@ include "IMX6" ident WANDBOARD-SOLO # Flattened Device Tree -options FDT_DTB_STATIC -makeoptions FDT_DTS_FILE=wandboard-solo.dts +options FDT_DTB_STATIC +makeoptions FDT_DTS_FILE=wandboard-solo.dts From 67304db7c1fa85e893f388e58fa8300e1ee51e4d Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 21 Dec 2014 12:13:49 +0000 Subject: [PATCH 054/207] Various mdoc fixes. Found with: mandoc -Tlint --- share/man/man5/periodic.conf.5 | 2 +- share/man/man5/pf.conf.5 | 2 +- share/man/man5/pf.os.5 | 6 +++--- share/man/man5/rc.conf.5 | 2 +- share/man/man5/services.5 | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/share/man/man5/periodic.conf.5 b/share/man/man5/periodic.conf.5 index 83897c15262..d5526f9b6a5 100644 --- a/share/man/man5/periodic.conf.5 +++ b/share/man/man5/periodic.conf.5 @@ -705,7 +705,7 @@ they will be always run unless their or .Va ..._period variable is set to -.Dq No . +.Dq NO . .Bl -tag -offset 4n -width 2n .It Va security_status_diff_flags .Pq Vt str diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5 index 4f959333a59..4ed941c40cf 100644 --- a/share/man/man5/pf.conf.5 +++ b/share/man/man5/pf.conf.5 @@ -28,7 +28,7 @@ .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 29 2012 +.Dd June 29, 2012 .Dt PF.CONF 5 .Os .Sh NAME diff --git a/share/man/man5/pf.os.5 b/share/man/man5/pf.os.5 index 59305257295..18c72468e64 100644 --- a/share/man/man5/pf.os.5 +++ b/share/man/man5/pf.os.5 @@ -16,7 +16,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 31 2007 +.Dd May 31, 2007 .Dt PF.OS 5 .Os .Sh NAME @@ -217,7 +217,7 @@ almost translates into the following fingerprint 57344:64:1:44:M1460: exampleOS:1.0::exampleOS 1.0 .Ed .Sh SEE ALSO +.Xr tcpdump 1 , .Xr pf 4 , .Xr pf.conf 5 , -.Xr pfctl 8 , -.Xr tcpdump 1 +.Xr pfctl 8 diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 09583ec1042..5c4803fcb87 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -4547,9 +4547,9 @@ ruleset to load for .Xr rfcomm_pppd 8 , .Xr route 8 , .Xr routed 8 , -.Xr rpcbind 8 , .Xr rpc.lockd 8 , .Xr rpc.statd 8 , +.Xr rpcbind 8 , .Xr rwhod 8 , .Xr savecore 8 , .Xr sdpd 8 , diff --git a/share/man/man5/services.5 b/share/man/man5/services.5 index 6469cfce7a0..adda70a92da 100644 --- a/share/man/man5/services.5 +++ b/share/man/man5/services.5 @@ -91,8 +91,8 @@ file resides in .Pa /etc . .El .Sh SEE ALSO -.Xr getservent 3 -.Xr nsswitch.conf 5 +.Xr getservent 3 , +.Xr nsswitch.conf 5 , .Xr services_mkdb 8 .Sh HISTORY The From 0aee91e1fb311f4f92779bb2c7ef0c1fe10d8d35 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 21 Dec 2014 12:36:36 +0000 Subject: [PATCH 055/207] Various mdoc fixes and a few EOL whitespace removals. Found with: mandoc -Tlint --- lib/libc/gen/cap_rights_get.3 | 2 +- lib/libc/gen/ftok.3 | 4 ++-- lib/libc/gen/ftw.3 | 10 ++++++---- lib/libc/gen/getcap.3 | 5 +++-- lib/libc/gen/posix_spawn.3 | 10 +++++----- lib/libc/gen/scandir.3 | 6 +++--- lib/libc/net/getaddrinfo.3 | 4 ++-- lib/libc/net/sctp_recvmsg.3 | 4 ++-- lib/libc/net/sctp_send.3 | 2 +- lib/libc/posix1e/acl_set_flagset_np.3 | 2 +- lib/libc/stdlib/atexit.3 | 4 ++-- lib/libc/stdlib/exit.3 | 2 +- lib/libc/string/strspn.3 | 2 +- lib/libc/sys/access.2 | 2 +- lib/libc/sys/getdirentries.2 | 5 +++-- lib/libc/sys/getrlimit.2 | 2 +- lib/libc/sys/poll.2 | 16 ++++++++-------- lib/libc/sys/posix_openpt.2 | 2 +- lib/libc/sys/procctl.2 | 2 +- lib/libc/sys/revoke.2 | 4 ++-- lib/libc/sys/sched_setscheduler.2 | 2 +- lib/libc/sys/sigwaitinfo.2 | 2 +- lib/libc/sys/vfork.2 | 2 +- 23 files changed, 50 insertions(+), 46 deletions(-) diff --git a/lib/libc/gen/cap_rights_get.3 b/lib/libc/gen/cap_rights_get.3 index f74d1f7aeda..a665465e533 100644 --- a/lib/libc/gen/cap_rights_get.3 +++ b/lib/libc/gen/cap_rights_get.3 @@ -100,10 +100,10 @@ argument points at an invalid address. .El .Sh SEE ALSO .Xr cap_rights_limit 2 , -.Xr cap_rights_init 3 , .Xr errno 2 , .Xr open 2 , .Xr assert 3 , +.Xr cap_rights_init 3 , .Xr err 3 , .Xr memcmp 3 , .Xr memset 3 , diff --git a/lib/libc/gen/ftok.3 b/lib/libc/gen/ftok.3 index 98f8bad878f..b819dbd185d 100644 --- a/lib/libc/gen/ftok.3 +++ b/lib/libc/gen/ftok.3 @@ -64,9 +64,9 @@ function will return -1 if .Fa path does not exist or if it cannot be accessed by the calling process. .Sh SEE ALSO +.Xr msgget 2 , .Xr semget 2 , -.Xr shmget 2 , -.Xr msgget 2 +.Xr shmget 2 .Sh HISTORY The .Fn ftok diff --git a/lib/libc/gen/ftw.3 b/lib/libc/gen/ftw.3 index ba8859b4a33..df8abab031b 100644 --- a/lib/libc/gen/ftw.3 +++ b/lib/libc/gen/ftw.3 @@ -87,8 +87,9 @@ A directory which cannot be read. The directory will not be descended into. .It Dv FTW_DP A directory being visited in post-order -.Fn ( nftw -only). +.Po Fn nftw +only +.Pc . .It Dv FTW_NS A file for which no .Xr stat 2 @@ -100,8 +101,9 @@ structure are undefined. A symbolic link. .It Dv FTW_SLN A symbolic link with a non-existent target -.Fn ( nftw -only). +.Po Fn nftw +only +.Pc . .El .Pp The diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3 index 73826ae7c0d..c3a9ce87a03 100644 --- a/lib/libc/gen/getcap.3 +++ b/lib/libc/gen/getcap.3 @@ -137,9 +137,10 @@ It must be called before the call. If a sequential access is being performed (see below), it must be called before the first sequential access call -.Fn ( cgetfirst +.Po Fn cgetfirst or -.Fn cgetnext ) , +.Fn cgetnext +.Pc , or be directly preceded by a .Fn cgetclose call. diff --git a/lib/libc/gen/posix_spawn.3 b/lib/libc/gen/posix_spawn.3 index dd5bd2b5ed8..52e81713660 100644 --- a/lib/libc/gen/posix_spawn.3 +++ b/lib/libc/gen/posix_spawn.3 @@ -413,6 +413,10 @@ including trying to close a descriptor that is not open. .Xr execve 2 , .Xr fcntl 2 , .Xr open 2 , +.Xr sched_setparam 2 , +.Xr sched_setscheduler 2 , +.Xr setpgid 2 , +.Xr vfork 2 , .Xr posix_spawn_file_actions_addclose 3 , .Xr posix_spawn_file_actions_adddup2 3 , .Xr posix_spawn_file_actions_addopen 3 , @@ -431,11 +435,7 @@ including trying to close a descriptor that is not open. .Xr posix_spawnattr_setschedparam 3 , .Xr posix_spawnattr_setschedpolicy 3 , .Xr posix_spawnattr_setsigdefault 3 , -.Xr posix_spawnattr_setsigmask 3 , -.Xr sched_setparam 2 , -.Xr sched_setscheduler 2 , -.Xr setpgid 2 , -.Xr vfork 2 +.Xr posix_spawnattr_setsigmask 3 .Sh STANDARDS The .Fn posix_spawn diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3 index eaba7547fed..aa8dea030a7 100644 --- a/lib/libc/gen/scandir.3 +++ b/lib/libc/gen/scandir.3 @@ -92,7 +92,7 @@ by freeing each pointer in the array and then the array itself. .Pp The .Fn scandir_b -function behaves in the same way as +function behaves in the same way as .Fn scandir , but takes blocks as arguments instead of function pointers and calls .Fn qsort_b @@ -106,8 +106,8 @@ cannot allocate enough memory to hold all the data structures. .Xr directory 3 , .Xr malloc 3 , .Xr qsort 3 , -.Xr dir 5 , -.Xr strcoll 3 +.Xr strcoll 3 , +.Xr dir 5 .Sh HISTORY The .Fn scandir diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3 index 5d03aab2a42..570fc2e3bcb 100644 --- a/lib/libc/net/getaddrinfo.3 +++ b/lib/libc/net/getaddrinfo.3 @@ -237,8 +237,8 @@ pointer in each .Li addrinfo structure until a null pointer is encountered. The three members -.Fa ai_family, -.Fa ai_socktype, +.Fa ai_family , +.Fa ai_socktype , and .Fa ai_protocol in each returned diff --git a/lib/libc/net/sctp_recvmsg.3 b/lib/libc/net/sctp_recvmsg.3 index e3ced9c42a9..bb1cf067122 100644 --- a/lib/libc/net/sctp_recvmsg.3 +++ b/lib/libc/net/sctp_recvmsg.3 @@ -282,12 +282,12 @@ This typically means that the socket is not connected and is a one-to-one style socket. .El .Sh SEE ALSO +.Xr getsockopt 2 , .Xr recv 2 , .Xr select 2 , +.Xr setsockopt 2 , .Xr socket 2 , .Xr write 2 , -.Xr getsockopt 2 , -.Xr setsockopt 2 , .Xr sctp_send 3 , .Xr sctp_sendmsg 3 , .Xr sendmsg 3 , diff --git a/lib/libc/net/sctp_send.3 b/lib/libc/net/sctp_send.3 index 37b0b7185b0..9c7f833918b 100644 --- a/lib/libc/net/sctp_send.3 +++ b/lib/libc/net/sctp_send.3 @@ -337,7 +337,7 @@ is not connected and is a one-to-one style socket. .Xr select 2 , .Xr sendmsg 2 , .Xr socket 2 , -.Xr write 2 +.Xr write 2 , .Xr sctp_connectx 3 , .Xr sctp_recvmsg 3 , .Xr sctp_sendmsg 3 , diff --git a/lib/libc/posix1e/acl_set_flagset_np.3 b/lib/libc/posix1e/acl_set_flagset_np.3 index 2230c4866b7..685680d3b35 100644 --- a/lib/libc/posix1e/acl_set_flagset_np.3 +++ b/lib/libc/posix1e/acl_set_flagset_np.3 @@ -64,9 +64,9 @@ ACL is already branded as POSIX.1e. .Sh SEE ALSO .Xr acl 3 , .Xr acl_add_flag_np 3 , -.Xr acl_get_brand_np 3 , .Xr acl_clear_flags_np 3 , .Xr acl_delete_flag_np 3 , +.Xr acl_get_brand_np 3 , .Xr acl_get_flagset_np 3 , .Xr posix1e 3 .Sh STANDARDS diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3 index 68f4e8fb1dc..3cdc59fed86 100644 --- a/lib/libc/stdlib/atexit.3 +++ b/lib/libc/stdlib/atexit.3 @@ -88,12 +88,12 @@ The existing list of functions is unmodified. .It Bq Er ENOSYS The .Fn atexit_b -function was called by a program that did not supply a +function was called by a program that did not supply a .Fn _Block_copy implementation. .El .Sh SEE ALSO -.Xr at_quick_exit 3 +.Xr at_quick_exit 3 , .Xr exit 3 .Sh STANDARDS The diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3 index 07ce0d77d10..7d657c922ce 100644 --- a/lib/libc/stdlib/exit.3 +++ b/lib/libc/stdlib/exit.3 @@ -117,8 +117,8 @@ never return. .Sh SEE ALSO .Xr _exit 2 , .Xr wait 2 , -.Xr atexit 3 , .Xr at_quick_exit 3 , +.Xr atexit 3 , .Xr intro 3 , .Xr quick_exit 3 , .Xr sysexits 3 , diff --git a/lib/libc/string/strspn.3 b/lib/libc/string/strspn.3 index 542b190f641..4a8e3f40ce5 100644 --- a/lib/libc/string/strspn.3 +++ b/lib/libc/string/strspn.3 @@ -71,7 +71,7 @@ spans the initial part of the null-terminated string .Fa s as long as the characters from .Fa s -.Sy do not +.Sy do not occur in the null-terminated string .Fa charset .Po it spans the diff --git a/lib/libc/sys/access.2 b/lib/libc/sys/access.2 index 46bf9488de8..c70e7a2d531 100644 --- a/lib/libc/sys/access.2 +++ b/lib/libc/sys/access.2 @@ -136,7 +136,7 @@ and .Fn access , .Fn eaccess , or -.Fn faccessat +.Fn faccessat will fail if: .Bl -tag -width Er .It Bq Er EINVAL diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2 index 3fe16327ed3..ab60ed2d71d 100644 --- a/lib/libc/sys/getdirentries.2 +++ b/lib/libc/sys/getdirentries.2 @@ -134,8 +134,9 @@ The current position pointer should only be set to a value returned by .Xr lseek 2 , a value returned in the location pointed to by .Fa basep -.Fn ( getdirentries -only) +.Po Fn getdirentries +only +.Pc or zero. .Sh RETURN VALUES If successful, the number of bytes actually transferred is returned. diff --git a/lib/libc/sys/getrlimit.2 b/lib/libc/sys/getrlimit.2 index 1f84bfb0f0e..5fdd58bf861 100644 --- a/lib/libc/sys/getrlimit.2 +++ b/lib/libc/sys/getrlimit.2 @@ -194,8 +194,8 @@ raised the maximum limit value, and the caller is not the super-user. .Xr csh 1 , .Xr quota 1 , .Xr quotactl 2 , -.Xr sigaltstack 2 , .Xr sigaction 2 , +.Xr sigaltstack 2 , .Xr sysctl 3 , .Xr ulimit 3 .Sh HISTORY diff --git a/lib/libc/sys/poll.2 b/lib/libc/sys/poll.2 index 466523be8c9..dbd641f50bf 100644 --- a/lib/libc/sys/poll.2 +++ b/lib/libc/sys/poll.2 @@ -148,8 +148,8 @@ is zero, then will return without blocking. .Pp The -.Fn ppoll -system call, unlike +.Fn ppoll +system call, unlike .Fn poll , is used to safely wait until either a set of file descriptors becomes ready or until a signal is caught. @@ -174,10 +174,10 @@ used by A null pointer may be passed to indicate that .Fn ppoll should wait indefinitely. -Finally, +Finally, .Fa newsigmask specifies a signal mask which is set while waiting for input. -When +When .Fn ppoll returns, the original signal mask is restored. .Bd -literal @@ -246,11 +246,11 @@ The specified time limit is invalid. One of its components is negative or too la .Xr write 2 .Sh STANDARDS The -.Fn poll +.Fn poll function conforms to .St -p1003.1-2001 . The -.Fn ppoll +.Fn ppoll is not specified by POSIX. .Sh HISTORY The @@ -261,8 +261,8 @@ This manual page and the core of the implementation was taken from .Nx . The .Fn ppoll -function first appeared in -.Fx 11.0 +function first appeared in +.Fx 11.0 .Sh BUGS The distinction between some of the fields in the .Fa events diff --git a/lib/libc/sys/posix_openpt.2 b/lib/libc/sys/posix_openpt.2 index 916e75ac586..d34385fb93e 100644 --- a/lib/libc/sys/posix_openpt.2 +++ b/lib/libc/sys/posix_openpt.2 @@ -110,8 +110,8 @@ is not valid. Out of pseudo-terminal resources. .El .Sh SEE ALSO -.Xr pts 4 , .Xr ptsname 3 , +.Xr pts 4 , .Xr tty 4 .Sh STANDARDS The diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2 index 70ee276922f..649e0ad8a0d 100644 --- a/lib/libc/sys/procctl.2 +++ b/lib/libc/sys/procctl.2 @@ -107,7 +107,6 @@ reaper. After the system initialization, .Xr init 8 is the default reaper. -.Pp .It Dv PROC_REAP_RELEASE Releases the reaper state for the current process. The reaper of the current process becomes the new reaper of the @@ -146,6 +145,7 @@ for the specified process id. The specified process is the root of the reaper tree, i.e. .Xr init 8 . .El +.Pp The .Fa rs_children field returns the number of children of the reaper. diff --git a/lib/libc/sys/revoke.2 b/lib/libc/sys/revoke.2 index 57abdbb65cb..482cbf661ba 100644 --- a/lib/libc/sys/revoke.2 +++ b/lib/libc/sys/revoke.2 @@ -97,8 +97,8 @@ operation on the named file. The caller is neither the owner of the file nor the super user. .El .Sh SEE ALSO -.Xr close 2 , -.Xr revoke 1 +.Xr revoke 1 , +.Xr close 2 .Sh HISTORY The .Fn revoke diff --git a/lib/libc/sys/sched_setscheduler.2 b/lib/libc/sys/sched_setscheduler.2 index 3e7c42b7ca7..b84c1a1c9e3 100644 --- a/lib/libc/sys/sched_setscheduler.2 +++ b/lib/libc/sys/sched_setscheduler.2 @@ -151,9 +151,9 @@ argument is invalid, or one or more of the parameters contained in is outside the valid range for the specified scheduling policy. .El .Sh SEE ALSO -.Xr sched_getparam 2 , .Xr sched_get_priority_max 2 , .Xr sched_get_priority_min 2 , +.Xr sched_getparam 2 , .Xr sched_rr_get_interval 2 , .Xr sched_setparam 2 , .Xr sched_yield 2 diff --git a/lib/libc/sys/sigwaitinfo.2 b/lib/libc/sys/sigwaitinfo.2 index 9109759bdf7..b497592ed1f 100644 --- a/lib/libc/sys/sigwaitinfo.2 +++ b/lib/libc/sys/sigwaitinfo.2 @@ -172,8 +172,8 @@ system calls fail if: .Bl -tag -width Er .It Bq Er EINTR The wait was interrupted by an unblocked, caught signal. -.Pp .El +.Pp The .Fn sigtimedwait system call may also fail if: diff --git a/lib/libc/sys/vfork.2 b/lib/libc/sys/vfork.2 index 1cfaa6130de..f93b4290320 100644 --- a/lib/libc/sys/vfork.2 +++ b/lib/libc/sys/vfork.2 @@ -100,8 +100,8 @@ since buffered data would then be flushed twice.) Same as for .Xr fork 2 . .Sh SEE ALSO -.Xr execve 2 , .Xr _exit 2 , +.Xr execve 2 , .Xr fork 2 , .Xr rfork 2 , .Xr sigaction 2 , From 789bdfdbc6343343efa7ad1e4c643c8ff405dd3b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 21 Dec 2014 13:29:33 +0000 Subject: [PATCH 056/207] Handle MAKEENTRY cnp flag in the VOP_CREATE(). Curiously, some fs, e.g. smbfs, already did it. Tested by: pho (previous version) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- .../contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 11 ++++++++--- sys/fs/ext2fs/ext2_vnops.c | 4 +++- sys/fs/msdosfs/msdosfs_vnops.c | 2 ++ sys/fs/nandfs/nandfs_vnops.c | 2 ++ sys/fs/tmpfs/tmpfs_vnops.c | 6 +++++- sys/ufs/ufs/ufs_vnops.c | 4 +++- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 5d7fa70544e..9b11652bb22 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -6180,15 +6180,20 @@ zfs_freebsd_create(ap) { struct componentname *cnp = ap->a_cnp; vattr_t *vap = ap->a_vap; - int mode; + int error, mode; ASSERT(cnp->cn_flags & SAVENAME); vattr_init_mask(vap); mode = vap->va_mode & ALLPERMS; - return (zfs_create(ap->a_dvp, cnp->cn_nameptr, vap, !EXCL, mode, - ap->a_vpp, cnp->cn_cred, cnp->cn_thread)); + error = zfs_create(ap->a_dvp, cnp->cn_nameptr, vap, !EXCL, mode, + ap->a_vpp, cnp->cn_cred, cnp->cn_thread); +#ifdef FREEBSD_NAMECACHE + if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0) + cache_enter(ap->a_dvp, *ap->a_vpp, cnp); +#endif + return (error); } static int diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c index 899ae7970d6..5baca5aacba 100644 --- a/sys/fs/ext2fs/ext2_vnops.c +++ b/sys/fs/ext2fs/ext2_vnops.c @@ -239,8 +239,10 @@ ext2_create(struct vop_create_args *ap) error = ext2_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), ap->a_dvp, ap->a_vpp, ap->a_cnp); - if (error) + if (error != 0) return (error); + if ((ap->a_cnp->cn_flags & MAKEENTRY) != 0) + cache_enter(ap->a_dvp, *ap->a_vpp, ap->a_cnp); return (0); } diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index a60fa1337bc..329465657e7 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -184,6 +184,8 @@ msdosfs_create(ap) if (error) goto bad; *ap->a_vpp = DETOV(dep); + if ((cnp->cn_flags & MAKEENTRY) != 0) + cache_enter(ap->a_dvp, *ap->a_vpp, cnp); return (0); bad: diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c index 65dcf6416e0..40dd8555d80 100644 --- a/sys/fs/nandfs/nandfs_vnops.c +++ b/sys/fs/nandfs/nandfs_vnops.c @@ -1411,6 +1411,8 @@ nandfs_create(struct vop_create_args *ap) return (error); } *vpp = NTOV(node); + if ((cnp->cn_flags & MAKEENTRY) != 0) + cache_enter(dvp, *vpp, cnp); DPRINTF(VNCALL, ("created file vp %p nandnode %p ino %jx\n", *vpp, node, (uintmax_t)node->nn_ino)); diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 29ee38915ab..c811b9a827e 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -213,10 +213,14 @@ tmpfs_create(struct vop_create_args *v) struct vnode **vpp = v->a_vpp; struct componentname *cnp = v->a_cnp; struct vattr *vap = v->a_vap; + int error; MPASS(vap->va_type == VREG || vap->va_type == VSOCK); - return tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL); + error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL); + if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0) + cache_enter(dvp, *vpp, cnp); + return (error); } static int diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 21d4ba4027c..3d7a21dca25 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -205,8 +205,10 @@ ufs_create(ap) error = ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), ap->a_dvp, ap->a_vpp, ap->a_cnp); - if (error) + if (error != 0) return (error); + if ((ap->a_cnp->cn_flags & MAKEENTRY) != 0) + cache_enter(ap->a_dvp, *ap->a_vpp, ap->a_cnp); return (0); } From 8ee9765a9d9471d4c0eca6af889e824ee918f5f1 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 21 Dec 2014 13:32:07 +0000 Subject: [PATCH 057/207] Add VN_OPEN_NAMECACHE flag for vn_open_cred(9), which requests that the created file name was cached. Use the flag for core dumps. Requested by: rpaulo Tested by: pho (previous version) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/kern/kern_sig.c | 3 ++- sys/kern/vfs_vnops.c | 2 ++ sys/sys/vnode.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index b34eb6281c8..a4f0f889005 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -3167,7 +3167,8 @@ corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td, sbuf_delete(&sb); cmode = S_IRUSR | S_IWUSR; - oflags = VN_OPEN_NOAUDIT | (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); + oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE | + (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0); /* * If the core format has a %I in it, then we need to check diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 40a69bbf27e..ed4ad4d18f1 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -217,6 +217,8 @@ restart: return (error); goto restart; } + if ((vn_open_flags & VN_OPEN_NAMECACHE) != 0) + ndp->ni_cnd.cn_flags |= MAKEENTRY; #ifdef MAC error = mac_vnode_check_create(cred, ndp->ni_dvp, &ndp->ni_cnd, vap); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 87382b80859..8a14f694db4 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -580,6 +580,7 @@ typedef void vop_getpages_iodone_t(void *, vm_page_t *, int, int); /* vn_open_flags */ #define VN_OPEN_NOAUDIT 0x00000001 #define VN_OPEN_NOCAPCHECK 0x00000002 +#define VN_OPEN_NAMECACHE 0x00000004 /* * Public vnode manipulation functions. From f3ba71bee46f50605a322bcd2298fb6438c3e129 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 21 Dec 2014 13:58:53 +0000 Subject: [PATCH 058/207] Don't check twice that inp is not NULL. Reported by: Coverity CID: 748671 MFC after: 3 days --- sys/netinet/sctputil.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index d066c741206..edf6ae852d3 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1949,7 +1949,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, * though we use a different timer. We also add the HB timer * PLUS a random jitter. */ - if ((inp == NULL) || (stcb == NULL) || (net == NULL)) { + if ((stcb == NULL) || (net == NULL)) { return; } else { uint32_t rndval; @@ -2004,9 +2004,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, * nothing needed but the endpoint here ususually about 60 * minutes. */ - if (inp == NULL) { - return; - } tmr = &inp->sctp_ep.signature_change; to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE]; break; @@ -2023,9 +2020,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, * timer since that has stopped and we are in the GONE * state. */ - if (inp == NULL) { - return; - } tmr = &inp->sctp_ep.signature_change; to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT); break; @@ -2034,10 +2028,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, * Here we use the value found in the EP for PMTU ususually * about 10 minutes. */ - if ((stcb == NULL) || (inp == NULL)) { - return; - } - if (net == NULL) { + if ((stcb == NULL) || (net == NULL)) { return; } if (net->dest_state & SCTP_ADDR_NO_PMTUD) { @@ -2063,7 +2054,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, * Here we use the endpoints shutdown guard timer usually * about 3 minutes. */ - if ((inp == NULL) || (stcb == NULL)) { + if (stcb == NULL) { return; } to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN]; From 55972826f2b0109d1b26864fdfce195da8aa18d2 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Sun, 21 Dec 2014 16:07:46 +0000 Subject: [PATCH 059/207] Add a constant AHCI_MAX_IRQS removing magic number Sponsored by: Multiplay --- sys/dev/ahci/ahci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h index f5a3ca8cd98..462f20427d0 100644 --- a/sys/dev/ahci/ahci.h +++ b/sys/dev/ahci/ahci.h @@ -143,6 +143,7 @@ #define AHCI_MAX_PORTS 32 #define AHCI_MAX_SLOTS 32 +#define AHCI_MAX_IRQS 16 /* SATA AHCI v1.0 register defines */ #define AHCI_CAP 0x00 @@ -494,7 +495,7 @@ struct ahci_controller { #define AHCI_IRQ_MODE_ALL 0 #define AHCI_IRQ_MODE_AFTER 1 #define AHCI_IRQ_MODE_ONE 2 - } irqs[16]; + } irqs[AHCI_MAX_IRQS]; uint32_t caps; /* Controller capabilities */ uint32_t caps2; /* Controller capabilities */ uint32_t capsem; /* Controller capabilities */ From a12f5777dfaa5be4dbd91cecea090c1456717ef5 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Sun, 21 Dec 2014 16:15:29 +0000 Subject: [PATCH 060/207] Clamp ahci max irq's to AHCI_MAX_IRQS This prevents the possiblity of any overruns on the statically allocated struct irqs field. Differential Revision: D838 MFC after: 2 weeks X-MFC-With: r276012 Sponsored by: Multiplay --- sys/dev/ahci/ahci.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 583983bff7e..8b4066f5820 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -356,6 +356,14 @@ ahci_setup_interrupt(device_t dev) device_printf(dev, "Falling back to one MSI\n"); ctlr->numirqs = 1; } + + /* Ensure we don't overrun irqs. */ + if (ctlr->numirqs > AHCI_MAX_IRQS) { + device_printf(dev, "Too many irqs %d > %d (clamping)\n", + ctlr->numirqs, AHCI_MAX_IRQS); + ctlr->numirqs = AHCI_MAX_IRQS; + } + /* Allocate all IRQs. */ for (i = 0; i < ctlr->numirqs; i++) { ctlr->irqs[i].ctlr = ctlr; From 2fe8c9e1320f4a1e67b384bea7218c5e4d554493 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 16:21:56 +0000 Subject: [PATCH 061/207] Reduce the diff to the arm_intrng project branch by having the read/write macros take the softc they are accessing. --- sys/arm/arm/gic.c | 91 +++++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index f1bb014b2ed..56041dae90e 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -118,14 +118,14 @@ static struct resource_spec arm_gic_spec[] = { static struct arm_gic_softc *arm_gic_sc = NULL; -#define gic_c_read_4(reg) \ - bus_space_read_4(arm_gic_sc->gic_c_bst, arm_gic_sc->gic_c_bsh, reg) -#define gic_c_write_4(reg, val) \ - bus_space_write_4(arm_gic_sc->gic_c_bst, arm_gic_sc->gic_c_bsh, reg, val) -#define gic_d_read_4(reg) \ - bus_space_read_4(arm_gic_sc->gic_d_bst, arm_gic_sc->gic_d_bsh, reg) -#define gic_d_write_4(reg, val) \ - bus_space_write_4(arm_gic_sc->gic_d_bst, arm_gic_sc->gic_d_bsh, reg, val) +#define gic_c_read_4(_sc, _reg) \ + bus_space_read_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg)) +#define gic_c_write_4(_sc, _reg, _val) \ + bus_space_write_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg), (_val)) +#define gic_d_read_4(_sc, _reg) \ + bus_space_read_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg)) +#define gic_d_write_4(_sc, _reg, _val) \ + bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val)) static int gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol); @@ -158,35 +158,36 @@ arm_gic_probe(device_t dev) void gic_init_secondary(void) { + struct arm_gic_softc *sc = arm_gic_sc; int i, nirqs; /* Get the number of interrupts */ - nirqs = gic_d_read_4(GICD_TYPER); + nirqs = gic_d_read_4(sc, GICD_TYPER); nirqs = 32 * ((nirqs & 0x1f) + 1); for (i = 0; i < nirqs; i += 4) - gic_d_write_4(GICD_IPRIORITYR(i >> 2), 0); + gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); /* Set all the interrupts to be in Group 0 (secure) */ for (i = 0; i < nirqs; i += 32) { - gic_d_write_4(GICD_IGROUPR(i >> 5), 0); + gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } /* Enable CPU interface */ - gic_c_write_4(GICC_CTLR, 1); + gic_c_write_4(sc, GICC_CTLR, 1); /* Set priority mask register. */ - gic_c_write_4(GICC_PMR, 0xff); + gic_c_write_4(sc, GICC_PMR, 0xff); /* Enable interrupt distribution */ - gic_d_write_4(GICD_CTLR, 0x01); + gic_d_write_4(sc, GICD_CTLR, 0x01); /* * Activate the timer interrupts: virtual, secure, and non-secure. */ - gic_d_write_4(GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F))); - gic_d_write_4(GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F))); - gic_d_write_4(GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F))); + gic_d_write_4(sc, GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F))); + gic_d_write_4(sc, GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F))); + gic_d_write_4(sc, GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F))); } int @@ -266,49 +267,50 @@ arm_gic_attach(device_t dev) arm_gic_sc = sc; /* Disable interrupt forwarding to the CPU interface */ - gic_d_write_4(GICD_CTLR, 0x00); + gic_d_write_4(sc, GICD_CTLR, 0x00); /* Get the number of interrupts */ - sc->nirqs = gic_d_read_4(GICD_TYPER); + sc->nirqs = gic_d_read_4(sc, GICD_TYPER); sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1); /* Set up function pointers */ arm_post_filter = gic_post_filter; arm_config_irq = gic_config_irq; - icciidr = gic_c_read_4(GICC_IIDR); + icciidr = gic_c_read_4(sc, GICC_IIDR); device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n", icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf, (icciidr & 0xfff), sc->nirqs); /* Set all global interrupts to be level triggered, active low. */ for (i = 32; i < sc->nirqs; i += 16) { - gic_d_write_4(GICD_ICFGR(i >> 4), 0x00000000); + gic_d_write_4(sc, GICD_ICFGR(i >> 4), 0x00000000); } /* Disable all interrupts. */ for (i = 32; i < sc->nirqs; i += 32) { - gic_d_write_4(GICD_ICENABLER(i >> 5), 0xFFFFFFFF); + gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF); } for (i = 0; i < sc->nirqs; i += 4) { - gic_d_write_4(GICD_IPRIORITYR(i >> 2), 0); - gic_d_write_4(GICD_ITARGETSR(i >> 2), 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24); + gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); + gic_d_write_4(sc, GICD_ITARGETSR(i >> 2), + 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24); } /* Set all the interrupts to be in Group 0 (secure) */ for (i = 0; i < sc->nirqs; i += 32) { - gic_d_write_4(GICD_IGROUPR(i >> 5), 0); + gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } /* Enable CPU interface */ - gic_c_write_4(GICC_CTLR, 1); + gic_c_write_4(sc, GICC_CTLR, 1); /* Set priority mask register. */ - gic_c_write_4(GICC_PMR, 0xff); + gic_c_write_4(sc, GICC_PMR, 0xff); /* Enable interrupt distribution */ - gic_d_write_4(GICD_CTLR, 0x01); + gic_d_write_4(sc, GICD_CTLR, 0x01); return (0); } @@ -335,28 +337,29 @@ EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0, static void gic_post_filter(void *arg) { + struct arm_gic_softc *sc = arm_gic_sc; uintptr_t irq = (uintptr_t) arg; if (irq > GIC_LAST_IPI) arm_irq_memory_barrier(irq); - gic_c_write_4(GICC_EOIR, irq); + gic_c_write_4(sc, GICC_EOIR, irq); } int arm_get_next_irq(int last_irq) { + struct arm_gic_softc *sc = arm_gic_sc; uint32_t active_irq; - active_irq = gic_c_read_4(GICC_IAR); + active_irq = gic_c_read_4(sc, GICC_IAR); /* * Immediatly EOIR the SGIs, because doing so requires the other * bits (ie CPU number), not just the IRQ number, and we do not * have this information later. */ - if ((active_irq & 0x3ff) <= GIC_LAST_IPI) - gic_c_write_4(GICC_EOIR, active_irq); + gic_c_write_4(sc, GICC_EOIR, active_irq); active_irq &= 0x3FF; if (active_irq == 0x3FF) { @@ -371,29 +374,32 @@ arm_get_next_irq(int last_irq) void arm_mask_irq(uintptr_t nb) { + struct arm_gic_softc *sc = arm_gic_sc; - gic_d_write_4(GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F))); - gic_c_write_4(GICC_EOIR, nb); + gic_d_write_4(sc, GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F))); + gic_c_write_4(sc, GICC_EOIR, nb); } void arm_unmask_irq(uintptr_t nb) { + struct arm_gic_softc *sc = arm_gic_sc; if (nb > GIC_LAST_IPI) arm_irq_memory_barrier(nb); - gic_d_write_4(GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F))); + gic_d_write_4(sc, GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F))); } static int gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol) { + struct arm_gic_softc *sc = arm_gic_sc; uint32_t reg; uint32_t mask; /* Function is public-accessible, so validate input arguments */ - if ((irq < 0) || (irq >= arm_gic_sc->nirqs)) + if ((irq < 0) || (irq >= sc->nirqs)) goto invalid_args; if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) && (trig != INTR_TRIGGER_CONFORM)) @@ -402,9 +408,9 @@ gic_config_irq(int irq, enum intr_trigger trig, (pol != INTR_POLARITY_CONFORM)) goto invalid_args; - mtx_lock_spin(&arm_gic_sc->mutex); + mtx_lock_spin(&sc->mutex); - reg = gic_d_read_4(GICD_ICFGR(irq >> 4)); + reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4)); mask = (reg >> 2*(irq % 16)) & 0x3; if (pol == INTR_POLARITY_LOW) { @@ -426,14 +432,14 @@ gic_config_irq(int irq, enum intr_trigger trig, /* Set mask */ reg = reg & ~(0x3 << 2*(irq % 16)); reg = reg | (mask << 2*(irq % 16)); - gic_d_write_4(GICD_ICFGR(irq >> 4), reg); + gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg); - mtx_unlock_spin(&arm_gic_sc->mutex); + mtx_unlock_spin(&sc->mutex); return (0); invalid_args: - device_printf(arm_gic_sc->dev, "gic_config_irg, invalid parameters\n"); + device_printf(sc->dev, "gic_config_irg, invalid parameters\n"); return (EINVAL); } @@ -441,13 +447,14 @@ invalid_args: void pic_ipi_send(cpuset_t cpus, u_int ipi) { + struct arm_gic_softc *sc = arm_gic_sc; uint32_t val = 0, i; for (i = 0; i < MAXCPU; i++) if (CPU_ISSET(i, &cpus)) val |= 1 << (16 + i); - gic_d_write_4(GICD_SGIR(0), val | ipi); + gic_d_write_4(sc, GICD_SGIR(0), val | ipi); } int From 5f59ea478ec0c061b477ba801a5698513f0418f5 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Sun, 21 Dec 2014 16:32:57 +0000 Subject: [PATCH 062/207] Return the error from ahci_setup_interrupt in ahci_attach Previously ahci_attach returned a hard coded ENXIO instead of the value from ahci_setup_interrupt. This is effectively a NOOP change as currently ahci_setup_interrupt only ever returns 0 or ENXIO, so just there to protect against any future changes to that. Differential Revision: D838 MFC after: 2 weeks Sponsored by: Multiplay --- sys/dev/ahci/ahci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 8b4066f5820..35a32c1c269 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -231,12 +231,12 @@ ahci_attach(device_t dev) ahci_ctlr_setup(dev); /* Setup interrupts. */ - if (ahci_setup_interrupt(dev)) { + if ((error = ahci_setup_interrupt(dev)) != 0) { bus_dma_tag_destroy(ctlr->dma_tag); bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); rman_fini(&ctlr->sc_iomem); - return ENXIO; + return error; } i = 0; From 171af33c53f246e08da0ca776c842289a8948f08 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 16:35:42 +0000 Subject: [PATCH 063/207] Reduce the diff between head and arm_intrng with the bcm2835 interrupt controller. --- sys/arm/broadcom/bcm2835/bcm2835_intr.c | 29 ++++++++++++++----------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c index 7a06eb0162d..4d1489279aa 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c @@ -83,10 +83,10 @@ struct bcm_intc_softc { static struct bcm_intc_softc *bcm_intc_sc = NULL; -#define intc_read_4(reg) \ - bus_space_read_4(bcm_intc_sc->intc_bst, bcm_intc_sc->intc_bsh, reg) -#define intc_write_4(reg, val) \ - bus_space_write_4(bcm_intc_sc->intc_bst, bcm_intc_sc->intc_bsh, reg, val) +#define intc_read_4(_sc, reg) \ + bus_space_read_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg)) +#define intc_write_4(_sc, reg, val) \ + bus_space_write_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg), (val)) static int bcm_intc_probe(device_t dev) @@ -145,6 +145,7 @@ DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass, 0, 0); int arm_get_next_irq(int last_irq) { + struct bcm_intc_softc *sc = bcm_intc_sc; uint32_t pending; int32_t irq = last_irq + 1; @@ -154,7 +155,7 @@ arm_get_next_irq(int last_irq) /* TODO: should we mask last_irq? */ if (irq < BANK1_START) { - pending = intc_read_4(INTC_PENDING_BASIC); + pending = intc_read_4(sc, INTC_PENDING_BASIC); if ((pending & 0xFF) == 0) { irq = BANK1_START; /* skip to next bank */ } else do { @@ -164,7 +165,7 @@ arm_get_next_irq(int last_irq) } while (irq < BANK1_START); } if (irq < BANK2_START) { - pending = intc_read_4(INTC_PENDING_BANK1); + pending = intc_read_4(sc, INTC_PENDING_BANK1); if (pending == 0) { irq = BANK2_START; /* skip to next bank */ } else do { @@ -174,7 +175,7 @@ arm_get_next_irq(int last_irq) } while (irq < BANK2_START); } if (irq < BANK3_START) { - pending = intc_read_4(INTC_PENDING_BANK2); + pending = intc_read_4(sc, INTC_PENDING_BANK2); if (pending != 0) do { if (pending & (1 << IRQ_BANK2(irq))) return irq; @@ -187,14 +188,15 @@ arm_get_next_irq(int last_irq) void arm_mask_irq(uintptr_t nb) { + struct bcm_intc_softc *sc = bcm_intc_sc; dprintf("%s: %d\n", __func__, nb); if (IS_IRQ_BASIC(nb)) - intc_write_4(INTC_DISABLE_BASIC, (1 << nb)); + intc_write_4(sc, INTC_DISABLE_BASIC, (1 << nb)); else if (IS_IRQ_BANK1(nb)) - intc_write_4(INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb))); + intc_write_4(sc, INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb))); else if (IS_IRQ_BANK2(nb)) - intc_write_4(INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb))); + intc_write_4(sc, INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb))); else printf("arm_mask_irq: Invalid IRQ number: %d\n", nb); } @@ -202,14 +204,15 @@ arm_mask_irq(uintptr_t nb) void arm_unmask_irq(uintptr_t nb) { + struct bcm_intc_softc *sc = bcm_intc_sc; dprintf("%s: %d\n", __func__, nb); if (IS_IRQ_BASIC(nb)) - intc_write_4(INTC_ENABLE_BASIC, (1 << nb)); + intc_write_4(sc, INTC_ENABLE_BASIC, (1 << nb)); else if (IS_IRQ_BANK1(nb)) - intc_write_4(INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb))); + intc_write_4(sc, INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb))); else if (IS_IRQ_BANK2(nb)) - intc_write_4(INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb))); + intc_write_4(sc, INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb))); else printf("arm_mask_irq: Invalid IRQ number: %d\n", nb); } From e4a8f2e2ecffede5aa2ca1c729b0fb17f3901cc4 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Sun, 21 Dec 2014 16:38:29 +0000 Subject: [PATCH 064/207] style (9) nits Use return (val); instead of return val; Differential Revision: D838 MFC after: 2 weeks Sponsored by: Multiplay --- sys/dev/ahci/ahci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 35a32c1c269..31aab5d3f0f 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -142,7 +142,7 @@ ahci_ctlr_reset(device_t dev) } if (timeout == 0) { device_printf(dev, "AHCI controller reset failure\n"); - return ENXIO; + return (ENXIO); } /* Reenable AHCI mode */ ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE); @@ -225,7 +225,7 @@ ahci_attach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); rman_fini(&ctlr->sc_iomem); - return ENXIO; + return (ENXIO); } ahci_ctlr_setup(dev); @@ -236,7 +236,7 @@ ahci_attach(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); rman_fini(&ctlr->sc_iomem); - return error; + return (error); } i = 0; @@ -315,7 +315,7 @@ ahci_attach(device_t dev) device_set_ivars(child, (void *)(intptr_t)-1); } bus_generic_attach(dev); - return 0; + return (0); } int @@ -380,7 +380,7 @@ ahci_setup_interrupt(device_t dev) if (!(ctlr->irqs[i].r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &ctlr->irqs[i].r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) { device_printf(dev, "unable to map interrupt\n"); - return ENXIO; + return (ENXIO); } if ((bus_setup_intr(dev, ctlr->irqs[i].r_irq, ATA_INTR_FLAGS, NULL, (ctlr->irqs[i].mode != AHCI_IRQ_MODE_ONE) ? ahci_intr : @@ -389,7 +389,7 @@ ahci_setup_interrupt(device_t dev) &ctlr->irqs[i], &ctlr->irqs[i].handle))) { /* SOS XXX release r_irq */ device_printf(dev, "unable to setup interrupt\n"); - return ENXIO; + return (ENXIO); } if (ctlr->numirqs > 1) { bus_describe_intr(dev, ctlr->irqs[i].r_irq, @@ -537,7 +537,7 @@ ahci_release_resource(device_t dev, device_t child, int type, int rid, return (0); case SYS_RES_IRQ: if (rid != ATA_IRQ_RID) - return ENOENT; + return (ENOENT); return (0); } return (EINVAL); From 3d6451aef8b28a10c449eccab8e04c1f7a4cabc4 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 16:48:57 +0000 Subject: [PATCH 065/207] Reduce the diff in the Ti aintc between head and arm_intrng --- sys/arm/ti/aintc.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/sys/arm/ti/aintc.c b/sys/arm/ti/aintc.c index 213a1d366c7..675a5f35cd8 100644 --- a/sys/arm/ti/aintc.c +++ b/sys/arm/ti/aintc.c @@ -72,10 +72,10 @@ static struct resource_spec ti_aintc_spec[] = { static struct ti_aintc_softc *ti_aintc_sc = NULL; -#define aintc_read_4(reg) \ - bus_space_read_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg) -#define aintc_write_4(reg, val) \ - bus_space_write_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg, val) +#define aintc_read_4(_sc, reg) \ + bus_space_read_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg)) +#define aintc_write_4(_sc, reg, val) \ + bus_space_write_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg), (val)) static int @@ -112,17 +112,17 @@ ti_aintc_attach(device_t dev) ti_aintc_sc = sc; - x = aintc_read_4(INTC_REVISION); + x = aintc_read_4(sc, INTC_REVISION); device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF); /* SoftReset */ - aintc_write_4(INTC_SYSCONFIG, 2); + aintc_write_4(sc, INTC_SYSCONFIG, 2); /* Wait for reset to complete */ - while(!(aintc_read_4(INTC_SYSSTATUS) & 1)); + while(!(aintc_read_4(sc, INTC_SYSSTATUS) & 1)); /*Set Priority Threshold */ - aintc_write_4(INTC_THRESHOLD, 0xFF); + aintc_write_4(sc, INTC_THRESHOLD, 0xFF); return (0); } @@ -146,22 +146,23 @@ DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0); int arm_get_next_irq(int last_irq) { + struct ti_aintc_softc *sc = ti_aintc_sc; uint32_t active_irq; if (last_irq != -1) { - aintc_write_4(INTC_ISR_CLEAR(last_irq >> 5), + aintc_write_4(sc, INTC_ISR_CLEAR(last_irq >> 5), 1UL << (last_irq & 0x1F)); - aintc_write_4(INTC_CONTROL,1); + aintc_write_4(sc, INTC_CONTROL, 1); } /* Get the next active interrupt */ - active_irq = aintc_read_4(INTC_SIR_IRQ); + active_irq = aintc_read_4(sc, INTC_SIR_IRQ); /* Check for spurious interrupt */ if ((active_irq & 0xffffff80)) { - device_printf(ti_aintc_sc->sc_dev, - "Spurious interrupt detected (0x%08x)\n", active_irq); - aintc_write_4(INTC_SIR_IRQ, 0); + device_printf(sc->sc_dev, + "Spurious interrupt detected (0x%08x)\n", active_irq); + aintc_write_4(sc, INTC_SIR_IRQ, 0); return -1; } @@ -174,13 +175,16 @@ arm_get_next_irq(int last_irq) void arm_mask_irq(uintptr_t nb) { - aintc_write_4(INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F))); + struct ti_aintc_softc *sc = ti_aintc_sc; + + aintc_write_4(sc, INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F))); } void arm_unmask_irq(uintptr_t nb) { + struct ti_aintc_softc *sc = ti_aintc_sc; arm_irq_memory_barrier(nb); - aintc_write_4(INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F))); + aintc_write_4(sc, INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F))); } From 27ad9746c02c89e3baea49fa92204890c6331b10 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 16:59:41 +0000 Subject: [PATCH 066/207] Reduce the diff between the lpc interrupt controller in head and arm_intrng --- sys/arm/lpc/lpc_intc.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/sys/arm/lpc/lpc_intc.c b/sys/arm/lpc/lpc_intc.c index 3137e89c572..bf26645d742 100644 --- a/sys/arm/lpc/lpc_intc.c +++ b/sys/arm/lpc/lpc_intc.c @@ -59,10 +59,10 @@ static void lpc_intc_eoi(void *); static struct lpc_intc_softc *intc_softc = NULL; -#define intc_read_4(reg) \ - bus_space_read_4(intc_softc->li_bst, intc_softc->li_bsh, reg) -#define intc_write_4(reg, val) \ - bus_space_write_4(intc_softc->li_bst, intc_softc->li_bsh, reg, val) +#define intc_read_4(_sc, _reg) \ + bus_space_read_4((_sc)->li_bst, (_sc)->li_bsh, (_reg)) +#define intc_write_4(_sc, _reg, _val) \ + bus_space_write_4((_sc)->li_bst, (_sc)->li_bsh, (_reg), (_val)) static int lpc_intc_probe(device_t dev) @@ -100,12 +100,12 @@ lpc_intc_attach(device_t dev) arm_post_filter = lpc_intc_eoi; /* Clear interrupt status registers and disable all interrupts */ - intc_write_4(LPC_INTC_MIC_ER, 0); - intc_write_4(LPC_INTC_SIC1_ER, 0); - intc_write_4(LPC_INTC_SIC2_ER, 0); - intc_write_4(LPC_INTC_MIC_RSR, ~0); - intc_write_4(LPC_INTC_SIC1_RSR, ~0); - intc_write_4(LPC_INTC_SIC2_RSR, ~0); + intc_write_4(sc, LPC_INTC_MIC_ER, 0); + intc_write_4(sc, LPC_INTC_SIC1_ER, 0); + intc_write_4(sc, LPC_INTC_SIC2_ER, 0); + intc_write_4(sc, LPC_INTC_MIC_RSR, ~0); + intc_write_4(sc, LPC_INTC_SIC1_RSR, ~0); + intc_write_4(sc, LPC_INTC_SIC2_RSR, ~0); return (0); } @@ -128,25 +128,26 @@ DRIVER_MODULE(pic, simplebus, lpc_intc_driver, lpc_intc_devclass, 0, 0); int arm_get_next_irq(int last) { + struct lpc_intc_softc *sc = intc_softc; uint32_t value; int i; /* IRQs 0-31 are mapped to LPC_INTC_MIC_SR */ - value = intc_read_4(LPC_INTC_MIC_SR); + value = intc_read_4(sc, LPC_INTC_MIC_SR); for (i = 0; i < 32; i++) { if (value & (1 << i)) return (i); } /* IRQs 32-63 are mapped to LPC_INTC_SIC1_SR */ - value = intc_read_4(LPC_INTC_SIC1_SR); + value = intc_read_4(sc, LPC_INTC_SIC1_SR); for (i = 0; i < 32; i++) { if (value & (1 << i)) return (i + 32); } /* IRQs 64-95 are mapped to LPC_INTC_SIC2_SR */ - value = intc_read_4(LPC_INTC_SIC2_SR); + value = intc_read_4(sc, LPC_INTC_SIC2_SR); for (i = 0; i < 32; i++) { if (value & (1 << i)) return (i + 64); @@ -158,6 +159,7 @@ arm_get_next_irq(int last) void arm_mask_irq(uintptr_t nb) { + struct lpc_intc_softc *sc = intc_softc; int reg; uint32_t value; @@ -174,14 +176,15 @@ arm_mask_irq(uintptr_t nb) reg = LPC_INTC_MIC_ER; /* Clear bit in ER register */ - value = intc_read_4(reg); + value = intc_read_4(sc, reg); value &= ~(1 << nb); - intc_write_4(reg, value); + intc_write_4(sc, reg, value); } void arm_unmask_irq(uintptr_t nb) { + struct lpc_intc_softc *sc = intc_softc; int reg; uint32_t value; @@ -195,14 +198,15 @@ arm_unmask_irq(uintptr_t nb) reg = LPC_INTC_MIC_ER; /* Set bit in ER register */ - value = intc_read_4(reg); + value = intc_read_4(sc, reg); value |= (1 << nb); - intc_write_4(reg, value); + intc_write_4(sc, reg, value); } static void lpc_intc_eoi(void *data) { + struct lpc_intc_softc *sc = intc_softc; int reg; int nb = (int)data; uint32_t value; @@ -217,9 +221,9 @@ lpc_intc_eoi(void *data) reg = LPC_INTC_MIC_RSR; /* Set bit in RSR register */ - value = intc_read_4(reg); + value = intc_read_4(sc, reg); value |= (1 << nb); - intc_write_4(reg, value); + intc_write_4(sc, reg, value); } From 18f4019f87d6453a429d4f5e34a53f3c30db4935 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Dec 2014 17:10:24 +0000 Subject: [PATCH 067/207] Allow whitspace to appear between device name and unit number in loaderdev. This allows the same value to be used in u-boot commands and the loaderdev env var that gets passed to ubldr, for example 'fatload mmc 1 ${bootfile}". --- sys/boot/uboot/common/main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/boot/uboot/common/main.c b/sys/boot/uboot/common/main.c index ae77766d1a8..f58d0c427e0 100644 --- a/sys/boot/uboot/common/main.c +++ b/sys/boot/uboot/common/main.c @@ -212,10 +212,11 @@ get_load_device(int *type, int *unit, int *slice, int *partition) p = get_device_type(devstr, type); - /* - * Empty device string, or unknown device name, or a bare, known - * device name. - */ + /* Ignore optional spaces after the device name. */ + while (*p == ' ') + p++; + + /* Unknown device name, or a known name without unit number. */ if ((*type == -1) || (*p == '\0')) { return; } From b4843bd68b17c8cb758f6dfb90ff7e72c9d54b0a Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Sun, 21 Dec 2014 17:21:29 +0000 Subject: [PATCH 068/207] Switch zfsboot installer force 4K option to use vfs.zfs.min_auto_ashift=12 Previously we used gnop(8) to fake 4K sector size disks but ZFS now has a sysctl to control this when creating new top level vdev's so use that instead. Differential Revision: D566 MFC after: 1 month Sponsored by: Multiplay --- usr.sbin/bsdinstall/scripts/zfsboot | 65 +++++++++-------------------- 1 file changed, 19 insertions(+), 46 deletions(-) diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot index 2b01dea09e1..673961aef98 100755 --- a/usr.sbin/bsdinstall/scripts/zfsboot +++ b/usr.sbin/bsdinstall/scripts/zfsboot @@ -65,9 +65,9 @@ f_include $BSDCFG_SHARE/variable.subr : ${ZFSBOOT_VDEV_TYPE:=stripe} # -# Should we use gnop(8) to configure a transparent mapping to 4K sectors? +# Should we use sysctl(8) vfs.zfs.min_auto_ashift=12 to force 4K sectors? # -: ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:=1} +: ${ZFSBOOT_FORCE_4K_SECTORS:=1} # # Should we use geli(8) to encrypt the drives? @@ -185,8 +185,6 @@ ECHO_APPEND='echo "%s" >> "%s"' GELI_ATTACH='geli attach -j - -k "%s" "%s"' GELI_DETACH_F='geli detach -f "%s"' GELI_PASSWORD_INIT='geli init -b -B "%s" -e %s -J - -K "%s" -l 256 -s 4096 "%s"' -GNOP_CREATE='gnop create -S 4096 "%s"' -GNOP_DESTROY='gnop destroy "%s"' GPART_ADD='gpart add -t %s "%s"' GPART_ADD_INDEX='gpart add -i %s -t %s "%s"' GPART_ADD_INDEX_WITH_SIZE='gpart add -i %s -t %s -s %s "%s"' @@ -205,6 +203,7 @@ PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\"" PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"' SHELL_TRUNCATE=':> "%s"' SWAP_GMIRROR_LABEL='gmirror label swap %s' +SYSCTL_ZFS_MIN_ASHIFT_12='sysctl vfs.zfs.min_auto_ashift=12' UMOUNT='umount "%s"' ZFS_CREATE_WITH_OPTIONS='zfs create %s "%s"' ZFS_SET='zfs set "%s" "%s"' @@ -236,7 +235,7 @@ msg_encrypt_disks="Encrypt Disks?" msg_encrypt_disks_help="Use geli(8) to encrypt all data partitions" msg_error="Error" msg_force_4k_sectors="Force 4K Sectors?" -msg_force_4k_sectors_help="Use gnop(8) to configure forced 4K sector alignment" +msg_force_4k_sectors_help="Use sysctl(8) vfs.zfs.min_auto_ashift=12 to force 4K sectors" msg_freebsd_installer="FreeBSD Installer" msg_geli_password="Enter a strong passphrase, used to protect your encryption keys. You will be required to enter this passphrase each time the system is booted" msg_geli_setup="Initializing encryption on selected disks,\n this will take several seconds per disk" @@ -315,7 +314,7 @@ dialog_menu_main() local usegeli="$msg_no" local swapgeli="$msg_no" local swapmirror="$msg_no" - [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && force4k="$msg_yes" + [ "$ZFSBOOT_FORCE_4K_SECTORS" ] && force4k="$msg_yes" [ "$ZFSBOOT_GELI_ENCRYPTION" ] && usegeli="$msg_yes" [ "$ZFSBOOT_SWAP_ENCRYPTION" ] && swapgeli="$msg_yes" [ "$ZFSBOOT_SWAP_MIRROR" ] && swapmirror="$msg_yes" @@ -1062,36 +1061,22 @@ zfs_create_boot() # Prepare the disks and build pool device list(s) # f_dprintf "$funcname: Preparing disk partitions for ZFS pool..." - [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && - f_dprintf "$funcname: With 4k alignment using gnop(8)..." + + # Force 4K sectors using vfs.zfs.min_auto_ashift=12 + if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then + f_dprintf "$funcname: With 4K sectors..." + f_eval_catch $funcname sysctl "$SYSCTL_ZFS_MIN_ASHIFT_12" \ + || return $FAILURE + fi local n=0 for disk in $disks; do zfs_create_diskpart $disk $n || return $FAILURE # Now $bootpart, $targetpart, and $swappart are set (suffix # for $disk) - - # Forced 4k alignment support using Geom NOP (see gnop(8)) - if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then - if [ "$ZFSBOOT_BOOT_POOL" ]; then - boot_vdevs="$boot_vdevs $disk$bootpart.nop" - f_eval_catch $funcname gnop "$GNOP_CREATE" \ - $disk$bootpart || return $FAILURE - fi - # Don't gnop encrypted partition - if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then - zroot_vdevs="$zroot_vdevs $disk$targetpart.eli" - else - zroot_vdevs="$zroot_vdevs $disk$targetpart.nop" - f_eval_catch $funcname gnop "$GNOP_CREATE" \ - $disk$targetpart || - return $FAILURE - fi - else - if [ "$ZFSBOOT_BOOT_POOL" ]; then - boot_vdevs="$boot_vdevs $disk$bootpart" - fi - zroot_vdevs="$zroot_vdevs $disk$targetpart" + if [ "$ZFSBOOT_BOOT_POOL" ]; then + boot_vdevs="$boot_vdevs $disk$bootpart" fi + zroot_vdevs="$zroot_vdevs $disk$targetpart" n=$(( $n + 1 )) done # disks @@ -1266,18 +1251,6 @@ zfs_create_boot() "$bootpool_name" || return $FAILURE fi - # Destroy the gnop devices (if enabled) - for disk in ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:+$disks}; do - if [ "$ZFSBOOT_BOOT_POOL" ]; then - f_eval_catch -d $funcname gnop "$GNOP_DESTROY" \ - $disk$bootpart.nop - fi - if [ ! "$ZFSBOOT_GELI_ENCRYPTION" ]; then - f_eval_catch -d $funcname gnop "$GNOP_DESTROY" \ - $disk$targetpart.nop - fi - done - # MBR boot loader touch-up if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then f_dprintf "$funcname: Updating MBR boot loader on disks..." @@ -1544,10 +1517,10 @@ while :; do ;; ?" $msg_force_4k_sectors") # Toggle the variable referenced both by the menu and later - if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then - ZFSBOOT_GNOP_4K_FORCE_ALIGN= + if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then + ZFSBOOT_FORCE_4K_SECTORS= else - ZFSBOOT_GNOP_4K_FORCE_ALIGN=1 + ZFSBOOT_FORCE_4K_SECTORS=1 fi ;; ?" $msg_encrypt_disks") @@ -1555,7 +1528,7 @@ while :; do if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then ZFSBOOT_GELI_ENCRYPTION= else - ZFSBOOT_GNOP_4K_FORCE_ALIGN=1 + ZFSBOOT_FORCE_4K_SECTORS=1 ZFSBOOT_GELI_ENCRYPTION=1 fi ;; From d0e17309d7926101dacb556035d5930bf9ecc471 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 17:25:21 +0000 Subject: [PATCH 069/207] Further reduce the diff between the arm_intrng gic driver and the version in head. --- sys/arm/arm/gic.c | 60 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index 56041dae90e..10513a68151 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -99,13 +99,13 @@ __FBSDID("$FreeBSD$"); #define GICD_ICFGR_TRIG_MASK 0x2 struct arm_gic_softc { + device_t gic_dev; struct resource * gic_res[3]; bus_space_tag_t gic_c_bst; bus_space_tag_t gic_d_bst; bus_space_handle_t gic_c_bsh; bus_space_handle_t gic_d_bsh; uint8_t ver; - device_t dev; struct mtx mutex; uint32_t nirqs; }; @@ -159,17 +159,13 @@ void gic_init_secondary(void) { struct arm_gic_softc *sc = arm_gic_sc; - int i, nirqs; + int i; - /* Get the number of interrupts */ - nirqs = gic_d_read_4(sc, GICD_TYPER); - nirqs = 32 * ((nirqs & 0x1f) + 1); - - for (i = 0; i < nirqs; i += 4) + for (i = 0; i < sc->nirqs; i += 4) gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0); /* Set all the interrupts to be in Group 0 (secure) */ - for (i = 0; i < nirqs; i += 32) { + for (i = 0; i < sc->nirqs; i += 32) { gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0); } @@ -246,13 +242,15 @@ arm_gic_attach(device_t dev) return (ENXIO); sc = device_get_softc(dev); - sc->dev = dev; if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) { device_printf(dev, "could not allocate resources\n"); return (ENXIO); } + sc->gic_dev = dev; + arm_gic_sc = sc; + /* Initialize mutex */ mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN); @@ -264,8 +262,6 @@ arm_gic_attach(device_t dev) sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]); sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]); - arm_gic_sc = sc; - /* Disable interrupt forwarding to the CPU interface */ gic_d_write_4(sc, GICD_CTLR, 0x00); @@ -315,25 +311,6 @@ arm_gic_attach(device_t dev) return (0); } -static device_method_t arm_gic_methods[] = { - DEVMETHOD(device_probe, arm_gic_probe), - DEVMETHOD(device_attach, arm_gic_attach), - { 0, 0 } -}; - -static driver_t arm_gic_driver = { - "gic", - arm_gic_methods, - sizeof(struct arm_gic_softc), -}; - -static devclass_t arm_gic_devclass; - -EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0, - BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); -EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0, - BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); - static void gic_post_filter(void *arg) { @@ -395,6 +372,7 @@ gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol) { struct arm_gic_softc *sc = arm_gic_sc; + device_t dev = sc->gic_dev; uint32_t reg; uint32_t mask; @@ -439,7 +417,7 @@ gic_config_irq(int irq, enum intr_trigger trig, return (0); invalid_args: - device_printf(sc->dev, "gic_config_irg, invalid parameters\n"); + device_printf(dev, "gic_config_irg, invalid parameters\n"); return (EINVAL); } @@ -470,6 +448,7 @@ pic_ipi_get(int i) return (0); return (i); } + return (0x3ff); } @@ -479,3 +458,22 @@ pic_ipi_clear(int ipi) } #endif +static device_method_t arm_gic_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, arm_gic_probe), + DEVMETHOD(device_attach, arm_gic_attach), + { 0, 0 } +}; + +static driver_t arm_gic_driver = { + "gic", + arm_gic_methods, + sizeof(struct arm_gic_softc), +}; + +static devclass_t arm_gic_devclass; + +EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); +EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0, + BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); From 9d87c6c8fb6f7cc932f03bf382a8cb0feebb9ab6 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Dec 2014 21:11:54 +0000 Subject: [PATCH 070/207] Remove a volatile qualifier on return type that is ignored and results in a -Wreturn-type warning when compiled with gcc. --- sys/arm/ti/ti_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/ti/ti_wdt.c b/sys/arm/ti/ti_wdt.c index 7f50a618d61..7e8e5aed07e 100644 --- a/sys/arm/ti/ti_wdt.c +++ b/sys/arm/ti/ti_wdt.c @@ -95,7 +95,7 @@ static devclass_t ti_wdt_devclass; DRIVER_MODULE(ti_wdt, simplebus, ti_wdt_driver, ti_wdt_devclass, 0, 0); -static volatile __inline uint32_t +static __inline uint32_t ti_wdt_reg_read(struct ti_wdt_softc *sc, uint32_t reg) { From f55abc7e4b6eda1f4250a9770396190019d9cf55 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Dec 2014 21:23:53 +0000 Subject: [PATCH 071/207] Eliminate a redundant declaration. --- sys/arm/at91/at91_machdep.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c index 0f6b79ba767..293a352cb10 100644 --- a/sys/arm/at91/at91_machdep.c +++ b/sys/arm/at91/at91_machdep.c @@ -117,8 +117,6 @@ extern struct bus_space at91_bs_tag; struct pv_addr kernel_pt_table[NUM_KERNEL_PTS]; -extern uint32_t at91_master_clock; - /* Static device mappings. */ const struct arm_devmap_entry at91_devmap[] = { /* From 734ba86366e6617f3fd62b5a5f1c9edde7093b1d Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Dec 2014 21:24:19 +0000 Subject: [PATCH 072/207] Eliminate a "cast discards qualifiers" warning when building with gcc. --- sys/dev/beri/virtio/virtio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/beri/virtio/virtio.c b/sys/dev/beri/virtio/virtio.c index 4cc25c2c468..cb7c2934d22 100644 --- a/sys/dev/beri/virtio/virtio.c +++ b/sys/dev/beri/virtio/virtio.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -156,7 +157,7 @@ vq_getchain(uint32_t offs, struct vqueue_info *vq, break; next = be16toh(vp->next); } - paddr_unmap((void *)vindir, be32toh(vdir->len)); + paddr_unmap(__DEVOLATILE(void *, vindir), be32toh(vdir->len)); } if ((be16toh(vdir->flags) & VRING_DESC_F_NEXT) == 0) From ec7d251e09845cca95abe7088b4ffb62849395ff Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 21:27:12 +0000 Subject: [PATCH 073/207] Pull out the fdt mapping code into intr.c. The arm_intrng branch also defines this function allowing the mapping method to change when we move to it. --- sys/arm/arm/intr.c | 39 +++++++++++++++++++++++++++++++++++++++ sys/arm/arm/nexus.c | 28 +++------------------------- sys/arm/include/intr.h | 8 ++++++++ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/sys/arm/arm/intr.c b/sys/arm/arm/intr.c index 83eca077782..030407a6ddc 100644 --- a/sys/arm/arm/intr.c +++ b/sys/arm/arm/intr.c @@ -36,8 +36,11 @@ * Soft interrupt and other generic interrupt functions. */ +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); + #include #include #include @@ -47,10 +50,16 @@ __FBSDID("$FreeBSD$"); #include #include #include + #include #include #include +#ifdef FDT +#include +#include +#endif + #define INTRNAME_LEN (MAXCOMLEN + 1) typedef void (*mask_fn)(void *); @@ -89,6 +98,36 @@ intr_init(void *unused) SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL); +#ifdef FDT +int +arm_fdt_map_irq(phandle_t iparent, pcell_t *intr, int icells) +{ + fdt_pic_decode_t intr_decode; + phandle_t intr_parent; + int i, rv, interrupt, trig, pol; + + intr_parent = OF_node_from_xref(iparent); + for (i = 0; i < icells; i++) + intr[i] = cpu_to_fdt32(intr[i]); + + for (i = 0; fdt_pic_table[i] != NULL; i++) { + intr_decode = fdt_pic_table[i]; + rv = intr_decode(intr_parent, intr, &interrupt, &trig, &pol); + + if (rv == 0) { + /* This was recognized as our PIC and decoded. */ + interrupt = FDT_MAP_IRQ(intr_parent, interrupt); + return (interrupt); + } + } + + /* Not in table, so guess */ + interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0])); + + return (interrupt); +} +#endif + void arm_setup_irqhandler(const char *name, driver_filter_t *filt, void (*hand)(void*), void *arg, int irq, int flags, void **cookiep) diff --git a/sys/arm/arm/nexus.c b/sys/arm/arm/nexus.c index 6678d5db9b8..06f2d6ff454 100644 --- a/sys/arm/arm/nexus.c +++ b/sys/arm/arm/nexus.c @@ -39,6 +39,8 @@ * and I/O memory address space. */ +#include "opt_platform.h" + #include __FBSDID("$FreeBSD$"); @@ -60,10 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include "opt_platform.h" - #ifdef FDT -#include #include #include "ofw_bus_if.h" #endif @@ -351,28 +350,7 @@ static int nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells, pcell_t *intr) { - fdt_pic_decode_t intr_decode; - phandle_t intr_parent; - int i, rv, interrupt, trig, pol; - intr_parent = OF_node_from_xref(iparent); - for (i = 0; i < icells; i++) - intr[i] = cpu_to_fdt32(intr[i]); - - for (i = 0; fdt_pic_table[i] != NULL; i++) { - intr_decode = fdt_pic_table[i]; - rv = intr_decode(intr_parent, intr, &interrupt, &trig, &pol); - - if (rv == 0) { - /* This was recognized as our PIC and decoded. */ - interrupt = FDT_MAP_IRQ(intr_parent, interrupt); - return (interrupt); - } - } - - /* Not in table, so guess */ - interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0])); - - return (interrupt); + return (arm_fdt_map_irq(iparent, intr, icells)); } #endif diff --git a/sys/arm/include/intr.h b/sys/arm/include/intr.h index 35097725b71..9ee86f342ce 100644 --- a/sys/arm/include/intr.h +++ b/sys/arm/include/intr.h @@ -39,6 +39,10 @@ #ifndef _MACHINE_INTR_H_ #define _MACHINE_INTR_H_ +#ifdef FDT +#include +#endif + /* XXX move to std.* files? */ #ifdef CPU_XSCALE_81342 #define NIRQ 128 @@ -85,4 +89,8 @@ void gic_init_secondary(void); int gic_decode_fdt(uint32_t iparentnode, uint32_t *intrcells, int *interrupt, int *trig, int *pol); +#ifdef FDT +int arm_fdt_map_irq(phandle_t, pcell_t *, int); +#endif + #endif /* _MACHINE_INTR_H */ From c18b81e54b2a5ceaaaba183ce44df9e7d3efbe5b Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Sun, 21 Dec 2014 21:38:12 +0000 Subject: [PATCH 074/207] Fix the unwinder to get past functions with no stack but may cause an exception. In this case no registers will be updated but the link register will be copied to the program counter to be used to find the calling function. In this case the program counter may be updated and we should continue with the trace. --- sys/arm/arm/db_trace.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c index e0d75526685..0f06486c9d1 100644 --- a/sys/arm/arm/db_trace.c +++ b/sys/arm/arm/db_trace.c @@ -345,9 +345,16 @@ db_unwind_tab(struct unwind_state *state) /* * The program counter was not updated, load it from the link register. */ - if (state->registers[PC] == 0) + if (state->registers[PC] == 0) { state->registers[PC] = state->registers[LR]; + /* + * If the program counter changed, flag it in the update mask. + */ + if (state->start_pc != state->registers[PC]) + state->update_mask |= 1 << PC; + } + return 0; } From f649ab8b15b86b697b7c678fa34235f08be041de Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 21 Dec 2014 22:18:30 +0000 Subject: [PATCH 075/207] sh: Remove EXP_REDIR. EXP_REDIR was supposed to generate pathnames in redirection if exactly one file matches, as permitted but not required by POSIX in interactive mode. It is unlikely this will be implemented. No functional change is intended. MFC after: 1 week --- bin/sh/eval.c | 4 ++-- bin/sh/expand.c | 18 ++++++------------ bin/sh/expand.h | 1 - 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/bin/sh/eval.c b/bin/sh/eval.c index d0460a024e3..486de9c1aa1 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -539,13 +539,13 @@ expredir(union node *n) case NFROMTO: case NAPPEND: case NCLOBBER: - expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); + expandarg(redir->nfile.fname, &fn, EXP_TILDE); redir->nfile.expfname = fn.list->text; break; case NFROMFD: case NTOFD: if (redir->ndup.vname) { - expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR); + expandarg(redir->ndup.vname, &fn, EXP_TILDE); fixredir(redir, fn.list->text, 1); } break; diff --git a/bin/sh/expand.c b/bin/sh/expand.c index fd8b996d7e4..b542303d239 100644 --- a/bin/sh/expand.c +++ b/bin/sh/expand.c @@ -171,17 +171,12 @@ expandarg(union node *arg, struct arglist *arglist, int flag) STPUTC('\0', expdest); p = grabstackstr(expdest); exparg.lastp = &exparg.list; - /* - * TODO - EXP_REDIR - */ if (flag & EXP_FULL) { ifsbreakup(p, &exparg); *exparg.lastp = NULL; exparg.lastp = &exparg.list; expandmeta(exparg.list, flag); } else { - if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ - rmescapes(p); sp = (struct strlist *)stalloc(sizeof (struct strlist)); sp->text = p; *exparg.lastp = sp; @@ -209,7 +204,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) * expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE. * Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'. * This is used to expand word in ${var+word} etc. - * If EXP_FULL, EXP_CASE or EXP_REDIR are set, keep and/or generate CTLESC + * If EXP_FULL or EXP_CASE are set, keep and/or generate CTLESC * characters to allow for further processing. * If EXP_FULL is set, also preserve CTLQUOTEMARK characters. */ @@ -217,7 +212,7 @@ static char * argstr(char *p, int flag) { char c; - int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */ + int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */ int firsteq = 1; int split_lit; int lit_quoted; @@ -303,7 +298,7 @@ exptilde(char *p, int flag) char c, *startp = p; struct passwd *pw; char *home; - int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); + int quotes = flag & (EXP_FULL | EXP_CASE); while ((c = *p) != '\0') { switch(c) { @@ -437,7 +432,7 @@ expbackq(union node *cmd, int quoted, int flag) char lastc; int startloc = dest - stackblock(); char const *syntax = quoted? DQSYNTAX : BASESYNTAX; - int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); + int quotes = flag & (EXP_FULL | EXP_CASE); size_t nnl; INTOFF; @@ -637,7 +632,7 @@ evalvar(char *p, int flag) int varlen; int varlenb; int easy; - int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); + int quotes = flag & (EXP_FULL | EXP_CASE); varflags = (unsigned char)*p++; subtype = varflags & VSTYPE; @@ -862,7 +857,7 @@ varisset(const char *name, int nulok) static void strtodest(const char *p, int flag, int subtype, int quoted) { - if (flag & (EXP_FULL | EXP_CASE | EXP_REDIR) && subtype != VSLENGTH) + if (flag & (EXP_FULL | EXP_CASE) && subtype != VSLENGTH) STPUTS_QUOTES(p, quoted ? DQSYNTAX : BASESYNTAX, expdest); else STPUTS(p, expdest); @@ -1104,7 +1099,6 @@ expandmeta(struct strlist *str, int flag __unused) struct strlist **savelastp; struct strlist *sp; char c; - /* TODO - EXP_REDIR */ while (str) { savelastp = exparg.lastp; diff --git a/bin/sh/expand.h b/bin/sh/expand.h index 7495a633ef4..93c80f3013e 100644 --- a/bin/sh/expand.h +++ b/bin/sh/expand.h @@ -50,7 +50,6 @@ struct arglist { #define EXP_FULL 0x1 /* perform word splitting & file globbing */ #define EXP_TILDE 0x2 /* do normal tilde expansion */ #define EXP_VARTILDE 0x4 /* expand tildes in an assignment */ -#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */ #define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */ #define EXP_SPLIT_LIT 0x20 /* IFS split literal text ${v+-a b c} */ #define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */ From 85052e7b56c16d12d8c705c9347408852ee94758 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 21 Dec 2014 23:09:59 +0000 Subject: [PATCH 076/207] sh: Move some code from onint() to onsig(), making onint() noreturn. As a result, the INTON macro which is used many times generates fewer bytes of code. --- bin/sh/error.c | 26 +++++++++----------------- bin/sh/error.h | 3 ++- bin/sh/trap.c | 12 ++++++++++-- bin/sh/trap.h | 1 - 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/bin/sh/error.c b/bin/sh/error.c index 96a0092d5bb..fedffaaaad6 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -90,13 +90,14 @@ exraise(int e) /* - * Called from trap.c when a SIGINT is received. (If the user specifies - * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. If SIGINTs are not suppressed and - * the shell is not a root shell, then we want to be terminated if we - * get here, as if we were terminated directly by a SIGINT. Arrange for - * this here. + * Called from trap.c when a SIGINT is received and not suppressed, or when + * an interrupt is pending and interrupts are re-enabled using INTON. + * (If the user specifies that SIGINT is to be trapped or ignored using the + * trap builtin, then this routine is not called.) Suppressint is nonzero + * when interrupts are held using the INTOFF macro. If SIGINTs are not + * suppressed and the shell is not a root shell, then we want to be + * terminated if we get here, as if we were terminated directly by a SIGINT. + * Arrange for this here. */ void @@ -104,16 +105,6 @@ onint(void) { sigset_t sigs; - /* - * The !in_dotrap here is safe. The only way we can arrive here - * with in_dotrap set is that a trap handler set SIGINT to SIG_DFL - * and killed itself. - */ - - if (suppressint && !in_dotrap) { - intpending++; - return; - } intpending = 0; sigemptyset(&sigs); sigprocmask(SIG_SETMASK, &sigs, NULL); @@ -130,6 +121,7 @@ onint(void) else { signal(SIGINT, SIG_DFL); kill(getpid(), SIGINT); + _exit(128 + SIGINT); } } diff --git a/bin/sh/error.h b/bin/sh/error.h index d0a4bca7477..a60b1fa1767 100644 --- a/bin/sh/error.h +++ b/bin/sh/error.h @@ -75,11 +75,12 @@ extern volatile sig_atomic_t intpending; #define is_int_on() suppressint #define SETINTON(s) suppressint = (s) #define FORCEINTON {suppressint = 0; if (intpending) onint();} +#define SET_PENDING_INT intpending = 1 #define CLEAR_PENDING_INT intpending = 0 #define int_pending() intpending void exraise(int) __dead2; -void onint(void); +void onint(void) __dead2; void warning(const char *, ...) __printflike(1, 2); void error(const char *, ...) __printf0like(1, 2) __dead2; void exerror(int, const char *, ...) __printf0like(2, 3) __dead2; diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 8ea3b126e1b..c23e6bc3b1a 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$"); static char sigmode[NSIG]; /* current value of signal */ volatile sig_atomic_t pendingsig; /* indicates some signal received */ volatile sig_atomic_t pendingsig_waitcmd; /* indicates SIGINT/SIGQUIT received */ -int in_dotrap; /* do we execute in a trap handler? */ +static int in_dotrap; /* do we execute in a trap handler? */ static char *volatile trap[NSIG]; /* trap handler commands */ static volatile sig_atomic_t gotsig[NSIG]; /* indicates specified signal received */ @@ -380,7 +380,15 @@ onsig(int signo) { if (signo == SIGINT && trap[SIGINT] == NULL) { - onint(); + /* + * The !in_dotrap here is safe. The only way we can arrive + * here with in_dotrap set is that a trap handler set SIGINT to + * SIG_DFL and killed itself. + */ + if (suppressint && !in_dotrap) + SET_PENDING_INT; + else + onint(); return; } diff --git a/bin/sh/trap.h b/bin/sh/trap.h index 541b9b149a8..a2728392699 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -35,7 +35,6 @@ extern volatile sig_atomic_t pendingsig; extern volatile sig_atomic_t pendingsig_waitcmd; -extern int in_dotrap; void clear_traps(void); int have_traps(void); From 040610408e9e0a676956e5ca32f40f58eb899f1e Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Dec 2014 23:45:13 +0000 Subject: [PATCH 077/207] Allow -march=armv7a on the gcc command line, for compatibility with clang. This will result in __ARM_ARCH_7A__ being defined during the compile. When compiling with gcc, it will still only generate armv6 opcodes itself, but should pass the arch to gas so that inline asm can use v7 opcodes. --- contrib/gcc/config/arm/arm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/gcc/config/arm/arm.c b/contrib/gcc/config/arm/arm.c index 4029e58bc78..d8f1f0791da 100644 --- a/contrib/gcc/config/arm/arm.c +++ b/contrib/gcc/config/arm/arm.c @@ -604,6 +604,8 @@ static const struct processors all_architectures[] = {"armv6k", mpcore, "6K", FL_CO_PROC | FL_FOR_ARCH6K, NULL}, {"armv6z", arm1176jzs, "6Z", FL_CO_PROC | FL_FOR_ARCH6Z, NULL}, {"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL}, + /* Clang compatibility... define __ARM_ARCH_7A__, but codegen is still 6ZK. */ + {"armv7a", arm1176jzs, "7A", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL}, {"ep9312", ep9312, "4T", FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL}, {"iwmmxt", iwmmxt, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL}, {NULL, arm_none, NULL, 0 , NULL} From 92e8bbfdfd2e8b645ab5bdca33bed75e88700d46 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Sun, 21 Dec 2014 23:47:30 +0000 Subject: [PATCH 078/207] Add __FreeBSD_version guards around hsearch_r to ease MFCing the code to stable/10 It was added when __FreeBSD_version was ~1100027 --- contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c index d66596747f3..a0e77d3fabb 100644 --- a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c @@ -231,6 +231,7 @@ ATF_TC_BODY(hsearch_two, tc) hdestroy(); } +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version #ifdef __NetBSD__ ATF_TC(hsearch_r_basic); ATF_TC_HEAD(hsearch_r_basic, tc) @@ -385,6 +386,7 @@ ATF_TC_BODY(hsearch_r_two, tc) hdestroy_r(&t); } +#endif ATF_TP_ADD_TCS(tp) { @@ -395,13 +397,15 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, hsearch_duplicate); ATF_TP_ADD_TC(tp, hsearch_nonexistent); ATF_TP_ADD_TC(tp, hsearch_two); - + +#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version #ifdef __NetBSD__ ATF_TP_ADD_TC(tp, hsearch_r_basic); #endif ATF_TP_ADD_TC(tp, hsearch_r_duplicate); ATF_TP_ADD_TC(tp, hsearch_r_nonexistent); ATF_TP_ADD_TC(tp, hsearch_r_two); +#endif return atf_no_error(); } From 88b80af7311d6dcce6c82040daab1be39580e8ff Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Sun, 21 Dec 2014 23:48:32 +0000 Subject: [PATCH 079/207] Add -march=armv7a to the kernel compile for all ARM systems which are v7a. Submitted by: Michal Meloun --- sys/arm/allwinner/a20/std.a20 | 1 + sys/arm/allwinner/std.a10 | 1 + sys/arm/altera/socfpga/std.socfpga | 1 + sys/arm/broadcom/bcm2835/std.bcm2835 | 1 + sys/arm/freescale/imx/std.imx51 | 1 + sys/arm/freescale/imx/std.imx53 | 1 + sys/arm/freescale/imx/std.imx6 | 1 + sys/arm/freescale/vybrid/std.vybrid | 1 + sys/arm/mv/std-pj4b.mv | 1 + sys/arm/rockchip/std.rk30xx | 1 + sys/arm/samsung/exynos/std.exynos5250 | 1 + sys/arm/samsung/exynos/std.exynos5420 | 1 + sys/arm/ti/std.ti | 1 + sys/arm/xilinx/std.zynq7 | 1 + 14 files changed, 14 insertions(+) diff --git a/sys/arm/allwinner/a20/std.a20 b/sys/arm/allwinner/a20/std.a20 index f582e91ea6a..7beb2bda953 100644 --- a/sys/arm/allwinner/a20/std.a20 +++ b/sys/arm/allwinner/a20/std.a20 @@ -3,6 +3,7 @@ cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" makeoption ARM_LITTLE_ENDIAN # Physical memory starts at 0x40200000. We assume images are loaded at diff --git a/sys/arm/allwinner/std.a10 b/sys/arm/allwinner/std.a10 index 11ef732c7b0..338395d1598 100644 --- a/sys/arm/allwinner/std.a10 +++ b/sys/arm/allwinner/std.a10 @@ -3,6 +3,7 @@ cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" makeoption ARM_LITTLE_ENDIAN # Physical memory starts at 0x40200000. We assume images are loaded at diff --git a/sys/arm/altera/socfpga/std.socfpga b/sys/arm/altera/socfpga/std.socfpga index c6607a5fade..2bc45b94e49 100644 --- a/sys/arm/altera/socfpga/std.socfpga +++ b/sys/arm/altera/socfpga/std.socfpga @@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" options PHYSADDR=0x00000000 diff --git a/sys/arm/broadcom/bcm2835/std.bcm2835 b/sys/arm/broadcom/bcm2835/std.bcm2835 index ebc1fb011d3..026f5b238e3 100644 --- a/sys/arm/broadcom/bcm2835/std.bcm2835 +++ b/sys/arm/broadcom/bcm2835/std.bcm2835 @@ -2,6 +2,7 @@ machine arm armv6 cpu CPU_ARM1176 +makeoptions CONF_CFLAGS="-mcpu=arm1176jzf-s -Wa,-mcpu=arm1176jzf-s" files "../broadcom/bcm2835/files.bcm2835" diff --git a/sys/arm/freescale/imx/std.imx51 b/sys/arm/freescale/imx/std.imx51 index ce9d7d26be7..4ffcac7bc88 100644 --- a/sys/arm/freescale/imx/std.imx51 +++ b/sys/arm/freescale/imx/std.imx51 @@ -1,6 +1,7 @@ # $FreeBSD$ machine arm armv6 cpu CPU_CORTEXA +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" makeoptions ARM_LITTLE_ENDIAN options ARM_L2_PIPT diff --git a/sys/arm/freescale/imx/std.imx53 b/sys/arm/freescale/imx/std.imx53 index 09bdb2d0e92..6bc96cf7d43 100644 --- a/sys/arm/freescale/imx/std.imx53 +++ b/sys/arm/freescale/imx/std.imx53 @@ -1,6 +1,7 @@ # $FreeBSD$ machine arm armv6 cpu CPU_CORTEXA +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" makeoptions ARM_LITTLE_ENDIAN options ARM_L2_PIPT diff --git a/sys/arm/freescale/imx/std.imx6 b/sys/arm/freescale/imx/std.imx6 index a559f17ceb0..4249f9e1bd9 100644 --- a/sys/arm/freescale/imx/std.imx6 +++ b/sys/arm/freescale/imx/std.imx6 @@ -1,6 +1,7 @@ # $FreeBSD$ machine arm armv6 cpu CPU_CORTEXA +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" makeoptions ARM_LITTLE_ENDIAN options ARM_L2_PIPT diff --git a/sys/arm/freescale/vybrid/std.vybrid b/sys/arm/freescale/vybrid/std.vybrid index 2fbd85c92d2..35a2a257527 100644 --- a/sys/arm/freescale/vybrid/std.vybrid +++ b/sys/arm/freescale/vybrid/std.vybrid @@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" options PHYSADDR=0x80000000 diff --git a/sys/arm/mv/std-pj4b.mv b/sys/arm/mv/std-pj4b.mv index 7d779c29cfc..1053ff0c3fc 100644 --- a/sys/arm/mv/std-pj4b.mv +++ b/sys/arm/mv/std-pj4b.mv @@ -3,5 +3,6 @@ files "../mv/files.mv" cpu CPU_MV_PJ4B machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" options VM_MAXUSER_ADDRESS="(KERNBASE-(1024*1024*1024))" diff --git a/sys/arm/rockchip/std.rk30xx b/sys/arm/rockchip/std.rk30xx index 79ddcc64209..b62b77a47fe 100644 --- a/sys/arm/rockchip/std.rk30xx +++ b/sys/arm/rockchip/std.rk30xx @@ -3,6 +3,7 @@ cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" makeoption ARM_LITTLE_ENDIAN # Physical memory starts at 0x60400000. We assume images are loaded at diff --git a/sys/arm/samsung/exynos/std.exynos5250 b/sys/arm/samsung/exynos/std.exynos5250 index 5f59adc50f3..39c378b6f57 100644 --- a/sys/arm/samsung/exynos/std.exynos5250 +++ b/sys/arm/samsung/exynos/std.exynos5250 @@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" options PHYSADDR=0x40000000 diff --git a/sys/arm/samsung/exynos/std.exynos5420 b/sys/arm/samsung/exynos/std.exynos5420 index c6468e7d3b8..b70537d8798 100644 --- a/sys/arm/samsung/exynos/std.exynos5420 +++ b/sys/arm/samsung/exynos/std.exynos5420 @@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" options PHYSADDR=0x20000000 diff --git a/sys/arm/ti/std.ti b/sys/arm/ti/std.ti index 218d731e0b3..5e859b687a6 100644 --- a/sys/arm/ti/std.ti +++ b/sys/arm/ti/std.ti @@ -2,5 +2,6 @@ cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" files "../ti/files.ti" diff --git a/sys/arm/xilinx/std.zynq7 b/sys/arm/xilinx/std.zynq7 index 1cee32da2e7..34e67399e7e 100644 --- a/sys/arm/xilinx/std.zynq7 +++ b/sys/arm/xilinx/std.zynq7 @@ -5,6 +5,7 @@ cpu CPU_CORTEXA machine arm armv6 +makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a" files "../xilinx/files.zynq7" From a0041e6d2fac6573685fffcb48190b69127e0351 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Mon, 22 Dec 2014 00:50:01 +0000 Subject: [PATCH 080/207] Replace the clock divisor terms with values that also result in a 1 MHz clock, but actually work on real hardware, unlike the original set of values I chose. PR: 195009 Submitted by: Scott Ellis --- sys/arm/ti/ti_i2c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c index 8f9af0c7a05..d304827c0d7 100644 --- a/sys/arm/ti/ti_i2c.c +++ b/sys/arm/ti/ti_i2c.c @@ -119,7 +119,7 @@ struct ti_i2c_clock_config static struct ti_i2c_clock_config ti_omap4_i2c_clock_configs[] = { { 100000, 23, 13, 15, 0, 0}, { 400000, 9, 5, 7, 0, 0}, - { 1000000, 5, 1, 3, 0, 0}, + { 1000000, 3, 5, 7, 0, 0}, /* { 3200000, 1, 113, 115, 7, 10}, - HS mode */ { 0 /* Table terminator */ } }; From 492c2b1f4992d1815c93fc75e70e2d16d078c914 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Mon, 22 Dec 2014 04:52:24 +0000 Subject: [PATCH 081/207] Build selective portions of gnu/usr.bin/texinfo as part of build-tools to ensure that building on a host without makeinfo (i.e. a host where make delete-old -DWITHOUT_INFO was run), then building with MK_INFO == yes doesn't manifest in build errors when building info pages This manifested itself like the following when I was build testing an MFC change on stable/10: makeinfo --no-split -I /usr/src/gnu/lib/libregex/doc -I /usr/src/gnu/lib/libregex/doc regex.texi -o regex.info makeinfo: not found *** [regex.info] Error code 127 make[6]: stopped in /usr/src/gnu/lib/libregex/doc 1 error Tested on a head VM without makeinfo installed and by building with MK_INFO=yes MFC after: 1 week --- Makefile.inc1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Makefile.inc1 b/Makefile.inc1 index 9b036f43106..0fe22c0011f 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1367,6 +1367,11 @@ _share= share/syscons/scrnmaps _gcc_tools= gnu/usr.bin/cc/cc_tools .endif +.if ${MK_INFO} != "no" +_texinfo= gnu/usr.bin/texinfo/libtxi \ + gnu/usr.bin/texinfo/makeinfo +.endif + .if ${MK_RESCUE} != "no" _rescue= rescue/rescue .endif @@ -1398,6 +1403,16 @@ build-tools: .MAKE ${MAKE} DIRPRFX=${_tool}/ depend && \ ${MAKE} DIRPRFX=${_tool}/ all .endfor +.for _tool in \ + ${_texinfo} + ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all)"; \ + cd ${.CURDIR}/${_tool} && \ + ${MAKE} DIRPRFX=${_tool}/ obj && \ + ${MAKE} DIRPRFX=${_tool}/ depend && \ + ${MAKE} DIRPRFX=${_tool}/ all && \ + ${MAKE} DIRPRFX=${_tool}/ install DESTDIR=${WORLDTMP} +.endfor + # # kernel-tools: Build kernel-building tools From 851cc4c0c380bf8a5bbc5af577d46b25ef714912 Mon Sep 17 00:00:00 2001 From: Enji Cooper Date: Mon, 22 Dec 2014 04:54:57 +0000 Subject: [PATCH 082/207] Update the text for building texinfo with build-tools to reflect the fact that make install is being called as well MFC after: 1 week X-MFC with: r276052 --- Makefile.inc1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 0fe22c0011f..2aa1645a5d1 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1405,7 +1405,7 @@ build-tools: .MAKE .endfor .for _tool in \ ${_texinfo} - ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all)"; \ + ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_tool} && \ ${MAKE} DIRPRFX=${_tool}/ obj && \ ${MAKE} DIRPRFX=${_tool}/ depend && \ From 89fc8bdbb6a861a51a1d3b0846e60dbb31aebb02 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Mon, 22 Dec 2014 08:59:44 +0000 Subject: [PATCH 083/207] Document flags of vm_page allocation functions. Reviewed by: alc --- sys/vm/vm_page.h | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index f12b76c3428..8aa145f82a9 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -376,22 +376,35 @@ extern long first_page; /* first physical page number */ vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa); -/* page allocation classes: */ +/* + * Page allocation parameters for vm_page for the functions + * vm_page_alloc(), vm_page_grab(), vm_page_alloc_contig() and + * vm_page_alloc_freelist(). Some functions support only a subset + * of the flags, and ignore others, see the flags legend. + * + * Bits 0 - 1 define class. + * Bits 2 - 15 dedicated for flags. + * Legend: + * (a) - vm_page_alloc() supports the flag. + * (c) - vm_page_alloc_contig() supports the flag. + * (f) - vm_page_alloc_freelist() supports the flag. + * (g) - vm_page_grab() supports the flag. + * Bits above 15 define the count of additional pages that the caller + * intends to allocate. + */ #define VM_ALLOC_NORMAL 0 #define VM_ALLOC_INTERRUPT 1 #define VM_ALLOC_SYSTEM 2 #define VM_ALLOC_CLASS_MASK 3 -/* page allocation flags: */ -#define VM_ALLOC_WIRED 0x0020 /* non pageable */ -#define VM_ALLOC_ZERO 0x0040 /* Try to obtain a zeroed page */ -#define VM_ALLOC_NOOBJ 0x0100 /* No associated object */ -#define VM_ALLOC_NOBUSY 0x0200 /* Do not busy the page */ -#define VM_ALLOC_IFCACHED 0x0400 /* Fail if the page is not cached */ -#define VM_ALLOC_IFNOTCACHED 0x0800 /* Fail if the page is cached */ -#define VM_ALLOC_IGN_SBUSY 0x1000 /* vm_page_grab() only */ -#define VM_ALLOC_NODUMP 0x2000 /* don't include in dump */ -#define VM_ALLOC_SBUSY 0x4000 /* Shared busy the page */ - +#define VM_ALLOC_WIRED 0x0020 /* (acfg) Allocate non pageable page */ +#define VM_ALLOC_ZERO 0x0040 /* (acfg) Try to obtain a zeroed page */ +#define VM_ALLOC_NOOBJ 0x0100 /* (acg) No associated object */ +#define VM_ALLOC_NOBUSY 0x0200 /* (acg) Do not busy the page */ +#define VM_ALLOC_IFCACHED 0x0400 /* (ag) Fail if page is not cached */ +#define VM_ALLOC_IFNOTCACHED 0x0800 /* (ag) Fail if page is cached */ +#define VM_ALLOC_IGN_SBUSY 0x1000 /* (g) Ignore shared busy flag */ +#define VM_ALLOC_NODUMP 0x2000 /* (ag) don't include in dump */ +#define VM_ALLOC_SBUSY 0x4000 /* (acg) Shared busy the page */ #define VM_ALLOC_COUNT_SHIFT 16 #define VM_ALLOC_COUNT(count) ((count) << VM_ALLOC_COUNT_SHIFT) From 6ee80f259c5d1df6299d52e15c30d6ac1e47382d Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Mon, 22 Dec 2014 09:00:47 +0000 Subject: [PATCH 084/207] Do not clear flag that vm_page_alloc() doesn't support. Submitted by: kib --- sys/vm/vm_page.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index b2877c11b5f..0ff789f80b4 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2736,7 +2736,7 @@ retrylookup: return (m); } } - m = vm_page_alloc(object, pindex, allocflags & ~VM_ALLOC_IGN_SBUSY); + m = vm_page_alloc(object, pindex, allocflags); if (m == NULL) { VM_OBJECT_WUNLOCK(object); VM_WAIT; From e3ed82bcf7e48c1d3f88f3cbbcf6bd104957a871 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Mon, 22 Dec 2014 09:02:21 +0000 Subject: [PATCH 085/207] Add flag VM_ALLOC_NOWAIT for vm_page_grab() that prevents sleeping and allows the function to fail. Reviewed by: kib, alc Sponsored by: Nginx, Inc. --- sys/vm/vm_page.c | 4 ++++ sys/vm/vm_page.h | 1 + 2 files changed, 5 insertions(+) diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 0ff789f80b4..79665ba9aab 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2711,6 +2711,8 @@ retrylookup: sleep = (allocflags & VM_ALLOC_IGN_SBUSY) != 0 ? vm_page_xbusied(m) : vm_page_busied(m); if (sleep) { + if ((allocflags & VM_ALLOC_NOWAIT) != 0) + return (NULL); /* * Reference the page before unlocking and * sleeping so that the page daemon is less @@ -2738,6 +2740,8 @@ retrylookup: } m = vm_page_alloc(object, pindex, allocflags); if (m == NULL) { + if ((allocflags & VM_ALLOC_NOWAIT) != 0) + return (NULL); VM_OBJECT_WUNLOCK(object); VM_WAIT; VM_OBJECT_WLOCK(object); diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 8aa145f82a9..cd3077232f9 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -405,6 +405,7 @@ vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa); #define VM_ALLOC_IGN_SBUSY 0x1000 /* (g) Ignore shared busy flag */ #define VM_ALLOC_NODUMP 0x2000 /* (ag) don't include in dump */ #define VM_ALLOC_SBUSY 0x4000 /* (acg) Shared busy the page */ +#define VM_ALLOC_NOWAIT 0x8000 /* (g) Do not sleep, return NULL */ #define VM_ALLOC_COUNT_SHIFT 16 #define VM_ALLOC_COUNT(count) ((count) << VM_ALLOC_COUNT_SHIFT) From 53b680caa2896d058adf77da315aee92e36ac8dc Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Mon, 22 Dec 2014 15:39:24 +0000 Subject: [PATCH 086/207] In sbappend*() family of functions clear M_PROTO flags of incoming mbufs. sbappendstream() already does this in m_demote(). PR: 196174 Sponsored by: Nginx, Inc. --- sys/kern/uipc_sockbuf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index acbccc9176e..88952ed6629 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -579,7 +579,7 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m) if (m == 0) return; - + m_clrprotoflags(m); SBLASTRECORDCHK(sb); n = sb->sb_mb; if (n) { @@ -732,6 +732,7 @@ sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0) if (m0 == 0) return; + m_clrprotoflags(m0); /* * Put the first mbuf on the queue. Note this permits zero length * records. @@ -777,6 +778,8 @@ sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa, return (0); m->m_len = asa->sa_len; bcopy(asa, mtod(m, caddr_t), asa->sa_len); + if (m0) + m_clrprotoflags(m0); if (ctrl_last) ctrl_last->m_next = m0; /* concatenate data to control */ else @@ -872,6 +875,7 @@ sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0, if (space > sbspace(sb)) return (0); + m_clrprotoflags(m0); n->m_next = m0; /* concatenate data to control */ SBLASTRECORDCHK(sb); From f9de33d49700fe9718adeaa0a16d6029680ed53c Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Mon, 22 Dec 2014 16:12:55 +0000 Subject: [PATCH 087/207] Simplify the use of locks where possible, remove the locking when it is not required. Simplify the code a little bit. Reviewed by: andrew (previous version) --- sys/arm/ti/ti_gpio.c | 111 ++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 70 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index 612ceb9a947..fe96078a56e 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -290,7 +290,7 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask) * * * LOCKING: - * Internally locks the context + * No locking required, returns static data. * * RETURNS: * Returns 0 on success otherwise an error code @@ -302,8 +302,6 @@ ti_gpio_pin_max(device_t dev, int *maxpin) unsigned int i; unsigned int banks = 0; - TI_GPIO_LOCK(sc); - /* Calculate how many valid banks we have and then multiply that by 32 to * give use the total number of pins. */ @@ -314,8 +312,6 @@ ti_gpio_pin_max(device_t dev, int *maxpin) *maxpin = (banks * PINS_PER_BANK) - 1; - TI_GPIO_UNLOCK(sc); - return (0); } @@ -332,7 +328,7 @@ ti_gpio_pin_max(device_t dev, int *maxpin) * - GPIO_PIN_PULLDOWN * * LOCKING: - * Internally locks the context + * No locking required, returns static data. * * RETURNS: * Returns 0 on success otherwise an error code @@ -343,19 +339,13 @@ ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); - TI_GPIO_LOCK(sc); - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } - *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |GPIO_PIN_PULLUP | + *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN); - TI_GPIO_UNLOCK(sc); - return (0); } @@ -381,17 +371,13 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); - TI_GPIO_LOCK(sc); - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } /* Get the current pin state */ + TI_GPIO_LOCK(sc); TI_GPIO_GET_FLAGS(dev, pin, flags); - TI_GPIO_UNLOCK(sc); return (0); @@ -407,7 +393,7 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) * of the pin. * * LOCKING: - * Internally locks the context + * No locking required, returns static data. * * RETURNS: * Returns 0 on success otherwise an error code @@ -418,20 +404,14 @@ ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); - TI_GPIO_LOCK(sc); - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } /* Set a very simple name */ snprintf(name, GPIOMAXNAME, "gpio_%u", pin); name[GPIOMAXNAME - 1] = '\0'; - TI_GPIO_UNLOCK(sc); - return (0); } @@ -460,30 +440,26 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); uint32_t mask = (1UL << (pin % PINS_PER_BANK)); - uint32_t reg_val; - - TI_GPIO_LOCK(sc); + uint32_t oe; /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } /* Set the GPIO mode and state */ + TI_GPIO_LOCK(sc); if (TI_GPIO_SET_FLAGS(dev, pin, flags) != 0) { TI_GPIO_UNLOCK(sc); return (EINVAL); } /* If configuring as an output set the "output enable" bit */ - reg_val = ti_gpio_read_4(sc, bank, TI_GPIO_OE); + oe = ti_gpio_read_4(sc, bank, TI_GPIO_OE); if (flags & GPIO_PIN_INPUT) - reg_val |= mask; + oe |= mask; else - reg_val &= ~mask; - ti_gpio_write_4(sc, bank, TI_GPIO_OE, reg_val); - + oe &= ~mask; + ti_gpio_write_4(sc, bank, TI_GPIO_OE, oe); TI_GPIO_UNLOCK(sc); return (0); @@ -509,18 +485,18 @@ ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); uint32_t mask = (1UL << (pin % PINS_PER_BANK)); - - TI_GPIO_LOCK(sc); + uint32_t reg; /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } - - ti_gpio_write_4(sc, bank, (value == GPIO_PIN_LOW) ? TI_GPIO_CLEARDATAOUT - : TI_GPIO_SETDATAOUT, mask); + TI_GPIO_LOCK(sc); + if (value == GPIO_PIN_LOW) + reg = TI_GPIO_CLEARDATAOUT; + else + reg = TI_GPIO_SETDATAOUT; + ti_gpio_write_4(sc, bank, reg, mask); TI_GPIO_UNLOCK(sc); return (0); @@ -547,25 +523,23 @@ ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); uint32_t mask = (1UL << (pin % PINS_PER_BANK)); - uint32_t val = 0; - - TI_GPIO_LOCK(sc); + uint32_t oe, reg; /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } - /* Sanity check the pin is not configured as an output */ - val = ti_gpio_read_4(sc, bank, TI_GPIO_OE); - - /* Read the value on the pin */ - if (val & mask) - *value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAIN) & mask) ? 1 : 0; + /* + * Return data from output latch when set as output and from the + * input register otherwise. + */ + TI_GPIO_LOCK(sc); + oe = ti_gpio_read_4(sc, bank, TI_GPIO_OE); + if (oe & mask) + reg = TI_GPIO_DATAIN; else - *value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT) & mask) ? 1 : 0; - + reg = TI_GPIO_DATAOUT; + *value = (ti_gpio_read_4(sc, bank, reg) & mask) ? 1 : 0; TI_GPIO_UNLOCK(sc); return (0); @@ -589,23 +563,20 @@ ti_gpio_pin_toggle(device_t dev, uint32_t pin) struct ti_gpio_softc *sc = device_get_softc(dev); uint32_t bank = (pin / PINS_PER_BANK); uint32_t mask = (1UL << (pin % PINS_PER_BANK)); - uint32_t val; - - TI_GPIO_LOCK(sc); + uint32_t reg, val; /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) { - TI_GPIO_UNLOCK(sc); + if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) return (EINVAL); - } /* Toggle the pin */ + TI_GPIO_LOCK(sc); val = ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT); if (val & mask) - ti_gpio_write_4(sc, bank, TI_GPIO_CLEARDATAOUT, mask); + reg = TI_GPIO_CLEARDATAOUT; else - ti_gpio_write_4(sc, bank, TI_GPIO_SETDATAOUT, mask); - + reg = TI_GPIO_SETDATAOUT; + ti_gpio_write_4(sc, bank, reg, mask); TI_GPIO_UNLOCK(sc); return (0); From a59806b25283f6e8de8ffed72aa25230445094b8 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Mon, 22 Dec 2014 16:29:15 +0000 Subject: [PATCH 088/207] Remove some leftovers from OMAP3 support. --- sys/arm/ti/ti_gpio.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index fe96078a56e..de88a48a21b 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -69,10 +69,13 @@ __FBSDID("$FreeBSD$"); #include "gpio_if.h" #include "ti_gpio_if.h" +#if !defined(SOC_OMAP4) && !defined(SOC_TI_AM335X) +#error "Unknown SoC" +#endif + /* Register definitions */ #define TI_GPIO_REVISION 0x0000 #define TI_GPIO_SYSCONFIG 0x0010 -#if defined(SOC_OMAP4) || defined(SOC_TI_AM335X) #define TI_GPIO_IRQSTATUS_RAW_0 0x0024 #define TI_GPIO_IRQSTATUS_RAW_1 0x0028 #define TI_GPIO_IRQSTATUS_0 0x002C @@ -103,9 +106,6 @@ __FBSDID("$FreeBSD$"); #define TI_GPIO_SETWKUENA 0x0184 #define TI_GPIO_CLEARDATAOUT 0x0190 #define TI_GPIO_SETDATAOUT 0x0194 -#else -#error "Unknown SoC" -#endif /* Other SoC Specific definitions */ #define OMAP4_MAX_GPIO_BANKS 6 @@ -273,13 +273,8 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask) { /* We clear both set of registers. */ -#if defined(SOC_OMAP4) || defined(SOC_TI_AM335X) ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_0, mask); ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_1, mask); -#else - ti_gpio_write_4(sc, bank, TI_GPIO_CLEARIRQENABLE1, mask); - ti_gpio_write_4(sc, bank, TI_GPIO_CLEARIRQENABLE2, mask); -#endif } /** From 9ef62fdb876af013c8280e46da33c407f7e0f09e Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 22 Dec 2014 16:31:09 +0000 Subject: [PATCH 089/207] Set up default shstrtab entries at shstrtab initialization Instead of waiting until the addition of the first non-default entry. This fixes a segfault when strip(1) is asked to remove every section from an object file. Upstream elftoolchain ticket 463 Reviewed by: imp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D1341 --- contrib/elftoolchain/elfcopy/sections.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c index 1704a6b3355..1ad725241cb 100644 --- a/contrib/elftoolchain/elfcopy/sections.c +++ b/contrib/elftoolchain/elfcopy/sections.c @@ -1139,12 +1139,6 @@ add_to_shstrtab(struct elfcopy *ecp, const char *name) struct section *s; s = ecp->shstrtab; - if (s->buf == NULL) { - insert_to_strtab(s, ""); - insert_to_strtab(s, ".symtab"); - insert_to_strtab(s, ".strtab"); - insert_to_strtab(s, ".shstrtab"); - } insert_to_strtab(s, name); } @@ -1206,6 +1200,11 @@ init_shstrtab(struct elfcopy *ecp) s->loadable = 0; s->type = SHT_STRTAB; s->vma = 0; + + insert_to_strtab(s, ""); + insert_to_strtab(s, ".symtab"); + insert_to_strtab(s, ".strtab"); + insert_to_strtab(s, ".shstrtab"); } void From b3f26809280ec1c4b2ec4d570a48315643961575 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 22 Dec 2014 16:34:59 +0000 Subject: [PATCH 090/207] Add AArch64 machine time and relocations for readelf Reviewed by: andrew Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D1333 --- contrib/elftoolchain/common/elfdefinitions.h | 2 + contrib/elftoolchain/readelf/readelf.c | 62 ++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h index 7bed9a19a0d..ccd785b1d09 100644 --- a/contrib/elftoolchain/common/elfdefinitions.h +++ b/contrib/elftoolchain/common/elfdefinitions.h @@ -770,6 +770,8 @@ _ELF_DEFINE_EM(EM_ETPU, 178, \ "Freescale Extended Time Processing Unit") \ _ELF_DEFINE_EM(EM_SLE9X, 179, \ "Infineon Technologies SLE9X core") \ +_ELF_DEFINE_EM(EM_AARCH64, 183, \ + "AArch64 (64-bit ARM)") \ _ELF_DEFINE_EM(EM_AVR32, 185, \ "Atmel Corporation 32-bit microprocessor family") \ _ELF_DEFINE_EM(EM_STM8, 186, \ diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c index 779a7ba9e87..8ae3e9b24a6 100644 --- a/contrib/elftoolchain/readelf/readelf.c +++ b/contrib/elftoolchain/readelf/readelf.c @@ -487,6 +487,7 @@ elf_machine(unsigned int mach) case EM_SEP: return "Sharp embedded microprocessor"; case EM_ARCA: return "Arca RISC Microprocessor"; case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd"; + case EM_AARCH64: return "AArch64"; default: snprintf(s_mach, sizeof(s_mach), "", mach); return (s_mach); @@ -1041,6 +1042,67 @@ r_type(unsigned int mach, unsigned int type) case 37: return "R_386_TLS_TPOFF32"; default: return ""; } + case EM_AARCH64: + switch(type) { + case 0: return "R_AARCH64_NONE"; + case 257: return "R_AARCH64_ABS64"; + case 258: return "R_AARCH64_ABS32"; + case 259: return "R_AARCH64_ABS16"; + case 260: return "R_AARCH64_PREL64"; + case 261: return "R_AARCH64_PREL32"; + case 262: return "R_AARCH64_PREL16"; + case 263: return "R_AARCH64_MOVW_UABS_G0"; + case 264: return "R_AARCH64_MOVW_UABS_G0_NC"; + case 265: return "R_AARCH64_MOVW_UABS_G1"; + case 266: return "R_AARCH64_MOVW_UABS_G1_NC"; + case 267: return "R_AARCH64_MOVW_UABS_G2"; + case 268: return "R_AARCH64_MOVW_UABS_G2_NC"; + case 269: return "R_AARCH64_MOVW_UABS_G3"; + case 270: return "R_AARCH64_MOVW_SABS_G0"; + case 271: return "R_AARCH64_MOVW_SABS_G1"; + case 272: return "R_AARCH64_MOVW_SABS_G2"; + case 273: return "R_AARCH64_LD_PREL_LO19"; + case 274: return "R_AARCH64_ADR_PREL_LO21"; + case 275: return "R_AARCH64_ADR_PREL_PG_HI21"; + case 276: return "R_AARCH64_ADR_PREL_PG_HI21_NC"; + case 277: return "R_AARCH64_ADD_ABS_LO12_NC"; + case 278: return "R_AARCH64_LDST8_ABS_LO12_NC"; + case 279: return "R_AARCH64_TSTBR14"; + case 280: return "R_AARCH64_CONDBR19"; + case 282: return "R_AARCH64_JUMP26"; + case 283: return "R_AARCH64_CALL26"; + case 284: return "R_AARCH64_LDST16_ABS_LO12_NC"; + case 285: return "R_AARCH64_LDST32_ABS_LO12_NC"; + case 286: return "R_AARCH64_LDST64_ABS_LO12_NC"; + case 287: return "R_AARCH64_MOVW_PREL_G0"; + case 288: return "R_AARCH64_MOVW_PREL_G0_NC"; + case 289: return "R_AARCH64_MOVW_PREL_G1"; + case 290: return "R_AARCH64_MOVW_PREL_G1_NC"; + case 291: return "R_AARCH64_MOVW_PREL_G2"; + case 292: return "R_AARCH64_MOVW_PREL_G2_NC"; + case 293: return "R_AARCH64_MOVW_PREL_G3"; + case 299: return "R_AARCH64_LDST128_ABS_LO12_NC"; + case 300: return "R_AARCH64_MOVW_GOTOFF_G0"; + case 301: return "R_AARCH64_MOVW_GOTOFF_G0_NC"; + case 302: return "R_AARCH64_MOVW_GOTOFF_G1"; + case 303: return "R_AARCH64_MOVW_GOTOFF_G1_NC"; + case 304: return "R_AARCH64_MOVW_GOTOFF_G2"; + case 305: return "R_AARCH64_MOVW_GOTOFF_G2_NC"; + case 306: return "R_AARCH64_MOVW_GOTOFF_G3"; + case 307: return "R_AARCH64_GOTREL64"; + case 308: return "R_AARCH64_GOTREL32"; + case 309: return "R_AARCH64_GOT_LD_PREL19"; + case 310: return "R_AARCH64_LD64_GOTOFF_LO15"; + case 311: return "R_AARCH64_ADR_GOT_PAGE"; + case 312: return "R_AARCH64_LD64_GOT_LO12_NC"; + case 313: return "R_AARCH64_LD64_GOTPAGE_LO15"; + case 1024: return "R_AARCH64_COPY"; + case 1025: return "R_AARCH64_GLOB_DAT"; + case 1026: return "R_AARCH64_JUMP_SLOT"; + case 1027: return "R_AARCH64_RELATIVE"; + case 1031: return "R_AARCH64_TLSDESC"; + default: return ""; + } case EM_ARM: switch(type) { case 0: return "R_ARM_NONE"; From 39c478eac469973596fbcd3fc7b6c6c23a933df0 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Mon, 22 Dec 2014 16:38:29 +0000 Subject: [PATCH 091/207] Standardise on illumos for #ifdef's in zvol.c Also correct as per style(9) on the use of #ifdef comments. This is a no-op change as pre-cursor to a full cleanup and merge with upstream zvol changes. Sponsored by: Multiplay --- .../opensolaris/uts/common/fs/zfs/zvol.c | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index 260822ce02d..7976eb38683 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -214,7 +214,7 @@ static void zvol_geom_worker(void *arg); static void zvol_size_changed(zvol_state_t *zv) { -#ifdef sun +#ifdef illumos dev_t dev = makedevice(maj, min); VERIFY(ddi_prop_update_int64(dev, zfs_dip, @@ -225,7 +225,7 @@ zvol_size_changed(zvol_state_t *zv) /* Notify specfs to invalidate the cached size */ spec_size_invalidate(dev, VBLK); spec_size_invalidate(dev, VCHR); -#else /* !sun */ +#else /* !illumos */ if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { struct g_provider *pp; @@ -236,7 +236,7 @@ zvol_size_changed(zvol_state_t *zv) g_resize_provider(pp, zv->zv_volsize); g_topology_unlock(); } -#endif /* !sun */ +#endif /* illumos */ } int @@ -517,7 +517,7 @@ zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = { zvol_replay_err, /* TX_WRITE2 */ }; -#ifdef sun +#ifdef illumos int zvol_name2minor(const char *name, minor_t *minor) { @@ -530,7 +530,7 @@ zvol_name2minor(const char *name, minor_t *minor) mutex_exit(&spa_namespace_lock); return (zv ? 0 : -1); } -#endif /* sun */ +#endif /* illumos */ /* * Create a minor node (plus a whole lot more) for the specified volume. @@ -565,7 +565,7 @@ zvol_create_minor(const char *name) return (error); } -#ifdef sun +#ifdef illumos if ((minor = zfsdev_minor_alloc()) == 0) { dmu_objset_disown(os, FTAG); mutex_exit(&spa_namespace_lock); @@ -604,7 +604,7 @@ zvol_create_minor(const char *name) zs = ddi_get_soft_state(zfsdev_state, minor); zs->zss_type = ZSST_ZVOL; zv = zs->zss_data = kmem_zalloc(sizeof (zvol_state_t), KM_SLEEP); -#else /* !sun */ +#else /* !illumos */ zv = kmem_zalloc(sizeof(*zv), KM_SLEEP); zv->zv_state = 0; @@ -651,7 +651,7 @@ zvol_create_minor(const char *name) dev->si_drv2 = zv; } LIST_INSERT_HEAD(&all_zvols, zv, zv_links); -#endif /* !sun */ +#endif /* illumos */ (void) strlcpy(zv->zv_name, name, MAXPATHLEN); zv->zv_min_bs = DEV_BSHIFT; @@ -681,7 +681,7 @@ zvol_create_minor(const char *name) mutex_exit(&spa_namespace_lock); -#ifndef sun +#ifndef illumos if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { zvol_geom_run(zv); g_topology_unlock(); @@ -700,7 +700,7 @@ zvol_create_minor(const char *name) static int zvol_remove_zv(zvol_state_t *zv) { -#ifdef sun +#ifdef illumos minor_t minor = zv->zv_minor; #endif @@ -710,7 +710,7 @@ zvol_remove_zv(zvol_state_t *zv) ZFS_LOG(1, "ZVOL %s destroyed.", zv->zv_name); -#ifdef sun +#ifdef illumos (void) snprintf(nmbuf, sizeof (nmbuf), "%u,raw", minor); ddi_remove_minor_node(zfs_dip, nmbuf); #else @@ -721,7 +721,7 @@ zvol_remove_zv(zvol_state_t *zv) g_topology_unlock(); } else if (zv->zv_volmode == ZFS_VOLMODE_DEV) destroy_dev(zv->zv_dev); -#endif /* sun */ +#endif avl_destroy(&zv->zv_znode.z_range_avl); mutex_destroy(&zv->zv_znode.z_range_lock); @@ -809,7 +809,7 @@ zvol_last_close(zvol_state_t *zv) zv->zv_objset = NULL; } -#ifdef sun +#ifdef illumos int zvol_prealloc(zvol_state_t *zv) { @@ -848,7 +848,7 @@ zvol_prealloc(zvol_state_t *zv) return (0); } -#endif /* sun */ +#endif /* illumos */ static int zvol_update_volsize(objset_t *os, uint64_t volsize) @@ -955,7 +955,7 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) } } -#ifdef sun +#ifdef illumos /* * Generate a LUN expansion event. */ @@ -976,7 +976,7 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) nvlist_free(attr); kmem_free(physpath, MAXPATHLEN); } -#endif /* sun */ +#endif /* illumos */ out: dmu_objset_rele(os, FTAG); @@ -1260,7 +1260,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid, } } -#ifdef sun +#ifdef illumos static int zvol_dumpio_vdev(vdev_t *vd, void *addr, uint64_t offset, uint64_t origoffset, uint64_t size, boolean_t doread, boolean_t isdump) @@ -1353,7 +1353,7 @@ zvol_dumpio(zvol_state_t *zv, void *addr, uint64_t offset, uint64_t size, return (error); } -#endif /* sun */ +#endif /* illumos */ void zvol_strategy(struct bio *bp) @@ -1494,7 +1494,7 @@ out: biofinish(bp, NULL, error); } -#ifdef sun +#ifdef illumos /* * Set the buffer count to the zvol maximum transfer. * Using our own routine instead of the default minphys() @@ -1550,17 +1550,17 @@ int zvol_read(dev_t dev, uio_t *uio, cred_t *cr) { minor_t minor = getminor(dev); -#else +#else /* !illumos */ int zvol_read(struct cdev *dev, struct uio *uio, int ioflag) { -#endif +#endif /* illumos */ zvol_state_t *zv; uint64_t volsize; rl_t *rl; int error = 0; -#ifdef sun +#ifdef illumos zv = zfsdev_get_soft_state(minor, ZSST_ZVOL); if (zv == NULL) return (SET_ERROR(ENXIO)); @@ -1602,24 +1602,24 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag) return (error); } -#ifdef sun +#ifdef illumos /*ARGSUSED*/ int zvol_write(dev_t dev, uio_t *uio, cred_t *cr) { minor_t minor = getminor(dev); -#else +#else /* !illumos */ int zvol_write(struct cdev *dev, struct uio *uio, int ioflag) { -#endif +#endif /* illumos */ zvol_state_t *zv; uint64_t volsize; rl_t *rl; int error = 0; boolean_t sync; -#ifdef sun +#ifdef illumos zv = zfsdev_get_soft_state(minor, ZSST_ZVOL); if (zv == NULL) return (SET_ERROR(ENXIO)); @@ -1638,9 +1638,7 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag) zvol_minphys, uio); return (error); } -#endif -#ifdef sun sync = !(zv->zv_flags & ZVOL_WCE) || #else sync = (ioflag & IO_SYNC) || @@ -1677,7 +1675,7 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag) return (error); } -#ifdef sun +#ifdef illumos int zvol_getefi(void *arg, int flag, uint64_t vs, uint8_t bs) { @@ -1806,7 +1804,7 @@ zvol_log_write_minor(void *minor_hdl, dmu_tx_t *tx, offset_t off, ssize_t resid, /* * END entry points to allow external callers access to the volume. */ -#endif /* sun */ +#endif /* illumos */ /* * Log a DKIOCFREE/free-long-range to the ZIL with TX_TRUNCATE. @@ -1832,7 +1830,7 @@ zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off, uint64_t len, zil_itx_assign(zilog, itx, tx); } -#ifdef sun +#ifdef illumos /* * Dirtbag ioctls to support mkfs(1M) for UFS filesystems. See dkio(7I). * Also a dirtbag dkio ioctl for unmap/free-block functionality. @@ -2047,7 +2045,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) mutex_exit(&spa_namespace_lock); return (error); } -#endif /* sun */ +#endif /* illumos */ int zvol_busy(void) @@ -2070,7 +2068,7 @@ zvol_fini(void) ZFS_LOG(1, "ZVOL Deinitialized."); } -#ifdef sun +#ifdef illumos /*ARGSUSED*/ static int zfs_mvdev_dump_feature_check(void *arg, dmu_tx_t *tx) @@ -2355,7 +2353,7 @@ zvol_dump_fini(zvol_state_t *zv) return (0); } -#endif /* sun */ +#endif /* illumos */ static void zvol_geom_run(zvol_state_t *zv) From acb332a8a188196ac0cdfef9598a15000f15b940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Mon, 22 Dec 2014 16:46:07 +0000 Subject: [PATCH 092/207] vt: register the memory regions used by the vt drivers Current VT drivers don't register the memory regions they use with the nexus. This patch makes vt_vga and vt_efifb register the memory regions they use. This is needed (at least) for Xen support, since the FreeBSD kernel will try to use the holes in the memory map to map memory from other domains and setup it's grant table. Sponsored by: Citrix Systems R&D Reported by: sbruno Tested by: emaste Reviewed by: ray PR: 195537 Differential Revision: https://reviews.freebsd.org/D1291 --- sys/dev/vt/hw/efifb/efifb.c | 53 +++++++++++++++++++++++++++++++++++ sys/dev/vt/hw/vga/vt_vga.c | 55 +++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/sys/dev/vt/hw/efifb/efifb.c b/sys/dev/vt/hw/efifb/efifb.c index 05b2d795228..769554725c7 100644 --- a/sys/dev/vt/hw/efifb/efifb.c +++ b/sys/dev/vt/hw/efifb/efifb.c @@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #include "opt_platform.h" @@ -179,3 +182,53 @@ vt_efifb_remap(void *xinfo) info->fb_size, VM_MEMATTR_WRITE_COMBINING); } +/* Dummy NewBus functions to reserve the resources used by the efifb driver */ +static void +vtefifb_identify(driver_t *driver, device_t parent) +{ + + if (local_info.fb_pbase == 0 || local_info.fb_size == 0) + return; + + if (BUS_ADD_CHILD(parent, 0, driver->name, 0) == NULL) + panic("Unable to attach vt_efifb console"); +} + +static int +vtefifb_probe(device_t dev) +{ + + device_set_desc(dev, "vt_efifb driver"); + return (BUS_PROBE_NOWILDCARD); +} + +static int +vtefifb_attach(device_t dev) +{ + struct resource *pseudo_phys_res; + int res_id; + + res_id = 0; + pseudo_phys_res = bus_alloc_resource(dev, SYS_RES_MEMORY, + &res_id, local_info.fb_pbase, + local_info.fb_pbase + local_info.fb_size, + local_info.fb_size, RF_ACTIVE); + if (pseudo_phys_res == NULL) + panic("Unable to reserve vt_efifb memory"); + return (0); +} + +/*-------------------- Private Device Attachment Data -----------------------*/ +static device_method_t vtefifb_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, vtefifb_identify), + DEVMETHOD(device_probe, vtefifb_probe), + DEVMETHOD(device_attach, vtefifb_attach), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(vtefifb, vtefifb_driver, vtefifb_methods, 0); +devclass_t vtefifb_devclass; + +DRIVER_MODULE(vtefifb, nexus, vtefifb_driver, vtefifb_devclass, NULL, NULL); diff --git a/sys/dev/vt/hw/vga/vt_vga.c b/sys/dev/vt/hw/vga/vt_vga.c index abddbf50ce1..7f350537a0d 100644 --- a/sys/dev/vt/hw/vga/vt_vga.c +++ b/sys/dev/vt/hw/vga/vt_vga.c @@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include #include #include @@ -56,6 +59,7 @@ struct vga_softc { bus_space_handle_t vga_reg_handle; int vga_wmode; term_color_t vga_curfg, vga_curbg; + boolean_t vga_enabled; }; /* Convenience macros. */ @@ -1228,6 +1232,7 @@ vga_init(struct vt_device *vd) vd->vd_height = VT_VGA_HEIGHT; } vga_initialize(vd, textmode); + sc->vga_enabled = true; return (CN_INTERNAL); } @@ -1241,3 +1246,53 @@ vga_postswitch(struct vt_device *vd) /* Ask vt(9) to update chars on visible area. */ vd->vd_flags |= VDF_INVALID; } + +/* Dummy NewBus functions to reserve the resources used by the vt_vga driver */ +static void +vtvga_identify(driver_t *driver, device_t parent) +{ + + if (!vga_conssoftc.vga_enabled) + return; + + if (BUS_ADD_CHILD(parent, 0, driver->name, 0) == NULL) + panic("Unable to attach vt_vga console"); +} + +static int +vtvga_probe(device_t dev) +{ + + device_set_desc(dev, "vt_vga driver"); + return (BUS_PROBE_NOWILDCARD); +} + +static int +vtvga_attach(device_t dev) +{ + struct resource *pseudo_phys_res; + int res_id; + + res_id = 0; + pseudo_phys_res = bus_alloc_resource(dev, SYS_RES_MEMORY, + &res_id, VGA_MEM_BASE, VGA_MEM_BASE + VGA_MEM_SIZE, + VGA_MEM_SIZE, RF_ACTIVE); + if (pseudo_phys_res == NULL) + panic("Unable to reserve vt_vga memory"); + return (0); +} + +/*-------------------- Private Device Attachment Data -----------------------*/ +static device_method_t vtvga_methods[] = { + /* Device interface */ + DEVMETHOD(device_identify, vtvga_identify), + DEVMETHOD(device_probe, vtvga_probe), + DEVMETHOD(device_attach, vtvga_attach), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(vtvga, vtvga_driver, vtvga_methods, 0); +devclass_t vtvga_devclass; + +DRIVER_MODULE(vtvga, nexus, vtvga_driver, vtvga_devclass, NULL, NULL); From 51f2504057c8a39b3ea244b777d66ea00a391701 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 22 Dec 2014 16:53:04 +0000 Subject: [PATCH 093/207] Explicitly treat timeouts when waiting for IBF or OBF to change state as an error. This fixes occasional hangs in the IPMI kcs thread when using ipmitool locally. MFC after: 1 week --- sys/dev/ipmi/ipmi_kcs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sys/dev/ipmi/ipmi_kcs.c b/sys/dev/ipmi/ipmi_kcs.c index 76adf8c9309..eb5884a86b5 100644 --- a/sys/dev/ipmi/ipmi_kcs.c +++ b/sys/dev/ipmi/ipmi_kcs.c @@ -184,6 +184,8 @@ kcs_start_write(struct ipmi_softc *sc) for (retry = 0; retry < 10; retry++) { /* Wait for IBF = 0 */ status = kcs_wait_for_ibf(sc, 0); + if (status & KCS_STATUS_IBF) + return (0); /* Clear OBF */ kcs_clear_obf(sc, status); @@ -193,6 +195,9 @@ kcs_start_write(struct ipmi_softc *sc) /* Wait for IBF = 0 */ status = kcs_wait_for_ibf(sc, 0); + if (status & KCS_STATUS_IBF) + return (0); + if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_WRITE) break; DELAY(1000000); @@ -222,6 +227,8 @@ kcs_write_byte(struct ipmi_softc *sc, u_char data) /* Wait for IBF = 0 */ status = kcs_wait_for_ibf(sc, 0); + if (status & KCS_STATUS_IBF) + return (0); if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE) return (0); @@ -244,6 +251,8 @@ kcs_write_last_byte(struct ipmi_softc *sc, u_char data) /* Wait for IBF = 0 */ status = kcs_wait_for_ibf(sc, 0); + if (status & KCS_STATUS_IBF) + return (0); if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE) /* error state */ @@ -274,6 +283,8 @@ kcs_read_byte(struct ipmi_softc *sc, u_char *data) /* Wait for OBF = 1 */ status = kcs_wait_for_obf(sc, 1); + if ((status & KCS_STATUS_OBF) == 0) + return (0); /* Read Data_out */ *data = INB(sc, KCS_DATA); @@ -288,6 +299,8 @@ kcs_read_byte(struct ipmi_softc *sc, u_char *data) /* Wait for OBF = 1*/ status = kcs_wait_for_obf(sc, 1); + if ((status & KCS_STATUS_OBF) == 0) + return (0); /* Read Dummy */ dummy = INB(sc, KCS_DATA); From 08c0f91ecc806fe0a344bf49444622a7735a24c8 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Mon, 22 Dec 2014 17:04:51 +0000 Subject: [PATCH 094/207] Refactor zvol locking to minimise diff with upstream Use #define zfsdev_state_lock spa_namespace_lock instead of replacing all zfsdev_state_lock with spa_namespace_lock to minimise changes from upstream. Differential Revision: D1302 MFC after: 1 month X-MFC-With r276063 Sponsored by: Multiplay --- .../opensolaris/uts/common/fs/zfs/zvol.c | 136 ++++++++++-------- 1 file changed, 76 insertions(+), 60 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index 7976eb38683..82ff3bcc70f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -110,11 +110,20 @@ static char *zvol_tag = "zvol_tag"; #define ZVOL_DUMPSIZE "dumpsize" /* - * The spa_namespace_lock protects the zfsdev_state structure from being - * modified while it's being used, e.g. an open that comes in before a - * create finishes. It also protects temporary opens of the dataset so that, + * This lock protects the zfsdev_state structure from being modified + * while it's being used, e.g. an open that comes in before a create + * finishes. It also protects temporary opens of the dataset so that, * e.g., an open doesn't get a spurious EBUSY. */ +#ifdef illumos +kmutex_t zfsdev_state_lock; +#else +/* + * In FreeBSD we've replaced the upstream zfsdev_state_lock with the + * spa_namespace_lock in the ZVOL code. + */ +#define zfsdev_state_lock spa_namespace_lock +#endif static uint32_t zvol_minors; SYSCTL_DECL(_vfs_zfs); @@ -294,7 +303,7 @@ zvol_minor_lookup(const char *name) { zvol_state_t *zv; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); LIST_FOREACH(zv, &all_zvols, zv_links) { if (strcmp(zv->zv_name, name) == 0) @@ -523,11 +532,11 @@ zvol_name2minor(const char *name, minor_t *minor) { zvol_state_t *zv; - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); zv = zvol_minor_lookup(name); if (minor && zv) *minor = zv->zv_minor; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (zv ? 0 : -1); } #endif /* illumos */ @@ -550,10 +559,10 @@ zvol_create_minor(const char *name) ZFS_LOG(1, "Creating ZVOL %s...", name); - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); if (zvol_minor_lookup(name) != NULL) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(EEXIST)); } @@ -561,20 +570,20 @@ zvol_create_minor(const char *name) error = dmu_objset_own(name, DMU_OST_ZVOL, B_TRUE, FTAG, &os); if (error) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (error); } #ifdef illumos if ((minor = zfsdev_minor_alloc()) == 0) { dmu_objset_disown(os, FTAG); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(ENXIO)); } if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS) { dmu_objset_disown(os, FTAG); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(EAGAIN)); } (void) ddi_prop_update_string(minor, zfs_dip, ZVOL_PROP_NAME, @@ -586,7 +595,7 @@ zvol_create_minor(const char *name) minor, DDI_PSEUDO, 0) == DDI_FAILURE) { ddi_soft_state_free(zfsdev_state, minor); dmu_objset_disown(os, FTAG); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(EAGAIN)); } @@ -597,7 +606,7 @@ zvol_create_minor(const char *name) ddi_remove_minor_node(zfs_dip, chrbuf); ddi_soft_state_free(zfsdev_state, minor); dmu_objset_disown(os, FTAG); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(EAGAIN)); } @@ -612,7 +621,7 @@ zvol_create_minor(const char *name) if (error) { kmem_free(zv, sizeof(*zv)); dmu_objset_disown(os, zvol_tag); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (error); } error = dsl_prop_get_integer(name, @@ -643,7 +652,7 @@ zvol_create_minor(const char *name) 0640, "%s/%s", ZVOL_DRIVER, name) != 0) { kmem_free(zv, sizeof(*zv)); dmu_objset_disown(os, FTAG); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(ENXIO)); } zv->zv_dev = dev; @@ -679,7 +688,7 @@ zvol_create_minor(const char *name) zvol_minors++; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); #ifndef illumos if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { @@ -704,7 +713,7 @@ zvol_remove_zv(zvol_state_t *zv) minor_t minor = zv->zv_minor; #endif - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); if (zv->zv_total_opens != 0) return (SET_ERROR(EBUSY)); @@ -738,13 +747,13 @@ zvol_remove_minor(const char *name) zvol_state_t *zv; int rc; - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); if ((zv = zvol_minor_lookup(name)) == NULL) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(ENXIO)); } rc = zvol_remove_zv(zv); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (rc); } @@ -856,7 +865,7 @@ zvol_update_volsize(objset_t *os, uint64_t volsize) dmu_tx_t *tx; int error; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); tx = dmu_tx_create(os); dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL); @@ -886,7 +895,7 @@ zvol_remove_minors(const char *name) namelen = strlen(name); DROP_GIANT(); - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); LIST_FOREACH_SAFE(zv, &all_zvols, zv_links, tzv) { if (strcmp(zv->zv_name, name) == 0 || @@ -897,7 +906,7 @@ zvol_remove_minors(const char *name) } } - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); PICKUP_GIANT(); } @@ -911,10 +920,10 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) uint64_t old_volsize = 0ULL; uint64_t readonly; - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); zv = zvol_minor_lookup(name); if ((error = dmu_objset_hold(name, FTAG, &os)) != 0) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (error); } @@ -981,7 +990,7 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) out: dmu_objset_rele(os, FTAG); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (error); } @@ -1005,15 +1014,15 @@ zvol_open(struct g_provider *pp, int flag, int count) * recursively, but that function already has all the * necessary protection. */ - if (!MUTEX_HELD(&spa_namespace_lock)) { - mutex_enter(&spa_namespace_lock); + if (!MUTEX_HELD(&zfsdev_state_lock)) { + mutex_enter(&zfsdev_state_lock); locked = B_TRUE; } zv = pp->private; if (zv == NULL) { if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(ENXIO)); } @@ -1021,7 +1030,7 @@ zvol_open(struct g_provider *pp, int flag, int count) err = zvol_first_open(zv); if (err) { if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (err); } pp->mediasize = zv->zv_volsize; @@ -1048,14 +1057,14 @@ zvol_open(struct g_provider *pp, int flag, int count) zv->zv_total_opens += count; if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (err); out: if (zv->zv_total_opens == 0) zvol_last_close(zv); if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (err); } @@ -1068,15 +1077,15 @@ zvol_close(struct g_provider *pp, int flag, int count) boolean_t locked = B_FALSE; /* See comment in zvol_open(). */ - if (!MUTEX_HELD(&spa_namespace_lock)) { - mutex_enter(&spa_namespace_lock); + if (!MUTEX_HELD(&zfsdev_state_lock)) { + mutex_enter(&zfsdev_state_lock); locked = B_TRUE; } zv = pp->private; if (zv == NULL) { if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(ENXIO)); } @@ -1100,7 +1109,7 @@ zvol_close(struct g_provider *pp, int flag, int count) zvol_last_close(zv); if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (error); } @@ -1844,12 +1853,12 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) int error = 0; rl_t *rl; - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); zv = zfsdev_get_soft_state(getminor(dev), ZSST_ZVOL); if (zv == NULL) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (SET_ERROR(ENXIO)); } ASSERT(zv->zv_total_opens > 0); @@ -1867,7 +1876,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) dki.dki_unit = getminor(dev); dki.dki_maxtransfer = 1 << (SPA_OLD_MAXBLOCKSHIFT - zv->zv_min_bs); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); if (ddi_copyout(&dki, (void *)arg, sizeof (dki), flag)) error = SET_ERROR(EFAULT); return (error); @@ -1881,7 +1890,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) dkm.dki_lbsize = 1U << zv->zv_min_bs; dkm.dki_capacity = zv->zv_volsize >> zv->zv_min_bs; dkm.dki_media_type = DK_UNKNOWN; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); if (ddi_copyout(&dkm, (void *)arg, sizeof (dkm), flag)) error = SET_ERROR(EFAULT); return (error); @@ -1896,7 +1905,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) dkmext.dki_pbsize = zv->zv_volblocksize; dkmext.dki_capacity = zv->zv_volsize >> zv->zv_min_bs; dkmext.dki_media_type = DK_UNKNOWN; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); if (ddi_copyout(&dkmext, (void *)arg, sizeof (dkmext), flag)) error = SET_ERROR(EFAULT); return (error); @@ -1907,14 +1916,14 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) uint64_t vs = zv->zv_volsize; uint8_t bs = zv->zv_min_bs; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); error = zvol_getefi((void *)arg, flag, vs, bs); return (error); } case DKIOCFLUSHWRITECACHE: dkc = (struct dk_callback *)arg; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); zil_commit(zv->zv_zilog, ZVOL_OBJ); if ((flag & FKIOCTL) && dkc != NULL && dkc->dkc_callback) { (*dkc->dkc_callback)(dkc->dkc_cookie, error); @@ -1940,10 +1949,10 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) } if (wce) { zv->zv_flags |= ZVOL_WCE; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); } else { zv->zv_flags &= ~ZVOL_WCE; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); zil_commit(zv->zv_zilog, ZVOL_OBJ); } return (0); @@ -1995,7 +2004,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) if (df.df_start >= zv->zv_volsize) break; /* No need to do anything... */ - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); rl = zfs_range_lock(&zv->zv_znode, df.df_start, df.df_length, RL_WRITER); @@ -2042,7 +2051,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) break; } - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (error); } #endif /* illumos */ @@ -2058,12 +2067,19 @@ zvol_init(void) { VERIFY(ddi_soft_state_init(&zfsdev_state, sizeof (zfs_soft_state_t), 1) == 0); +#ifdef illumos + mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL); +#else ZFS_LOG(1, "ZVOL Initialized."); +#endif } void zvol_fini(void) { +#ifdef illumos + mutex_destroy(&zfsdev_state_lock); +#endif ddi_soft_state_fini(&zfsdev_state); ZFS_LOG(1, "ZVOL Deinitialized."); } @@ -2101,7 +2117,7 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize) uint64_t version = spa_version(spa); enum zio_checksum checksum; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); ASSERT(vd->vdev_ops == &vdev_root_ops); error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, 0, @@ -2668,7 +2684,7 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname) struct g_provider *pp; struct cdev *dev; - ASSERT(MUTEX_HELD(&spa_namespace_lock)); + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { g_topology_lock(); @@ -2721,8 +2737,8 @@ zvol_rename_minors(const char *oldname, const char *newname) DROP_GIANT(); /* See comment in zvol_open(). */ - if (!MUTEX_HELD(&spa_namespace_lock)) { - mutex_enter(&spa_namespace_lock); + if (!MUTEX_HELD(&zfsdev_state_lock)) { + mutex_enter(&zfsdev_state_lock); locked = B_TRUE; } @@ -2740,7 +2756,7 @@ zvol_rename_minors(const char *oldname, const char *newname) } if (locked) - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); PICKUP_GIANT(); } @@ -2750,17 +2766,17 @@ zvol_d_open(struct cdev *dev, int flags, int fmt, struct thread *td) zvol_state_t *zv; int err = 0; - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); zv = dev->si_drv2; if (zv == NULL) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return(ENXIO); /* zvol_create_minor() not done yet */ } if (zv->zv_total_opens == 0) err = zvol_first_open(zv); if (err) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (err); } if ((flags & FWRITE) && (zv->zv_flags & ZVOL_RDONLY)) { @@ -2782,12 +2798,12 @@ zvol_d_open(struct cdev *dev, int flags, int fmt, struct thread *td) #endif zv->zv_total_opens++; - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (err); out: if (zv->zv_total_opens == 0) zvol_last_close(zv); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (err); } @@ -2797,10 +2813,10 @@ zvol_d_close(struct cdev *dev, int flags, int fmt, struct thread *td) zvol_state_t *zv; int err = 0; - mutex_enter(&spa_namespace_lock); + mutex_enter(&zfsdev_state_lock); zv = dev->si_drv2; if (zv == NULL) { - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return(ENXIO); } @@ -2823,7 +2839,7 @@ zvol_d_close(struct cdev *dev, int flags, int fmt, struct thread *td) if (zv->zv_total_opens == 0) zvol_last_close(zv); - mutex_exit(&spa_namespace_lock); + mutex_exit(&zfsdev_state_lock); return (0); } From 6831cf6aa6cefe358fa59afb774e42f15d03fd10 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Mon, 22 Dec 2014 18:39:38 +0000 Subject: [PATCH 095/207] Fix panic when resizing ZFS zvol's Resizing a ZFS ZVOL with debug enabled would result in a panic due to recursion on dp_config_rwlock. The upstream change "3464 zfs synctask code needs restructuring" changed zvol_set_volsize to avoid the recursion on dp_config_rwlock, but this was missed when originally merged in by r248571 due to significant differences in our codebases in this area. These changes also relied on bring in changes from upstream: 3557 dumpvp_size is not updated correctly when a dump zvol's size is changed, which where also not present. In order to help prevent future issues in this area a direct comparison and diff minimisation from current upstream version (b515258) of zvol.c. Differential Revision: https://reviews.freebsd.org/D1302 MFC after: 1 month X-MFC-With: r276063 & r276066 Sponsored by: Multiplay --- .../opensolaris/uts/common/fs/zfs/sys/zvol.h | 2 +- .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 3 +- .../opensolaris/uts/common/fs/zfs/zvol.c | 381 ++++++++++++++---- 3 files changed, 303 insertions(+), 83 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h index 52b8f301e2e..75c6b3757c1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h @@ -43,7 +43,7 @@ extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx); extern int zvol_create_minor(const char *); extern int zvol_remove_minor(const char *); extern void zvol_remove_minors(const char *); -extern int zvol_set_volsize(const char *, major_t, uint64_t); +extern int zvol_set_volsize(const char *, uint64_t); #ifdef sun extern int zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index d7300836e01..383b789e611 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -2482,8 +2482,7 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, err = dsl_dataset_set_refreservation(dsname, source, intval); break; case ZFS_PROP_VOLSIZE: - err = zvol_set_volsize(dsname, ddi_driver_major(zfs_dip), - intval); + err = zvol_set_volsize(dsname, intval); break; case ZFS_PROP_VERSION: { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index 82ff3bcc70f..f9cc3eb65e8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -97,6 +97,7 @@ #include "zfs_namecheck.h" +#ifndef illumos struct g_class zfs_zvol_class = { .name = "ZFS::ZVOL", .version = G_VERSION, @@ -104,6 +105,7 @@ struct g_class zfs_zvol_class = { DECLARE_GEOM_CLASS(zfs_zvol_class, zfs_zvol); +#endif void *zfsdev_state; static char *zvol_tag = "zvol_tag"; @@ -126,12 +128,14 @@ kmutex_t zfsdev_state_lock; #endif static uint32_t zvol_minors; +#ifndef illumos SYSCTL_DECL(_vfs_zfs); SYSCTL_NODE(_vfs_zfs, OID_AUTO, vol, CTLFLAG_RW, 0, "ZFS VOLUME"); static int volmode = ZFS_VOLMODE_GEOM; SYSCTL_INT(_vfs_zfs_vol, OID_AUTO, mode, CTLFLAG_RWTUN, &volmode, 0, "Expose as GEOM providers (1), device files (2) or neither"); +#endif typedef struct zvol_extent { list_node_t ze_node; dva_t ze_dva; /* dva associated with this extent */ @@ -142,28 +146,40 @@ typedef struct zvol_extent { * The in-core state of each volume. */ typedef struct zvol_state { +#ifndef illumos LIST_ENTRY(zvol_state) zv_links; +#endif char zv_name[MAXPATHLEN]; /* pool/dd name */ uint64_t zv_volsize; /* amount of space we advertise */ uint64_t zv_volblocksize; /* volume block size */ +#ifdef illumos + minor_t zv_minor; /* minor number */ +#else struct cdev *zv_dev; /* non-GEOM device */ struct g_provider *zv_provider; /* GEOM provider */ +#endif uint8_t zv_min_bs; /* minimum addressable block shift */ uint8_t zv_flags; /* readonly, dumpified, etc. */ objset_t *zv_objset; /* objset handle */ +#ifdef illumos + uint32_t zv_open_count[OTYPCNT]; /* open counts */ +#endif uint32_t zv_total_opens; /* total open count */ zilog_t *zv_zilog; /* ZIL handle */ list_t zv_extents; /* List of extents for dump */ znode_t zv_znode; /* for range locking */ dmu_buf_t *zv_dbuf; /* bonus handle */ +#ifndef illumos int zv_state; int zv_volmode; /* Provide GEOM or cdev */ struct bio_queue_head zv_queue; struct mtx zv_queue_mtx; /* zv_queue mutex */ +#endif } zvol_state_t; +#ifndef illumos static LIST_HEAD(, zvol_state) all_zvols; - +#endif /* * zvol specific flags */ @@ -181,6 +197,7 @@ int zvol_maxphys = DMU_MAX_ACCESS/2; * Toggle unmap functionality. */ boolean_t zvol_unmap_enabled = B_TRUE; +#ifndef illumos SYSCTL_INT(_vfs_zfs_vol, OID_AUTO, unmap_enabled, CTLFLAG_RWTUN, &zvol_unmap_enabled, 0, "Enable UNMAP functionality"); @@ -204,28 +221,30 @@ static struct cdevsw zvol_cdevsw = { .d_flags = D_DISK | D_TRACKCLOSE, }; -extern int zfs_set_prop_nvlist(const char *, zprop_source_t, - nvlist_t *, nvlist_t *); +static void zvol_geom_run(zvol_state_t *zv); +static void zvol_geom_destroy(zvol_state_t *zv); +static int zvol_geom_access(struct g_provider *pp, int acr, int acw, int ace); +static void zvol_geom_start(struct bio *bp); +static void zvol_geom_worker(void *arg); static void zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off, uint64_t len, boolean_t sync); +#endif /* !illumos */ + +extern int zfs_set_prop_nvlist(const char *, zprop_source_t, + nvlist_t *, nvlist_t *); static int zvol_remove_zv(zvol_state_t *); static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio); static int zvol_dumpify(zvol_state_t *zv); static int zvol_dump_fini(zvol_state_t *zv); static int zvol_dump_init(zvol_state_t *zv, boolean_t resize); -static void zvol_geom_run(zvol_state_t *zv); -static void zvol_geom_destroy(zvol_state_t *zv); -static int zvol_geom_access(struct g_provider *pp, int acr, int acw, int ace); -static void zvol_geom_start(struct bio *bp); -static void zvol_geom_worker(void *arg); - static void -zvol_size_changed(zvol_state_t *zv) +zvol_size_changed(zvol_state_t *zv, uint64_t volsize) { #ifdef illumos - dev_t dev = makedevice(maj, min); + dev_t dev = makedevice(ddi_driver_major(zfs_dip), zv->zv_minor); + zv->zv_volsize = volsize; VERIFY(ddi_prop_update_int64(dev, zfs_dip, "Size", volsize) == DDI_SUCCESS); VERIFY(ddi_prop_update_int64(dev, zfs_dip, @@ -235,6 +254,7 @@ zvol_size_changed(zvol_state_t *zv) spec_size_invalidate(dev, VBLK); spec_size_invalidate(dev, VCHR); #else /* !illumos */ + zv->zv_volsize = volsize; if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { struct g_provider *pp; @@ -301,16 +321,26 @@ zvol_get_stats(objset_t *os, nvlist_t *nv) static zvol_state_t * zvol_minor_lookup(const char *name) { +#ifdef illumos + minor_t minor; +#endif zvol_state_t *zv; ASSERT(MUTEX_HELD(&zfsdev_state_lock)); +#ifdef illumos + for (minor = 1; minor <= ZFSDEV_MAX_MINOR; minor++) { + zv = zfsdev_get_soft_state(minor, ZSST_ZVOL); + if (zv == NULL) + continue; +#else LIST_FOREACH(zv, &all_zvols, zv_links) { +#endif if (strcmp(zv->zv_name, name) == 0) - break; + return (zv); } - return (zv); + return (NULL); } /* extent mapping arg */ @@ -550,14 +580,21 @@ zvol_create_minor(const char *name) zfs_soft_state_t *zs; zvol_state_t *zv; objset_t *os; + dmu_object_info_t doi; +#ifdef illumos + minor_t minor = 0; + char chrbuf[30], blkbuf[30]; +#else struct cdev *dev; struct g_provider *pp; struct g_geom *gp; - dmu_object_info_t doi; uint64_t volsize, mode; +#endif int error; +#ifndef illumos ZFS_LOG(1, "Creating ZVOL %s...", name); +#endif mutex_enter(&zfsdev_state_lock); @@ -664,6 +701,9 @@ zvol_create_minor(const char *name) (void) strlcpy(zv->zv_name, name, MAXPATHLEN); zv->zv_min_bs = DEV_BSHIFT; +#ifdef illumos + zv->zv_minor = minor; +#endif zv->zv_objset = os; if (dmu_objset_is_snapshot(os) || !spa_writeable(dmu_objset_spa(os))) zv->zv_flags |= ZVOL_RDONLY; @@ -689,16 +729,15 @@ zvol_create_minor(const char *name) zvol_minors++; mutex_exit(&zfsdev_state_lock); - #ifndef illumos if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { zvol_geom_run(zv); g_topology_unlock(); } PICKUP_GIANT(); -#endif ZFS_LOG(1, "ZVOL %s created.", name); +#endif return (0); } @@ -710,6 +749,7 @@ static int zvol_remove_zv(zvol_state_t *zv) { #ifdef illumos + char nmbuf[20]; minor_t minor = zv->zv_minor; #endif @@ -717,12 +757,15 @@ zvol_remove_zv(zvol_state_t *zv) if (zv->zv_total_opens != 0) return (SET_ERROR(EBUSY)); - ZFS_LOG(1, "ZVOL %s destroyed.", zv->zv_name); - #ifdef illumos (void) snprintf(nmbuf, sizeof (nmbuf), "%u,raw", minor); ddi_remove_minor_node(zfs_dip, nmbuf); + + (void) snprintf(nmbuf, sizeof (nmbuf), "%u", minor); + ddi_remove_minor_node(zfs_dip, nmbuf); #else + ZFS_LOG(1, "ZVOL %s destroyed.", zv->zv_name); + LIST_REMOVE(zv, zv_links); if (zv->zv_volmode == ZFS_VOLMODE_GEOM) { g_topology_lock(); @@ -735,8 +778,10 @@ zvol_remove_zv(zvol_state_t *zv) avl_destroy(&zv->zv_znode.z_range_avl); mutex_destroy(&zv->zv_znode.z_range_lock); - kmem_free(zv, sizeof(*zv)); - + kmem_free(zv, sizeof (zvol_state_t)); +#ifdef illumos + ddi_soft_state_free(zfsdev_state, minor); +#endif zvol_minors--; return (0); } @@ -771,21 +816,22 @@ zvol_first_open(zvol_state_t *zv) if (error) return (error); + zv->zv_objset = os; error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize); if (error) { ASSERT(error == 0); dmu_objset_disown(os, zvol_tag); return (error); } - zv->zv_objset = os; + error = dmu_bonus_hold(os, ZVOL_OBJ, zvol_tag, &zv->zv_dbuf); if (error) { dmu_objset_disown(os, zvol_tag); return (error); } - zv->zv_volsize = volsize; + + zvol_size_changed(zv, volsize); zv->zv_zilog = zil_open(os, zvol_get_data); - zvol_size_changed(zv); VERIFY(dsl_prop_get_integer(zv->zv_name, "readonly", &readonly, NULL) == 0); @@ -889,6 +935,27 @@ zvol_update_volsize(objset_t *os, uint64_t volsize) void zvol_remove_minors(const char *name) { +#ifdef illumos + zvol_state_t *zv; + char *namebuf; + minor_t minor; + + namebuf = kmem_zalloc(strlen(name) + 2, KM_SLEEP); + (void) strncpy(namebuf, name, strlen(name)); + (void) strcat(namebuf, "/"); + mutex_enter(&zfsdev_state_lock); + for (minor = 1; minor <= ZFSDEV_MAX_MINOR; minor++) { + + zv = zfsdev_get_soft_state(minor, ZSST_ZVOL); + if (zv == NULL) + continue; + if (strncmp(namebuf, zv->zv_name, strlen(namebuf)) == 0) + (void) zvol_remove_zv(zv); + } + kmem_free(namebuf, strlen(name) + 2); + + mutex_exit(&zfsdev_state_lock); +#else /* !illumos */ zvol_state_t *zv, *tzv; size_t namelen; @@ -908,67 +975,46 @@ zvol_remove_minors(const char *name) mutex_exit(&zfsdev_state_lock); PICKUP_GIANT(); +#endif /* illumos */ } -int -zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) +static int +zvol_update_live_volsize(zvol_state_t *zv, uint64_t volsize) { - zvol_state_t *zv = NULL; - objset_t *os; - int error; - dmu_object_info_t doi; uint64_t old_volsize = 0ULL; - uint64_t readonly; + int error = 0; - mutex_enter(&zfsdev_state_lock); - zv = zvol_minor_lookup(name); - if ((error = dmu_objset_hold(name, FTAG, &os)) != 0) { - mutex_exit(&zfsdev_state_lock); - return (error); - } + ASSERT(MUTEX_HELD(&zfsdev_state_lock)); - if ((error = dmu_object_info(os, ZVOL_OBJ, &doi)) != 0 || - (error = zvol_check_volsize(volsize, - doi.doi_data_block_size)) != 0) - goto out; - - VERIFY(dsl_prop_get_integer(name, "readonly", &readonly, - NULL) == 0); - if (readonly) { - error = EROFS; - goto out; - } - - error = zvol_update_volsize(os, volsize); /* * Reinitialize the dump area to the new size. If we * failed to resize the dump area then restore it back to - * its original size. + * its original size. We must set the new volsize prior + * to calling dumpvp_resize() to ensure that the devices' + * size(9P) is not visible by the dump subsystem. */ - if (zv && error == 0) { + old_volsize = zv->zv_volsize; + zvol_size_changed(zv, volsize); + #ifdef ZVOL_DUMP - if (zv->zv_flags & ZVOL_DUMPIFIED) { - old_volsize = zv->zv_volsize; - zv->zv_volsize = volsize; - if ((error = zvol_dumpify(zv)) != 0 || - (error = dumpvp_resize()) != 0) { - (void) zvol_update_volsize(os, old_volsize); - zv->zv_volsize = old_volsize; - error = zvol_dumpify(zv); - } - } -#endif /* ZVOL_DUMP */ - if (error == 0) { - zv->zv_volsize = volsize; - zvol_size_changed(zv); + if (zv->zv_flags & ZVOL_DUMPIFIED) { + if ((error = zvol_dumpify(zv)) != 0 || + (error = dumpvp_resize()) != 0) { + int dumpify_error; + + (void) zvol_update_volsize(zv->zv_objset, old_volsize); + zvol_size_changed(zv, old_volsize); + dumpify_error = zvol_dumpify(zv); + error = dumpify_error ? dumpify_error : error; } } +#endif /* ZVOL_DUMP */ #ifdef illumos /* * Generate a LUN expansion event. */ - if (zv && error == 0) { + if (error == 0) { sysevent_id_t eid; nvlist_t *attr; char *physpath = kmem_zalloc(MAXPATHLEN, KM_SLEEP); @@ -986,21 +1032,88 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize) kmem_free(physpath, MAXPATHLEN); } #endif /* illumos */ + return (error); +} +int +zvol_set_volsize(const char *name, uint64_t volsize) +{ + zvol_state_t *zv = NULL; + objset_t *os; + int error; + dmu_object_info_t doi; + uint64_t readonly; + boolean_t owned = B_FALSE; + + error = dsl_prop_get_integer(name, + zfs_prop_to_name(ZFS_PROP_READONLY), &readonly, NULL); + if (error != 0) + return (error); + if (readonly) + return (SET_ERROR(EROFS)); + + mutex_enter(&zfsdev_state_lock); + zv = zvol_minor_lookup(name); + + if (zv == NULL || zv->zv_objset == NULL) { + if ((error = dmu_objset_own(name, DMU_OST_ZVOL, B_FALSE, + FTAG, &os)) != 0) { + mutex_exit(&zfsdev_state_lock); + return (error); + } + owned = B_TRUE; + if (zv != NULL) + zv->zv_objset = os; + } else { + os = zv->zv_objset; + } + + if ((error = dmu_object_info(os, ZVOL_OBJ, &doi)) != 0 || + (error = zvol_check_volsize(volsize, doi.doi_data_block_size)) != 0) + goto out; + + error = zvol_update_volsize(os, volsize); + + if (error == 0 && zv != NULL) + error = zvol_update_live_volsize(zv, volsize); out: - dmu_objset_rele(os, FTAG); - + if (owned) { + dmu_objset_disown(os, FTAG); + if (zv != NULL) + zv->zv_objset = NULL; + } mutex_exit(&zfsdev_state_lock); - return (error); } /*ARGSUSED*/ +#ifdef illumos +int +zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr) +#else static int zvol_open(struct g_provider *pp, int flag, int count) +#endif { zvol_state_t *zv; int err = 0; +#ifdef illumos + + mutex_enter(&zfsdev_state_lock); + + zv = zfsdev_get_soft_state(getminor(*devp), ZSST_ZVOL); + if (zv == NULL) { + mutex_exit(&zfsdev_state_lock); + return (SET_ERROR(ENXIO)); + } + + if (zv->zv_total_opens == 0) + err = zvol_first_open(zv); + if (err) { + mutex_exit(&zfsdev_state_lock); + return (err); + } +#else /* !illumos */ boolean_t locked = B_FALSE; /* @@ -1037,6 +1150,7 @@ zvol_open(struct g_provider *pp, int flag, int count) pp->stripeoffset = 0; pp->stripesize = zv->zv_volblocksize; } +#endif /* illumos */ if ((flag & FWRITE) && (zv->zv_flags & ZVOL_RDONLY)) { err = SET_ERROR(EROFS); goto out; @@ -1055,20 +1169,46 @@ zvol_open(struct g_provider *pp, int flag, int count) } #endif +#ifdef illumos + if (zv->zv_open_count[otyp] == 0 || otyp == OTYP_LYR) { + zv->zv_open_count[otyp]++; + zv->zv_total_opens++; + } + mutex_exit(&zfsdev_state_lock); +#else zv->zv_total_opens += count; if (locked) mutex_exit(&zfsdev_state_lock); +#endif return (err); out: if (zv->zv_total_opens == 0) zvol_last_close(zv); +#ifdef illumos + mutex_exit(&zfsdev_state_lock); +#else if (locked) mutex_exit(&zfsdev_state_lock); +#endif return (err); } /*ARGSUSED*/ +#ifdef illumos +int +zvol_close(dev_t dev, int flag, int otyp, cred_t *cr) +{ + minor_t minor = getminor(dev); + zvol_state_t *zv; + int error = 0; + + mutex_enter(&zfsdev_state_lock); + + zv = zfsdev_get_soft_state(minor, ZSST_ZVOL); + if (zv == NULL) { + mutex_exit(&zfsdev_state_lock); +#else /* !illumos */ static int zvol_close(struct g_provider *pp, int flag, int count) { @@ -1086,6 +1226,7 @@ zvol_close(struct g_provider *pp, int flag, int count) if (zv == NULL) { if (locked) mutex_exit(&zfsdev_state_lock); +#endif /* illumos */ return (SET_ERROR(ENXIO)); } @@ -1098,18 +1239,30 @@ zvol_close(struct g_provider *pp, int flag, int count) * If the open count is zero, this is a spurious close. * That indicates a bug in the kernel / DDI framework. */ +#ifdef illumos + ASSERT(zv->zv_open_count[otyp] != 0); +#endif ASSERT(zv->zv_total_opens != 0); /* * You may get multiple opens, but only one close. */ +#ifdef illumos + zv->zv_open_count[otyp]--; + zv->zv_total_opens--; +#else zv->zv_total_opens -= count; +#endif if (zv->zv_total_opens == 0) zvol_last_close(zv); +#ifdef illumos + mutex_exit(&zfsdev_state_lock); +#else if (locked) mutex_exit(&zfsdev_state_lock); +#endif return (error); } @@ -1362,11 +1515,16 @@ zvol_dumpio(zvol_state_t *zv, void *addr, uint64_t offset, uint64_t size, return (error); } -#endif /* illumos */ +int +zvol_strategy(buf_t *bp) +{ + zfs_soft_state_t *zs = NULL; +#else /* !illumos */ void zvol_strategy(struct bio *bp) { +#endif /* illumos */ zvol_state_t *zv; uint64_t off, volsize; size_t resid; @@ -1374,22 +1532,53 @@ zvol_strategy(struct bio *bp) objset_t *os; rl_t *rl; int error = 0; +#ifdef illumos + boolean_t doread = bp->b_flags & B_READ; +#else boolean_t doread = 0; +#endif boolean_t is_dumpified; boolean_t sync; +#ifdef illumos + if (getminor(bp->b_edev) == 0) { + error = SET_ERROR(EINVAL); + } else { + zs = ddi_get_soft_state(zfsdev_state, getminor(bp->b_edev)); + if (zs == NULL) + error = SET_ERROR(ENXIO); + else if (zs->zss_type != ZSST_ZVOL) + error = SET_ERROR(EINVAL); + } + + if (error) { + bioerror(bp, error); + biodone(bp); + return (0); + } + + zv = zs->zss_data; + + if (!(bp->b_flags & B_READ) && (zv->zv_flags & ZVOL_RDONLY)) { + bioerror(bp, EROFS); + biodone(bp); + return (0); + } + + off = ldbtob(bp->b_blkno); +#else /* !illumos */ if (bp->bio_to) zv = bp->bio_to->private; else zv = bp->bio_dev->si_drv2; if (zv == NULL) { - error = ENXIO; + error = SET_ERROR(ENXIO); goto out; } if (bp->bio_cmd != BIO_READ && (zv->zv_flags & ZVOL_RDONLY)) { - error = EROFS; + error = SET_ERROR(EROFS); goto out; } @@ -1407,26 +1596,41 @@ zvol_strategy(struct bio *bp) } off = bp->bio_offset; +#endif /* illumos */ volsize = zv->zv_volsize; os = zv->zv_objset; ASSERT(os != NULL); +#ifdef illumos + bp_mapin(bp); + addr = bp->b_un.b_addr; + resid = bp->b_bcount; + + if (resid > 0 && (off < 0 || off >= volsize)) { + bioerror(bp, EIO); + biodone(bp); + return (0); + } + + is_dumpified = zv->zv_flags & ZVOL_DUMPIFIED; + sync = ((!(bp->b_flags & B_ASYNC) && + !(zv->zv_flags & ZVOL_WCE)) || + (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS)) && + !doread && !is_dumpified; +#else /* !illumos */ addr = bp->bio_data; resid = bp->bio_length; if (resid > 0 && (off < 0 || off >= volsize)) { - error = EIO; + error = SET_ERROR(EIO); goto out; } -#ifdef illumos - is_dumpified = zv->zv_flags & ZVOL_DUMPIFIED; -#else is_dumpified = B_FALSE; -#endif - sync = !doread && !is_dumpified && + sync = !doread && !is_dumpified && zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS; +#endif /* illumos */ /* * There must be no buffer changes when doing a dmu_sync() because @@ -1435,6 +1639,7 @@ zvol_strategy(struct bio *bp) rl = zfs_range_lock(&zv->zv_znode, off, resid, doread ? RL_READER : RL_WRITER); +#ifndef illumos if (bp->bio_cmd == BIO_DELETE) { dmu_tx_t *tx = dmu_tx_create(zv->zv_objset); error = dmu_tx_assign(tx, TXG_WAIT); @@ -1449,7 +1654,7 @@ zvol_strategy(struct bio *bp) } goto unlock; } - +#endif while (resid != 0 && off < volsize) { size_t size = MIN(resid, zvol_maxphys); #ifdef illumos @@ -1485,9 +1690,21 @@ zvol_strategy(struct bio *bp) addr += size; resid -= size; } +#ifndef illumos unlock: +#endif zfs_range_unlock(rl); +#ifdef illumos + if ((bp->b_resid = resid) == bp->b_bcount) + bioerror(bp, off > volsize ? EINVAL : error); + + if (sync) + zil_commit(zv->zv_zilog, ZVOL_OBJ); + biodone(bp); + + return (0); +#else /* !illumos */ bp->bio_completed = bp->bio_length - resid; if (bp->bio_completed < bp->bio_length && off > volsize) error = EINVAL; @@ -1501,6 +1718,7 @@ out: g_io_deliver(bp, error); else biofinish(bp, NULL, error); +#endif /* illumos */ } #ifdef illumos @@ -1578,6 +1796,7 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag) #endif volsize = zv->zv_volsize; + /* uio_loffset == volsize isn't an error as its required for EOF processing. */ if (uio->uio_resid > 0 && (uio->uio_loffset < 0 || uio->uio_loffset > volsize)) return (SET_ERROR(EIO)); @@ -1637,6 +1856,7 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag) #endif volsize = zv->zv_volsize; + /* uio_loffset == volsize isn't an error as its required for EOF processing. */ if (uio->uio_resid > 0 && (uio->uio_loffset < 0 || uio->uio_loffset > volsize)) return (SET_ERROR(EIO)); @@ -2369,7 +2589,7 @@ zvol_dump_fini(zvol_state_t *zv) return (0); } -#endif /* illumos */ +#else /* !illumos */ static void zvol_geom_run(zvol_state_t *zv) @@ -2947,3 +3167,4 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa return (error); } +#endif /* illumos */ From 2f834a0b41079f9be4dc33ff877d50a5fba869d4 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 22 Dec 2014 18:54:55 +0000 Subject: [PATCH 096/207] Fix multiple ntp vulnerabilities. Reviewed by: roberto (earlier revision), philip Security: CVE-2014-9293, CVE-2014-9294 Security: CVE-2014-9295, CVE-2014-9296 Security: FreeBSD-SA-14:31.ntp Differential Revision: https://reviews.freebsd.org/D1343 --- contrib/ntp/ntpd/ntp_config.c | 2 +- contrib/ntp/ntpd/ntp_control.c | 17 ++++++++++++++++- contrib/ntp/ntpd/ntp_crypto.c | 22 +++++++++++++++++----- contrib/ntp/ntpd/ntp_proto.c | 1 + contrib/ntp/util/ntp-keygen.c | 6 +++--- 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/contrib/ntp/ntpd/ntp_config.c b/contrib/ntp/ntpd/ntp_config.c index a28bd1b417c..e038f205790 100644 --- a/contrib/ntp/ntpd/ntp_config.c +++ b/contrib/ntp/ntpd/ntp_config.c @@ -1887,7 +1887,7 @@ getconfig( for (i = 0; i < 8; i++) for (j = 1; j < 100; ++j) { - rankey[i] = (char) (ntp_random() & 0xff); + rankey[i] = (char) (arc4random() & 0xff); if (rankey[i] != 0) break; } rankey[8] = 0; diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c index 15f5856f279..dbee89a0cdc 100644 --- a/contrib/ntp/ntpd/ntp_control.c +++ b/contrib/ntp/ntpd/ntp_control.c @@ -24,6 +24,10 @@ #include #include +#ifndef MIN +#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) +#endif + /* * Structure to hold request procedure information */ @@ -893,6 +897,7 @@ ctl_putdata( ) { int overhead; + unsigned int currentlen; overhead = 0; if (!bin) { @@ -916,12 +921,22 @@ ctl_putdata( /* * Save room for trailing junk */ - if (dlen + overhead + datapt > dataend) { + while (dlen + overhead + datapt > dataend) { /* * Not enough room in this one, flush it out. */ + currentlen = MIN(dlen, dataend - datapt); + + memcpy(datapt, dp, currentlen); + + datapt += currentlen; + dp += currentlen; + dlen -= currentlen; + datalinelen += currentlen; + ctl_flushpkt(CTL_MORE); } + memmove((char *)datapt, dp, (unsigned)dlen); datapt += dlen; datalinelen += dlen; diff --git a/contrib/ntp/ntpd/ntp_crypto.c b/contrib/ntp/ntpd/ntp_crypto.c index cce95a8e1ea..37427f4ee6c 100644 --- a/contrib/ntp/ntpd/ntp_crypto.c +++ b/contrib/ntp/ntpd/ntp_crypto.c @@ -864,12 +864,24 @@ crypto_recv( * errors. */ if (vallen == (u_int) EVP_PKEY_size(host_pkey)) { - RSA_private_decrypt(vallen, + u_int32 *cookiebuf = malloc( + RSA_size(host_pkey->pkey.rsa)); + if (cookiebuf == NULL) { + rval = XEVNT_CKY; + break; + } + if (RSA_private_decrypt(vallen, (u_char *)ep->pkt, - (u_char *)&temp32, + (u_char *)cookiebuf, host_pkey->pkey.rsa, - RSA_PKCS1_OAEP_PADDING); - cookie = ntohl(temp32); + RSA_PKCS1_OAEP_PADDING) != 4) { + rval = XEVNT_CKY; + free(cookiebuf); + break; + } else { + cookie = ntohl(*cookiebuf); + free(cookiebuf); + } } else { rval = XEVNT_CKY; break; @@ -3914,7 +3926,7 @@ crypto_setup(void) rand_file); exit (-1); } - get_systime(&seed); + arc4random_buf(&seed, sizeof(l_fp)); RAND_seed(&seed, sizeof(l_fp)); RAND_write_file(rand_file); OpenSSL_add_all_algorithms(); diff --git a/contrib/ntp/ntpd/ntp_proto.c b/contrib/ntp/ntpd/ntp_proto.c index 0ab24988301..179e118b5f0 100644 --- a/contrib/ntp/ntpd/ntp_proto.c +++ b/contrib/ntp/ntpd/ntp_proto.c @@ -649,6 +649,7 @@ receive( has_mac)) { is_authentic = AUTH_ERROR; sys_badauth++; + return; } else { is_authentic = AUTH_OK; } diff --git a/contrib/ntp/util/ntp-keygen.c b/contrib/ntp/util/ntp-keygen.c index 6c145188955..056121e68c8 100644 --- a/contrib/ntp/util/ntp-keygen.c +++ b/contrib/ntp/util/ntp-keygen.c @@ -642,7 +642,7 @@ gen_md5( for (i = 1; i <= MD5KEYS; i++) { for (j = 0; j < 16; j++) { while (1) { - temp = ntp_random() & 0xff; + temp = arc4random() & 0xff; if (temp == '#') continue; if (temp > 0x20 && temp < 0x7f) @@ -675,7 +675,7 @@ gen_rsa( FILE *str; fprintf(stderr, "Generating RSA keys (%d bits)...\n", modulus); - rsa = RSA_generate_key(modulus, 3, cb, "RSA"); + rsa = RSA_generate_key(modulus, 65537, cb, "RSA"); fprintf(stderr, "\n"); if (rsa == NULL) { fprintf(stderr, "RSA generate keys fails\n%s\n", @@ -954,7 +954,7 @@ gen_gqpar( */ fprintf(stderr, "Generating GQ parameters (%d bits)...\n", modulus); - rsa = RSA_generate_key(modulus, 3, cb, "GQ"); + rsa = RSA_generate_key(modulus, 65537, cb, "GQ"); fprintf(stderr, "\n"); if (rsa == NULL) { fprintf(stderr, "RSA generate keys fails\n%s\n", From f9f0d902c123af52ef6aa0b13faf5bdee619cbbf Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 22 Dec 2014 19:10:11 +0000 Subject: [PATCH 097/207] Make this compile when TERM_EMU is not defined. --- sys/boot/i386/libi386/spinconsole.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/boot/i386/libi386/spinconsole.c b/sys/boot/i386/libi386/spinconsole.c index 752c29f5d4d..161d81066b2 100644 --- a/sys/boot/i386/libi386/spinconsole.c +++ b/sys/boot/i386/libi386/spinconsole.c @@ -86,9 +86,11 @@ spinc_putchar(int c) if (now < (lasttime + 1)) return; lasttime = now; +#ifdef TERM_EMU get_pos(&curx, &cury); if (curx > 0) curs_move(&curx, &cury, curx - 1, cury); +#endif vidc_biosputchar((char)tw_chars); tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24); } From 87570696588537e63ba3b6906c1dc6b5c4857596 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 22 Dec 2014 19:10:21 +0000 Subject: [PATCH 098/207] Don't require ${SYSDIR}/../COPYRIGHT to exist. Fall back to the current date if we can't find it. MFC After: 2 weeks --- sys/conf/newvers.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 9b3b84b0618..c06eeaf1768 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -52,7 +52,11 @@ else fi b=share/examples/etc/bsd-style-copyright -year=$(sed -Ee '/^Copyright .* The FreeBSD Project/!d;s/^.*1992-([0-9]*) .*$/\1/g' ${SYSDIR}/../COPYRIGHT) +if [ -r "${SYSDIR}/../COPYRIGHT" ]; then + year=$(sed -Ee '/^Copyright .* The FreeBSD Project/!d;s/^.*1992-([0-9]*) .*$/\1/g' ${SYSDIR}/../COPYRIGHT) +else + year=$(date +%Y) +fi # look for copyright template for bsd_copyright in ../$b ../../$b ../../../$b /usr/src/$b /usr/$b do From 7668336c8e14f9960ba8954449adc72847c9c187 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Mon, 22 Dec 2014 20:42:36 +0000 Subject: [PATCH 099/207] Add a divisor parameter to twiddle() so that callers can request that output only happen on every Nth call. Update the existing twiddle() calls done in various IO loops to roughly reflect the relative IO sizes. That is, tftp and nfs call twiddle() on every 1K block, ufs on every filesystem block, so the network calls now use a much larger divisor than disk IO calls. Also add a new twiddle_divisor() function that allows an application to set a global divisor that is applied on top of the per-call divisors. Nothing calls this yet, but loader(8) will be using it to further throttle the cursor for slow serial consoles. --- lib/libstand/cd9660.c | 8 ++++---- lib/libstand/ext2fs.c | 12 ++++++------ lib/libstand/nandfs.c | 2 +- lib/libstand/nfs.c | 4 ++-- lib/libstand/read.c | 2 +- lib/libstand/stand.h | 3 ++- lib/libstand/tftp.c | 4 +--- lib/libstand/twiddle.c | 21 +++++++++++++++++++-- lib/libstand/ufs.c | 14 +++++++------- lib/libstand/write.c | 2 +- 10 files changed, 44 insertions(+), 28 deletions(-) diff --git a/lib/libstand/cd9660.c b/lib/libstand/cd9660.c index c6bcef2ec9c..5bee87936f6 100644 --- a/lib/libstand/cd9660.c +++ b/lib/libstand/cd9660.c @@ -281,7 +281,7 @@ cd9660_open(const char *path, struct open_file *f) buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE); vd = buf; for (bno = 16;; bno++) { - twiddle(); + twiddle(1); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno), ISO_DEFAULT_BLOCK_SIZE, buf, &read); if (rc) @@ -314,7 +314,7 @@ cd9660_open(const char *path, struct open_file *f) while (off < dsize) { if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) { - twiddle(); + twiddle(1); rc = f->f_dev->dv_strategy (f->f_devdata, F_READ, cdb2devb(bno + boff), @@ -374,7 +374,7 @@ cd9660_open(const char *path, struct open_file *f) /* Check for Rock Ridge since we didn't in the loop above. */ bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length); - twiddle(); + twiddle(1); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno), ISO_DEFAULT_BLOCK_SIZE, buf, &read); if (rc) @@ -431,7 +431,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p) if (fp->f_buf == (char *)0) fp->f_buf = malloc(ISO_DEFAULT_BLOCK_SIZE); - twiddle(); + twiddle(16); rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(blkno), ISO_DEFAULT_BLOCK_SIZE, fp->f_buf, &read); if (rc) diff --git a/lib/libstand/ext2fs.c b/lib/libstand/ext2fs.c index e0afb3eddd6..d0b91e04466 100644 --- a/lib/libstand/ext2fs.c +++ b/lib/libstand/ext2fs.c @@ -353,7 +353,7 @@ ext2fs_open(const char *upath, struct open_file *f) /* allocate space and read super block */ fs = (struct ext2fs *)malloc(sizeof(*fs)); fp->f_fs = fs; - twiddle(); + twiddle(1); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, EXT2_SBLOCK, EXT2_SBSIZE, (char *)fs, &buf_size); if (error) @@ -395,7 +395,7 @@ ext2fs_open(const char *upath, struct open_file *f) len = blkgrps * fs->fs_bsize; fp->f_bg = malloc(len); - twiddle(); + twiddle(1); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, EXT2_SBLOCK + EXT2_SBSIZE / DEV_BSIZE, len, (char *)fp->f_bg, &buf_size); @@ -507,7 +507,7 @@ ext2fs_open(const char *upath, struct open_file *f) if (error) goto out; - twiddle(); + twiddle(1); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsb_to_db(fs, disk_block), fs->fs_bsize, buf, &buf_size); @@ -568,7 +568,7 @@ read_inode(ino_t inumber, struct open_file *f) * Read inode and save it. */ buf = malloc(fs->fs_bsize); - twiddle(); + twiddle(1); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, ino_to_db(fs, fp->f_bg, inumber), fs->fs_bsize, buf, &rsize); if (error) @@ -665,7 +665,7 @@ block_map(struct open_file *f, daddr_t file_block, daddr_t *disk_block_p) if (fp->f_blk[level] == (char *)0) fp->f_blk[level] = malloc(fs->fs_bsize); - twiddle(); + twiddle(1); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsb_to_db(fp->f_fs, ind_block_num), fs->fs_bsize, fp->f_blk[level], &fp->f_blksize[level]); @@ -723,7 +723,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p) bzero(fp->f_buf, block_size); fp->f_buf_size = block_size; } else { - twiddle(); + twiddle(4); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsb_to_db(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); diff --git a/lib/libstand/nandfs.c b/lib/libstand/nandfs.c index 713dc125de7..b8c51e3b5a9 100644 --- a/lib/libstand/nandfs.c +++ b/lib/libstand/nandfs.c @@ -921,7 +921,7 @@ nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node, return (0); } - twiddle(); + twiddle(1); NANDFS_DEBUG("calling get_map with %jx\n", ind_block_num); map = nandfs_get_map(fs, node, ind_block_num, phys); if (map == NULL) diff --git a/lib/libstand/nfs.c b/lib/libstand/nfs.c index adb0a11f176..a0b726cde3f 100644 --- a/lib/libstand/nfs.c +++ b/lib/libstand/nfs.c @@ -662,7 +662,7 @@ nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid) (int)fp->off); #endif while ((int)size > 0) { - twiddle(); + twiddle(16); cc = nfs_readdata(fp, fp->off, (void *)addr, size); /* XXX maybe should retry on certain errors */ if (cc == -1) { @@ -1311,7 +1311,7 @@ nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid) (int)fp->off); #endif while ((int)size > 0) { - twiddle(); + twiddle(16); cc = nfs_readdata(fp, fp->off, (void *)addr, size); /* XXX maybe should retry on certain errors */ if (cc == -1) { diff --git a/lib/libstand/read.c b/lib/libstand/read.c index 4c67dbeb3b5..a984dbe3050 100644 --- a/lib/libstand/read.c +++ b/lib/libstand/read.c @@ -77,7 +77,7 @@ read(int fd, void *dest, size_t bcount) return (-1); } if (f->f_flags & F_RAW) { - twiddle(); + twiddle(4); errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, btodb(f->f_offset), bcount, dest, &resid); if (errno) diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h index bcd146af5d6..22ee3199234 100644 --- a/lib/libstand/stand.h +++ b/lib/libstand/stand.h @@ -242,7 +242,8 @@ extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3); extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4); extern void vsprintf(char *buf, const char *cfmt, __va_list); -extern void twiddle(void); +extern void twiddle(u_int callerdiv); +extern void twiddle_divisor(u_int globaldiv); extern void ngets(char *, int); #define gets(x) ngets((x), 0) diff --git a/lib/libstand/tftp.c b/lib/libstand/tftp.c index e3983c3af45..6527c4ed749 100644 --- a/lib/libstand/tftp.c +++ b/lib/libstand/tftp.c @@ -447,14 +447,12 @@ tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid /* out */) { struct tftp_handle *tftpfile; - static int tc = 0; tftpfile = (struct tftp_handle *) f->f_fsdata; while (size > 0) { int needblock, count; - if (!(tc++ % 16)) - twiddle(); + twiddle(32); needblock = tftpfile->off / tftpfile->tftp_blksize + 1; diff --git a/lib/libstand/twiddle.c b/lib/libstand/twiddle.c index e0a4c08f27b..96ebbbec43c 100644 --- a/lib/libstand/twiddle.c +++ b/lib/libstand/twiddle.c @@ -42,11 +42,28 @@ __FBSDID("$FreeBSD$"); /* Extra functions from NetBSD standalone printf.c */ +static u_int globaldiv; + void -twiddle() +twiddle(u_int callerdiv) { - static int pos; + static u_int callercnt, globalcnt, pos; + + callercnt++; + if (callerdiv > 1 && (callercnt % callerdiv) != 0) + return; + + globalcnt++; + if (globaldiv > 1 && (globalcnt % globaldiv) != 0) + return; putchar("|/-\\"[pos++ & 3]); putchar('\b'); } + +void +twiddle_divisor(u_int gdiv) +{ + + globaldiv = gdiv; +} diff --git a/lib/libstand/ufs.c b/lib/libstand/ufs.c index b6f781572bb..928a1d1d2a8 100644 --- a/lib/libstand/ufs.c +++ b/lib/libstand/ufs.c @@ -155,7 +155,7 @@ read_inode(inumber, f) * Read inode and save it. */ buf = malloc(fs->fs_bsize); - twiddle(); + twiddle(1); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize, buf, &rsize); @@ -265,7 +265,7 @@ block_map(f, file_block, disk_block_p) if (fp->f_blk[level] == (char *)0) fp->f_blk[level] = malloc(fs->fs_bsize); - twiddle(); + twiddle(1); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fp->f_fs, ind_block_num), fs->fs_bsize, @@ -346,7 +346,7 @@ buf_write_file(f, buf_p, size_p) if (fp->f_buf == (char *)0) fp->f_buf = malloc(fs->fs_bsize); - twiddle(); + twiddle(4); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); @@ -365,7 +365,7 @@ buf_write_file(f, buf_p, size_p) * Write the block out to storage. */ - twiddle(); + twiddle(4); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, fsbtodb(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); @@ -406,7 +406,7 @@ buf_read_file(f, buf_p, size_p) bzero(fp->f_buf, block_size); fp->f_buf_size = block_size; } else { - twiddle(); + twiddle(4); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), block_size, fp->f_buf, &fp->f_buf_size); @@ -515,7 +515,7 @@ ufs_open(upath, f) /* allocate space and read super block */ fs = malloc(SBLOCKSIZE); fp->f_fs = fs; - twiddle(); + twiddle(1); /* * Try reading the superblock in each of its possible locations. */ @@ -649,7 +649,7 @@ ufs_open(upath, f) if (rc) goto out; - twiddle(); + twiddle(1); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), fs->fs_bsize, buf, &buf_size); diff --git a/lib/libstand/write.c b/lib/libstand/write.c index dccdb8bb2b4..9e02f083f24 100644 --- a/lib/libstand/write.c +++ b/lib/libstand/write.c @@ -80,7 +80,7 @@ write(fd, dest, bcount) return (-1); } if (f->f_flags & F_RAW) { - twiddle(); + twiddle(4); errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, btodb(f->f_offset), bcount, dest, &resid); if (errno) From 1b055b0ecaa05e979d591195e0061be433f64c1a Mon Sep 17 00:00:00 2001 From: Dmitry Morozovsky Date: Mon, 22 Dec 2014 21:26:49 +0000 Subject: [PATCH 100/207] Add VAMI (VMware Appliance Management Interface) port. Reviewed by: eadler MFC after: 2 weeks --- etc/services | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/services b/etc/services index 13ad4c820f6..1311799c76c 100644 --- a/etc/services +++ b/etc/services @@ -2345,6 +2345,8 @@ mdns 5353/tcp #Multicast DNS mdns 5353/udp #Multicast DNS postgresql 5432/tcp #PostgreSQL Database postgresql 5432/udp #PostgreSQL Database +vami 5480/tcp #VMware Appliance Management Interface, HTTPS-like +vami 5480/udp #VMware Appliance Management Interface, HTTPS-like rplay 5555/udp amqp 5672/sctp #AMQP amqp 5672/tcp #AMQP From 7e654612dcb1b373da4271f69662a87e9e783928 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Mon, 22 Dec 2014 21:52:37 +0000 Subject: [PATCH 101/207] Strip trailing / characters from paths in "not present" index entries, not just "directory" entries. Prior to this commit, if / was added as part of a security update (how? In the most recent case, because lib32 was accidentally omitted and was then re-added, and every installer distribution set gets its own paths) then the code which was supposed to filter out updates to deleted parts of the base system (if someone decides to delete / then we shouldn't re-create it for them) would instead get confused and decided that while / should exist, // should not exist and needs to be removed. This fixes the bug which caused freebsd-update to want to delete / (which is harmless, since `rm /` fails, but scary nonetheless). A workaround is being applied to the update bits in order to avoid triggering the bug on unpatched systems. PR: 196055, 196091, 196147 --- usr.sbin/freebsd-update/freebsd-update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index f586909caa3..57ea25152b0 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -1395,6 +1395,7 @@ fetch_filter_metadata () { # matter, since we add a leading "/" when we use paths later. cut -f 3- -d '|' $1 | sed -e 's,/|d|,|d|,' | + sed -e 's,/|-|,|-|,' | sort -u > $1.tmp # Figure out which lines to ignore and remove them. From af3cafd76c3f003b78babe051d768406da0afc1a Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Mon, 22 Dec 2014 22:07:22 +0000 Subject: [PATCH 102/207] Add a new loader(8) variable, twiddle_divisor, allowing control over the output frequency of the "twiddle" IO progress indicator. The default value is 1. For larger values N, the next stage of the animation is only output on every Nth call to the output routine. A sufficiently large N effectively disables the animation completely. --- sys/boot/common/console.c | 29 +++++++++++++++++++++++++++++ sys/boot/common/loader.8 | 8 +++++++- sys/boot/forth/loader.conf | 1 + 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/sys/boot/common/console.c b/sys/boot/common/console.c index 6c1fdab87f0..6656eabf2a0 100644 --- a/sys/boot/common/console.c +++ b/sys/boot/common/console.c @@ -39,6 +39,7 @@ static int cons_set(struct env_var *ev, int flags, const void *value); static int cons_find(const char *name); static int cons_check(const char *string); static void cons_change(const char *string); +static int twiddle_set(struct env_var *ev, int flags, const void *value); /* * Detect possible console(s) to use. If preferred console(s) have been @@ -52,6 +53,9 @@ cons_probe(void) int active; char *prefconsole; + /* We want a callback to install the new value when this var changes. */ + env_setenv("twiddle_divisor", EV_VOLATILE, "1", twiddle_set, env_nounset); + /* Do all console probes */ for (cons = 0; consoles[cons] != NULL; cons++) { consoles[cons]->c_flags = 0; @@ -232,3 +236,28 @@ cons_change(const char *string) free(dup); } + +/* + * Change the twiddle divisor. + * + * The user can set the twiddle_divisor variable to directly control how fast + * the progress twiddle spins, useful for folks with slow serial consoles. The + * code to monitor changes to the variable and propagate them to the twiddle + * routines has to live somewhere. Twiddling is console-related so it's here. + */ +static int +twiddle_set(struct env_var *ev, int flags, const void *value) +{ + u_long tdiv; + char * eptr; + + tdiv = strtoul(value, &eptr, 0); + if (*(const char *)value == 0 || *eptr != 0) { + printf("invalid twiddle_divisor '%s'\n", (const char *)value); + return (CMD_ERROR); + } + twiddle_divisor((u_int)tdiv); + env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); + + return(CMD_OK); +} diff --git a/sys/boot/common/loader.8 b/sys/boot/common/loader.8 index fe247ac89c5..cac56743a69 100644 --- a/sys/boot/common/loader.8 +++ b/sys/boot/common/loader.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 1, 2013 +.Dd December 22, 2014 .Dt LOADER 8 .Os .Sh NAME @@ -670,6 +670,12 @@ Overrides the compile-time set value of .Dv TCBHASHSIZE or the preset default of 512. Must be a power of 2. +.It Va twiddle_divisor +Throttles the output of the `twiddle' I/O progress indicator displayed +while loading the kernel and modules. +This is useful on slow serial consoles where the time spent waiting for +these characters to be written can add up to many seconds. +The default is 1 (full speed); a value of 2 spins half as fast, and so on. .It Va vm.kmem_size Sets the size of kernel memory (bytes). This overrides the value determined when the kernel was compiled. diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index bd7d296e984..fd0b0de5fec 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -75,6 +75,7 @@ module_path="/boot/modules" # Set the module search path # the block size is set to 512. If the value # is out of range ( < 8 || > 9008 ) an error is # returned. +#twiddle_divisor="1" # >1 means slow down the progress indicator. ############################################################## From 6d514f104ec744210e4cd2e815fcf5384d405c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Mon, 22 Dec 2014 23:03:18 +0000 Subject: [PATCH 103/207] Use "RCS tag" instead of "$FreeBSD$ tag", since svn will obediently expand the latter. MFC after: 3 days --- usr.sbin/freebsd-update/freebsd-update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index 57ea25152b0..4979c014825 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -2264,7 +2264,7 @@ upgrade_oldall_to_oldnew () { } # Helper for upgrade_merge: Return zero true iff the two files differ only -# in the contents of their $FreeBSD$ tags. +# in the contents of their RCS tags. samef () { X=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $1 | ${SHA256}` Y=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $2 | ${SHA256}` @@ -2360,7 +2360,7 @@ upgrade_merge () { # Ask the user to handle any files which didn't merge. while read F; do # If the installed file differs from the version in - # the old release only due to $FreeBSD$ tag expansion + # the old release only due to RCS tag expansion # then just use the version in the new release. if samef merge/old/${F} merge/${OLDRELNUM}/${F}; then cp merge/${RELNUM}/${F} merge/new/${F} @@ -2382,14 +2382,14 @@ manually... # of merging files. while read F; do # Skip files which haven't changed except possibly - # in their $FreeBSD$ tags. + # in their RCS tags. if [ -f merge/old/${F} ] && [ -f merge/new/${F} ] && samef merge/old/${F} merge/new/${F}; then continue fi # Skip files where the installed file differs from - # the old file only due to $FreeBSD$ tags. + # the old file only due to RCS tags. if [ -f merge/old/${F} ] && [ -f merge/${OLDRELNUM}/${F} ] && samef merge/old/${F} merge/${OLDRELNUM}/${F}; then From c15882f09100c13fc41902bd2620242a424a83be Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 23 Dec 2014 00:47:46 +0000 Subject: [PATCH 104/207] Remove the old NFS client and server from head, which means that the NFSCLIENT and NFSSERVER kernel options will no longer work. This commit only removes the kernel components. Removal of unused code in the user utilities will be done later. This commit does not include an addition to UPDATING, but that will be committed in a few minutes. Discussed on: freebsd-fs --- sys/arm/conf/DOCKSTAR | 2 +- sys/arm/conf/DREAMPLUG-1001 | 2 +- sys/arm/conf/EA3250 | 2 +- sys/conf/NOTES | 5 +- sys/conf/files | 76 +- sys/conf/options | 5 - sys/fs/nfs/nfs_commonkrpc.c | 6 +- sys/fs/nfsclient/nfs_clnode.c | 2 +- sys/fs/nfsclient/nfs_clport.c | 2 +- sys/fs/nfsclient/nfs_clvfsops.c | 6 +- sys/modules/Makefile | 3 - sys/modules/dtrace/Makefile | 1 - sys/modules/dtrace/dtnfsclient/Makefile | 17 - sys/modules/dtrace/dtraceall/dtraceall.c | 3 - sys/modules/nfs_common/Makefile | 8 - sys/modules/nfsclient/Makefile | 32 - sys/modules/nfsserver/Makefile | 12 - sys/nfs/bootp_subr.c | 3 - sys/nfs/nfs_common.c | 407 --- sys/nfsclient/nfs_bio.c | 1794 ----------- sys/nfsclient/nfs_kdtrace.c | 542 ---- sys/nfsclient/nfs_krpc.c | 887 ----- sys/nfsclient/nfs_nfsiod.c | 346 -- sys/nfsclient/nfs_node.c | 276 -- sys/nfsclient/nfs_subs.c | 1140 ------- sys/nfsclient/nfs_vfsops.c | 1582 --------- sys/nfsclient/nfs_vnops.c | 3544 -------------------- sys/nfsserver/nfs_fha_old.c | 265 -- sys/nfsserver/nfs_serv.c | 3767 ---------------------- sys/nfsserver/nfs_srvkrpc.c | 545 ---- sys/nfsserver/nfs_srvsubs.c | 1418 -------- sys/sys/param.h | 2 +- 32 files changed, 46 insertions(+), 16656 deletions(-) delete mode 100644 sys/modules/dtrace/dtnfsclient/Makefile delete mode 100644 sys/modules/nfs_common/Makefile delete mode 100644 sys/modules/nfsclient/Makefile delete mode 100644 sys/modules/nfsserver/Makefile delete mode 100644 sys/nfs/nfs_common.c delete mode 100644 sys/nfsclient/nfs_bio.c delete mode 100644 sys/nfsclient/nfs_kdtrace.c delete mode 100644 sys/nfsclient/nfs_krpc.c delete mode 100644 sys/nfsclient/nfs_nfsiod.c delete mode 100644 sys/nfsclient/nfs_node.c delete mode 100644 sys/nfsclient/nfs_subs.c delete mode 100644 sys/nfsclient/nfs_vfsops.c delete mode 100644 sys/nfsclient/nfs_vnops.c delete mode 100644 sys/nfsserver/nfs_fha_old.c delete mode 100644 sys/nfsserver/nfs_serv.c delete mode 100644 sys/nfsserver/nfs_srvkrpc.c delete mode 100644 sys/nfsserver/nfs_srvsubs.c diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index 73a0811f557..ad1e74d6eaf 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -154,7 +154,7 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require # Enable these options for nfs root configured via BOOTP. options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager -#options NFS_ROOT # NFS usable as /, requires NFSCLIENT +#options NFS_ROOT # NFS usable as /, requires NFSCL #options BOOTP #options BOOTP_NFSROOT #options BOOTP_NFSV3 diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index 5b5b002880f..135cba0cd6f 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -162,7 +162,7 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require # Enable these options for nfs root configured via BOOTP. options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager -#options NFS_ROOT # NFS usable as /, requires NFSCLIENT +#options NFS_ROOT # NFS usable as /, requires NFSCL #options BOOTP #options BOOTP_NFSROOT #options BOOTP_NFSV3 diff --git a/sys/arm/conf/EA3250 b/sys/arm/conf/EA3250 index 82bc38696ea..d2d691b3212 100644 --- a/sys/arm/conf/EA3250 +++ b/sys/arm/conf/EA3250 @@ -19,7 +19,7 @@ options INET6 # IPv6 communications protocols options FFS # Berkeley Fast Filesystem options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager -options NFS_ROOT # NFS usable as /, requires NFSCLIENT +options NFS_ROOT # NFS usable as /, requires NFSCL options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 1436a3bc166..dfa3514aa03 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1019,7 +1019,7 @@ options DUMMYNET # One of these is mandatory: options FFS #Fast filesystem -options NFSCLIENT #Network File System client +options NFSCL #Network File System client # The rest are optional: options AUTOFS #Automounter filesystem @@ -1027,7 +1027,6 @@ options CD9660 #ISO 9660 filesystem options FDESCFS #File descriptor filesystem options FUSE #FUSE support module options MSDOSFS #MS DOS File System (FAT, FAT32) -options NFSSERVER #Network File System server options NFSLOCKD #Network Lock Manager options NFSCL #New Network Filesystem Client options NFSD #New Network Filesystem Server @@ -2596,7 +2595,7 @@ device pcfclock # Kernel BOOTP support options BOOTP # Use BOOTP to obtain IP address/hostname - # Requires NFSCLIENT and NFS_ROOT + # Requires NFSCL and NFS_ROOT options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info options BOOTP_NFSV3 # Use NFS v3 to NFS mount root options BOOTP_COMPAT # Workaround for broken bootp daemons. diff --git a/sys/conf/files b/sys/conf/files index 939b63517d3..d419d4a64ae 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3559,24 +3559,12 @@ netsmb/smb_smb.c optional netsmb netsmb/smb_subr.c optional netsmb netsmb/smb_trantcp.c optional netsmb netsmb/smb_usr.c optional netsmb -nfs/bootp_subr.c optional bootp nfsclient | bootp nfscl -nfs/krpc_subr.c optional bootp nfsclient | bootp nfscl -nfs/nfs_common.c optional nfsclient | nfsserver -nfs/nfs_diskless.c optional nfsclient nfs_root | nfscl nfs_root -nfs/nfs_fha.c optional nfsserver | nfsd -nfs/nfs_lock.c optional nfsclient | nfscl | nfslockd | nfsd -nfsclient/nfs_bio.c optional nfsclient -nfsclient/nfs_node.c optional nfsclient -nfsclient/nfs_krpc.c optional nfsclient -nfsclient/nfs_subs.c optional nfsclient -nfsclient/nfs_nfsiod.c optional nfsclient -nfsclient/nfs_vfsops.c optional nfsclient -nfsclient/nfs_vnops.c optional nfsclient -nfsserver/nfs_fha_old.c optional nfsserver -nfsserver/nfs_serv.c optional nfsserver -nfsserver/nfs_srvkrpc.c optional nfsserver -nfsserver/nfs_srvsubs.c optional nfsserver -nfs/nfs_nfssvc.c optional nfsserver | nfscl | nfsd +nfs/bootp_subr.c optional bootp nfscl +nfs/krpc_subr.c optional bootp nfscl +nfs/nfs_diskless.c optional nfscl nfs_root +nfs/nfs_fha.c optional nfsd +nfs/nfs_lock.c optional nfscl | nfslockd | nfsd +nfs/nfs_nfssvc.c optional nfscl | nfsd nlm/nlm_advlock.c optional nfslockd | nfsd nlm/nlm_prot_clnt.c optional nfslockd | nfsd nlm/nlm_prot_impl.c optional nfslockd | nfsd @@ -3887,26 +3875,26 @@ opencrypto/gfmult.c optional crypto opencrypto/rmd160.c optional crypto | ipsec opencrypto/skipjack.c optional crypto opencrypto/xform.c optional crypto -rpc/auth_none.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/auth_unix.c optional krpc | nfslockd | nfsclient | nfscl | nfsd -rpc/authunix_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/clnt_bck.c optional krpc | nfslockd | nfsserver | nfscl | nfsd -rpc/clnt_dg.c optional krpc | nfslockd | nfsclient | nfscl | nfsd -rpc/clnt_rc.c optional krpc | nfslockd | nfsclient | nfscl | nfsd -rpc/clnt_vc.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/getnetconfig.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/replay.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/rpc_callmsg.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/rpc_generic.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/rpc_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/rpcb_clnt.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/rpcb_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/svc.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/svc_auth.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/svc_auth_unix.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -rpc/svc_dg.c optional krpc | nfslockd | nfsserver | nfscl | nfsd -rpc/svc_generic.c optional krpc | nfslockd | nfsserver | nfscl | nfsd -rpc/svc_vc.c optional krpc | nfslockd | nfsserver | nfscl | nfsd +rpc/auth_none.c optional krpc | nfslockd | nfscl | nfsd +rpc/auth_unix.c optional krpc | nfslockd | nfscl | nfsd +rpc/authunix_prot.c optional krpc | nfslockd | nfscl | nfsd +rpc/clnt_bck.c optional krpc | nfslockd | nfscl | nfsd +rpc/clnt_dg.c optional krpc | nfslockd | nfscl | nfsd +rpc/clnt_rc.c optional krpc | nfslockd | nfscl | nfsd +rpc/clnt_vc.c optional krpc | nfslockd | nfscl | nfsd +rpc/getnetconfig.c optional krpc | nfslockd | nfscl | nfsd +rpc/replay.c optional krpc | nfslockd | nfscl | nfsd +rpc/rpc_callmsg.c optional krpc | nfslockd | nfscl | nfsd +rpc/rpc_generic.c optional krpc | nfslockd | nfscl | nfsd +rpc/rpc_prot.c optional krpc | nfslockd | nfscl | nfsd +rpc/rpcb_clnt.c optional krpc | nfslockd | nfscl | nfsd +rpc/rpcb_prot.c optional krpc | nfslockd | nfscl | nfsd +rpc/svc.c optional krpc | nfslockd | nfscl | nfsd +rpc/svc_auth.c optional krpc | nfslockd | nfscl | nfsd +rpc/svc_auth_unix.c optional krpc | nfslockd | nfscl | nfsd +rpc/svc_dg.c optional krpc | nfslockd | nfscl | nfsd +rpc/svc_generic.c optional krpc | nfslockd | nfscl | nfsd +rpc/svc_vc.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcsec_gss/rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_conf.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_misc.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi @@ -4012,9 +4000,9 @@ xen/xenbus/xenbusb_if.m optional xen | xenhvm xen/xenbus/xenbusb.c optional xen | xenhvm xen/xenbus/xenbusb_front.c optional xen | xenhvm xen/xenbus/xenbusb_back.c optional xen | xenhvm -xdr/xdr.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -xdr/xdr_array.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -xdr/xdr_mbuf.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -xdr/xdr_mem.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -xdr/xdr_reference.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd -xdr/xdr_sizeof.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd +xdr/xdr.c optional krpc | nfslockd | nfscl | nfsd +xdr/xdr_array.c optional krpc | nfslockd | nfscl | nfsd +xdr/xdr_mbuf.c optional krpc | nfslockd | nfscl | nfsd +xdr/xdr_mem.c optional krpc | nfslockd | nfscl | nfsd +xdr/xdr_reference.c optional krpc | nfslockd | nfscl | nfsd +xdr/xdr_sizeof.c optional krpc | nfslockd | nfscl | nfsd diff --git a/sys/conf/options b/sys/conf/options index ae0f852bfd6..475d960d99a 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -253,11 +253,6 @@ KGSSAPI_DEBUG opt_kgssapi.h # sys/i386/i386/autoconf.c. If any of these filesystems are # statically compiled into the kernel, code for mounting them as root # filesystems will be enabled - but look below. -NFSCLIENT opt_nfs.h -NFSSERVER opt_nfs.h - -# Use these options to compile the experimental nfs client and/or -# server that supports NFSv4 into a kernel. # NFSCL - client # NFSD - server NFSCL opt_nfs.h diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 363ff8957a4..c1d50f4cfb2 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -260,7 +260,7 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp, client = clnt_reconnect_create(nconf, saddr, nrp->nr_prog, nrp->nr_vers, sndreserve, rcvreserve); - CLNT_CONTROL(client, CLSET_WAITCHAN, "newnfsreq"); + CLNT_CONTROL(client, CLSET_WAITCHAN, "nfsreq"); if (nmp != NULL) { if ((nmp->nm_flag & NFSMNT_INT)) CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one); @@ -1166,10 +1166,10 @@ nfs_msg(struct thread *td, const char *server, const char *msg, int error) p = td ? td->td_proc : NULL; if (error) { - tprintf(p, LOG_INFO, "newnfs server %s: %s, error %d\n", + tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server, msg, error); } else { - tprintf(p, LOG_INFO, "newnfs server %s: %s\n", server, msg); + tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg); } return (0); } diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index 5052261ed86..b1a3451f084 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -122,7 +122,7 @@ ncl_nget(struct mount *mntp, u_int8_t *fhp, int fhsize, struct nfsnode **npp, } np = uma_zalloc(newnfsnode_zone, M_WAITOK | M_ZERO); - error = getnewvnode("newnfs", mntp, &newnfs_vnodeops, &nvp); + error = getnewvnode("nfs", mntp, &newnfs_vnodeops, &nvp); if (error) { uma_zfree(newnfsnode_zone, np); return (error); diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 8529c7639b4..efdc812610d 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -198,7 +198,7 @@ nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp, } np = uma_zalloc(newnfsnode_zone, M_WAITOK | M_ZERO); - error = getnewvnode("newnfs", mntp, &newnfs_vnodeops, &nvp); + error = getnewvnode("nfs", mntp, &newnfs_vnodeops, &nvp); if (error) { uma_zfree(newnfsnode_zone, np); FREE((caddr_t)nfhp, M_NFSFH); diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 33f92c6767d..68122df4cff 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -152,7 +152,7 @@ MODULE_DEPEND(nfs, nfslock, 1, 1, 1); * will be defined for kernels built without NFS_ROOT, although it * isn't used in that case. */ -#if !defined(NFS_ROOT) && !defined(NFSCLIENT) +#if !defined(NFS_ROOT) struct nfs_diskless nfs_diskless = { { { 0 } } }; struct nfsv3_diskless nfsv3_diskless = { { { 0 } } }; int nfs_diskless_valid = 0; @@ -704,7 +704,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, while (newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0)) { printf("newnfs_args: retrying connect\n"); - (void) nfs_catnap(PSOCK, 0, "newnfscon"); + (void) nfs_catnap(PSOCK, 0, "nfscon"); } } } else { @@ -1063,7 +1063,7 @@ nfs_mount(struct mount *mp) * greater than NFS_MAXDGRAMDATA, those thread(s) will be * hung, retrying the RPC(s) forever. Usually these threads * will be seen doing an uninterruptible sleep on wait channel - * "newnfsreq" (truncated to "newnfsre" by procstat). + * "nfsreq". */ if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM) tprintf(td->td_proc, LOG_WARNING, diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 54533f21230..0b1252de4ca 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -248,14 +248,11 @@ SUBDIR= \ netfpga10g \ ${_netgraph} \ ${_nfe} \ - nfs_common \ nfscl \ - nfsclient \ nfscommon \ nfsd \ nfslock \ nfslockd \ - nfsserver \ nfssvc \ nge \ nmdm \ diff --git a/sys/modules/dtrace/Makefile b/sys/modules/dtrace/Makefile index b84c632d482..08b6937bb4d 100644 --- a/sys/modules/dtrace/Makefile +++ b/sys/modules/dtrace/Makefile @@ -4,7 +4,6 @@ SUBDIR= dtmalloc \ dtnfscl \ - dtnfsclient \ dtrace \ dtraceall \ dtrace_test \ diff --git a/sys/modules/dtrace/dtnfsclient/Makefile b/sys/modules/dtrace/dtnfsclient/Makefile deleted file mode 100644 index 1c5208f9bd7..00000000000 --- a/sys/modules/dtrace/dtnfsclient/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -SYSDIR?= ${.CURDIR}/../../.. - -.PATH: ${SYSDIR}/nfsclient - -KMOD= dtnfsclient -SRCS= nfs_kdtrace.c -SRCS+= vnode_if.h - -CFLAGS+= -I${SYSDIR}/cddl/compat/opensolaris \ - -I${SYSDIR}/cddl/contrib/opensolaris/uts/common \ - -I${SYSDIR} - -.include - -CFLAGS+= -include ${SYSDIR}/cddl/compat/opensolaris/sys/debug_compat.h diff --git a/sys/modules/dtrace/dtraceall/dtraceall.c b/sys/modules/dtrace/dtraceall/dtraceall.c index eda740e7980..c144d064678 100644 --- a/sys/modules/dtrace/dtraceall/dtraceall.c +++ b/sys/modules/dtrace/dtraceall/dtraceall.c @@ -69,9 +69,6 @@ MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1); #if defined(NFSCLIENT) MODULE_DEPEND(dtraceall, dtnfscl, 1, 1, 1); #endif -#if defined(NFSCLIENT) -MODULE_DEPEND(dtraceall, dtnfsclient, 1, 1, 1); -#endif #if defined(__amd64__) || defined(__i386__) || defined(__powerpc__) MODULE_DEPEND(dtraceall, fbt, 1, 1, 1); #endif diff --git a/sys/modules/nfs_common/Makefile b/sys/modules/nfs_common/Makefile deleted file mode 100644 index 8f51f185d8d..00000000000 --- a/sys/modules/nfs_common/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../nfs - -KMOD= nfs_common -SRCS= nfs_common.c opt_nfs.h vnode_if.h - -.include diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile deleted file mode 100644 index a015f343b64..00000000000 --- a/sys/modules/nfsclient/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc - -KMOD= nfsclient -SRCS= vnode_if.h \ - nfs_bio.c nfs_node.c nfs_subs.c nfs_nfsiod.c \ - nfs_vfsops.c nfs_vnops.c nfs_krpc.c \ - opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h -SRCS+= opt_inet6.h opt_kgssapi.h - -.if !defined(KERNBUILDDIR) -NFS_ROOT?= 1 # 0/1 - requires NFS_ROOT to be configured in kernel - -.if ${NFS_ROOT} > 0 -opt_nfsroot.h: - echo "#define NFS_ROOT 1" > ${.TARGET} -.endif -.else -OPT_NFS_ROOT!= cat ${KERNBUILDDIR}/opt_nfsroot.h -.if empty(OPT_NFS_ROOT) -NFS_ROOT= 0 -.else -NFS_ROOT= 1 -.endif -.endif - -.if ${NFS_ROOT} > 0 -SRCS+= nfs_diskless.c -.endif - -.include diff --git a/sys/modules/nfsserver/Makefile b/sys/modules/nfsserver/Makefile deleted file mode 100644 index d00fe47bd03..00000000000 --- a/sys/modules/nfsserver/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../nfsserver ${.CURDIR}/../../nfs -KMOD= nfsserver -SRCS= vnode_if.h \ - nfs_fha.c nfs_fha_old.c nfs_serv.c nfs_srvkrpc.c nfs_srvsubs.c \ - opt_mac.h \ - opt_kgssapi.h \ - opt_nfs.h -SRCS+= opt_inet6.h - -.include diff --git a/sys/nfs/bootp_subr.c b/sys/nfs/bootp_subr.c index 5e3145e8dfb..c5bd4cb5fc7 100644 --- a/sys/nfs/bootp_subr.c +++ b/sys/nfs/bootp_subr.c @@ -1735,9 +1735,6 @@ retry: goto out; } rootdevnames[0] = "nfs:"; -#ifdef NFSCLIENT - rootdevnames[1] = "oldnfs:"; -#endif nfs_diskless_valid = 3; } diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c deleted file mode 100644 index ad9e7a14352..00000000000 --- a/sys/nfs/nfs_common.c +++ /dev/null @@ -1,407 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * These functions support the macros and help fiddle mbuf chains for - * the nfs op functions. They do things like create the rpc header and - * copy data between mbuf chains and uio lists. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -enum vtype nv3tov_type[8]= { - VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO -}; -nfstype nfsv3_type[9] = { - NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFSOCK, NFFIFO, NFNON -}; - -static void *nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, - int how); - -SYSCTL_NODE(_vfs, OID_AUTO, nfs_common, CTLFLAG_RD, 0, "NFS common support"); - -static int nfs_realign_test; -SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_test, CTLFLAG_RD, - &nfs_realign_test, 0, "Number of realign tests done"); - -static int nfs_realign_count; -SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_count, CTLFLAG_RD, - &nfs_realign_count, 0, "Number of mbuf realignments done"); - -/* - * copies mbuf chain to the uio scatter/gather list - */ -int -nfsm_mbuftouio(struct mbuf **mrep, struct uio *uiop, int siz, caddr_t *dpos) -{ - char *mbufcp, *uiocp; - int xfer, left, len; - struct mbuf *mp; - long uiosiz, rem; - int error = 0; - - mp = *mrep; - mbufcp = *dpos; - len = mtod(mp, caddr_t)+mp->m_len-mbufcp; - rem = nfsm_rndup(siz)-siz; - while (siz > 0) { - if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL) - return (EFBIG); - left = uiop->uio_iov->iov_len; - uiocp = uiop->uio_iov->iov_base; - if (left > siz) - left = siz; - uiosiz = left; - while (left > 0) { - while (len == 0) { - mp = mp->m_next; - if (mp == NULL) - return (EBADRPC); - mbufcp = mtod(mp, caddr_t); - len = mp->m_len; - } - xfer = (left > len) ? len : left; -#ifdef notdef - /* Not Yet.. */ - if (uiop->uio_iov->iov_op != NULL) - (*(uiop->uio_iov->iov_op)) - (mbufcp, uiocp, xfer); - else -#endif - if (uiop->uio_segflg == UIO_SYSSPACE) - bcopy(mbufcp, uiocp, xfer); - else - copyout(mbufcp, uiocp, xfer); - left -= xfer; - len -= xfer; - mbufcp += xfer; - uiocp += xfer; - uiop->uio_offset += xfer; - uiop->uio_resid -= xfer; - } - if (uiop->uio_iov->iov_len <= siz) { - uiop->uio_iovcnt--; - uiop->uio_iov++; - } else { - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + uiosiz; - uiop->uio_iov->iov_len -= uiosiz; - } - siz -= uiosiz; - } - *dpos = mbufcp; - *mrep = mp; - if (rem > 0) { - if (len < rem) - error = nfs_adv(mrep, dpos, rem, len); - else - *dpos += rem; - } - return (error); -} - -/* - * Help break down an mbuf chain by setting the first siz bytes contiguous - * pointed to by returned val. - * This is used by the macros nfsm_dissect for tough - * cases. (The macros use the vars. dpos and dpos2) - */ -void * -nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how) -{ - struct mbuf *mp, *mp2; - int siz2, xfer; - caddr_t ptr, npos = NULL; - void *ret; - - mp = *mdp; - while (left == 0) { - *mdp = mp = mp->m_next; - if (mp == NULL) - return (NULL); - left = mp->m_len; - *dposp = mtod(mp, caddr_t); - } - if (left >= siz) { - ret = *dposp; - *dposp += siz; - } else if (mp->m_next == NULL) { - return (NULL); - } else if (siz > MHLEN) { - panic("nfs S too big"); - } else { - mp2 = m_get(how, MT_DATA); - if (mp2 == NULL) - return (NULL); - mp2->m_len = siz; - mp2->m_next = mp->m_next; - mp->m_next = mp2; - mp->m_len -= left; - mp = mp2; - ptr = mtod(mp, caddr_t); - ret = ptr; - bcopy(*dposp, ptr, left); /* Copy what was left */ - siz2 = siz-left; - ptr += left; - mp2 = mp->m_next; - npos = mtod(mp2, caddr_t); - /* Loop around copying up the siz2 bytes */ - while (siz2 > 0) { - if (mp2 == NULL) - return (NULL); - xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2; - if (xfer > 0) { - bcopy(mtod(mp2, caddr_t), ptr, xfer); - mp2->m_data += xfer; - mp2->m_len -= xfer; - ptr += xfer; - siz2 -= xfer; - } - if (siz2 > 0) { - mp2 = mp2->m_next; - if (mp2 != NULL) - npos = mtod(mp2, caddr_t); - } - } - *mdp = mp2; - *dposp = mtod(mp2, caddr_t); - if (!nfsm_aligned(*dposp, u_int32_t)) { - bcopy(*dposp, npos, mp2->m_len); - mp2->m_data = npos; - *dposp = npos; - } - } - return (ret); -} - -/* - * Advance the position in the mbuf chain. - */ -int -nfs_adv(struct mbuf **mdp, caddr_t *dposp, int offs, int left) -{ - struct mbuf *m; - int s; - - m = *mdp; - s = left; - while (s < offs) { - offs -= s; - m = m->m_next; - if (m == NULL) - return (EBADRPC); - s = m->m_len; - } - *mdp = m; - *dposp = mtod(m, caddr_t)+offs; - return (0); -} - -void * -nfsm_build_xx(int s, struct mbuf **mb, caddr_t *bpos) -{ - struct mbuf *mb2; - void *ret; - - if (s > M_TRAILINGSPACE(*mb)) { - mb2 = m_get(M_WAITOK, MT_DATA); - if (s > MLEN) - panic("build > MLEN"); - (*mb)->m_next = mb2; - *mb = mb2; - (*mb)->m_len = 0; - *bpos = mtod(*mb, caddr_t); - } - ret = *bpos; - (*mb)->m_len += s; - *bpos += s; - return (ret); -} - -void * -nfsm_dissect_xx(int s, struct mbuf **md, caddr_t *dpos) -{ - - return (nfsm_dissect_xx_sub(s, md, dpos, M_WAITOK)); -} - -void * -nfsm_dissect_xx_nonblock(int s, struct mbuf **md, caddr_t *dpos) -{ - - return (nfsm_dissect_xx_sub(s, md, dpos, M_NOWAIT)); -} - -static void * -nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, int how) -{ - int t1; - char *cp2; - void *ret; - - t1 = mtod(*md, caddr_t) + (*md)->m_len - *dpos; - if (t1 >= s) { - ret = *dpos; - *dpos += s; - return (ret); - } - cp2 = nfsm_disct(md, dpos, s, t1, how); - return (cp2); -} - -int -nfsm_strsiz_xx(int *s, int m, struct mbuf **mb, caddr_t *bpos) -{ - u_int32_t *tl; - - tl = nfsm_dissect_xx(NFSX_UNSIGNED, mb, bpos); - if (tl == NULL) - return (EBADRPC); - *s = fxdr_unsigned(int32_t, *tl); - if (*s > m) - return (EBADRPC); - return (0); -} - -int -nfsm_adv_xx(int s, struct mbuf **md, caddr_t *dpos) -{ - int t1; - - t1 = mtod(*md, caddr_t) + (*md)->m_len - *dpos; - if (t1 >= s) { - *dpos += s; - return (0); - } - t1 = nfs_adv(md, dpos, s, t1); - if (t1) - return (t1); - return (0); -} - -/* - * Check for badly aligned mbuf data and realign by copying the unaligned - * portion of the data into a new mbuf chain and freeing the portions of the - * old chain that were replaced. - * - * We cannot simply realign the data within the existing mbuf chain because - * the underlying buffers may contain other rpc commands and we cannot afford - * to overwrite them. - * - * We would prefer to avoid this situation entirely. The situation does not - * occur with NFS/UDP and is supposed to only occassionally occur with TCP. - * Use vfs.nfs_common.realign_count and realign_test to check this. - */ -int -nfs_realign(struct mbuf **pm, int how) -{ - struct mbuf *m, *n; - int off; - - ++nfs_realign_test; - while ((m = *pm) != NULL) { - if (!nfsm_aligned(m->m_len, u_int32_t) || - !nfsm_aligned(mtod(m, intptr_t), u_int32_t)) { - /* - * NB: we can't depend on m_pkthdr.len to help us - * decide what to do here. May not be worth doing - * the m_length calculation as m_copyback will - * expand the mbuf chain below as needed. - */ - if (m_length(m, NULL) >= MINCLSIZE) { - /* NB: m_copyback handles space > MCLBYTES */ - n = m_getcl(how, MT_DATA, 0); - } else - n = m_get(how, MT_DATA); - if (n == NULL) - return (ENOMEM); - /* - * Align the remainder of the mbuf chain. - */ - n->m_len = 0; - off = 0; - while (m != NULL) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } - m_freem(*pm); - *pm = n; - ++nfs_realign_count; - break; - } - pm = &m->m_next; - } - return (0); -} - -static moduledata_t nfs_common_mod = { - "nfs_common", - NULL, - NULL -}; - -DECLARE_MODULE(nfs_common, nfs_common_mod, SI_SUB_VFS, SI_ORDER_ANY); -MODULE_VERSION(nfs_common, 1); diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c deleted file mode 100644 index 1a5b15639d1..00000000000 --- a/sys/nfsclient/nfs_bio.c +++ /dev/null @@ -1,1794 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -static struct buf *nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, - struct thread *td); -static int nfs_directio_write(struct vnode *vp, struct uio *uiop, - struct ucred *cred, int ioflag); - -extern int nfs_directio_enable; -extern int nfs_directio_allow_mmap; - -/* - * Vnode op for VM getpages. - */ -int -nfs_getpages(struct vop_getpages_args *ap) -{ - int i, error, nextoff, size, toff, count, npages; - struct uio uio; - struct iovec iov; - vm_offset_t kva; - struct buf *bp; - struct vnode *vp; - struct thread *td; - struct ucred *cred; - struct nfsmount *nmp; - vm_object_t object; - vm_page_t *pages; - struct nfsnode *np; - - vp = ap->a_vp; - np = VTONFS(vp); - td = curthread; /* XXX */ - cred = curthread->td_ucred; /* XXX */ - nmp = VFSTONFS(vp->v_mount); - pages = ap->a_m; - count = ap->a_count; - - if ((object = vp->v_object) == NULL) { - nfs_printf("nfs_getpages: called with non-merged cache vnode??\n"); - return (VM_PAGER_ERROR); - } - - if (nfs_directio_enable && !nfs_directio_allow_mmap) { - mtx_lock(&np->n_mtx); - if ((np->n_flag & NNONCACHE) && (vp->v_type == VREG)) { - mtx_unlock(&np->n_mtx); - nfs_printf("nfs_getpages: called on non-cacheable vnode??\n"); - return (VM_PAGER_ERROR); - } else - mtx_unlock(&np->n_mtx); - } - - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 && - (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { - mtx_unlock(&nmp->nm_mtx); - /* We'll never get here for v4, because we always have fsinfo */ - (void)nfs_fsinfo(nmp, vp, cred, td); - } else - mtx_unlock(&nmp->nm_mtx); - - npages = btoc(count); - - /* - * Since the caller has busied the requested page, that page's valid - * field will not be changed by other threads. - */ - vm_page_assert_xbusied(pages[ap->a_reqpage]); - - /* - * If the requested page is partially valid, just return it and - * allow the pager to zero-out the blanks. Partially valid pages - * can only occur at the file EOF. - */ - if (pages[ap->a_reqpage]->valid != 0) { - vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages); - return (VM_PAGER_OK); - } - - /* - * We use only the kva address for the buffer, but this is extremely - * convienient and fast. - */ - bp = getpbuf(&nfs_pbuf_freecnt); - - kva = (vm_offset_t) bp->b_data; - pmap_qenter(kva, pages, npages); - PCPU_INC(cnt.v_vnodein); - PCPU_ADD(cnt.v_vnodepgsin, npages); - - iov.iov_base = (caddr_t) kva; - iov.iov_len = count; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = IDX_TO_OFF(pages[0]->pindex); - uio.uio_resid = count; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_rw = UIO_READ; - uio.uio_td = td; - - error = (nmp->nm_rpcops->nr_readrpc)(vp, &uio, cred); - pmap_qremove(kva, npages); - - relpbuf(bp, &nfs_pbuf_freecnt); - - if (error && (uio.uio_resid == count)) { - nfs_printf("nfs_getpages: error %d\n", error); - vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages); - return (VM_PAGER_ERROR); - } - - /* - * Calculate the number of bytes read and validate only that number - * of bytes. Note that due to pending writes, size may be 0. This - * does not mean that the remaining data is invalid! - */ - - size = count - uio.uio_resid; - VM_OBJECT_WLOCK(object); - for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { - vm_page_t m; - nextoff = toff + PAGE_SIZE; - m = pages[i]; - - if (nextoff <= size) { - /* - * Read operation filled an entire page - */ - m->valid = VM_PAGE_BITS_ALL; - KASSERT(m->dirty == 0, - ("nfs_getpages: page %p is dirty", m)); - } else if (size > toff) { - /* - * Read operation filled a partial page. - */ - m->valid = 0; - vm_page_set_valid_range(m, 0, size - toff); - KASSERT(m->dirty == 0, - ("nfs_getpages: page %p is dirty", m)); - } else { - /* - * Read operation was short. If no error - * occured we may have hit a zero-fill - * section. We leave valid set to 0, and page - * is freed by vm_page_readahead_finish() if - * its index is not equal to requested, or - * page is zeroed and set valid by - * vm_pager_get_pages() for requested page. - */ - ; - } - if (i != ap->a_reqpage) - vm_page_readahead_finish(m); - } - VM_OBJECT_WUNLOCK(object); - return (0); -} - -/* - * Vnode op for VM putpages. - */ -int -nfs_putpages(struct vop_putpages_args *ap) -{ - struct uio uio; - struct iovec iov; - vm_offset_t kva; - struct buf *bp; - int iomode, must_commit, i, error, npages, count; - off_t offset; - int *rtvals; - struct vnode *vp; - struct thread *td; - struct ucred *cred; - struct nfsmount *nmp; - struct nfsnode *np; - vm_page_t *pages; - - vp = ap->a_vp; - np = VTONFS(vp); - td = curthread; /* XXX */ - /* Set the cred to n_writecred for the write rpcs. */ - if (np->n_writecred != NULL) - cred = crhold(np->n_writecred); - else - cred = crhold(curthread->td_ucred); /* XXX */ - nmp = VFSTONFS(vp->v_mount); - pages = ap->a_m; - count = ap->a_count; - rtvals = ap->a_rtvals; - npages = btoc(count); - offset = IDX_TO_OFF(pages[0]->pindex); - - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 && - (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { - mtx_unlock(&nmp->nm_mtx); - (void)nfs_fsinfo(nmp, vp, cred, td); - } else - mtx_unlock(&nmp->nm_mtx); - - mtx_lock(&np->n_mtx); - if (nfs_directio_enable && !nfs_directio_allow_mmap && - (np->n_flag & NNONCACHE) && (vp->v_type == VREG)) { - mtx_unlock(&np->n_mtx); - nfs_printf("nfs_putpages: called on noncache-able vnode??\n"); - mtx_lock(&np->n_mtx); - } - - for (i = 0; i < npages; i++) - rtvals[i] = VM_PAGER_ERROR; - - /* - * When putting pages, do not extend file past EOF. - */ - if (offset + count > np->n_size) { - count = np->n_size - offset; - if (count < 0) - count = 0; - } - mtx_unlock(&np->n_mtx); - - /* - * We use only the kva address for the buffer, but this is extremely - * convienient and fast. - */ - bp = getpbuf(&nfs_pbuf_freecnt); - - kva = (vm_offset_t) bp->b_data; - pmap_qenter(kva, pages, npages); - PCPU_INC(cnt.v_vnodeout); - PCPU_ADD(cnt.v_vnodepgsout, count); - - iov.iov_base = (caddr_t) kva; - iov.iov_len = count; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = offset; - uio.uio_resid = count; - uio.uio_segflg = UIO_SYSSPACE; - uio.uio_rw = UIO_WRITE; - uio.uio_td = td; - - if ((ap->a_sync & VM_PAGER_PUT_SYNC) == 0) - iomode = NFSV3WRITE_UNSTABLE; - else - iomode = NFSV3WRITE_FILESYNC; - - error = (nmp->nm_rpcops->nr_writerpc)(vp, &uio, cred, &iomode, &must_commit); - crfree(cred); - - pmap_qremove(kva, npages); - relpbuf(bp, &nfs_pbuf_freecnt); - - if (!error) { - vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid); - if (must_commit) { - nfs_clearcommit(vp->v_mount); - } - } - return rtvals[0]; -} - -/* - * For nfs, cache consistency can only be maintained approximately. - * Although RFC1094 does not specify the criteria, the following is - * believed to be compatible with the reference port. - * For nfs: - * If the file's modify time on the server has changed since the - * last read rpc or you have written to the file, - * you may have lost data cache consistency with the - * server, so flush all of the file's data out of the cache. - * Then force a getattr rpc to ensure that you have up to date - * attributes. - * NB: This implies that cache data can be read when up to - * NFS_ATTRTIMEO seconds out of date. If you find that you need current - * attributes this could be forced by setting n_attrstamp to 0 before - * the VOP_GETATTR() call. - */ -static inline int -nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred) -{ - int error = 0; - struct vattr vattr; - struct nfsnode *np = VTONFS(vp); - int old_lock; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - - /* - * Grab the exclusive lock before checking whether the cache is - * consistent. - * XXX - We can make this cheaper later (by acquiring cheaper locks). - * But for now, this suffices. - */ - old_lock = nfs_upgrade_vnlock(vp); - if (vp->v_iflag & VI_DOOMED) { - nfs_downgrade_vnlock(vp, old_lock); - return (EBADF); - } - - mtx_lock(&np->n_mtx); - if (np->n_flag & NMODIFIED) { - mtx_unlock(&np->n_mtx); - if (vp->v_type != VREG) { - if (vp->v_type != VDIR) - panic("nfs: bioread, not dir"); - (nmp->nm_rpcops->nr_invaldir)(vp); - error = nfs_vinvalbuf(vp, V_SAVE, td, 1); - if (error) - goto out; - } - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - error = VOP_GETATTR(vp, &vattr, cred); - if (error) - goto out; - mtx_lock(&np->n_mtx); - np->n_mtime = vattr.va_mtime; - mtx_unlock(&np->n_mtx); - } else { - mtx_unlock(&np->n_mtx); - error = VOP_GETATTR(vp, &vattr, cred); - if (error) - return (error); - mtx_lock(&np->n_mtx); - if ((np->n_flag & NSIZECHANGED) - || (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime))) { - mtx_unlock(&np->n_mtx); - if (vp->v_type == VDIR) - (nmp->nm_rpcops->nr_invaldir)(vp); - error = nfs_vinvalbuf(vp, V_SAVE, td, 1); - if (error) - goto out; - mtx_lock(&np->n_mtx); - np->n_mtime = vattr.va_mtime; - np->n_flag &= ~NSIZECHANGED; - } - mtx_unlock(&np->n_mtx); - } -out: - nfs_downgrade_vnlock(vp, old_lock); - return error; -} - -/* - * Vnode op for read using bio - */ -int -nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) -{ - struct nfsnode *np = VTONFS(vp); - int biosize, i; - struct buf *bp, *rabp; - struct thread *td; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - daddr_t lbn, rabn; - off_t end; - int bcount; - int seqcount; - int nra, error = 0, n = 0, on = 0; - - KASSERT(uio->uio_rw == UIO_READ, ("nfs_read mode")); - if (uio->uio_resid == 0) - return (0); - if (uio->uio_offset < 0) /* XXX VDIR cookies can be negative */ - return (EINVAL); - td = uio->uio_td; - - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 && - (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { - mtx_unlock(&nmp->nm_mtx); - (void)nfs_fsinfo(nmp, vp, cred, td); - } else - mtx_unlock(&nmp->nm_mtx); - - end = uio->uio_offset + uio->uio_resid; - if (vp->v_type != VDIR && - (end > nmp->nm_maxfilesize || end < uio->uio_offset)) - return (EFBIG); - - if (nfs_directio_enable && (ioflag & IO_DIRECT) && (vp->v_type == VREG)) - /* No caching/ no readaheads. Just read data into the user buffer */ - return nfs_readrpc(vp, uio, cred); - - biosize = vp->v_bufobj.bo_bsize; - seqcount = (int)((off_t)(ioflag >> IO_SEQSHIFT) * biosize / BKVASIZE); - - error = nfs_bioread_check_cons(vp, td, cred); - if (error) - return error; - - do { - u_quad_t nsize; - - mtx_lock(&np->n_mtx); - nsize = np->n_size; - mtx_unlock(&np->n_mtx); - - switch (vp->v_type) { - case VREG: - nfsstats.biocache_reads++; - lbn = uio->uio_offset / biosize; - on = uio->uio_offset - (lbn * biosize); - - /* - * Start the read ahead(s), as required. - */ - if (nmp->nm_readahead > 0) { - for (nra = 0; nra < nmp->nm_readahead && nra < seqcount && - (off_t)(lbn + 1 + nra) * biosize < nsize; nra++) { - rabn = lbn + 1 + nra; - if (incore(&vp->v_bufobj, rabn) == NULL) { - rabp = nfs_getcacheblk(vp, rabn, biosize, td); - if (!rabp) { - error = nfs_sigintr(nmp, td); - return (error ? error : EINTR); - } - if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { - rabp->b_flags |= B_ASYNC; - rabp->b_iocmd = BIO_READ; - vfs_busy_pages(rabp, 0); - if (nfs_asyncio(nmp, rabp, cred, td)) { - rabp->b_flags |= B_INVAL; - rabp->b_ioflags |= BIO_ERROR; - vfs_unbusy_pages(rabp); - brelse(rabp); - break; - } - } else { - brelse(rabp); - } - } - } - } - - /* Note that bcount is *not* DEV_BSIZE aligned. */ - bcount = biosize; - if ((off_t)lbn * biosize >= nsize) { - bcount = 0; - } else if ((off_t)(lbn + 1) * biosize > nsize) { - bcount = nsize - (off_t)lbn * biosize; - } - bp = nfs_getcacheblk(vp, lbn, bcount, td); - - if (!bp) { - error = nfs_sigintr(nmp, td); - return (error ? error : EINTR); - } - - /* - * If B_CACHE is not set, we must issue the read. If this - * fails, we return an error. - */ - - if ((bp->b_flags & B_CACHE) == 0) { - bp->b_iocmd = BIO_READ; - vfs_busy_pages(bp, 0); - error = nfs_doio(vp, bp, cred, td); - if (error) { - brelse(bp); - return (error); - } - } - - /* - * on is the offset into the current bp. Figure out how many - * bytes we can copy out of the bp. Note that bcount is - * NOT DEV_BSIZE aligned. - * - * Then figure out how many bytes we can copy into the uio. - */ - - n = 0; - if (on < bcount) - n = MIN((unsigned)(bcount - on), uio->uio_resid); - break; - case VLNK: - nfsstats.biocache_readlinks++; - bp = nfs_getcacheblk(vp, (daddr_t)0, NFS_MAXPATHLEN, td); - if (!bp) { - error = nfs_sigintr(nmp, td); - return (error ? error : EINTR); - } - if ((bp->b_flags & B_CACHE) == 0) { - bp->b_iocmd = BIO_READ; - vfs_busy_pages(bp, 0); - error = nfs_doio(vp, bp, cred, td); - if (error) { - bp->b_ioflags |= BIO_ERROR; - brelse(bp); - return (error); - } - } - n = MIN(uio->uio_resid, NFS_MAXPATHLEN - bp->b_resid); - on = 0; - break; - case VDIR: - nfsstats.biocache_readdirs++; - if (np->n_direofoffset - && uio->uio_offset >= np->n_direofoffset) { - return (0); - } - lbn = (uoff_t)uio->uio_offset / NFS_DIRBLKSIZ; - on = uio->uio_offset & (NFS_DIRBLKSIZ - 1); - bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, td); - if (!bp) { - error = nfs_sigintr(nmp, td); - return (error ? error : EINTR); - } - if ((bp->b_flags & B_CACHE) == 0) { - bp->b_iocmd = BIO_READ; - vfs_busy_pages(bp, 0); - error = nfs_doio(vp, bp, cred, td); - if (error) { - brelse(bp); - } - while (error == NFSERR_BAD_COOKIE) { - (nmp->nm_rpcops->nr_invaldir)(vp); - error = nfs_vinvalbuf(vp, 0, td, 1); - /* - * Yuck! The directory has been modified on the - * server. The only way to get the block is by - * reading from the beginning to get all the - * offset cookies. - * - * Leave the last bp intact unless there is an error. - * Loop back up to the while if the error is another - * NFSERR_BAD_COOKIE (double yuch!). - */ - for (i = 0; i <= lbn && !error; i++) { - if (np->n_direofoffset - && (i * NFS_DIRBLKSIZ) >= np->n_direofoffset) - return (0); - bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, td); - if (!bp) { - error = nfs_sigintr(nmp, td); - return (error ? error : EINTR); - } - if ((bp->b_flags & B_CACHE) == 0) { - bp->b_iocmd = BIO_READ; - vfs_busy_pages(bp, 0); - error = nfs_doio(vp, bp, cred, td); - /* - * no error + B_INVAL == directory EOF, - * use the block. - */ - if (error == 0 && (bp->b_flags & B_INVAL)) - break; - } - /* - * An error will throw away the block and the - * for loop will break out. If no error and this - * is not the block we want, we throw away the - * block and go for the next one via the for loop. - */ - if (error || i < lbn) - brelse(bp); - } - } - /* - * The above while is repeated if we hit another cookie - * error. If we hit an error and it wasn't a cookie error, - * we give up. - */ - if (error) - return (error); - } - - /* - * If not eof and read aheads are enabled, start one. - * (You need the current block first, so that you have the - * directory offset cookie of the next block.) - */ - if (nmp->nm_readahead > 0 && - (bp->b_flags & B_INVAL) == 0 && - (np->n_direofoffset == 0 || - (lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) && - incore(&vp->v_bufobj, lbn + 1) == NULL) { - rabp = nfs_getcacheblk(vp, lbn + 1, NFS_DIRBLKSIZ, td); - if (rabp) { - if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) { - rabp->b_flags |= B_ASYNC; - rabp->b_iocmd = BIO_READ; - vfs_busy_pages(rabp, 0); - if (nfs_asyncio(nmp, rabp, cred, td)) { - rabp->b_flags |= B_INVAL; - rabp->b_ioflags |= BIO_ERROR; - vfs_unbusy_pages(rabp); - brelse(rabp); - } - } else { - brelse(rabp); - } - } - } - /* - * Unlike VREG files, whos buffer size ( bp->b_bcount ) is - * chopped for the EOF condition, we cannot tell how large - * NFS directories are going to be until we hit EOF. So - * an NFS directory buffer is *not* chopped to its EOF. Now, - * it just so happens that b_resid will effectively chop it - * to EOF. *BUT* this information is lost if the buffer goes - * away and is reconstituted into a B_CACHE state ( due to - * being VMIO ) later. So we keep track of the directory eof - * in np->n_direofoffset and chop it off as an extra step - * right here. - */ - n = lmin(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on); - if (np->n_direofoffset && n > np->n_direofoffset - uio->uio_offset) - n = np->n_direofoffset - uio->uio_offset; - break; - default: - nfs_printf(" nfs_bioread: type %x unexpected\n", vp->v_type); - bp = NULL; - break; - }; - - if (n > 0) { - error = uiomove(bp->b_data + on, (int)n, uio); - } - if (vp->v_type == VLNK) - n = 0; - if (bp != NULL) - brelse(bp); - } while (error == 0 && uio->uio_resid > 0 && n > 0); - return (error); -} - -/* - * The NFS write path cannot handle iovecs with len > 1. So we need to - * break up iovecs accordingly (restricting them to wsize). - * For the SYNC case, we can do this with 1 copy (user buffer -> mbuf). - * For the ASYNC case, 2 copies are needed. The first a copy from the - * user buffer to a staging buffer and then a second copy from the staging - * buffer to mbufs. This can be optimized by copying from the user buffer - * directly into mbufs and passing the chain down, but that requires a - * fair amount of re-working of the relevant codepaths (and can be done - * later). - */ -static int -nfs_directio_write(vp, uiop, cred, ioflag) - struct vnode *vp; - struct uio *uiop; - struct ucred *cred; - int ioflag; -{ - int error; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - struct thread *td = uiop->uio_td; - int size; - int wsize; - - mtx_lock(&nmp->nm_mtx); - wsize = nmp->nm_wsize; - mtx_unlock(&nmp->nm_mtx); - if (ioflag & IO_SYNC) { - int iomode, must_commit; - struct uio uio; - struct iovec iov; -do_sync: - while (uiop->uio_resid > 0) { - size = MIN(uiop->uio_resid, wsize); - size = MIN(uiop->uio_iov->iov_len, size); - iov.iov_base = uiop->uio_iov->iov_base; - iov.iov_len = size; - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_offset = uiop->uio_offset; - uio.uio_resid = size; - uio.uio_segflg = UIO_USERSPACE; - uio.uio_rw = UIO_WRITE; - uio.uio_td = td; - iomode = NFSV3WRITE_FILESYNC; - error = (nmp->nm_rpcops->nr_writerpc)(vp, &uio, cred, - &iomode, &must_commit); - KASSERT((must_commit == 0), - ("nfs_directio_write: Did not commit write")); - if (error) - return (error); - uiop->uio_offset += size; - uiop->uio_resid -= size; - if (uiop->uio_iov->iov_len <= size) { - uiop->uio_iovcnt--; - uiop->uio_iov++; - } else { - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + size; - uiop->uio_iov->iov_len -= size; - } - } - } else { - struct uio *t_uio; - struct iovec *t_iov; - struct buf *bp; - - /* - * Break up the write into blocksize chunks and hand these - * over to nfsiod's for write back. - * Unfortunately, this incurs a copy of the data. Since - * the user could modify the buffer before the write is - * initiated. - * - * The obvious optimization here is that one of the 2 copies - * in the async write path can be eliminated by copying the - * data here directly into mbufs and passing the mbuf chain - * down. But that will require a fair amount of re-working - * of the code and can be done if there's enough interest - * in NFS directio access. - */ - while (uiop->uio_resid > 0) { - size = MIN(uiop->uio_resid, wsize); - size = MIN(uiop->uio_iov->iov_len, size); - bp = getpbuf(&nfs_pbuf_freecnt); - t_uio = malloc(sizeof(struct uio), M_NFSDIRECTIO, M_WAITOK); - t_iov = malloc(sizeof(struct iovec), M_NFSDIRECTIO, M_WAITOK); - t_iov->iov_base = malloc(size, M_NFSDIRECTIO, M_WAITOK); - t_iov->iov_len = size; - t_uio->uio_iov = t_iov; - t_uio->uio_iovcnt = 1; - t_uio->uio_offset = uiop->uio_offset; - t_uio->uio_resid = size; - t_uio->uio_segflg = UIO_SYSSPACE; - t_uio->uio_rw = UIO_WRITE; - t_uio->uio_td = td; - KASSERT(uiop->uio_segflg == UIO_USERSPACE || - uiop->uio_segflg == UIO_SYSSPACE, - ("nfs_directio_write: Bad uio_segflg")); - if (uiop->uio_segflg == UIO_USERSPACE) { - error = copyin(uiop->uio_iov->iov_base, - t_iov->iov_base, size); - if (error != 0) - goto err_free; - } else - /* - * UIO_SYSSPACE may never happen, but handle - * it just in case it does. - */ - bcopy(uiop->uio_iov->iov_base, t_iov->iov_base, - size); - bp->b_flags |= B_DIRECT; - bp->b_iocmd = BIO_WRITE; - if (cred != NOCRED) { - crhold(cred); - bp->b_wcred = cred; - } else - bp->b_wcred = NOCRED; - bp->b_caller1 = (void *)t_uio; - bp->b_vp = vp; - error = nfs_asyncio(nmp, bp, NOCRED, td); -err_free: - if (error) { - free(t_iov->iov_base, M_NFSDIRECTIO); - free(t_iov, M_NFSDIRECTIO); - free(t_uio, M_NFSDIRECTIO); - bp->b_vp = NULL; - relpbuf(bp, &nfs_pbuf_freecnt); - if (error == EINTR) - return (error); - goto do_sync; - } - uiop->uio_offset += size; - uiop->uio_resid -= size; - if (uiop->uio_iov->iov_len <= size) { - uiop->uio_iovcnt--; - uiop->uio_iov++; - } else { - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + size; - uiop->uio_iov->iov_len -= size; - } - } - } - return (0); -} - -/* - * Vnode op for write using bio - */ -int -nfs_write(struct vop_write_args *ap) -{ - int biosize; - struct uio *uio = ap->a_uio; - struct thread *td = uio->uio_td; - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct ucred *cred = ap->a_cred; - int ioflag = ap->a_ioflag; - struct buf *bp; - struct vattr vattr; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - daddr_t lbn; - off_t end; - int bcount; - int n, on, error = 0; - - KASSERT(uio->uio_rw == UIO_WRITE, ("nfs_write mode")); - KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, - ("nfs_write proc")); - if (vp->v_type != VREG) - return (EIO); - mtx_lock(&np->n_mtx); - if (np->n_flag & NWRITEERR) { - np->n_flag &= ~NWRITEERR; - mtx_unlock(&np->n_mtx); - return (np->n_error); - } else - mtx_unlock(&np->n_mtx); - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 && - (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { - mtx_unlock(&nmp->nm_mtx); - (void)nfs_fsinfo(nmp, vp, cred, td); - } else - mtx_unlock(&nmp->nm_mtx); - - /* - * Synchronously flush pending buffers if we are in synchronous - * mode or if we are appending. - */ - if (ioflag & (IO_APPEND | IO_SYNC)) { - mtx_lock(&np->n_mtx); - if (np->n_flag & NMODIFIED) { - mtx_unlock(&np->n_mtx); -#ifdef notyet /* Needs matching nonblock semantics elsewhere, too. */ - /* - * Require non-blocking, synchronous writes to - * dirty files to inform the program it needs - * to fsync(2) explicitly. - */ - if (ioflag & IO_NDELAY) - return (EAGAIN); -#endif -flush_and_restart: - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - error = nfs_vinvalbuf(vp, V_SAVE, td, 1); - if (error) - return (error); - } else - mtx_unlock(&np->n_mtx); - } - - /* - * If IO_APPEND then load uio_offset. We restart here if we cannot - * get the append lock. - */ - if (ioflag & IO_APPEND) { - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - error = VOP_GETATTR(vp, &vattr, cred); - if (error) - return (error); - mtx_lock(&np->n_mtx); - uio->uio_offset = np->n_size; - mtx_unlock(&np->n_mtx); - } - - if (uio->uio_offset < 0) - return (EINVAL); - end = uio->uio_offset + uio->uio_resid; - if (end > nmp->nm_maxfilesize || end < uio->uio_offset) - return (EFBIG); - if (uio->uio_resid == 0) - return (0); - - if (nfs_directio_enable && (ioflag & IO_DIRECT) && vp->v_type == VREG) - return nfs_directio_write(vp, uio, cred, ioflag); - - /* - * Maybe this should be above the vnode op call, but so long as - * file servers have no limits, i don't think it matters - */ - if (vn_rlimit_fsize(vp, uio, td)) - return (EFBIG); - - biosize = vp->v_bufobj.bo_bsize; - /* - * Find all of this file's B_NEEDCOMMIT buffers. If our writes - * would exceed the local maximum per-file write commit size when - * combined with those, we must decide whether to flush, - * go synchronous, or return error. We don't bother checking - * IO_UNIT -- we just make all writes atomic anyway, as there's - * no point optimizing for something that really won't ever happen. - */ - if (!(ioflag & IO_SYNC)) { - int nflag; - - mtx_lock(&np->n_mtx); - nflag = np->n_flag; - mtx_unlock(&np->n_mtx); - int needrestart = 0; - if (nmp->nm_wcommitsize < uio->uio_resid) { - /* - * If this request could not possibly be completed - * without exceeding the maximum outstanding write - * commit size, see if we can convert it into a - * synchronous write operation. - */ - if (ioflag & IO_NDELAY) - return (EAGAIN); - ioflag |= IO_SYNC; - if (nflag & NMODIFIED) - needrestart = 1; - } else if (nflag & NMODIFIED) { - int wouldcommit = 0; - BO_LOCK(&vp->v_bufobj); - if (vp->v_bufobj.bo_dirty.bv_cnt != 0) { - TAILQ_FOREACH(bp, &vp->v_bufobj.bo_dirty.bv_hd, - b_bobufs) { - if (bp->b_flags & B_NEEDCOMMIT) - wouldcommit += bp->b_bcount; - } - } - BO_UNLOCK(&vp->v_bufobj); - /* - * Since we're not operating synchronously and - * bypassing the buffer cache, we are in a commit - * and holding all of these buffers whether - * transmitted or not. If not limited, this - * will lead to the buffer cache deadlocking, - * as no one else can flush our uncommitted buffers. - */ - wouldcommit += uio->uio_resid; - /* - * If we would initially exceed the maximum - * outstanding write commit size, flush and restart. - */ - if (wouldcommit > nmp->nm_wcommitsize) - needrestart = 1; - } - if (needrestart) - goto flush_and_restart; - } - - do { - nfsstats.biocache_writes++; - lbn = uio->uio_offset / biosize; - on = uio->uio_offset - (lbn * biosize); - n = MIN((unsigned)(biosize - on), uio->uio_resid); -again: - /* - * Handle direct append and file extension cases, calculate - * unaligned buffer size. - */ - mtx_lock(&np->n_mtx); - if (uio->uio_offset == np->n_size && n) { - mtx_unlock(&np->n_mtx); - /* - * Get the buffer (in its pre-append state to maintain - * B_CACHE if it was previously set). Resize the - * nfsnode after we have locked the buffer to prevent - * readers from reading garbage. - */ - bcount = on; - bp = nfs_getcacheblk(vp, lbn, bcount, td); - - if (bp != NULL) { - long save; - - mtx_lock(&np->n_mtx); - np->n_size = uio->uio_offset + n; - np->n_flag |= NMODIFIED; - vnode_pager_setsize(vp, np->n_size); - mtx_unlock(&np->n_mtx); - - save = bp->b_flags & B_CACHE; - bcount += n; - allocbuf(bp, bcount); - bp->b_flags |= save; - } - } else { - /* - * Obtain the locked cache block first, and then - * adjust the file's size as appropriate. - */ - bcount = on + n; - if ((off_t)lbn * biosize + bcount < np->n_size) { - if ((off_t)(lbn + 1) * biosize < np->n_size) - bcount = biosize; - else - bcount = np->n_size - (off_t)lbn * biosize; - } - mtx_unlock(&np->n_mtx); - bp = nfs_getcacheblk(vp, lbn, bcount, td); - mtx_lock(&np->n_mtx); - if (uio->uio_offset + n > np->n_size) { - np->n_size = uio->uio_offset + n; - np->n_flag |= NMODIFIED; - vnode_pager_setsize(vp, np->n_size); - } - mtx_unlock(&np->n_mtx); - } - - if (!bp) { - error = nfs_sigintr(nmp, td); - if (!error) - error = EINTR; - break; - } - - /* - * Issue a READ if B_CACHE is not set. In special-append - * mode, B_CACHE is based on the buffer prior to the write - * op and is typically set, avoiding the read. If a read - * is required in special append mode, the server will - * probably send us a short-read since we extended the file - * on our end, resulting in b_resid == 0 and, thusly, - * B_CACHE getting set. - * - * We can also avoid issuing the read if the write covers - * the entire buffer. We have to make sure the buffer state - * is reasonable in this case since we will not be initiating - * I/O. See the comments in kern/vfs_bio.c's getblk() for - * more information. - * - * B_CACHE may also be set due to the buffer being cached - * normally. - */ - - if (on == 0 && n == bcount) { - bp->b_flags |= B_CACHE; - bp->b_flags &= ~B_INVAL; - bp->b_ioflags &= ~BIO_ERROR; - } - - if ((bp->b_flags & B_CACHE) == 0) { - bp->b_iocmd = BIO_READ; - vfs_busy_pages(bp, 0); - error = nfs_doio(vp, bp, cred, td); - if (error) { - brelse(bp); - break; - } - } - if (bp->b_wcred == NOCRED) - bp->b_wcred = crhold(cred); - mtx_lock(&np->n_mtx); - np->n_flag |= NMODIFIED; - mtx_unlock(&np->n_mtx); - - /* - * If dirtyend exceeds file size, chop it down. This should - * not normally occur but there is an append race where it - * might occur XXX, so we log it. - * - * If the chopping creates a reverse-indexed or degenerate - * situation with dirtyoff/end, we 0 both of them. - */ - - if (bp->b_dirtyend > bcount) { - nfs_printf("NFS append race @%lx:%d\n", - (long)bp->b_blkno * DEV_BSIZE, - bp->b_dirtyend - bcount); - bp->b_dirtyend = bcount; - } - - if (bp->b_dirtyoff >= bp->b_dirtyend) - bp->b_dirtyoff = bp->b_dirtyend = 0; - - /* - * If the new write will leave a contiguous dirty - * area, just update the b_dirtyoff and b_dirtyend, - * otherwise force a write rpc of the old dirty area. - * - * While it is possible to merge discontiguous writes due to - * our having a B_CACHE buffer ( and thus valid read data - * for the hole), we don't because it could lead to - * significant cache coherency problems with multiple clients, - * especially if locking is implemented later on. - * - * as an optimization we could theoretically maintain - * a linked list of discontinuous areas, but we would still - * have to commit them separately so there isn't much - * advantage to it except perhaps a bit of asynchronization. - */ - - if (bp->b_dirtyend > 0 && - (on > bp->b_dirtyend || (on + n) < bp->b_dirtyoff)) { - if (bwrite(bp) == EINTR) { - error = EINTR; - break; - } - goto again; - } - - error = uiomove((char *)bp->b_data + on, n, uio); - - /* - * Since this block is being modified, it must be written - * again and not just committed. Since write clustering does - * not work for the stage 1 data write, only the stage 2 - * commit rpc, we have to clear B_CLUSTEROK as well. - */ - bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); - - if (error) { - bp->b_ioflags |= BIO_ERROR; - brelse(bp); - break; - } - - /* - * Only update dirtyoff/dirtyend if not a degenerate - * condition. - */ - if (n) { - if (bp->b_dirtyend > 0) { - bp->b_dirtyoff = min(on, bp->b_dirtyoff); - bp->b_dirtyend = max((on + n), bp->b_dirtyend); - } else { - bp->b_dirtyoff = on; - bp->b_dirtyend = on + n; - } - vfs_bio_set_valid(bp, on, n); - } - - /* - * If IO_SYNC do bwrite(). - * - * IO_INVAL appears to be unused. The idea appears to be - * to turn off caching in this case. Very odd. XXX - */ - if ((ioflag & IO_SYNC)) { - if (ioflag & IO_INVAL) - bp->b_flags |= B_NOCACHE; - error = bwrite(bp); - if (error) - break; - } else if ((n + on) == biosize) { - bp->b_flags |= B_ASYNC; - (void) (nmp->nm_rpcops->nr_writebp)(bp, 0, NULL); - } else { - bdwrite(bp); - } - } while (uio->uio_resid > 0 && n > 0); - - return (error); -} - -/* - * Get an nfs cache block. - * - * Allocate a new one if the block isn't currently in the cache - * and return the block marked busy. If the calling process is - * interrupted by a signal for an interruptible mount point, return - * NULL. - * - * The caller must carefully deal with the possible B_INVAL state of - * the buffer. nfs_doio() clears B_INVAL (and nfs_asyncio() clears it - * indirectly), so synchronous reads can be issued without worrying about - * the B_INVAL state. We have to be a little more careful when dealing - * with writes (see comments in nfs_write()) when extending a file past - * its EOF. - */ -static struct buf * -nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td) -{ - struct buf *bp; - struct mount *mp; - struct nfsmount *nmp; - - mp = vp->v_mount; - nmp = VFSTONFS(mp); - - if (nmp->nm_flag & NFSMNT_INT) { - sigset_t oldset; - - nfs_set_sigmask(td, &oldset); - bp = getblk(vp, bn, size, PCATCH, 0, 0); - nfs_restore_sigmask(td, &oldset); - while (bp == NULL) { - if (nfs_sigintr(nmp, td)) - return (NULL); - bp = getblk(vp, bn, size, 0, 2 * hz, 0); - } - } else { - bp = getblk(vp, bn, size, 0, 0, 0); - } - - if (vp->v_type == VREG) - bp->b_blkno = bn * (vp->v_bufobj.bo_bsize / DEV_BSIZE); - return (bp); -} - -/* - * Flush and invalidate all dirty buffers. If another process is already - * doing the flush, just wait for completion. - */ -int -nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg) -{ - struct nfsnode *np = VTONFS(vp); - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - int error = 0, slpflag, slptimeo; - int old_lock = 0; - - ASSERT_VOP_LOCKED(vp, "nfs_vinvalbuf"); - - if ((nmp->nm_flag & NFSMNT_INT) == 0) - intrflg = 0; - if (intrflg) { - slpflag = PCATCH; - slptimeo = 2 * hz; - } else { - slpflag = 0; - slptimeo = 0; - } - - old_lock = nfs_upgrade_vnlock(vp); - if (vp->v_iflag & VI_DOOMED) { - /* - * Since vgonel() uses the generic vinvalbuf() to flush - * dirty buffers and it does not call this function, it - * is safe to just return OK when VI_DOOMED is set. - */ - nfs_downgrade_vnlock(vp, old_lock); - return (0); - } - - /* - * Now, flush as required. - */ - if ((flags & V_SAVE) && (vp->v_bufobj.bo_object != NULL)) { - VM_OBJECT_WLOCK(vp->v_bufobj.bo_object); - vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_WUNLOCK(vp->v_bufobj.bo_object); - /* - * If the page clean was interrupted, fail the invalidation. - * Not doing so, we run the risk of losing dirty pages in the - * vinvalbuf() call below. - */ - if (intrflg && (error = nfs_sigintr(nmp, td))) - goto out; - } - - error = vinvalbuf(vp, flags, slpflag, 0); - while (error) { - if (intrflg && (error = nfs_sigintr(nmp, td))) - goto out; - error = vinvalbuf(vp, flags, 0, slptimeo); - } - mtx_lock(&np->n_mtx); - if (np->n_directio_asyncwr == 0) - np->n_flag &= ~NMODIFIED; - mtx_unlock(&np->n_mtx); -out: - nfs_downgrade_vnlock(vp, old_lock); - return error; -} - -/* - * Initiate asynchronous I/O. Return an error if no nfsiods are available. - * This is mainly to avoid queueing async I/O requests when the nfsiods - * are all hung on a dead server. - * - * Note: nfs_asyncio() does not clear (BIO_ERROR|B_INVAL) but when the bp - * is eventually dequeued by the async daemon, nfs_doio() *will*. - */ -int -nfs_asyncio(struct nfsmount *nmp, struct buf *bp, struct ucred *cred, struct thread *td) -{ - int iod; - int gotiod; - int slpflag = 0; - int slptimeo = 0; - int error, error2; - - /* - * Commits are usually short and sweet so lets save some cpu and - * leave the async daemons for more important rpc's (such as reads - * and writes). - * - * Readdirplus RPCs do vget()s to acquire the vnodes for entries - * in the directory in order to update attributes. This can deadlock - * with another thread that is waiting for async I/O to be done by - * an nfsiod thread while holding a lock on one of these vnodes. - * To avoid this deadlock, don't allow the async nfsiod threads to - * perform Readdirplus RPCs. - */ - mtx_lock(&nfs_iod_mtx); - if ((bp->b_iocmd == BIO_WRITE && (bp->b_flags & B_NEEDCOMMIT) && - (nmp->nm_bufqiods > nfs_numasync / 2)) || - (bp->b_vp->v_type == VDIR && (nmp->nm_flag & NFSMNT_RDIRPLUS))) { - mtx_unlock(&nfs_iod_mtx); - return(EIO); - } -again: - if (nmp->nm_flag & NFSMNT_INT) - slpflag = PCATCH; - gotiod = FALSE; - - /* - * Find a free iod to process this request. - */ - for (iod = 0; iod < nfs_numasync; iod++) - if (nfs_iodwant[iod] == NFSIOD_AVAILABLE) { - gotiod = TRUE; - break; - } - - /* - * Try to create one if none are free. - */ - if (!gotiod) - nfs_nfsiodnew(); - else { - /* - * Found one, so wake it up and tell it which - * mount to process. - */ - NFS_DPF(ASYNCIO, ("nfs_asyncio: waking iod %d for mount %p\n", - iod, nmp)); - nfs_iodwant[iod] = NFSIOD_NOT_AVAILABLE; - nfs_iodmount[iod] = nmp; - nmp->nm_bufqiods++; - wakeup(&nfs_iodwant[iod]); - } - - /* - * If none are free, we may already have an iod working on this mount - * point. If so, it will process our request. - */ - if (!gotiod) { - if (nmp->nm_bufqiods > 0) { - NFS_DPF(ASYNCIO, - ("nfs_asyncio: %d iods are already processing mount %p\n", - nmp->nm_bufqiods, nmp)); - gotiod = TRUE; - } - } - - /* - * If we have an iod which can process the request, then queue - * the buffer. - */ - if (gotiod) { - /* - * Ensure that the queue never grows too large. We still want - * to asynchronize so we block rather then return EIO. - */ - while (nmp->nm_bufqlen >= 2 * nfs_numasync) { - NFS_DPF(ASYNCIO, - ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp)); - nmp->nm_bufqwant = TRUE; - error = nfs_msleep(td, &nmp->nm_bufq, &nfs_iod_mtx, - slpflag | PRIBIO, - "nfsaio", slptimeo); - if (error) { - error2 = nfs_sigintr(nmp, td); - if (error2) { - mtx_unlock(&nfs_iod_mtx); - return (error2); - } - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - } - /* - * We might have lost our iod while sleeping, - * so check and loop if nescessary. - */ - goto again; - } - - /* We might have lost our nfsiod */ - if (nmp->nm_bufqiods == 0) { - NFS_DPF(ASYNCIO, -("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp)); - goto again; - } - - if (bp->b_iocmd == BIO_READ) { - if (bp->b_rcred == NOCRED && cred != NOCRED) - bp->b_rcred = crhold(cred); - } else { - if (bp->b_wcred == NOCRED && cred != NOCRED) - bp->b_wcred = crhold(cred); - } - - if (bp->b_flags & B_REMFREE) - bremfreef(bp); - BUF_KERNPROC(bp); - TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist); - nmp->nm_bufqlen++; - if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) { - mtx_lock(&(VTONFS(bp->b_vp))->n_mtx); - VTONFS(bp->b_vp)->n_flag |= NMODIFIED; - VTONFS(bp->b_vp)->n_directio_asyncwr++; - mtx_unlock(&(VTONFS(bp->b_vp))->n_mtx); - } - mtx_unlock(&nfs_iod_mtx); - return (0); - } - - mtx_unlock(&nfs_iod_mtx); - - /* - * All the iods are busy on other mounts, so return EIO to - * force the caller to process the i/o synchronously. - */ - NFS_DPF(ASYNCIO, ("nfs_asyncio: no iods available, i/o is synchronous\n")); - return (EIO); -} - -void -nfs_doio_directwrite(struct buf *bp) -{ - int iomode, must_commit; - struct uio *uiop = (struct uio *)bp->b_caller1; - char *iov_base = uiop->uio_iov->iov_base; - struct nfsmount *nmp = VFSTONFS(bp->b_vp->v_mount); - - iomode = NFSV3WRITE_FILESYNC; - uiop->uio_td = NULL; /* NULL since we're in nfsiod */ - (nmp->nm_rpcops->nr_writerpc)(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit); - KASSERT((must_commit == 0), ("nfs_doio_directwrite: Did not commit write")); - free(iov_base, M_NFSDIRECTIO); - free(uiop->uio_iov, M_NFSDIRECTIO); - free(uiop, M_NFSDIRECTIO); - if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) { - struct nfsnode *np = VTONFS(bp->b_vp); - mtx_lock(&np->n_mtx); - np->n_directio_asyncwr--; - if (np->n_directio_asyncwr == 0) { - VTONFS(bp->b_vp)->n_flag &= ~NMODIFIED; - if ((np->n_flag & NFSYNCWAIT)) { - np->n_flag &= ~NFSYNCWAIT; - wakeup((caddr_t)&np->n_directio_asyncwr); - } - } - mtx_unlock(&np->n_mtx); - } - bp->b_vp = NULL; - relpbuf(bp, &nfs_pbuf_freecnt); -} - -/* - * Do an I/O operation to/from a cache block. This may be called - * synchronously or from an nfsiod. - */ -int -nfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td) -{ - struct uio *uiop; - struct nfsnode *np; - struct nfsmount *nmp; - int error = 0, iomode, must_commit = 0; - struct uio uio; - struct iovec io; - struct proc *p = td ? td->td_proc : NULL; - uint8_t iocmd; - - np = VTONFS(vp); - nmp = VFSTONFS(vp->v_mount); - uiop = &uio; - uiop->uio_iov = &io; - uiop->uio_iovcnt = 1; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_td = td; - - /* - * clear BIO_ERROR and B_INVAL state prior to initiating the I/O. We - * do this here so we do not have to do it in all the code that - * calls us. - */ - bp->b_flags &= ~B_INVAL; - bp->b_ioflags &= ~BIO_ERROR; - - KASSERT(!(bp->b_flags & B_DONE), ("nfs_doio: bp %p already marked done", bp)); - iocmd = bp->b_iocmd; - if (iocmd == BIO_READ) { - io.iov_len = uiop->uio_resid = bp->b_bcount; - io.iov_base = bp->b_data; - uiop->uio_rw = UIO_READ; - - switch (vp->v_type) { - case VREG: - uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; - nfsstats.read_bios++; - error = (nmp->nm_rpcops->nr_readrpc)(vp, uiop, cr); - - if (!error) { - if (uiop->uio_resid) { - /* - * If we had a short read with no error, we must have - * hit a file hole. We should zero-fill the remainder. - * This can also occur if the server hits the file EOF. - * - * Holes used to be able to occur due to pending - * writes, but that is not possible any longer. - */ - int nread = bp->b_bcount - uiop->uio_resid; - int left = uiop->uio_resid; - - if (left > 0) - bzero((char *)bp->b_data + nread, left); - uiop->uio_resid = 0; - } - } - /* ASSERT_VOP_LOCKED(vp, "nfs_doio"); */ - if (p && (vp->v_vflag & VV_TEXT)) { - mtx_lock(&np->n_mtx); - if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &np->n_vattr.va_mtime)) { - mtx_unlock(&np->n_mtx); - PROC_LOCK(p); - killproc(p, "text file modification"); - PROC_UNLOCK(p); - } else - mtx_unlock(&np->n_mtx); - } - break; - case VLNK: - uiop->uio_offset = (off_t)0; - nfsstats.readlink_bios++; - error = (nmp->nm_rpcops->nr_readlinkrpc)(vp, uiop, cr); - break; - case VDIR: - nfsstats.readdir_bios++; - uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ; - if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) { - error = nfs_readdirplusrpc(vp, uiop, cr); - if (error == NFSERR_NOTSUPP) - nmp->nm_flag &= ~NFSMNT_RDIRPLUS; - } - if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0) - error = nfs_readdirrpc(vp, uiop, cr); - /* - * end-of-directory sets B_INVAL but does not generate an - * error. - */ - if (error == 0 && uiop->uio_resid == bp->b_bcount) - bp->b_flags |= B_INVAL; - break; - default: - nfs_printf("nfs_doio: type %x unexpected\n", vp->v_type); - break; - }; - if (error) { - bp->b_ioflags |= BIO_ERROR; - bp->b_error = error; - } - } else { - /* - * If we only need to commit, try to commit - */ - if (bp->b_flags & B_NEEDCOMMIT) { - int retv; - off_t off; - - off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff; - retv = (nmp->nm_rpcops->nr_commit)( - vp, off, bp->b_dirtyend-bp->b_dirtyoff, - bp->b_wcred, td); - if (retv == 0) { - bp->b_dirtyoff = bp->b_dirtyend = 0; - bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); - bp->b_resid = 0; - bufdone(bp); - return (0); - } - if (retv == NFSERR_STALEWRITEVERF) { - nfs_clearcommit(vp->v_mount); - } - } - - /* - * Setup for actual write - */ - mtx_lock(&np->n_mtx); - if ((off_t)bp->b_blkno * DEV_BSIZE + bp->b_dirtyend > np->n_size) - bp->b_dirtyend = np->n_size - (off_t)bp->b_blkno * DEV_BSIZE; - mtx_unlock(&np->n_mtx); - - if (bp->b_dirtyend > bp->b_dirtyoff) { - io.iov_len = uiop->uio_resid = bp->b_dirtyend - - bp->b_dirtyoff; - uiop->uio_offset = (off_t)bp->b_blkno * DEV_BSIZE - + bp->b_dirtyoff; - io.iov_base = (char *)bp->b_data + bp->b_dirtyoff; - uiop->uio_rw = UIO_WRITE; - nfsstats.write_bios++; - - if ((bp->b_flags & (B_ASYNC | B_NEEDCOMMIT | B_NOCACHE | B_CLUSTER)) == B_ASYNC) - iomode = NFSV3WRITE_UNSTABLE; - else - iomode = NFSV3WRITE_FILESYNC; - - error = (nmp->nm_rpcops->nr_writerpc)(vp, uiop, cr, &iomode, &must_commit); - - /* - * When setting B_NEEDCOMMIT also set B_CLUSTEROK to try - * to cluster the buffers needing commit. This will allow - * the system to submit a single commit rpc for the whole - * cluster. We can do this even if the buffer is not 100% - * dirty (relative to the NFS blocksize), so we optimize the - * append-to-file-case. - * - * (when clearing B_NEEDCOMMIT, B_CLUSTEROK must also be - * cleared because write clustering only works for commit - * rpc's, not for the data portion of the write). - */ - - if (!error && iomode == NFSV3WRITE_UNSTABLE) { - bp->b_flags |= B_NEEDCOMMIT; - if (bp->b_dirtyoff == 0 - && bp->b_dirtyend == bp->b_bcount) - bp->b_flags |= B_CLUSTEROK; - } else { - bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); - } - - /* - * For an interrupted write, the buffer is still valid - * and the write hasn't been pushed to the server yet, - * so we can't set BIO_ERROR and report the interruption - * by setting B_EINTR. For the B_ASYNC case, B_EINTR - * is not relevant, so the rpc attempt is essentially - * a noop. For the case of a V3 write rpc not being - * committed to stable storage, the block is still - * dirty and requires either a commit rpc or another - * write rpc with iomode == NFSV3WRITE_FILESYNC before - * the block is reused. This is indicated by setting - * the B_DELWRI and B_NEEDCOMMIT flags. - * - * If the buffer is marked B_PAGING, it does not reside on - * the vp's paging queues so we cannot call bdirty(). The - * bp in this case is not an NFS cache block so we should - * be safe. XXX - * - * The logic below breaks up errors into recoverable and - * unrecoverable. For the former, we clear B_INVAL|B_NOCACHE - * and keep the buffer around for potential write retries. - * For the latter (eg ESTALE), we toss the buffer away (B_INVAL) - * and save the error in the nfsnode. This is less than ideal - * but necessary. Keeping such buffers around could potentially - * cause buffer exhaustion eventually (they can never be written - * out, so will get constantly be re-dirtied). It also causes - * all sorts of vfs panics. For non-recoverable write errors, - * also invalidate the attrcache, so we'll be forced to go over - * the wire for this object, returning an error to user on next - * call (most of the time). - */ - if (error == EINTR || error == EIO || error == ETIMEDOUT - || (!error && (bp->b_flags & B_NEEDCOMMIT))) { - int s; - - s = splbio(); - bp->b_flags &= ~(B_INVAL|B_NOCACHE); - if ((bp->b_flags & B_PAGING) == 0) { - bdirty(bp); - bp->b_flags &= ~B_DONE; - } - if (error && (bp->b_flags & B_ASYNC) == 0) - bp->b_flags |= B_EINTR; - splx(s); - } else { - if (error) { - bp->b_ioflags |= BIO_ERROR; - bp->b_flags |= B_INVAL; - bp->b_error = np->n_error = error; - mtx_lock(&np->n_mtx); - np->n_flag |= NWRITEERR; - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - mtx_unlock(&np->n_mtx); - } - bp->b_dirtyoff = bp->b_dirtyend = 0; - } - } else { - bp->b_resid = 0; - bufdone(bp); - return (0); - } - } - bp->b_resid = uiop->uio_resid; - if (must_commit) - nfs_clearcommit(vp->v_mount); - bufdone(bp); - return (error); -} - -/* - * Used to aid in handling ftruncate() operations on the NFS client side. - * Truncation creates a number of special problems for NFS. We have to - * throw away VM pages and buffer cache buffers that are beyond EOF, and - * we have to properly handle VM pages or (potentially dirty) buffers - * that straddle the truncation point. - */ - -int -nfs_meta_setsize(struct vnode *vp, struct ucred *cred, struct thread *td, u_quad_t nsize) -{ - struct nfsnode *np = VTONFS(vp); - u_quad_t tsize; - int biosize = vp->v_bufobj.bo_bsize; - int error = 0; - - mtx_lock(&np->n_mtx); - tsize = np->n_size; - np->n_size = nsize; - mtx_unlock(&np->n_mtx); - - if (nsize < tsize) { - struct buf *bp; - daddr_t lbn; - int bufsize; - - /* - * vtruncbuf() doesn't get the buffer overlapping the - * truncation point. We may have a B_DELWRI and/or B_CACHE - * buffer that now needs to be truncated. - */ - error = vtruncbuf(vp, cred, nsize, biosize); - lbn = nsize / biosize; - bufsize = nsize - (lbn * biosize); - bp = nfs_getcacheblk(vp, lbn, bufsize, td); - if (!bp) - return EINTR; - if (bp->b_dirtyoff > bp->b_bcount) - bp->b_dirtyoff = bp->b_bcount; - if (bp->b_dirtyend > bp->b_bcount) - bp->b_dirtyend = bp->b_bcount; - bp->b_flags |= B_RELBUF; /* don't leave garbage around */ - brelse(bp); - } else { - vnode_pager_setsize(vp, nsize); - } - return(error); -} - diff --git a/sys/nfsclient/nfs_kdtrace.c b/sys/nfsclient/nfs_kdtrace.c deleted file mode 100644 index 429dbc3baeb..00000000000 --- a/sys/nfsclient/nfs_kdtrace.c +++ /dev/null @@ -1,542 +0,0 @@ -/*- - * Copyright (c) 2009 Robert N. M. Watson - * All rights reserved. - * - * This software was developed at the University of Cambridge Computer - * Laboratory with support from a grant from Google, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -/* - * dtnfsclient is a DTrace provider that tracks the intent to perform RPCs - * in the NFS client, as well as acess to and maintenance of the access and - * attribute caches. This is not quite the same as RPCs, because NFS may - * issue multiple RPC transactions in the event that authentication fails, - * there's a jukebox error, or none at all if the access or attribute cache - * hits. However, it cleanly represents the logical layer between RPC - * transmission and vnode/vfs operations, providing access to state linking - * the two. - */ - -static int dtnfsclient_unload(void); -static void dtnfsclient_getargdesc(void *, dtrace_id_t, void *, - dtrace_argdesc_t *); -static void dtnfsclient_provide(void *, dtrace_probedesc_t *); -static void dtnfsclient_destroy(void *, dtrace_id_t, void *); -static void dtnfsclient_enable(void *, dtrace_id_t, void *); -static void dtnfsclient_disable(void *, dtrace_id_t, void *); -static void dtnfsclient_load(void *); - -static dtrace_pattr_t dtnfsclient_attr = { -{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, -{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, -{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, -}; - -/* - * Description of NFSv3 and (optional) NFSv2 probes for a procedure. - */ -struct dtnfsclient_rpc { - char *nr_v3_name; - char *nr_v2_name; /* Or NULL if none. */ - - /* - * IDs for the start and done cases, for both NFSv2 and NFSv3. - */ - uint32_t nr_v2_id_start, nr_v2_id_done; - uint32_t nr_v3_id_start, nr_v3_id_done; -}; - -/* - * This table is indexed by NFSv3 procedure number, but also used for NFSv2 - * procedure names. - */ -static struct dtnfsclient_rpc dtnfsclient_rpcs[NFS_NPROCS] = { - { "null", "null" }, - { "getattr", "getattr" }, - { "setattr", "setattr" }, - { "lookup", "lookup" }, - { "access" }, - { "readlink", "readlink" }, - { "read", "read" }, - { "write", "write" }, - { "create", "create" }, - { "mkdir", "mkdir" }, - { "symlink", "symlink" }, - { "mknod" }, - { "remove", "remove" }, - { "rmdir", "rmdir" }, - { "rename", "rename" }, - { "link", "link" }, - { "readdir", "readdir" }, - { "readdirplus" }, - { "fsstat", "statfs" }, - { "fsinfo" }, - { "pathconf" }, - { "commit" }, - { "noop" }, -}; - -/* - * Module name strings. - */ -static char *dtnfsclient_accesscache_str = "accesscache"; -static char *dtnfsclient_attrcache_str = "attrcache"; -static char *dtnfsclient_nfs2_str = "nfs2"; -static char *dtnfsclient_nfs3_str = "nfs3"; - -/* - * Function name strings. - */ -static char *dtnfsclient_flush_str = "flush"; -static char *dtnfsclient_load_str = "load"; -static char *dtnfsclient_get_str = "get"; - -/* - * Name strings. - */ -static char *dtnfsclient_done_str = "done"; -static char *dtnfsclient_hit_str = "hit"; -static char *dtnfsclient_miss_str = "miss"; -static char *dtnfsclient_start_str = "start"; - -static dtrace_pops_t dtnfsclient_pops = { - dtnfsclient_provide, - NULL, - dtnfsclient_enable, - dtnfsclient_disable, - NULL, - NULL, - dtnfsclient_getargdesc, - NULL, - NULL, - dtnfsclient_destroy -}; - -static dtrace_provider_id_t dtnfsclient_id; - -/* - * Most probes are generated from the above RPC table, but for access and - * attribute caches, we have specific IDs we recognize and handle specially - * in various spots. - */ -extern uint32_t nfsclient_accesscache_flush_done_id; -extern uint32_t nfsclient_accesscache_get_hit_id; -extern uint32_t nfsclient_accesscache_get_miss_id; -extern uint32_t nfsclient_accesscache_load_done_id; - -extern uint32_t nfsclient_attrcache_flush_done_id; -extern uint32_t nfsclient_attrcache_get_hit_id; -extern uint32_t nfsclient_attrcache_get_miss_id; -extern uint32_t nfsclient_attrcache_load_done_id; - -/* - * When tracing on a procedure is enabled, the DTrace ID for an RPC event is - * stored in one of these two NFS client-allocated arrays; 0 indicates that - * the event is not being traced so probes should not be called. - * - * For simplicity, we allocate both v2 and v3 arrays as NFS_NPROCS, and the - * v2 array is simply sparse. - */ -extern uint32_t nfsclient_nfs2_start_probes[NFS_NPROCS]; -extern uint32_t nfsclient_nfs2_done_probes[NFS_NPROCS]; - -extern uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS]; -extern uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS]; - -/* - * Look up a DTrace probe ID to see if it's associated with a "done" event -- - * if so, we will return a fourth argument type of "int". - */ -static int -dtnfs23_isdoneprobe(dtrace_id_t id) -{ - int i; - - for (i = 0; i < NFS_NPROCS; i++) { - if (dtnfsclient_rpcs[i].nr_v3_id_done == id || - dtnfsclient_rpcs[i].nr_v2_id_done == id) - return (1); - } - return (0); -} - -static void -dtnfsclient_getargdesc(void *arg, dtrace_id_t id, void *parg, - dtrace_argdesc_t *desc) -{ - const char *p = NULL; - - if (id == nfsclient_accesscache_flush_done_id || - id == nfsclient_attrcache_flush_done_id || - id == nfsclient_attrcache_get_miss_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_accesscache_get_hit_id || - id == nfsclient_accesscache_get_miss_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "uid_t"; - break; - case 2: - p = "uint32_t"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_accesscache_load_done_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "uid_t"; - break; - case 2: - p = "uint32_t"; - break; - case 3: - p = "int"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_attrcache_get_hit_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "struct vattr *"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_attrcache_load_done_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "struct vattr *"; - break; - case 2: - p = "int"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "struct mbuf *"; - break; - case 2: - p = "struct ucred *"; - break; - case 3: - p = "int"; - break; - case 4: - if (dtnfs23_isdoneprobe(id)) { - p = "int"; - break; - } - /* FALLSTHROUGH */ - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } - if (p != NULL) - strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native)); -} - -static void -dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc) -{ - int i; - - if (desc != NULL) - return; - - /* - * Register access cache probes. - */ - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_flush_str, dtnfsclient_done_str) == 0) { - nfsclient_accesscache_flush_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_hit_str) == 0) { - nfsclient_accesscache_get_hit_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_miss_str) == 0) { - nfsclient_accesscache_get_miss_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_load_str, dtnfsclient_done_str) == 0) { - nfsclient_accesscache_load_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL); - } - - /* - * Register attribute cache probes. - */ - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_flush_str, dtnfsclient_done_str) == 0) { - nfsclient_attrcache_flush_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_hit_str) == 0) { - nfsclient_attrcache_get_hit_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_miss_str) == 0) { - nfsclient_attrcache_get_miss_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_load_str, dtnfsclient_done_str) == 0) { - nfsclient_attrcache_load_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL); - } - - /* - * Register NFSv2 RPC procedures; note sparseness check for each slot - * in the NFSv3 procnum-indexed array. - */ - for (i = 0; i < NFS_NPROCS; i++) { - if (dtnfsclient_rpcs[i].nr_v2_name != NULL && - dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) == - 0) { - dtnfsclient_rpcs[i].nr_v2_id_start = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, - dtnfsclient_start_str, 0, - &nfsclient_nfs2_start_probes[i]); - } - if (dtnfsclient_rpcs[i].nr_v2_name != NULL && - dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) == - 0) { - dtnfsclient_rpcs[i].nr_v2_id_done = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, - dtnfsclient_done_str, 0, - &nfsclient_nfs2_done_probes[i]); - } - } - - /* - * Register NFSv3 RPC procedures. - */ - for (i = 0; i < NFS_NPROCS; i++) { - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) == - 0) { - dtnfsclient_rpcs[i].nr_v3_id_start = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, - dtnfsclient_start_str, 0, - &nfsclient_nfs3_start_probes[i]); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) == - 0) { - dtnfsclient_rpcs[i].nr_v3_id_done = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, - dtnfsclient_done_str, 0, - &nfsclient_nfs3_done_probes[i]); - } - } -} - -static void -dtnfsclient_destroy(void *arg, dtrace_id_t id, void *parg) -{ -} - -static void -dtnfsclient_enable(void *arg, dtrace_id_t id, void *parg) -{ - uint32_t *p = parg; - void *f = dtrace_probe; - - if (id == nfsclient_accesscache_flush_done_id) - dtrace_nfsclient_accesscache_flush_done_probe = f; - else if (id == nfsclient_accesscache_get_hit_id) - dtrace_nfsclient_accesscache_get_hit_probe = f; - else if (id == nfsclient_accesscache_get_miss_id) - dtrace_nfsclient_accesscache_get_miss_probe = f; - else if (id == nfsclient_accesscache_load_done_id) - dtrace_nfsclient_accesscache_load_done_probe = f; - else if (id == nfsclient_attrcache_flush_done_id) - dtrace_nfsclient_attrcache_flush_done_probe = f; - else if (id == nfsclient_attrcache_get_hit_id) - dtrace_nfsclient_attrcache_get_hit_probe = f; - else if (id == nfsclient_attrcache_get_miss_id) - dtrace_nfsclient_attrcache_get_miss_probe = f; - else if (id == nfsclient_attrcache_load_done_id) - dtrace_nfsclient_attrcache_load_done_probe = f; - else - *p = id; -} - -static void -dtnfsclient_disable(void *arg, dtrace_id_t id, void *parg) -{ - uint32_t *p = parg; - - if (id == nfsclient_accesscache_flush_done_id) - dtrace_nfsclient_accesscache_flush_done_probe = NULL; - else if (id == nfsclient_accesscache_get_hit_id) - dtrace_nfsclient_accesscache_get_hit_probe = NULL; - else if (id == nfsclient_accesscache_get_miss_id) - dtrace_nfsclient_accesscache_get_miss_probe = NULL; - else if (id == nfsclient_accesscache_load_done_id) - dtrace_nfsclient_accesscache_load_done_probe = NULL; - else if (id == nfsclient_attrcache_flush_done_id) - dtrace_nfsclient_attrcache_flush_done_probe = NULL; - else if (id == nfsclient_attrcache_get_hit_id) - dtrace_nfsclient_attrcache_get_hit_probe = NULL; - else if (id == nfsclient_attrcache_get_miss_id) - dtrace_nfsclient_attrcache_get_miss_probe = NULL; - else if (id == nfsclient_attrcache_load_done_id) - dtrace_nfsclient_attrcache_load_done_probe = NULL; - else - *p = 0; -} - -static void -dtnfsclient_load(void *dummy) -{ - - if (dtrace_register("nfsclient", &dtnfsclient_attr, - DTRACE_PRIV_USER, NULL, &dtnfsclient_pops, NULL, - &dtnfsclient_id) != 0) - return; - - dtrace_nfsclient_nfs23_start_probe = - (dtrace_nfsclient_nfs23_start_probe_func_t)dtrace_probe; - dtrace_nfsclient_nfs23_done_probe = - (dtrace_nfsclient_nfs23_done_probe_func_t)dtrace_probe; -} - - -static int -dtnfsclient_unload() -{ - - dtrace_nfsclient_nfs23_start_probe = NULL; - dtrace_nfsclient_nfs23_done_probe = NULL; - - return (dtrace_unregister(dtnfsclient_id)); -} - -static int -dtnfsclient_modevent(module_t mod __unused, int type, void *data __unused) -{ - int error = 0; - - switch (type) { - case MOD_LOAD: - break; - - case MOD_UNLOAD: - break; - - case MOD_SHUTDOWN: - break; - - default: - error = EOPNOTSUPP; - break; - } - - return (error); -} - -SYSINIT(dtnfsclient_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, - dtnfsclient_load, NULL); -SYSUNINIT(dtnfsclient_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, - dtnfsclient_unload, NULL); - -DEV_MODULE(dtnfsclient, dtnfsclient_modevent, NULL); -MODULE_VERSION(dtnfsclient, 1); -MODULE_DEPEND(dtnfsclient, dtrace, 1, 1, 1); -MODULE_DEPEND(dtnfsclient, opensolaris, 1, 1, 1); -MODULE_DEPEND(dtnfsclient, oldnfs, 1, 1, 1); diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c deleted file mode 100644 index f88e47f4f4e..00000000000 --- a/sys/nfsclient/nfs_krpc.c +++ /dev/null @@ -1,887 +0,0 @@ -/*- - * Copyright (c) 1989, 1991, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * Socket operations for use by nfs - */ - -#include "opt_inet6.h" -#include "opt_kgssapi.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#ifdef KDTRACE_HOOKS -#include - -dtrace_nfsclient_nfs23_start_probe_func_t - dtrace_nfsclient_nfs23_start_probe; - -dtrace_nfsclient_nfs23_done_probe_func_t - dtrace_nfsclient_nfs23_done_probe; - -/* - * Registered probes by RPC type. - */ -uint32_t nfsclient_nfs2_start_probes[NFS_NPROCS]; -uint32_t nfsclient_nfs2_done_probes[NFS_NPROCS]; - -uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS]; -uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS]; -#endif - -static int nfs_bufpackets = 4; -static int nfs_reconnects; -static int nfs3_jukebox_delay = 10; -static int nfs_skip_wcc_data_onerr = 1; -static int fake_wchan; - -SYSCTL_DECL(_vfs_oldnfs); - -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0, - "Buffer reservation size 2 < x < 64"); -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0, - "Number of times the nfs client has had to reconnect"); -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW, - &nfs3_jukebox_delay, 0, - "Number of seconds to delay a retry after receiving EJUKEBOX"); -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW, - &nfs_skip_wcc_data_onerr, 0, - "Disable weak cache consistency checking when server returns an error"); - -static void nfs_down(struct nfsmount *, struct thread *, const char *, - int, int); -static void nfs_up(struct nfsmount *, struct thread *, const char *, - int, int); -static int nfs_msg(struct thread *, const char *, const char *, int); - -extern int nfsv2_procid[]; - -struct nfs_cached_auth { - int ca_refs; /* refcount, including 1 from the cache */ - uid_t ca_uid; /* uid that corresponds to this auth */ - AUTH *ca_auth; /* RPC auth handle */ -}; - -/* - * RTT estimator - */ - -static enum nfs_rto_timer_t nfs_proct[NFS_NPROCS] = { - NFS_DEFAULT_TIMER, /* NULL */ - NFS_GETATTR_TIMER, /* GETATTR */ - NFS_DEFAULT_TIMER, /* SETATTR */ - NFS_LOOKUP_TIMER, /* LOOKUP */ - NFS_GETATTR_TIMER, /* ACCESS */ - NFS_READ_TIMER, /* READLINK */ - NFS_READ_TIMER, /* READ */ - NFS_WRITE_TIMER, /* WRITE */ - NFS_DEFAULT_TIMER, /* CREATE */ - NFS_DEFAULT_TIMER, /* MKDIR */ - NFS_DEFAULT_TIMER, /* SYMLINK */ - NFS_DEFAULT_TIMER, /* MKNOD */ - NFS_DEFAULT_TIMER, /* REMOVE */ - NFS_DEFAULT_TIMER, /* RMDIR */ - NFS_DEFAULT_TIMER, /* RENAME */ - NFS_DEFAULT_TIMER, /* LINK */ - NFS_READ_TIMER, /* READDIR */ - NFS_READ_TIMER, /* READDIRPLUS */ - NFS_DEFAULT_TIMER, /* FSSTAT */ - NFS_DEFAULT_TIMER, /* FSINFO */ - NFS_DEFAULT_TIMER, /* PATHCONF */ - NFS_DEFAULT_TIMER, /* COMMIT */ - NFS_DEFAULT_TIMER, /* NOOP */ -}; - -/* - * Choose the correct RTT timer for this NFS procedure. - */ -static inline enum nfs_rto_timer_t -nfs_rto_timer(u_int32_t procnum) -{ - - return (nfs_proct[procnum]); -} - -/* - * Initialize the RTT estimator state for a new mount point. - */ -static void -nfs_init_rtt(struct nfsmount *nmp) -{ - int i; - - for (i = 0; i < NFS_MAX_TIMER; i++) { - nmp->nm_timers[i].rt_srtt = hz; - nmp->nm_timers[i].rt_deviate = 0; - nmp->nm_timers[i].rt_rtxcur = hz; - } -} - -/* - * Initialize sockets and congestion for a new NFS connection. - * We do not free the sockaddr if error. - */ -int -nfs_connect(struct nfsmount *nmp) -{ - int rcvreserve, sndreserve; - int pktscale; - struct sockaddr *saddr; - struct ucred *origcred; - struct thread *td = curthread; - CLIENT *client; - struct netconfig *nconf; - rpcvers_t vers; - int one = 1, retries; - struct timeval timo; - - /* - * We need to establish the socket using the credentials of - * the mountpoint. Some parts of this process (such as - * sobind() and soconnect()) will use the curent thread's - * credential instead of the socket credential. To work - * around this, temporarily change the current thread's - * credential to that of the mountpoint. - * - * XXX: It would be better to explicitly pass the correct - * credential to sobind() and soconnect(). - */ - origcred = td->td_ucred; - td->td_ucred = nmp->nm_mountp->mnt_cred; - saddr = nmp->nm_nam; - - vers = NFS_VER2; - if (nmp->nm_flag & NFSMNT_NFSV3) - vers = NFS_VER3; - else if (nmp->nm_flag & NFSMNT_NFSV4) - vers = NFS_VER4; - if (saddr->sa_family == AF_INET) - if (nmp->nm_sotype == SOCK_DGRAM) - nconf = getnetconfigent("udp"); - else - nconf = getnetconfigent("tcp"); - else - if (nmp->nm_sotype == SOCK_DGRAM) - nconf = getnetconfigent("udp6"); - else - nconf = getnetconfigent("tcp6"); - - /* - * Get buffer reservation size from sysctl, but impose reasonable - * limits. - */ - pktscale = nfs_bufpackets; - if (pktscale < 2) - pktscale = 2; - if (pktscale > 64) - pktscale = 64; - mtx_lock(&nmp->nm_mtx); - if (nmp->nm_sotype == SOCK_DGRAM) { - sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale; - rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) + - NFS_MAXPKTHDR) * pktscale; - } else if (nmp->nm_sotype == SOCK_SEQPACKET) { - sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale; - rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) + - NFS_MAXPKTHDR) * pktscale; - } else { - if (nmp->nm_sotype != SOCK_STREAM) - panic("nfscon sotype"); - sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR + - sizeof (u_int32_t)) * pktscale; - rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR + - sizeof (u_int32_t)) * pktscale; - } - mtx_unlock(&nmp->nm_mtx); - - client = clnt_reconnect_create(nconf, saddr, NFS_PROG, vers, - sndreserve, rcvreserve); - CLNT_CONTROL(client, CLSET_WAITCHAN, "nfsreq"); - if (nmp->nm_flag & NFSMNT_INT) - CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one); - if (nmp->nm_flag & NFSMNT_RESVPORT) - CLNT_CONTROL(client, CLSET_PRIVPORT, &one); - if ((nmp->nm_flag & NFSMNT_SOFT) != 0) { - if (nmp->nm_sotype == SOCK_DGRAM) - /* - * For UDP, the large timeout for a reconnect will - * be set to "nm_retry * nm_timeo / 2", so we only - * want to do 2 reconnect timeout retries. - */ - retries = 2; - else - retries = nmp->nm_retry; - } else - retries = INT_MAX; - CLNT_CONTROL(client, CLSET_RETRIES, &retries); - - /* - * For UDP, there are 2 timeouts: - * - CLSET_RETRY_TIMEOUT sets the initial timeout for the timer - * that does a retransmit of an RPC request using the same socket - * and xid. This is what you normally want to do, since NFS - * servers depend on "same xid" for their Duplicate Request Cache. - * - timeout specified in CLNT_CALL_MBUF(), which specifies when - * retransmits on the same socket should fail and a fresh socket - * created. Each of these timeouts counts as one CLSET_RETRIES, - * as set above. - * Set the initial retransmit timeout for UDP. This timeout doesn't - * exist for TCP and the following call just fails, which is ok. - */ - timo.tv_sec = nmp->nm_timeo / NFS_HZ; - timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ; - CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, &timo); - - mtx_lock(&nmp->nm_mtx); - if (nmp->nm_client) { - /* - * Someone else already connected. - */ - CLNT_RELEASE(client); - } else - nmp->nm_client = client; - - /* - * Protocols that do not require connections may be optionally left - * unconnected for servers that reply from a port other than NFS_PORT. - */ - if (!(nmp->nm_flag & NFSMNT_NOCONN)) { - mtx_unlock(&nmp->nm_mtx); - CLNT_CONTROL(client, CLSET_CONNECT, &one); - } else - mtx_unlock(&nmp->nm_mtx); - - /* Restore current thread's credentials. */ - td->td_ucred = origcred; - - mtx_lock(&nmp->nm_mtx); - /* Initialize other non-zero congestion variables. */ - nfs_init_rtt(nmp); - mtx_unlock(&nmp->nm_mtx); - return (0); -} - -/* - * NFS disconnect. Clean up and unlink. - */ -void -nfs_disconnect(struct nfsmount *nmp) -{ - CLIENT *client; - - mtx_lock(&nmp->nm_mtx); - if (nmp->nm_client) { - client = nmp->nm_client; - nmp->nm_client = NULL; - mtx_unlock(&nmp->nm_mtx); - rpc_gss_secpurge_call(client); - CLNT_CLOSE(client); - CLNT_RELEASE(client); - } else - mtx_unlock(&nmp->nm_mtx); -} - -void -nfs_safedisconnect(struct nfsmount *nmp) -{ - - nfs_disconnect(nmp); -} - -static AUTH * -nfs_getauth(struct nfsmount *nmp, struct ucred *cred) -{ - rpc_gss_service_t svc; - AUTH *auth; - - switch (nmp->nm_secflavor) { - case RPCSEC_GSS_KRB5: - case RPCSEC_GSS_KRB5I: - case RPCSEC_GSS_KRB5P: - if (!nmp->nm_mech_oid) - if (!rpc_gss_mech_to_oid_call("kerberosv5", - &nmp->nm_mech_oid)) - return (NULL); - if (nmp->nm_secflavor == RPCSEC_GSS_KRB5) - svc = rpc_gss_svc_none; - else if (nmp->nm_secflavor == RPCSEC_GSS_KRB5I) - svc = rpc_gss_svc_integrity; - else - svc = rpc_gss_svc_privacy; - auth = rpc_gss_secfind_call(nmp->nm_client, cred, - nmp->nm_principal, nmp->nm_mech_oid, svc); - if (auth) - return (auth); - /* fallthrough */ - case AUTH_SYS: - default: - return (authunix_create(cred)); - - } -} - -/* - * Callback from the RPC code to generate up/down notifications. - */ - -struct nfs_feedback_arg { - struct nfsmount *nf_mount; - int nf_lastmsg; /* last tprintf */ - int nf_tprintfmsg; - struct thread *nf_td; -}; - -static void -nfs_feedback(int type, int proc, void *arg) -{ - struct nfs_feedback_arg *nf = (struct nfs_feedback_arg *) arg; - struct nfsmount *nmp = nf->nf_mount; - time_t now; - - switch (type) { - case FEEDBACK_REXMIT2: - case FEEDBACK_RECONNECT: - now = time_uptime; - if (nf->nf_lastmsg + nmp->nm_tprintf_delay < now) { - nfs_down(nmp, nf->nf_td, - "not responding", 0, NFSSTA_TIMEO); - nf->nf_tprintfmsg = TRUE; - nf->nf_lastmsg = now; - } - break; - - case FEEDBACK_OK: - nfs_up(nf->nf_mount, nf->nf_td, - "is alive again", NFSSTA_TIMEO, nf->nf_tprintfmsg); - break; - } -} - -/* - * nfs_request - goes something like this - * - fill in request struct - * - links it into list - * - calls nfs_send() for first transmit - * - calls nfs_receive() to get reply - * - break down rpc header and return with nfs reply pointed to - * by mrep or error - * nb: always frees up mreq mbuf list - */ -int -nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum, - struct thread *td, struct ucred *cred, struct mbuf **mrp, - struct mbuf **mdp, caddr_t *dposp) -{ - struct mbuf *mrep; - u_int32_t *tl; - struct nfsmount *nmp; - struct mbuf *md; - time_t waituntil; - caddr_t dpos; - int error = 0, timeo; - AUTH *auth = NULL; - enum nfs_rto_timer_t timer; - struct nfs_feedback_arg nf; - struct rpc_callextra ext; - enum clnt_stat stat; - struct timeval timo; - - /* Reject requests while attempting a forced unmount. */ - if (vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) { - m_freem(mreq); - return (ESTALE); - } - nmp = VFSTONFS(vp->v_mount); - bzero(&nf, sizeof(struct nfs_feedback_arg)); - nf.nf_mount = nmp; - nf.nf_td = td; - nf.nf_lastmsg = time_uptime - - ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay)); - - /* - * XXX if not already connected call nfs_connect now. Longer - * term, change nfs_mount to call nfs_connect unconditionally - * and let clnt_reconnect_create handle reconnects. - */ - if (!nmp->nm_client) - nfs_connect(nmp); - - auth = nfs_getauth(nmp, cred); - if (!auth) { - m_freem(mreq); - return (EACCES); - } - bzero(&ext, sizeof(ext)); - ext.rc_auth = auth; - - ext.rc_feedback = nfs_feedback; - ext.rc_feedback_arg = &nf; - - /* - * Use a conservative timeout for RPCs other than getattr, - * lookup, read or write. The justification for doing "other" - * this way is that these RPCs happen so infrequently that - * timer est. would probably be stale. Also, since many of - * these RPCs are non-idempotent, a conservative timeout is - * desired. - */ - timer = nfs_rto_timer(procnum); - if (timer != NFS_DEFAULT_TIMER) - ext.rc_timers = &nmp->nm_timers[timer - 1]; - else - ext.rc_timers = NULL; - -#ifdef KDTRACE_HOOKS - if (dtrace_nfsclient_nfs23_start_probe != NULL) { - uint32_t probe_id; - int probe_procnum; - - if (nmp->nm_flag & NFSMNT_NFSV3) { - probe_id = nfsclient_nfs3_start_probes[procnum]; - probe_procnum = procnum; - } else { - probe_id = nfsclient_nfs2_start_probes[procnum]; - probe_procnum = nfsv2_procid[procnum]; - } - if (probe_id != 0) - (dtrace_nfsclient_nfs23_start_probe)(probe_id, vp, - mreq, cred, probe_procnum); - } -#endif - - nfsstats.rpcrequests++; -tryagain: - /* - * This timeout specifies when a new socket should be created, - * along with new xid values. For UDP, this should be done - * infrequently, since retransmits of RPC requests should normally - * use the same xid. - */ - if (nmp->nm_sotype == SOCK_DGRAM) { - if ((nmp->nm_flag & NFSMNT_SOFT) != 0) { - /* - * CLSET_RETRIES is set to 2, so this should be half - * of the total timeout required. - */ - timeo = nmp->nm_retry * nmp->nm_timeo / 2; - if (timeo < 1) - timeo = 1; - timo.tv_sec = timeo / NFS_HZ; - timo.tv_usec = (timeo % NFS_HZ) * 1000000 / NFS_HZ; - } else { - /* For UDP hard mounts, use a large value. */ - timo.tv_sec = NFS_MAXTIMEO / NFS_HZ; - timo.tv_usec = 0; - } - } else { - timo.tv_sec = nmp->nm_timeo / NFS_HZ; - timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ; - } - mrep = NULL; - stat = CLNT_CALL_MBUF(nmp->nm_client, &ext, - (nmp->nm_flag & NFSMNT_NFSV3) ? procnum : nfsv2_procid[procnum], - mreq, &mrep, timo); - - /* - * If there was a successful reply and a tprintf msg. - * tprintf a response. - */ - if (stat == RPC_SUCCESS) - error = 0; - else if (stat == RPC_TIMEDOUT) { - nfsstats.rpctimeouts++; - error = ETIMEDOUT; - } else if (stat == RPC_VERSMISMATCH) { - nfsstats.rpcinvalid++; - error = EOPNOTSUPP; - } else if (stat == RPC_PROGVERSMISMATCH) { - nfsstats.rpcinvalid++; - error = EPROTONOSUPPORT; - } else if (stat == RPC_INTR) { - error = EINTR; - } else { - nfsstats.rpcinvalid++; - error = EACCES; - } - if (error) - goto nfsmout; - - KASSERT(mrep != NULL, ("mrep shouldn't be NULL if no error\n")); - - /* - * Search for any mbufs that are not a multiple of 4 bytes long - * or with m_data not longword aligned. - * These could cause pointer alignment problems, so copy them to - * well aligned mbufs. - */ - error = nfs_realign(&mrep, M_NOWAIT); - if (error == ENOMEM) { - m_freem(mrep); - AUTH_DESTROY(auth); - nfsstats.rpcinvalid++; - return (error); - } - - md = mrep; - dpos = mtod(mrep, caddr_t); - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - if (*tl != 0) { - error = fxdr_unsigned(int, *tl); - if ((nmp->nm_flag & NFSMNT_NFSV3) && - error == NFSERR_TRYLATER) { - m_freem(mrep); - error = 0; - waituntil = time_second + nfs3_jukebox_delay; - while (time_second < waituntil) - (void)tsleep(&fake_wchan, PSOCK, "nqnfstry", - hz); - goto tryagain; - } - /* - * Make sure NFSERR_RETERR isn't bogusly set by a server - * such as amd. (No actual NFS error has bit 31 set.) - */ - error &= ~NFSERR_RETERR; - - /* - * If the File Handle was stale, invalidate the lookup - * cache, just in case. - */ - if (error == ESTALE) - nfs_purgecache(vp); - /* - * Skip wcc data on non-ENOENT NFS errors for now. - * NetApp filers return corrupt postop attrs in the - * wcc data for NFS err EROFS. Not sure if they could - * return corrupt postop attrs for others errors. - * Blocking ENOENT post-op attributes breaks negative - * name caching, so always allow it through. - */ - if ((nmp->nm_flag & NFSMNT_NFSV3) && - (!nfs_skip_wcc_data_onerr || error == ENOENT)) { - *mrp = mrep; - *mdp = md; - *dposp = dpos; - error |= NFSERR_RETERR; - } else - m_freem(mrep); - goto nfsmout; - } - -#ifdef KDTRACE_HOOKS - if (dtrace_nfsclient_nfs23_done_probe != NULL) { - uint32_t probe_id; - int probe_procnum; - - if (nmp->nm_flag & NFSMNT_NFSV3) { - probe_id = nfsclient_nfs3_done_probes[procnum]; - probe_procnum = procnum; - } else { - probe_id = nfsclient_nfs2_done_probes[procnum]; - probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ? - procnum : nfsv2_procid[procnum]; - } - if (probe_id != 0) - (dtrace_nfsclient_nfs23_done_probe)(probe_id, vp, - mreq, cred, probe_procnum, 0); - } -#endif - m_freem(mreq); - *mrp = mrep; - *mdp = md; - *dposp = dpos; - AUTH_DESTROY(auth); - return (0); - -nfsmout: -#ifdef KDTRACE_HOOKS - if (dtrace_nfsclient_nfs23_done_probe != NULL) { - uint32_t probe_id; - int probe_procnum; - - if (nmp->nm_flag & NFSMNT_NFSV3) { - probe_id = nfsclient_nfs3_done_probes[procnum]; - probe_procnum = procnum; - } else { - probe_id = nfsclient_nfs2_done_probes[procnum]; - probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ? - procnum : nfsv2_procid[procnum]; - } - if (probe_id != 0) - (dtrace_nfsclient_nfs23_done_probe)(probe_id, vp, - mreq, cred, probe_procnum, error); - } -#endif - m_freem(mreq); - if (auth) - AUTH_DESTROY(auth); - return (error); -} - -/* - * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and - * wait for all requests to complete. This is used by forced unmounts - * to terminate any outstanding RPCs. - */ -int -nfs_nmcancelreqs(struct nfsmount *nmp) -{ - - if (nmp->nm_client) - CLNT_CLOSE(nmp->nm_client); - return (0); -} - -/* - * Any signal that can interrupt an NFS operation in an intr mount - * should be added to this set. SIGSTOP and SIGKILL cannot be masked. - */ -int nfs_sig_set[] = { - SIGINT, - SIGTERM, - SIGHUP, - SIGKILL, - SIGQUIT -}; - -/* - * Check to see if one of the signals in our subset is pending on - * the process (in an intr mount). - */ -static int -nfs_sig_pending(sigset_t set) -{ - int i; - - for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) - if (SIGISMEMBER(set, nfs_sig_set[i])) - return (1); - return (0); -} - -/* - * The set/restore sigmask functions are used to (temporarily) overwrite - * the thread td_sigmask during an RPC call (for example). These are also - * used in other places in the NFS client that might tsleep(). - */ -void -nfs_set_sigmask(struct thread *td, sigset_t *oldset) -{ - sigset_t newset; - int i; - struct proc *p; - - SIGFILLSET(newset); - if (td == NULL) - td = curthread; /* XXX */ - p = td->td_proc; - /* Remove the NFS set of signals from newset. */ - PROC_LOCK(p); - mtx_lock(&p->p_sigacts->ps_mtx); - for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) { - /* - * But make sure we leave the ones already masked - * by the process, i.e. remove the signal from the - * temporary signalmask only if it wasn't already - * in p_sigmask. - */ - if (!SIGISMEMBER(td->td_sigmask, nfs_sig_set[i]) && - !SIGISMEMBER(p->p_sigacts->ps_sigignore, nfs_sig_set[i])) - SIGDELSET(newset, nfs_sig_set[i]); - } - mtx_unlock(&p->p_sigacts->ps_mtx); - kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, - SIGPROCMASK_PROC_LOCKED); - PROC_UNLOCK(p); -} - -void -nfs_restore_sigmask(struct thread *td, sigset_t *set) -{ - if (td == NULL) - td = curthread; /* XXX */ - kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0); -} - -/* - * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the - * old one after msleep() returns. - */ -int -nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority, - char *wmesg, int timo) -{ - sigset_t oldset; - int error; - struct proc *p; - - if ((priority & PCATCH) == 0) - return msleep(ident, mtx, priority, wmesg, timo); - if (td == NULL) - td = curthread; /* XXX */ - nfs_set_sigmask(td, &oldset); - error = msleep(ident, mtx, priority, wmesg, timo); - nfs_restore_sigmask(td, &oldset); - p = td->td_proc; - return (error); -} - -/* - * Test for a termination condition pending on the process. - * This is used for NFSMNT_INT mounts. - */ -int -nfs_sigintr(struct nfsmount *nmp, struct thread *td) -{ - struct proc *p; - sigset_t tmpset; - - /* Terminate all requests while attempting a forced unmount. */ - if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) - return (EIO); - if (!(nmp->nm_flag & NFSMNT_INT)) - return (0); - if (td == NULL) - return (0); - p = td->td_proc; - PROC_LOCK(p); - tmpset = p->p_siglist; - SIGSETOR(tmpset, td->td_siglist); - SIGSETNAND(tmpset, td->td_sigmask); - mtx_lock(&p->p_sigacts->ps_mtx); - SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore); - mtx_unlock(&p->p_sigacts->ps_mtx); - if ((SIGNOTEMPTY(p->p_siglist) || SIGNOTEMPTY(td->td_siglist)) - && nfs_sig_pending(tmpset)) { - PROC_UNLOCK(p); - return (EINTR); - } - PROC_UNLOCK(p); - return (0); -} - -static int -nfs_msg(struct thread *td, const char *server, const char *msg, int error) -{ - struct proc *p; - - p = td ? td->td_proc : NULL; - if (error) - tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server, - msg, error); - else - tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg); - return (0); -} - -static void -nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg, - int error, int flags) -{ - if (nmp == NULL) - return; - mtx_lock(&nmp->nm_mtx); - if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) { - nmp->nm_state |= NFSSTA_TIMEO; - mtx_unlock(&nmp->nm_mtx); - vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, - VQ_NOTRESP, 0); - } else - mtx_unlock(&nmp->nm_mtx); - mtx_lock(&nmp->nm_mtx); - if ((flags & NFSSTA_LOCKTIMEO) && - !(nmp->nm_state & NFSSTA_LOCKTIMEO)) { - nmp->nm_state |= NFSSTA_LOCKTIMEO; - mtx_unlock(&nmp->nm_mtx); - vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, - VQ_NOTRESPLOCK, 0); - } else - mtx_unlock(&nmp->nm_mtx); - nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error); -} - -static void -nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg, - int flags, int tprintfmsg) -{ - if (nmp == NULL) - return; - if (tprintfmsg) - nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0); - - mtx_lock(&nmp->nm_mtx); - if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) { - nmp->nm_state &= ~NFSSTA_TIMEO; - mtx_unlock(&nmp->nm_mtx); - vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, - VQ_NOTRESP, 1); - } else - mtx_unlock(&nmp->nm_mtx); - - mtx_lock(&nmp->nm_mtx); - if ((flags & NFSSTA_LOCKTIMEO) && - (nmp->nm_state & NFSSTA_LOCKTIMEO)) { - nmp->nm_state &= ~NFSSTA_LOCKTIMEO; - mtx_unlock(&nmp->nm_mtx); - vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid, - VQ_NOTRESPLOCK, 1); - } else - mtx_unlock(&nmp->nm_mtx); -} diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c deleted file mode 100644 index 2fb2c88151a..00000000000 --- a/sys/nfsclient/nfs_nfsiod.c +++ /dev/null @@ -1,346 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static MALLOC_DEFINE(M_NFSSVC, "nfsclient_srvsock", "Nfs server structure"); - -static void nfssvc_iod(void *); - -static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON]; - -SYSCTL_DECL(_vfs_oldnfs); - -/* Maximum number of seconds a nfsiod kthread will sleep before exiting */ -static unsigned int nfs_iodmaxidle = 120; -SYSCTL_UINT(_vfs_oldnfs, OID_AUTO, iodmaxidle, CTLFLAG_RW, &nfs_iodmaxidle, 0, - "Max number of seconds an nfsiod kthread will sleep before exiting"); - -/* Maximum number of nfsiod kthreads */ -unsigned int nfs_iodmax = 20; - -/* Minimum number of nfsiod kthreads to keep as spares */ -static unsigned int nfs_iodmin = 0; - -static int nfs_nfsiodnew_sync(void); - -static int -sysctl_iodmin(SYSCTL_HANDLER_ARGS) -{ - int error, i; - int newmin; - - newmin = nfs_iodmin; - error = sysctl_handle_int(oidp, &newmin, 0, req); - if (error || (req->newptr == NULL)) - return (error); - mtx_lock(&nfs_iod_mtx); - if (newmin > nfs_iodmax) { - error = EINVAL; - goto out; - } - nfs_iodmin = newmin; - if (nfs_numasync >= nfs_iodmin) - goto out; - /* - * If the current number of nfsiod is lower - * than the new minimum, create some more. - */ - for (i = nfs_iodmin - nfs_numasync; i > 0; i--) - nfs_nfsiodnew_sync(); -out: - mtx_unlock(&nfs_iod_mtx); - return (0); -} -SYSCTL_PROC(_vfs_oldnfs, OID_AUTO, iodmin, CTLTYPE_UINT | CTLFLAG_RW, 0, - sizeof (nfs_iodmin), sysctl_iodmin, "IU", - "Min number of nfsiod kthreads to keep as spares"); - - -static int -sysctl_iodmax(SYSCTL_HANDLER_ARGS) -{ - int error, i; - int iod, newmax; - - newmax = nfs_iodmax; - error = sysctl_handle_int(oidp, &newmax, 0, req); - if (error || (req->newptr == NULL)) - return (error); - if (newmax > NFS_MAXASYNCDAEMON) - return (EINVAL); - mtx_lock(&nfs_iod_mtx); - nfs_iodmax = newmax; - if (nfs_numasync <= nfs_iodmax) - goto out; - /* - * If there are some asleep nfsiods that should - * exit, wakeup() them so that they check nfs_iodmax - * and exit. Those who are active will exit as - * soon as they finish I/O. - */ - iod = nfs_numasync - 1; - for (i = 0; i < nfs_numasync - nfs_iodmax; i++) { - if (nfs_iodwant[iod] == NFSIOD_AVAILABLE) - wakeup(&nfs_iodwant[iod]); - iod--; - } -out: - mtx_unlock(&nfs_iod_mtx); - return (0); -} -SYSCTL_PROC(_vfs_oldnfs, OID_AUTO, iodmax, CTLTYPE_UINT | CTLFLAG_RW, 0, - sizeof (nfs_iodmax), sysctl_iodmax, "IU", - "Max number of nfsiod kthreads"); - -static int -nfs_nfsiodnew_sync(void) -{ - int error, i; - - mtx_assert(&nfs_iod_mtx, MA_OWNED); - for (i = 0; i < nfs_iodmax; i++) { - if (nfs_asyncdaemon[i] == 0) { - nfs_asyncdaemon[i] = 1; - break; - } - } - if (i == nfs_iodmax) - return (0); - mtx_unlock(&nfs_iod_mtx); - error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, - RFHIGHPID, 0, "nfsiod %d", i); - mtx_lock(&nfs_iod_mtx); - if (error == 0) { - nfs_numasync++; - nfs_iodwant[i] = NFSIOD_AVAILABLE; - } else - nfs_asyncdaemon[i] = 0; - return (error); -} - -void -nfs_nfsiodnew_tq(__unused void *arg, int pending) -{ - - mtx_lock(&nfs_iod_mtx); - while (pending > 0) { - pending--; - nfs_nfsiodnew_sync(); - } - mtx_unlock(&nfs_iod_mtx); -} - -void -nfs_nfsiodnew(void) -{ - - mtx_assert(&nfs_iod_mtx, MA_OWNED); - taskqueue_enqueue(taskqueue_thread, &nfs_nfsiodnew_task); -} - -static void -nfsiod_setup(void *dummy) -{ - int error; - - TUNABLE_INT_FETCH("vfs.oldnfs.iodmin", &nfs_iodmin); - mtx_lock(&nfs_iod_mtx); - /* Silently limit the start number of nfsiod's */ - if (nfs_iodmin > NFS_MAXASYNCDAEMON) - nfs_iodmin = NFS_MAXASYNCDAEMON; - - while (nfs_numasync < nfs_iodmin) { - error = nfs_nfsiodnew_sync(); - if (error == -1) - panic("nfsiod_setup: nfs_nfsiodnew failed"); - } - mtx_unlock(&nfs_iod_mtx); -} -SYSINIT(nfsiod, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, nfsiod_setup, NULL); - -static int nfs_defect = 0; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0, - "Allow nfsiods to migrate serving different mounts"); - -/* - * Asynchronous I/O daemons for client nfs. - * They do read-ahead and write-behind operations on the block I/O cache. - * Returns if we hit the timeout defined by the iodmaxidle sysctl. - */ -static void -nfssvc_iod(void *instance) -{ - struct buf *bp; - struct nfsmount *nmp; - int myiod, timo; - int error = 0; - - mtx_lock(&nfs_iod_mtx); - myiod = (int *)instance - nfs_asyncdaemon; - /* - * Main loop - */ - for (;;) { - while (((nmp = nfs_iodmount[myiod]) == NULL) - || !TAILQ_FIRST(&nmp->nm_bufq)) { - if (myiod >= nfs_iodmax) - goto finish; - if (nmp) - nmp->nm_bufqiods--; - if (nfs_iodwant[myiod] == NFSIOD_NOT_AVAILABLE) - nfs_iodwant[myiod] = NFSIOD_AVAILABLE; - nfs_iodmount[myiod] = NULL; - /* - * Always keep at least nfs_iodmin kthreads. - */ - timo = (myiod < nfs_iodmin) ? 0 : nfs_iodmaxidle * hz; - error = msleep(&nfs_iodwant[myiod], &nfs_iod_mtx, PWAIT | PCATCH, - "-", timo); - if (error) { - nmp = nfs_iodmount[myiod]; - /* - * Rechecking the nm_bufq closes a rare race where the - * nfsiod is woken up at the exact time the idle timeout - * fires - */ - if (nmp && TAILQ_FIRST(&nmp->nm_bufq)) - error = 0; - break; - } - } - if (error) - break; - while ((bp = TAILQ_FIRST(&nmp->nm_bufq)) != NULL) { - int giant_locked = 0; - - /* Take one off the front of the list */ - TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist); - nmp->nm_bufqlen--; - if (nmp->nm_bufqwant && nmp->nm_bufqlen <= nfs_numasync) { - nmp->nm_bufqwant = 0; - wakeup(&nmp->nm_bufq); - } - mtx_unlock(&nfs_iod_mtx); - if (NFS_ISV4(bp->b_vp)) { - giant_locked = 1; - mtx_lock(&Giant); - } - if (bp->b_flags & B_DIRECT) { - KASSERT((bp->b_iocmd == BIO_WRITE), ("nfscvs_iod: BIO_WRITE not set")); - (void)nfs_doio_directwrite(bp); - } else { - if (bp->b_iocmd == BIO_READ) - (void) nfs_doio(bp->b_vp, bp, bp->b_rcred, NULL); - else - (void) nfs_doio(bp->b_vp, bp, bp->b_wcred, NULL); - } - if (giant_locked) - mtx_unlock(&Giant); - mtx_lock(&nfs_iod_mtx); - /* - * Make sure the nmp hasn't been dismounted as soon as - * nfs_doio() completes for the last buffer. - */ - nmp = nfs_iodmount[myiod]; - if (nmp == NULL) - break; - - /* - * If there are more than one iod on this mount, then defect - * so that the iods can be shared out fairly between the mounts - */ - if (nfs_defect && nmp->nm_bufqiods > 1) { - NFS_DPF(ASYNCIO, - ("nfssvc_iod: iod %d defecting from mount %p\n", - myiod, nmp)); - nfs_iodmount[myiod] = NULL; - nmp->nm_bufqiods--; - break; - } - } - } -finish: - nfs_asyncdaemon[myiod] = 0; - if (nmp) - nmp->nm_bufqiods--; - nfs_iodwant[myiod] = NFSIOD_NOT_AVAILABLE; - nfs_iodmount[myiod] = NULL; - /* Someone may be waiting for the last nfsiod to terminate. */ - if (--nfs_numasync == 0) - wakeup(&nfs_numasync); - mtx_unlock(&nfs_iod_mtx); - if ((error == 0) || (error == EWOULDBLOCK)) - kproc_exit(0); - /* Abnormal termination */ - kproc_exit(1); -} diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c deleted file mode 100644 index cee4343156b..00000000000 --- a/sys/nfsclient/nfs_node.c +++ /dev/null @@ -1,276 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_node.c 8.6 (Berkeley) 5/22/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -static uma_zone_t nfsnode_zone; - -static void nfs_freesillyrename(void *arg, __unused int pending); - -#define TRUE 1 -#define FALSE 0 - -void -nfs_nhinit(void) -{ - - nfsnode_zone = uma_zcreate("NFSNODE", sizeof(struct nfsnode), NULL, - NULL, NULL, NULL, UMA_ALIGN_PTR, 0); -} - -void -nfs_nhuninit(void) -{ - uma_zdestroy(nfsnode_zone); -} - -struct nfs_vncmp { - int fhsize; - void *fh; -}; - -static int -nfs_vncmpf(struct vnode *vp, void *arg) -{ - struct nfs_vncmp *a; - struct nfsnode *np; - - a = arg; - np = VTONFS(vp); - return (bcmp(a->fh, np->n_fhp, a->fhsize)); -} - -/* - * Look up a vnode/nfsnode by file handle. - * Callers must check for mount points!! - * In all cases, a pointer to a - * nfsnode structure is returned. - */ -int -nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int flags) -{ - struct thread *td = curthread; /* XXX */ - struct nfsnode *np; - struct vnode *vp; - struct vnode *nvp; - int error; - u_int hash; - struct nfsmount *nmp; - struct nfs_vncmp ncmp; - - nmp = VFSTONFS(mntp); - *npp = NULL; - - hash = fnv_32_buf(fhp->fh_bytes, fhsize, FNV1_32_INIT); - ncmp.fhsize = fhsize; - ncmp.fh = fhp; - - error = vfs_hash_get(mntp, hash, flags, - td, &nvp, nfs_vncmpf, &ncmp); - if (error) - return (error); - if (nvp != NULL) { - *npp = VTONFS(nvp); - return (0); - } - np = uma_zalloc(nfsnode_zone, M_WAITOK | M_ZERO); - - error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp); - if (error) { - uma_zfree(nfsnode_zone, np); - return (error); - } - vp = nvp; - vp->v_bufobj.bo_ops = &buf_ops_nfs; - vp->v_data = np; - np->n_vnode = vp; - /* - * Initialize the mutex even if the vnode is going to be a loser. - * This simplifies the logic in reclaim, which can then unconditionally - * destroy the mutex (in the case of the loser, or if hash_insert happened - * to return an error no special casing is needed). - */ - mtx_init(&np->n_mtx, "NFSnode lock", NULL, MTX_DEF); - /* - * NFS supports recursive and shared locking. - */ - lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL); - VN_LOCK_AREC(vp); - VN_LOCK_ASHARE(vp); - if (fhsize > NFS_SMALLFH) { - np->n_fhp = malloc(fhsize, M_NFSBIGFH, M_WAITOK); - } else - np->n_fhp = &np->n_fh; - bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize); - np->n_fhsize = fhsize; - error = insmntque(vp, mntp); - if (error != 0) { - *npp = NULL; - if (np->n_fhsize > NFS_SMALLFH) { - free((caddr_t)np->n_fhp, M_NFSBIGFH); - } - mtx_destroy(&np->n_mtx); - uma_zfree(nfsnode_zone, np); - return (error); - } - error = vfs_hash_insert(vp, hash, flags, - td, &nvp, nfs_vncmpf, &ncmp); - if (error) - return (error); - if (nvp != NULL) { - *npp = VTONFS(nvp); - /* vfs_hash_insert() vput()'s the losing vnode */ - return (0); - } - *npp = np; - - return (0); -} - -/* - * Do the vrele(sp->s_dvp) as a separate task in order to avoid a - * deadlock because of a LOR when vrele() locks the directory vnode. - */ -static void -nfs_freesillyrename(void *arg, __unused int pending) -{ - struct sillyrename *sp; - - sp = arg; - vrele(sp->s_dvp); - free(sp, M_NFSREQ); -} - -int -nfs_inactive(struct vop_inactive_args *ap) -{ - struct nfsnode *np; - struct sillyrename *sp; - struct thread *td = curthread; /* XXX */ - - np = VTONFS(ap->a_vp); - mtx_lock(&np->n_mtx); - if (ap->a_vp->v_type != VDIR) { - sp = np->n_sillyrename; - np->n_sillyrename = NULL; - } else - sp = NULL; - if (sp) { - mtx_unlock(&np->n_mtx); - (void)nfs_vinvalbuf(ap->a_vp, 0, td, 1); - /* - * Remove the silly file that was rename'd earlier - */ - (sp->s_removeit)(sp); - crfree(sp->s_cred); - TASK_INIT(&sp->s_task, 0, nfs_freesillyrename, sp); - taskqueue_enqueue(taskqueue_thread, &sp->s_task); - mtx_lock(&np->n_mtx); - } - np->n_flag &= NMODIFIED; - mtx_unlock(&np->n_mtx); - return (0); -} - -/* - * Reclaim an nfsnode so that it can be used for other purposes. - */ -int -nfs_reclaim(struct vop_reclaim_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct nfsdmap *dp, *dp2; - - /* - * If the NLM is running, give it a chance to abort pending - * locks. - */ - if (nfs_reclaim_p) - nfs_reclaim_p(ap); - - /* - * Destroy the vm object and flush associated pages. - */ - vnode_destroy_vobject(vp); - - vfs_hash_remove(vp); - - /* - * Free up any directory cookie structures and - * large file handle structures that might be associated with - * this nfs node. - */ - if (vp->v_type == VDIR) { - dp = LIST_FIRST(&np->n_cookies); - while (dp) { - dp2 = dp; - dp = LIST_NEXT(dp, ndm_list); - free((caddr_t)dp2, M_NFSDIROFF); - } - } - if (np->n_writecred != NULL) - crfree(np->n_writecred); - if (np->n_fhsize > NFS_SMALLFH) { - free((caddr_t)np->n_fhp, M_NFSBIGFH); - } - mtx_destroy(&np->n_mtx); - uma_zfree(nfsnode_zone, vp->v_data); - vp->v_data = NULL; - return (0); -} diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c deleted file mode 100644 index d4fd5eb0238..00000000000 --- a/sys/nfsclient/nfs_subs.c +++ /dev/null @@ -1,1140 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * These functions support the macros and help fiddle mbuf chains for - * the nfs op functions. They do things like create the rpc header and - * copy data between mbuf chains and uio lists. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -/* - * Note that stdarg.h and the ANSI style va_start macro is used for both - * ANSI and traditional C compilers. - */ -#include - -#ifdef KDTRACE_HOOKS -dtrace_nfsclient_attrcache_flush_probe_func_t - dtrace_nfsclient_attrcache_flush_done_probe; -uint32_t nfsclient_attrcache_flush_done_id; - -dtrace_nfsclient_attrcache_get_hit_probe_func_t - dtrace_nfsclient_attrcache_get_hit_probe; -uint32_t nfsclient_attrcache_get_hit_id; - -dtrace_nfsclient_attrcache_get_miss_probe_func_t - dtrace_nfsclient_attrcache_get_miss_probe; -uint32_t nfsclient_attrcache_get_miss_id; - -dtrace_nfsclient_attrcache_load_probe_func_t - dtrace_nfsclient_attrcache_load_done_probe; -uint32_t nfsclient_attrcache_load_done_id; -#endif /* !KDTRACE_HOOKS */ - -/* - * Data items converted to xdr at startup, since they are constant - * This is kinda hokey, but may save a little time doing byte swaps - */ -u_int32_t nfs_xdrneg1; -u_int32_t nfs_true, nfs_false; - -/* And other global data */ -static u_int32_t nfs_xid = 0; -static enum vtype nv2tov_type[8]= { - VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON -}; - -int nfs_ticks; -int nfs_pbuf_freecnt = -1; /* start out unlimited */ - -struct nfs_bufq nfs_bufq; -static struct mtx nfs_xid_mtx; -struct task nfs_nfsiodnew_task; - -/* - * and the reverse mapping from generic to Version 2 procedure numbers - */ -int nfsv2_procid[NFS_NPROCS] = { - NFSV2PROC_NULL, - NFSV2PROC_GETATTR, - NFSV2PROC_SETATTR, - NFSV2PROC_LOOKUP, - NFSV2PROC_NOOP, - NFSV2PROC_READLINK, - NFSV2PROC_READ, - NFSV2PROC_WRITE, - NFSV2PROC_CREATE, - NFSV2PROC_MKDIR, - NFSV2PROC_SYMLINK, - NFSV2PROC_CREATE, - NFSV2PROC_REMOVE, - NFSV2PROC_RMDIR, - NFSV2PROC_RENAME, - NFSV2PROC_LINK, - NFSV2PROC_READDIR, - NFSV2PROC_NOOP, - NFSV2PROC_STATFS, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, -}; - -LIST_HEAD(nfsnodehashhead, nfsnode); - -u_int32_t -nfs_xid_gen(void) -{ - uint32_t xid; - - mtx_lock(&nfs_xid_mtx); - - /* Get a pretty random xid to start with */ - if (!nfs_xid) - nfs_xid = random(); - /* - * Skip zero xid if it should ever happen. - */ - if (++nfs_xid == 0) - nfs_xid++; - xid = nfs_xid; - mtx_unlock(&nfs_xid_mtx); - return xid; -} - -/* - * copies a uio scatter/gather list to an mbuf chain. - * NOTE: can ony handle iovcnt == 1 - */ -int -nfsm_uiotombuf(struct uio *uiop, struct mbuf **mq, int siz, caddr_t *bpos) -{ - char *uiocp; - struct mbuf *mp, *mp2; - int xfer, left, mlen; - int uiosiz, clflg, rem; - char *cp; - - KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1")); - - if (siz > MLEN) /* or should it >= MCLBYTES ?? */ - clflg = 1; - else - clflg = 0; - rem = nfsm_rndup(siz)-siz; - mp = mp2 = *mq; - while (siz > 0) { - left = uiop->uio_iov->iov_len; - uiocp = uiop->uio_iov->iov_base; - if (left > siz) - left = siz; - uiosiz = left; - while (left > 0) { - mlen = M_TRAILINGSPACE(mp); - if (mlen == 0) { - if (clflg) - mp = m_getcl(M_WAITOK, MT_DATA, 0); - else - mp = m_get(M_WAITOK, MT_DATA); - mp2->m_next = mp; - mp2 = mp; - mlen = M_TRAILINGSPACE(mp); - } - xfer = (left > mlen) ? mlen : left; -#ifdef notdef - /* Not Yet.. */ - if (uiop->uio_iov->iov_op != NULL) - (*(uiop->uio_iov->iov_op)) - (uiocp, mtod(mp, caddr_t)+mp->m_len, xfer); - else -#endif - if (uiop->uio_segflg == UIO_SYSSPACE) - bcopy(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer); - else - copyin(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer); - mp->m_len += xfer; - left -= xfer; - uiocp += xfer; - uiop->uio_offset += xfer; - uiop->uio_resid -= xfer; - } - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + uiosiz; - uiop->uio_iov->iov_len -= uiosiz; - siz -= uiosiz; - } - if (rem > 0) { - if (rem > M_TRAILINGSPACE(mp)) { - mp = m_get(M_WAITOK, MT_DATA); - mp2->m_next = mp; - } - cp = mtod(mp, caddr_t)+mp->m_len; - for (left = 0; left < rem; left++) - *cp++ = '\0'; - mp->m_len += rem; - *bpos = cp; - } else - *bpos = mtod(mp, caddr_t)+mp->m_len; - *mq = mp; - return (0); -} - -/* - * Copy a string into mbufs for the hard cases... - */ -int -nfsm_strtmbuf(struct mbuf **mb, char **bpos, const char *cp, long siz) -{ - struct mbuf *m1 = NULL, *m2; - long left, xfer, len, tlen; - u_int32_t *tl; - int putsize; - - putsize = 1; - m2 = *mb; - left = M_TRAILINGSPACE(m2); - if (left > 0) { - tl = ((u_int32_t *)(*bpos)); - *tl++ = txdr_unsigned(siz); - putsize = 0; - left -= NFSX_UNSIGNED; - m2->m_len += NFSX_UNSIGNED; - if (left > 0) { - bcopy(cp, (caddr_t) tl, left); - siz -= left; - cp += left; - m2->m_len += left; - left = 0; - } - } - /* Loop around adding mbufs */ - while (siz > 0) { - if (siz > MLEN) { - m1 = m_getcl(M_WAITOK, MT_DATA, 0); - m1->m_len = MCLBYTES; - } else { - m1 = m_get(M_WAITOK, MT_DATA); - m1->m_len = MLEN; - } - m2->m_next = m1; - m2 = m1; - tl = mtod(m1, u_int32_t *); - tlen = 0; - if (putsize) { - *tl++ = txdr_unsigned(siz); - m1->m_len -= NFSX_UNSIGNED; - tlen = NFSX_UNSIGNED; - putsize = 0; - } - if (siz < m1->m_len) { - len = nfsm_rndup(siz); - xfer = siz; - if (xfer < len) - *(tl+(xfer>>2)) = 0; - } else { - xfer = len = m1->m_len; - } - bcopy(cp, (caddr_t) tl, xfer); - m1->m_len = len+tlen; - siz -= xfer; - cp += xfer; - } - *mb = m1; - *bpos = mtod(m1, caddr_t)+m1->m_len; - return (0); -} - -/* - * Called once to initialize data structures... - */ -int -nfs_init(struct vfsconf *vfsp) -{ - int i; - - nfsmount_zone = uma_zcreate("NFSMOUNT", sizeof(struct nfsmount), - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - nfs_true = txdr_unsigned(TRUE); - nfs_false = txdr_unsigned(FALSE); - nfs_xdrneg1 = txdr_unsigned(-1); - nfs_ticks = (hz * NFS_TICKINTVL + 500) / 1000; - if (nfs_ticks < 1) - nfs_ticks = 1; - /* Ensure async daemons disabled */ - for (i = 0; i < NFS_MAXASYNCDAEMON; i++) { - nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE; - nfs_iodmount[i] = NULL; - } - nfs_nhinit(); /* Init the nfsnode table */ - - /* - * Initialize reply list and start timer - */ - mtx_init(&nfs_iod_mtx, "NFS iod lock", NULL, MTX_DEF); - mtx_init(&nfs_xid_mtx, "NFS xid lock", NULL, MTX_DEF); - TASK_INIT(&nfs_nfsiodnew_task, 0, nfs_nfsiodnew_tq, NULL); - - nfs_pbuf_freecnt = nswbuf / 2 + 1; - - return (0); -} - -int -nfs_uninit(struct vfsconf *vfsp) -{ - int i; - - /* - * Tell all nfsiod processes to exit. Clear nfs_iodmax, and wakeup - * any sleeping nfsiods so they check nfs_iodmax and exit. - * Drain nfsiodnew task before we wait for them to finish. - */ - mtx_lock(&nfs_iod_mtx); - nfs_iodmax = 0; - mtx_unlock(&nfs_iod_mtx); - taskqueue_drain(taskqueue_thread, &nfs_nfsiodnew_task); - mtx_lock(&nfs_iod_mtx); - for (i = 0; i < nfs_numasync; i++) - if (nfs_iodwant[i] == NFSIOD_AVAILABLE) - wakeup(&nfs_iodwant[i]); - /* The last nfsiod to exit will wake us up when nfs_numasync hits 0 */ - while (nfs_numasync) - msleep(&nfs_numasync, &nfs_iod_mtx, PWAIT, "ioddie", 0); - mtx_unlock(&nfs_iod_mtx); - nfs_nhuninit(); - uma_zdestroy(nfsmount_zone); - return (0); -} - -void -nfs_dircookie_lock(struct nfsnode *np) -{ - mtx_lock(&np->n_mtx); - while (np->n_flag & NDIRCOOKIELK) - (void) msleep(&np->n_flag, &np->n_mtx, PZERO, "nfsdirlk", 0); - np->n_flag |= NDIRCOOKIELK; - mtx_unlock(&np->n_mtx); -} - -void -nfs_dircookie_unlock(struct nfsnode *np) -{ - mtx_lock(&np->n_mtx); - np->n_flag &= ~NDIRCOOKIELK; - wakeup(&np->n_flag); - mtx_unlock(&np->n_mtx); -} - -int -nfs_upgrade_vnlock(struct vnode *vp) -{ - int old_lock; - - ASSERT_VOP_LOCKED(vp, "nfs_upgrade_vnlock"); - old_lock = VOP_ISLOCKED(vp); - if (old_lock != LK_EXCLUSIVE) { - KASSERT(old_lock == LK_SHARED, - ("nfs_upgrade_vnlock: wrong old_lock %d", old_lock)); - /* Upgrade to exclusive lock, this might block */ - vn_lock(vp, LK_UPGRADE | LK_RETRY); - } - return (old_lock); -} - -void -nfs_downgrade_vnlock(struct vnode *vp, int old_lock) -{ - if (old_lock != LK_EXCLUSIVE) { - KASSERT(old_lock == LK_SHARED, ("wrong old_lock %d", old_lock)); - /* Downgrade from exclusive lock. */ - vn_lock(vp, LK_DOWNGRADE | LK_RETRY); - } -} - -void -nfs_printf(const char *fmt, ...) -{ - va_list ap; - - mtx_lock(&Giant); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - mtx_unlock(&Giant); -} - -/* - * Attribute cache routines. - * nfs_loadattrcache() - loads or updates the cache contents from attributes - * that are on the mbuf list - * nfs_getattrcache() - returns valid attributes if found in cache, returns - * error otherwise - */ - -/* - * Load the attribute cache (that lives in the nfsnode entry) with - * the values on the mbuf list and - * Iff vap not NULL - * copy the attributes to *vaper - */ -int -nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, - struct vattr *vaper, int dontshrink) -{ - struct vnode *vp = *vpp; - struct vattr *vap; - struct nfs_fattr *fp; - struct nfsnode *np = NULL; - int32_t t1; - caddr_t cp2; - int rdev; - struct mbuf *md; - enum vtype vtyp; - u_short vmode; - struct timespec mtime, mtime_save; - int v3 = NFS_ISV3(vp); - int error = 0; - u_quad_t nsize; - int setnsize; - - md = *mdp; - t1 = (mtod(md, caddr_t) + md->m_len) - *dposp; - cp2 = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, M_WAITOK); - if (cp2 == NULL) { - error = EBADRPC; - goto out; - } - fp = (struct nfs_fattr *)cp2; - if (v3) { - vtyp = nfsv3tov_type(fp->fa_type); - vmode = fxdr_unsigned(u_short, fp->fa_mode); - rdev = makedev(fxdr_unsigned(int, fp->fa3_rdev.specdata1), - fxdr_unsigned(int, fp->fa3_rdev.specdata2)); - fxdr_nfsv3time(&fp->fa3_mtime, &mtime); - } else { - vtyp = nfsv2tov_type(fp->fa_type); - vmode = fxdr_unsigned(u_short, fp->fa_mode); - /* - * XXX - * - * The duplicate information returned in fa_type and fa_mode - * is an ambiguity in the NFS version 2 protocol. - * - * VREG should be taken literally as a regular file. If a - * server intents to return some type information differently - * in the upper bits of the mode field (e.g. for sockets, or - * FIFOs), NFSv2 mandates fa_type to be VNON. Anyway, we - * leave the examination of the mode bits even in the VREG - * case to avoid breakage for bogus servers, but we make sure - * that there are actually type bits set in the upper part of - * fa_mode (and failing that, trust the va_type field). - * - * NFSv3 cleared the issue, and requires fa_mode to not - * contain any type information (while also introduing sockets - * and FIFOs for fa_type). - */ - if (vtyp == VNON || (vtyp == VREG && (vmode & S_IFMT) != 0)) - vtyp = IFTOVT(vmode); - rdev = fxdr_unsigned(int32_t, fp->fa2_rdev); - fxdr_nfsv2time(&fp->fa2_mtime, &mtime); - - /* - * Really ugly NFSv2 kludge. - */ - if (vtyp == VCHR && rdev == 0xffffffff) - vtyp = VFIFO; - } - - /* - * If v_type == VNON it is a new node, so fill in the v_type, - * n_mtime fields. Check to see if it represents a special - * device, and if so, check for a possible alias. Once the - * correct vnode has been obtained, fill in the rest of the - * information. - */ - np = VTONFS(vp); - mtx_lock(&np->n_mtx); - if (vp->v_type != vtyp) { - vp->v_type = vtyp; - if (vp->v_type == VFIFO) - vp->v_op = &nfs_fifoops; - np->n_mtime = mtime; - } - vap = &np->n_vattr; - vap->va_type = vtyp; - vap->va_mode = (vmode & 07777); - vap->va_rdev = rdev; - mtime_save = vap->va_mtime; - vap->va_mtime = mtime; - vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; - if (v3) { - vap->va_nlink = fxdr_unsigned(u_short, fp->fa_nlink); - vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid); - vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid); - vap->va_size = fxdr_hyper(&fp->fa3_size); - vap->va_blocksize = NFS_FABLKSIZE; - vap->va_bytes = fxdr_hyper(&fp->fa3_used); - vap->va_fileid = fxdr_unsigned(int32_t, - fp->fa3_fileid.nfsuquad[1]); - fxdr_nfsv3time(&fp->fa3_atime, &vap->va_atime); - fxdr_nfsv3time(&fp->fa3_ctime, &vap->va_ctime); - vap->va_flags = 0; - vap->va_filerev = 0; - } else { - vap->va_nlink = fxdr_unsigned(u_short, fp->fa_nlink); - vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid); - vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid); - vap->va_size = fxdr_unsigned(u_int32_t, fp->fa2_size); - vap->va_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize); - vap->va_bytes = (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) - * NFS_FABLKSIZE; - vap->va_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid); - fxdr_nfsv2time(&fp->fa2_atime, &vap->va_atime); - vap->va_flags = 0; - vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t, - fp->fa2_ctime.nfsv2_sec); - vap->va_ctime.tv_nsec = 0; - vap->va_gen = fxdr_unsigned(u_int32_t, fp->fa2_ctime.nfsv2_usec); - vap->va_filerev = 0; - } - np->n_attrstamp = time_second; - setnsize = 0; - nsize = 0; - if (vap->va_size != np->n_size) { - if (vap->va_type == VREG) { - if (dontshrink && vap->va_size < np->n_size) { - /* - * We've been told not to shrink the file; - * zero np->n_attrstamp to indicate that - * the attributes are stale. - */ - vap->va_size = np->n_size; - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - vnode_pager_setsize(vp, np->n_size); - } else if (np->n_flag & NMODIFIED) { - /* - * We've modified the file: Use the larger - * of our size, and the server's size. - */ - if (vap->va_size < np->n_size) { - vap->va_size = np->n_size; - } else { - np->n_size = vap->va_size; - np->n_flag |= NSIZECHANGED; - } - vnode_pager_setsize(vp, np->n_size); - } else if (vap->va_size < np->n_size) { - /* - * When shrinking the size, the call to - * vnode_pager_setsize() cannot be done - * with the mutex held, so delay it until - * after the mtx_unlock call. - */ - nsize = np->n_size = vap->va_size; - np->n_flag |= NSIZECHANGED; - setnsize = 1; - } else { - np->n_size = vap->va_size; - np->n_flag |= NSIZECHANGED; - vnode_pager_setsize(vp, np->n_size); - } - } else { - np->n_size = vap->va_size; - } - } - /* - * The following checks are added to prevent a race between (say) - * a READDIR+ and a WRITE. - * READDIR+, WRITE requests sent out. - * READDIR+ resp, WRITE resp received on client. - * However, the WRITE resp was handled before the READDIR+ resp - * causing the post op attrs from the write to be loaded first - * and the attrs from the READDIR+ to be loaded later. If this - * happens, we have stale attrs loaded into the attrcache. - * We detect this by for the mtime moving back. We invalidate the - * attrcache when this happens. - */ - if (timespeccmp(&mtime_save, &vap->va_mtime, >)) { - /* Size changed or mtime went backwards */ - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - } - if (vaper != NULL) { - bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap)); - if (np->n_flag & NCHG) { - if (np->n_flag & NACC) - vaper->va_atime = np->n_atim; - if (np->n_flag & NUPD) - vaper->va_mtime = np->n_mtim; - } - } - -#ifdef KDTRACE_HOOKS - if (np->n_attrstamp != 0) - KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, &np->n_vattr, 0); -#endif - mtx_unlock(&np->n_mtx); - if (setnsize) - vnode_pager_setsize(vp, nsize); -out: -#ifdef KDTRACE_HOOKS - if (error) - KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, NULL, error); -#endif - return (error); -} - -#ifdef NFS_ACDEBUG -#include -SYSCTL_DECL(_vfs_oldnfs); -static int nfs_acdebug; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, acdebug, CTLFLAG_RW, &nfs_acdebug, 0, - "Toggle acdebug (attribute cache debug) flag"); -#endif - -/* - * Check the time stamp - * If the cache is valid, copy contents to *vap and return 0 - * otherwise return an error - */ -int -nfs_getattrcache(struct vnode *vp, struct vattr *vaper) -{ - struct nfsnode *np; - struct vattr *vap; - struct nfsmount *nmp; - int timeo; - - np = VTONFS(vp); - vap = &np->n_vattr; - nmp = VFSTONFS(vp->v_mount); -#ifdef NFS_ACDEBUG - mtx_lock(&Giant); /* nfs_printf() */ -#endif - mtx_lock(&np->n_mtx); - /* XXX n_mtime doesn't seem to be updated on a miss-and-reload */ - timeo = (time_second - np->n_mtime.tv_sec) / 10; - -#ifdef NFS_ACDEBUG - if (nfs_acdebug>1) - nfs_printf("nfs_getattrcache: initial timeo = %d\n", timeo); -#endif - - if (vap->va_type == VDIR) { - if ((np->n_flag & NMODIFIED) || timeo < nmp->nm_acdirmin) - timeo = nmp->nm_acdirmin; - else if (timeo > nmp->nm_acdirmax) - timeo = nmp->nm_acdirmax; - } else { - if ((np->n_flag & NMODIFIED) || timeo < nmp->nm_acregmin) - timeo = nmp->nm_acregmin; - else if (timeo > nmp->nm_acregmax) - timeo = nmp->nm_acregmax; - } - -#ifdef NFS_ACDEBUG - if (nfs_acdebug > 2) - nfs_printf("acregmin %d; acregmax %d; acdirmin %d; acdirmax %d\n", - nmp->nm_acregmin, nmp->nm_acregmax, - nmp->nm_acdirmin, nmp->nm_acdirmax); - - if (nfs_acdebug) - nfs_printf("nfs_getattrcache: age = %d; final timeo = %d\n", - (time_second - np->n_attrstamp), timeo); -#endif - - if ((time_second - np->n_attrstamp) >= timeo) { - nfsstats.attrcache_misses++; - mtx_unlock(&np->n_mtx); -#ifdef NFS_ACDEBUG - mtx_unlock(&Giant); /* nfs_printf() */ -#endif - KDTRACE_NFS_ATTRCACHE_GET_MISS(vp); - return (ENOENT); - } - nfsstats.attrcache_hits++; - if (vap->va_size != np->n_size) { - if (vap->va_type == VREG) { - if (np->n_flag & NMODIFIED) { - if (vap->va_size < np->n_size) - vap->va_size = np->n_size; - else - np->n_size = vap->va_size; - } else { - np->n_size = vap->va_size; - } - vnode_pager_setsize(vp, np->n_size); - } else { - np->n_size = vap->va_size; - } - } - bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(struct vattr)); - if (np->n_flag & NCHG) { - if (np->n_flag & NACC) - vaper->va_atime = np->n_atim; - if (np->n_flag & NUPD) - vaper->va_mtime = np->n_mtim; - } - mtx_unlock(&np->n_mtx); -#ifdef NFS_ACDEBUG - mtx_unlock(&Giant); /* nfs_printf() */ -#endif - KDTRACE_NFS_ATTRCACHE_GET_HIT(vp, vap); - return (0); -} - -/* - * Purge all cached information about an NFS vnode including name - * cache entries, the attribute cache, and the access cache. This is - * called when an NFS request for a node fails with a stale - * filehandle. - */ -void -nfs_purgecache(struct vnode *vp) -{ - struct nfsnode *np; - int i; - - np = VTONFS(vp); - cache_purge(vp); - mtx_lock(&np->n_mtx); - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - for (i = 0; i < NFS_ACCESSCACHESIZE; i++) - np->n_accesscache[i].stamp = 0; - KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp); - mtx_unlock(&np->n_mtx); -} - -static nfsuint64 nfs_nullcookie = { { 0, 0 } }; -/* - * This function finds the directory cookie that corresponds to the - * logical byte offset given. - */ -nfsuint64 * -nfs_getcookie(struct nfsnode *np, off_t off, int add) -{ - struct nfsdmap *dp, *dp2; - int pos; - nfsuint64 *retval = NULL; - - pos = (uoff_t)off / NFS_DIRBLKSIZ; - if (pos == 0 || off < 0) { - KASSERT(!add, ("nfs getcookie add at <= 0")); - return (&nfs_nullcookie); - } - pos--; - dp = LIST_FIRST(&np->n_cookies); - if (!dp) { - if (add) { - dp = malloc(sizeof (struct nfsdmap), - M_NFSDIROFF, M_WAITOK); - dp->ndm_eocookie = 0; - LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list); - } else - goto out; - } - while (pos >= NFSNUMCOOKIES) { - pos -= NFSNUMCOOKIES; - if (LIST_NEXT(dp, ndm_list)) { - if (!add && dp->ndm_eocookie < NFSNUMCOOKIES && - pos >= dp->ndm_eocookie) - goto out; - dp = LIST_NEXT(dp, ndm_list); - } else if (add) { - dp2 = malloc(sizeof (struct nfsdmap), - M_NFSDIROFF, M_WAITOK); - dp2->ndm_eocookie = 0; - LIST_INSERT_AFTER(dp, dp2, ndm_list); - dp = dp2; - } else - goto out; - } - if (pos >= dp->ndm_eocookie) { - if (add) - dp->ndm_eocookie = pos + 1; - else - goto out; - } - retval = &dp->ndm_cookies[pos]; -out: - return (retval); -} - -/* - * Invalidate cached directory information, except for the actual directory - * blocks (which are invalidated separately). - * Done mainly to avoid the use of stale offset cookies. - */ -void -nfs_invaldir(struct vnode *vp) -{ - struct nfsnode *np = VTONFS(vp); - - KASSERT(vp->v_type == VDIR, ("nfs: invaldir not dir")); - nfs_dircookie_lock(np); - np->n_direofoffset = 0; - np->n_cookieverf.nfsuquad[0] = 0; - np->n_cookieverf.nfsuquad[1] = 0; - if (LIST_FIRST(&np->n_cookies)) - LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0; - nfs_dircookie_unlock(np); -} - -/* - * The write verifier has changed (probably due to a server reboot), so all - * B_NEEDCOMMIT blocks will have to be written again. Since they are on the - * dirty block list as B_DELWRI, all this takes is clearing the B_NEEDCOMMIT - * and B_CLUSTEROK flags. Once done the new write verifier can be set for the - * mount point. - * - * B_CLUSTEROK must be cleared along with B_NEEDCOMMIT because stage 1 data - * writes are not clusterable. - */ -void -nfs_clearcommit(struct mount *mp) -{ - struct vnode *vp, *nvp; - struct buf *bp, *nbp; - struct bufobj *bo; - - MNT_VNODE_FOREACH_ALL(vp, mp, nvp) { - bo = &vp->v_bufobj; - vholdl(vp); - VI_UNLOCK(vp); - BO_LOCK(bo); - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (!BUF_ISLOCKED(bp) && - (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) - == (B_DELWRI | B_NEEDCOMMIT)) - bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); - } - BO_UNLOCK(bo); - vdrop(vp); - } -} - -/* - * Helper functions for former macros. Some of these should be - * moved to their callers. - */ - -int -nfsm_mtofh_xx(struct vnode *d, struct vnode **v, int v3, int *f, - struct mbuf **md, caddr_t *dpos) -{ - struct nfsnode *ttnp; - struct vnode *ttvp; - nfsfh_t *ttfhp; - u_int32_t *tl; - int ttfhsize; - int t1; - - if (v3) { - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - *f = fxdr_unsigned(int, *tl); - } else - *f = 1; - if (*f) { - t1 = nfsm_getfh_xx(&ttfhp, &ttfhsize, (v3), md, dpos); - if (t1 != 0) - return t1; - t1 = nfs_nget(d->v_mount, ttfhp, ttfhsize, &ttnp, LK_EXCLUSIVE); - if (t1 != 0) - return t1; - *v = NFSTOV(ttnp); - } - if (v3) { - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - if (*f) - *f = fxdr_unsigned(int, *tl); - else if (fxdr_unsigned(int, *tl)) - nfsm_adv_xx(NFSX_V3FATTR, md, dpos); - } - if (*f) { - ttvp = *v; - t1 = nfs_loadattrcache(&ttvp, md, dpos, NULL, 0); - if (t1) - return t1; - *v = ttvp; - } - return 0; -} - -int -nfsm_getfh_xx(nfsfh_t **f, int *s, int v3, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - - if (v3) { - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - *s = fxdr_unsigned(int, *tl); - if (*s <= 0 || *s > NFSX_V3FHMAX) - return EBADRPC; - } else - *s = NFSX_V2FH; - *f = nfsm_dissect_xx(nfsm_rndup(*s), md, dpos); - if (*f == NULL) - return EBADRPC; - else - return 0; -} - - -int -nfsm_loadattr_xx(struct vnode **v, struct vattr *va, struct mbuf **md, - caddr_t *dpos) -{ - int t1; - - struct vnode *ttvp = *v; - t1 = nfs_loadattrcache(&ttvp, md, dpos, va, 0); - if (t1 != 0) - return t1; - *v = ttvp; - return 0; -} - -int -nfsm_postop_attr_xx(struct vnode **v, int *f, struct vattr *va, - struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - int t1; - - struct vnode *ttvp = *v; - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - *f = fxdr_unsigned(int, *tl); - if (*f != 0) { - t1 = nfs_loadattrcache(&ttvp, md, dpos, va, 1); - if (t1 != 0) { - *f = 0; - return t1; - } - *v = ttvp; - } - return 0; -} - -int -nfsm_wcc_data_xx(struct vnode **v, int *f, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - int ttattrf, ttretf = 0; - int t1; - - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - if (*tl == nfs_true) { - tl = nfsm_dissect_xx(6 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - mtx_lock(&(VTONFS(*v))->n_mtx); - if (*f) - ttretf = (VTONFS(*v)->n_mtime.tv_sec == fxdr_unsigned(u_int32_t, *(tl + 2)) && - VTONFS(*v)->n_mtime.tv_nsec == fxdr_unsigned(u_int32_t, *(tl + 3))); - mtx_unlock(&(VTONFS(*v))->n_mtx); - } - t1 = nfsm_postop_attr_xx(v, &ttattrf, NULL, md, dpos); - if (t1) - return t1; - if (*f) - *f = ttretf; - else - *f = ttattrf; - return 0; -} - -int -nfsm_strtom_xx(const char *a, int s, int m, struct mbuf **mb, caddr_t *bpos) -{ - u_int32_t *tl; - int t1; - - if (s > m) - return ENAMETOOLONG; - t1 = nfsm_rndup(s) + NFSX_UNSIGNED; - if (t1 <= M_TRAILINGSPACE(*mb)) { - tl = nfsm_build_xx(t1, mb, bpos); - *tl++ = txdr_unsigned(s); - *(tl + ((t1 >> 2) - 2)) = 0; - bcopy(a, tl, s); - } else { - t1 = nfsm_strtmbuf(mb, bpos, a, s); - if (t1 != 0) - return t1; - } - return 0; -} - -int -nfsm_fhtom_xx(struct vnode *v, int v3, struct mbuf **mb, caddr_t *bpos) -{ - u_int32_t *tl; - int t1; - caddr_t cp; - - if (v3) { - t1 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED; - if (t1 < M_TRAILINGSPACE(*mb)) { - tl = nfsm_build_xx(t1, mb, bpos); - *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize); - *(tl + ((t1 >> 2) - 2)) = 0; - bcopy(VTONFS(v)->n_fhp, tl, VTONFS(v)->n_fhsize); - } else { - t1 = nfsm_strtmbuf(mb, bpos, - (const char *)VTONFS(v)->n_fhp, - VTONFS(v)->n_fhsize); - if (t1 != 0) - return t1; - } - } else { - cp = nfsm_build_xx(NFSX_V2FH, mb, bpos); - bcopy(VTONFS(v)->n_fhp, cp, NFSX_V2FH); - } - return 0; -} - -void -nfsm_v3attrbuild_xx(struct vattr *va, int full, struct mbuf **mb, - caddr_t *bpos) -{ - u_int32_t *tl; - - if (va->va_mode != (mode_t)VNOVAL) { - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - *tl++ = nfs_true; - *tl = txdr_unsigned(va->va_mode); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = nfs_false; - } - if (full && va->va_uid != (uid_t)VNOVAL) { - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - *tl++ = nfs_true; - *tl = txdr_unsigned(va->va_uid); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = nfs_false; - } - if (full && va->va_gid != (gid_t)VNOVAL) { - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - *tl++ = nfs_true; - *tl = txdr_unsigned(va->va_gid); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = nfs_false; - } - if (full && va->va_size != VNOVAL) { - tl = nfsm_build_xx(3 * NFSX_UNSIGNED, mb, bpos); - *tl++ = nfs_true; - txdr_hyper(va->va_size, tl); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = nfs_false; - } - if (va->va_atime.tv_sec != VNOVAL) { - if ((va->va_vaflags & VA_UTIMES_NULL) == 0) { - tl = nfsm_build_xx(3 * NFSX_UNSIGNED, mb, bpos); - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&va->va_atime, tl); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); - } - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); - } - if (va->va_mtime.tv_sec != VNOVAL) { - if ((va->va_vaflags & VA_UTIMES_NULL) == 0) { - tl = nfsm_build_xx(3 * NFSX_UNSIGNED, mb, bpos); - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&va->va_mtime, tl); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); - } - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); - } -} diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c deleted file mode 100644 index 0c002d2e78b..00000000000 --- a/sys/nfsclient/nfs_vfsops.c +++ /dev/null @@ -1,1582 +0,0 @@ -/*- - * Copyright (c) 1989, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95 - */ - -#include -__FBSDID("$FreeBSD$"); - - -#include "opt_bootp.h" -#include "opt_nfsroot.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -FEATURE(nfsclient, "NFS client"); - -MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header"); -MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle"); -MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data"); -MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables"); -MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state"); - -uma_zone_t nfsmount_zone; - -struct nfsstats nfsstats; - -SYSCTL_NODE(_vfs, OID_AUTO, oldnfs, CTLFLAG_RW, 0, "Old NFS filesystem"); -SYSCTL_STRUCT(_vfs_oldnfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW, - &nfsstats, nfsstats, "S,nfsstats"); -static int nfs_ip_paranoia = 1; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW, - &nfs_ip_paranoia, 0, - "Disallow accepting replies from IPs which differ from those sent"); -#ifdef NFS_DEBUG -int nfs_debug; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, - "Toggle debug flag"); -#endif -static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY; -SYSCTL_INT(_vfs_oldnfs, NFS_TPRINTF_INITIAL_DELAY, - downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0, - "Delay before printing \"nfs server not responding\" messages"); -/* how long between console messages "nfs server foo not responding" */ -static int nfs_tprintf_delay = NFS_TPRINTF_DELAY; -SYSCTL_INT(_vfs_oldnfs, NFS_TPRINTF_DELAY, - downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, - "Delay between printing \"nfs server not responding\" messages"); - -static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, - struct nfs_args *argp, const char *hostname); -static int mountnfs(struct nfs_args *, struct mount *, - struct sockaddr *, char *, struct vnode **, - struct ucred *cred, int, int); -static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *, - struct sockaddr_storage *, int *, off_t *, - struct timeval *); -static vfs_mount_t nfs_mount; -static vfs_cmount_t nfs_cmount; -static vfs_unmount_t nfs_unmount; -static vfs_root_t nfs_root; -static vfs_statfs_t nfs_statfs; -static vfs_sync_t nfs_sync; -static vfs_sysctl_t nfs_sysctl; - -static int fake_wchan; - -/* - * nfs vfs operations. - */ -static struct vfsops nfs_vfsops = { - .vfs_init = nfs_init, - .vfs_mount = nfs_mount, - .vfs_cmount = nfs_cmount, - .vfs_root = nfs_root, - .vfs_statfs = nfs_statfs, - .vfs_sync = nfs_sync, - .vfs_uninit = nfs_uninit, - .vfs_unmount = nfs_unmount, - .vfs_sysctl = nfs_sysctl, -}; -VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK | VFCF_SBDRY); - -/* So that loader and kldload(2) can find us, wherever we are.. */ -MODULE_VERSION(oldnfs, 1); -MODULE_DEPEND(oldnfs, krpc, 1, 1, 1); -#ifdef KGSSAPI -MODULE_DEPEND(oldnfs, kgssapi, 1, 1, 1); -#endif -MODULE_DEPEND(oldnfs, nfs_common, 1, 1, 1); -MODULE_DEPEND(oldnfs, nfslock, 1, 1, 1); - -static struct nfs_rpcops nfs_rpcops = { - nfs_readrpc, - nfs_writerpc, - nfs_writebp, - nfs_readlinkrpc, - nfs_invaldir, - nfs_commit, -}; - -/* - * This structure is now defined in sys/nfs/nfs_diskless.c so that it - * can be shared by both NFS clients. It is declared here so that it - * will be defined for kernels built without NFS_ROOT, although it - * isn't used in that case. - */ -#ifndef NFS_ROOT -struct nfs_diskless nfs_diskless = { { { 0 } } }; -struct nfsv3_diskless nfsv3_diskless = { { { 0 } } }; -int nfs_diskless_valid = 0; -#endif - -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, diskless_valid, CTLFLAG_RD, - &nfs_diskless_valid, 0, - "Has the diskless struct been filled correctly"); - -SYSCTL_STRING(_vfs_oldnfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD, - nfsv3_diskless.root_hostnam, 0, "Path to nfs root"); - -SYSCTL_OPAQUE(_vfs_oldnfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD, - &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr, - "%Ssockaddr_in", "Diskless root nfs address"); - - -void nfsargs_ntoh(struct nfs_args *); -static int nfs_mountdiskless(char *, - struct sockaddr_in *, struct nfs_args *, - struct thread *, struct vnode **, struct mount *); -static void nfs_convert_diskless(void); -static void nfs_convert_oargs(struct nfs_args *args, - struct onfs_args *oargs); - -int -nfs_iosize(struct nfsmount *nmp) -{ - int iosize; - - /* - * Calculate the size used for io buffers. Use the larger - * of the two sizes to minimise nfs requests but make sure - * that it is at least one VM page to avoid wasting buffer - * space. - */ - iosize = imax(nmp->nm_rsize, nmp->nm_wsize); - iosize = imax(iosize, PAGE_SIZE); - return (iosize); -} - -static void -nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs) -{ - - args->version = NFS_ARGSVERSION; - args->addr = oargs->addr; - args->addrlen = oargs->addrlen; - args->sotype = oargs->sotype; - args->proto = oargs->proto; - args->fh = oargs->fh; - args->fhsize = oargs->fhsize; - args->flags = oargs->flags; - args->wsize = oargs->wsize; - args->rsize = oargs->rsize; - args->readdirsize = oargs->readdirsize; - args->timeo = oargs->timeo; - args->retrans = oargs->retrans; - args->maxgrouplist = oargs->maxgrouplist; - args->readahead = oargs->readahead; - args->deadthresh = oargs->deadthresh; - args->hostname = oargs->hostname; -} - -static void -nfs_convert_diskless(void) -{ - - bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif, - sizeof(struct ifaliasreq)); - bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway, - sizeof(struct sockaddr_in)); - nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args); - if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) { - nfsv3_diskless.root_fhsize = NFSX_V3FH; - bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH); - } else { - nfsv3_diskless.root_fhsize = NFSX_V2FH; - bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH); - } - bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr, - sizeof(struct sockaddr_in)); - bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN); - nfsv3_diskless.root_time = nfs_diskless.root_time; - bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam, - MAXHOSTNAMELEN); - nfs_diskless_valid = 3; -} - -/* - * nfs statfs call - */ -static int -nfs_statfs(struct mount *mp, struct statfs *sbp) -{ - struct vnode *vp; - struct thread *td; - struct nfs_statfs *sfp; - caddr_t bpos, dpos; - struct nfsmount *nmp = VFSTONFS(mp); - int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr; - struct mbuf *mreq, *mrep, *md, *mb; - struct nfsnode *np; - u_quad_t tquad; - - td = curthread; -#ifndef nolint - sfp = NULL; -#endif - error = vfs_busy(mp, MBF_NOWAIT); - if (error) - return (error); - error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE); - if (error) { - vfs_unbusy(mp); - return (error); - } - vp = NFSTOV(np); - mtx_lock(&nmp->nm_mtx); - if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) { - mtx_unlock(&nmp->nm_mtx); - (void)nfs_fsinfo(nmp, vp, td->td_ucred, td); - } else - mtx_unlock(&nmp->nm_mtx); - nfsstats.rpccnt[NFSPROC_FSSTAT]++; - mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred); - if (v3) - nfsm_postop_attr(vp, retattr); - if (error) { - if (mrep != NULL) - m_freem(mrep); - goto nfsmout; - } - sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3)); - mtx_lock(&nmp->nm_mtx); - sbp->f_iosize = nfs_iosize(nmp); - mtx_unlock(&nmp->nm_mtx); - if (v3) { - sbp->f_bsize = NFS_FABLKSIZE; - tquad = fxdr_hyper(&sfp->sf_tbytes); - sbp->f_blocks = tquad / NFS_FABLKSIZE; - tquad = fxdr_hyper(&sfp->sf_fbytes); - sbp->f_bfree = tquad / NFS_FABLKSIZE; - tquad = fxdr_hyper(&sfp->sf_abytes); - sbp->f_bavail = tquad / NFS_FABLKSIZE; - sbp->f_files = (fxdr_unsigned(int32_t, - sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff); - sbp->f_ffree = (fxdr_unsigned(int32_t, - sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff); - } else { - sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize); - sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks); - sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree); - sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail); - sbp->f_files = 0; - sbp->f_ffree = 0; - } - m_freem(mrep); -nfsmout: - vput(vp); - vfs_unbusy(mp); - return (error); -} - -/* - * nfs version 3 fsinfo rpc call - */ -int -nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred, - struct thread *td) -{ - struct nfsv3_fsinfo *fsp; - u_int32_t pref, max; - caddr_t bpos, dpos; - int error = 0, retattr; - struct mbuf *mreq, *mrep, *md, *mb; - u_int64_t maxfsize; - - nfsstats.rpccnt[NFSPROC_FSINFO]++; - mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, 1); - nfsm_request(vp, NFSPROC_FSINFO, td, cred); - nfsm_postop_attr(vp, retattr); - if (!error) { - fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO); - pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref); - mtx_lock(&nmp->nm_mtx); - if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE) - nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & - ~(NFS_FABLKSIZE - 1); - max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax); - if (max < nmp->nm_wsize && max > 0) { - nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1); - if (nmp->nm_wsize == 0) - nmp->nm_wsize = max; - } - pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref); - if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE) - nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) & - ~(NFS_FABLKSIZE - 1); - max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax); - if (max < nmp->nm_rsize && max > 0) { - nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1); - if (nmp->nm_rsize == 0) - nmp->nm_rsize = max; - } - pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref); - if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ) - nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) & - ~(NFS_DIRBLKSIZ - 1); - if (max < nmp->nm_readdirsize && max > 0) { - nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1); - if (nmp->nm_readdirsize == 0) - nmp->nm_readdirsize = max; - } - maxfsize = fxdr_hyper(&fsp->fs_maxfilesize); - if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize) - nmp->nm_maxfilesize = maxfsize; - nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp); - nmp->nm_state |= NFSSTA_GOTFSINFO; - mtx_unlock(&nmp->nm_mtx); - } - m_freem(mrep); -nfsmout: - return (error); -} - -/* - * Mount a remote root fs via. nfs. This depends on the info in the - * nfs_diskless structure that has been filled in properly by some primary - * bootstrap. - * It goes something like this: - * - do enough of "ifconfig" by calling ifioctl() so that the system - * can talk to the server - * - If nfs_diskless.mygateway is filled in, use that address as - * a default gateway. - * - build the rootfs mount point and call mountnfs() to do the rest. - * - * It is assumed to be safe to read, modify, and write the nfsv3_diskless - * structure, as well as other global NFS client variables here, as - * nfs_mountroot() will be called once in the boot before any other NFS - * client activity occurs. - */ -int -nfs_mountroot(struct mount *mp) -{ - struct thread *td = curthread; - struct nfsv3_diskless *nd = &nfsv3_diskless; - struct socket *so; - struct vnode *vp; - struct ifreq ir; - int error; - u_long l; - char buf[128]; - char *cp; - - -#if defined(BOOTP_NFSROOT) && defined(BOOTP) - bootpc_init(); /* use bootp to get nfs_diskless filled in */ -#elif defined(NFS_ROOT) - nfs_setup_diskless(); -#endif - - if (nfs_diskless_valid == 0) { - return (-1); - } - if (nfs_diskless_valid == 1) - nfs_convert_diskless(); - - /* - * XXX splnet, so networks will receive... - */ - splnet(); - - /* - * Do enough of ifconfig(8) so that the critical net interface can - * talk to the server. - */ - error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0, - td->td_ucred, td); - if (error) - panic("nfs_mountroot: socreate(%04x): %d", - nd->myif.ifra_addr.sa_family, error); - -#if 0 /* XXX Bad idea */ - /* - * We might not have been told the right interface, so we pass - * over the first ten interfaces of the same kind, until we get - * one of them configured. - */ - - for (i = strlen(nd->myif.ifra_name) - 1; - nd->myif.ifra_name[i] >= '0' && - nd->myif.ifra_name[i] <= '9'; - nd->myif.ifra_name[i] ++) { - error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td); - if(!error) - break; - } -#endif - - error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td); - if (error) - panic("nfs_mountroot: SIOCAIFADDR: %d", error); - - if ((cp = kern_getenv("boot.netif.mtu")) != NULL) { - ir.ifr_mtu = strtol(cp, NULL, 10); - bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ); - freeenv(cp); - error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td); - if (error) - printf("nfs_mountroot: SIOCSIFMTU: %d", error); - } - soclose(so); - - /* - * If the gateway field is filled in, set it as the default route. - * Note that pxeboot will set a default route of 0 if the route - * is not set by the DHCP server. Check also for a value of 0 - * to avoid panicking inappropriately in that situation. - */ - if (nd->mygateway.sin_len != 0 && - nd->mygateway.sin_addr.s_addr != 0) { - struct sockaddr_in mask, sin; - - bzero((caddr_t)&mask, sizeof(mask)); - sin = mask; - sin.sin_family = AF_INET; - sin.sin_len = sizeof(sin); - /* XXX MRT use table 0 for this sort of thing */ - CURVNET_SET(TD_TO_VNET(td)); - error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin, - (struct sockaddr *)&nd->mygateway, - (struct sockaddr *)&mask, - RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB); - CURVNET_RESTORE(); - if (error) - panic("nfs_mountroot: RTM_ADD: %d", error); - } - - /* - * Create the rootfs mount point. - */ - nd->root_args.fh = nd->root_fh; - nd->root_args.fhsize = nd->root_fhsize; - l = ntohl(nd->root_saddr.sin_addr.s_addr); - snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s", - (l >> 24) & 0xff, (l >> 16) & 0xff, - (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam); - printf("NFS ROOT: %s\n", buf); - nd->root_args.hostname = buf; - if ((error = nfs_mountdiskless(buf, - &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) { - return (error); - } - - /* - * This is not really an nfs issue, but it is much easier to - * set hostname here and then let the "/etc/rc.xxx" files - * mount the right /var based upon its preset value. - */ - mtx_lock(&prison0.pr_mtx); - strlcpy(prison0.pr_hostname, nd->my_hostnam, - sizeof (prison0.pr_hostname)); - mtx_unlock(&prison0.pr_mtx); - inittodr(ntohl(nd->root_time)); - return (0); -} - -/* - * Internal version of mount system call for diskless setup. - */ -static int -nfs_mountdiskless(char *path, - struct sockaddr_in *sin, struct nfs_args *args, struct thread *td, - struct vnode **vpp, struct mount *mp) -{ - struct sockaddr *nam; - int error; - - nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK); - if ((error = mountnfs(args, mp, nam, path, vpp, td->td_ucred, - NFS_DEFAULT_NAMETIMEO, NFS_DEFAULT_NEGNAMETIMEO)) != 0) { - printf("nfs_mountroot: mount %s on /: %d\n", path, error); - return (error); - } - return (0); -} - -static int -nfs_sec_name_to_num(char *sec) -{ - if (!strcmp(sec, "krb5")) - return (RPCSEC_GSS_KRB5); - if (!strcmp(sec, "krb5i")) - return (RPCSEC_GSS_KRB5I); - if (!strcmp(sec, "krb5p")) - return (RPCSEC_GSS_KRB5P); - if (!strcmp(sec, "sys")) - return (AUTH_SYS); - /* - * Userland should validate the string but we will try and - * cope with unexpected values. - */ - return (AUTH_SYS); -} - -static void -nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, - const char *hostname) -{ - int s; - int adjsock; - int maxio; - char *p; - char *secname; - char *principal; - - s = splnet(); - - /* - * Set read-only flag if requested; otherwise, clear it if this is - * an update. If this is not an update, then either the read-only - * flag is already clear, or this is a root mount and it was set - * intentionally at some previous point. - */ - if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) { - MNT_ILOCK(mp); - mp->mnt_flag |= MNT_RDONLY; - MNT_IUNLOCK(mp); - } else if (mp->mnt_flag & MNT_UPDATE) { - MNT_ILOCK(mp); - mp->mnt_flag &= ~MNT_RDONLY; - MNT_IUNLOCK(mp); - } - - /* - * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes - * no sense in that context. Also, set up appropriate retransmit - * and soft timeout behavior. - */ - if (argp->sotype == SOCK_STREAM) { - nmp->nm_flag &= ~NFSMNT_NOCONN; - nmp->nm_flag |= NFSMNT_DUMBTIMR; - nmp->nm_timeo = NFS_MAXTIMEO; - nmp->nm_retry = NFS_RETRANS_TCP; - } - - /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */ - if ((argp->flags & NFSMNT_NFSV3) == 0) - nmp->nm_flag &= ~NFSMNT_RDIRPLUS; - - /* Re-bind if rsrvd port requested and wasn't on one */ - adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT) - && (argp->flags & NFSMNT_RESVPORT); - /* Also re-bind if we're switching to/from a connected UDP socket */ - adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != - (argp->flags & NFSMNT_NOCONN)); - - /* Update flags atomically. Don't change the lock bits. */ - nmp->nm_flag = argp->flags | nmp->nm_flag; - splx(s); - - if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) { - nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10; - if (nmp->nm_timeo < NFS_MINTIMEO) - nmp->nm_timeo = NFS_MINTIMEO; - else if (nmp->nm_timeo > NFS_MAXTIMEO) - nmp->nm_timeo = NFS_MAXTIMEO; - } - - if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) { - nmp->nm_retry = argp->retrans; - if (nmp->nm_retry > NFS_MAXREXMIT) - nmp->nm_retry = NFS_MAXREXMIT; - } - - if (argp->flags & NFSMNT_NFSV3) { - if (argp->sotype == SOCK_DGRAM) - maxio = NFS_MAXDGRAMDATA; - else - maxio = NFS_MAXDATA; - } else - maxio = NFS_V2MAXDATA; - - if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) { - nmp->nm_wsize = argp->wsize; - /* Round down to multiple of blocksize */ - nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1); - if (nmp->nm_wsize <= 0) - nmp->nm_wsize = NFS_FABLKSIZE; - } - if (nmp->nm_wsize > maxio) - nmp->nm_wsize = maxio; - if (nmp->nm_wsize > MAXBSIZE) - nmp->nm_wsize = MAXBSIZE; - - if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) { - nmp->nm_rsize = argp->rsize; - /* Round down to multiple of blocksize */ - nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1); - if (nmp->nm_rsize <= 0) - nmp->nm_rsize = NFS_FABLKSIZE; - } - if (nmp->nm_rsize > maxio) - nmp->nm_rsize = maxio; - if (nmp->nm_rsize > MAXBSIZE) - nmp->nm_rsize = MAXBSIZE; - - if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) { - nmp->nm_readdirsize = argp->readdirsize; - } - if (nmp->nm_readdirsize > maxio) - nmp->nm_readdirsize = maxio; - if (nmp->nm_readdirsize > nmp->nm_rsize) - nmp->nm_readdirsize = nmp->nm_rsize; - - if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0) - nmp->nm_acregmin = argp->acregmin; - else - nmp->nm_acregmin = NFS_MINATTRTIMO; - if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0) - nmp->nm_acregmax = argp->acregmax; - else - nmp->nm_acregmax = NFS_MAXATTRTIMO; - if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0) - nmp->nm_acdirmin = argp->acdirmin; - else - nmp->nm_acdirmin = NFS_MINDIRATTRTIMO; - if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0) - nmp->nm_acdirmax = argp->acdirmax; - else - nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO; - if (nmp->nm_acdirmin > nmp->nm_acdirmax) - nmp->nm_acdirmin = nmp->nm_acdirmax; - if (nmp->nm_acregmin > nmp->nm_acregmax) - nmp->nm_acregmin = nmp->nm_acregmax; - - if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) { - if (argp->maxgrouplist <= NFS_MAXGRPS) - nmp->nm_numgrps = argp->maxgrouplist; - else - nmp->nm_numgrps = NFS_MAXGRPS; - } - if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) { - if (argp->readahead <= NFS_MAXRAHEAD) - nmp->nm_readahead = argp->readahead; - else - nmp->nm_readahead = NFS_MAXRAHEAD; - } - if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) { - if (argp->wcommitsize < nmp->nm_wsize) - nmp->nm_wcommitsize = nmp->nm_wsize; - else - nmp->nm_wcommitsize = argp->wcommitsize; - } - if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) { - if (argp->deadthresh <= NFS_MAXDEADTHRESH) - nmp->nm_deadthresh = argp->deadthresh; - else - nmp->nm_deadthresh = NFS_MAXDEADTHRESH; - } - - adjsock |= ((nmp->nm_sotype != argp->sotype) || - (nmp->nm_soproto != argp->proto)); - nmp->nm_sotype = argp->sotype; - nmp->nm_soproto = argp->proto; - - if (nmp->nm_client && adjsock) { - nfs_safedisconnect(nmp); - if (nmp->nm_sotype == SOCK_DGRAM) - while (nfs_connect(nmp)) { - printf("nfs_args: retrying connect\n"); - (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz); - } - } - - if (hostname) { - strlcpy(nmp->nm_hostname, hostname, - sizeof(nmp->nm_hostname)); - p = strchr(nmp->nm_hostname, ':'); - if (p) - *p = '\0'; - } - - if (vfs_getopt(mp->mnt_optnew, "sec", - (void **) &secname, NULL) == 0) { - nmp->nm_secflavor = nfs_sec_name_to_num(secname); - } else { - nmp->nm_secflavor = AUTH_SYS; - } - - if (vfs_getopt(mp->mnt_optnew, "principal", - (void **) &principal, NULL) == 0) { - strlcpy(nmp->nm_principal, principal, - sizeof(nmp->nm_principal)); - } else { - snprintf(nmp->nm_principal, sizeof(nmp->nm_principal), - "nfs@%s", nmp->nm_hostname); - } -} - -static const char *nfs_opts[] = { "from", "nfs_args", - "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union", - "noclusterr", "noclusterw", "multilabel", "acls", "force", "update", - "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport", - "readahead", "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", - "wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin", - "acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3", - "sec", "maxgroups", "principal", "negnametimeo", "nocto", "wcommitsize", - "nametimeo", - NULL }; - -/* - * VFS Operations. - * - * mount system call - * It seems a bit dumb to copyinstr() the host and path here and then - * bcopy() them in mountnfs(), but I wanted to detect errors before - * doing the sockargs() call because sockargs() allocates an mbuf and - * an error after that means that I have to release the mbuf. - */ -/* ARGSUSED */ -static int -nfs_mount(struct mount *mp) -{ - struct nfs_args args = { - .version = NFS_ARGSVERSION, - .addr = NULL, - .addrlen = sizeof (struct sockaddr_in), - .sotype = SOCK_STREAM, - .proto = 0, - .fh = NULL, - .fhsize = 0, - .flags = NFSMNT_RESVPORT, - .wsize = NFS_WSIZE, - .rsize = NFS_RSIZE, - .readdirsize = NFS_READDIRSIZE, - .timeo = 10, - .retrans = NFS_RETRANS, - .maxgrouplist = NFS_MAXGRPS, - .readahead = NFS_DEFRAHEAD, - .wcommitsize = 0, /* was: NQ_DEFLEASE */ - .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */ - .hostname = NULL, - /* args version 4 */ - .acregmin = NFS_MINATTRTIMO, - .acregmax = NFS_MAXATTRTIMO, - .acdirmin = NFS_MINDIRATTRTIMO, - .acdirmax = NFS_MAXDIRATTRTIMO, - }; - int error, ret, has_nfs_args_opt; - int has_addr_opt, has_fh_opt, has_hostname_opt; - struct sockaddr *nam; - struct vnode *vp; - char hst[MNAMELEN]; - size_t len; - u_char nfh[NFSX_V3FHMAX]; - char *opt; - int nametimeo = NFS_DEFAULT_NAMETIMEO; - int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO; - - has_nfs_args_opt = 0; - has_addr_opt = 0; - has_fh_opt = 0; - has_hostname_opt = 0; - - if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { - error = EINVAL; - goto out; - } - - if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) { - error = nfs_mountroot(mp); - goto out; - } - - /* - * The old mount_nfs program passed the struct nfs_args - * from userspace to kernel. The new mount_nfs program - * passes string options via nmount() from userspace to kernel - * and we populate the struct nfs_args in the kernel. - */ - if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) { - error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, - sizeof args); - if (error) - goto out; - - if (args.version != NFS_ARGSVERSION) { - error = EPROGMISMATCH; - goto out; - } - has_nfs_args_opt = 1; - } - - if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0) - args.flags |= NFSMNT_DUMBTIMR; - if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0) - args.flags |= NFSMNT_NOCONN; - if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0) - args.flags |= NFSMNT_NOCONN; - if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0) - args.flags |= NFSMNT_NOLOCKD; - if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0) - args.flags &= ~NFSMNT_NOLOCKD; - if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0) - args.flags |= NFSMNT_INT; - if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0) - args.flags |= NFSMNT_RDIRPLUS; - if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0) - args.flags |= NFSMNT_RESVPORT; - if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0) - args.flags &= ~NFSMNT_RESVPORT; - if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0) - args.flags |= NFSMNT_SOFT; - if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0) - args.flags &= ~NFSMNT_SOFT; - if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0) - args.sotype = SOCK_DGRAM; - if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0) - args.sotype = SOCK_DGRAM; - if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0) - args.sotype = SOCK_STREAM; - if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0) - args.flags |= NFSMNT_NFSV3; - if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0) - args.flags |= NFSMNT_NOCTO; - if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) { - if (opt == NULL) { - vfs_mount_error(mp, "illegal readdirsize"); - error = EINVAL; - goto out; - } - ret = sscanf(opt, "%d", &args.readdirsize); - if (ret != 1 || args.readdirsize <= 0) { - vfs_mount_error(mp, "illegal readdirsize: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_READDIRSIZE; - } - if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) { - if (opt == NULL) { - vfs_mount_error(mp, "illegal readahead"); - error = EINVAL; - goto out; - } - ret = sscanf(opt, "%d", &args.readahead); - if (ret != 1 || args.readahead <= 0) { - vfs_mount_error(mp, "illegal readahead: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_READAHEAD; - } - if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) { - if (opt == NULL) { - vfs_mount_error(mp, "illegal wsize"); - error = EINVAL; - goto out; - } - ret = sscanf(opt, "%d", &args.wsize); - if (ret != 1 || args.wsize <= 0) { - vfs_mount_error(mp, "illegal wsize: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_WSIZE; - } - if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) { - if (opt == NULL) { - vfs_mount_error(mp, "illegal rsize"); - error = EINVAL; - goto out; - } - ret = sscanf(opt, "%d", &args.rsize); - if (ret != 1 || args.rsize <= 0) { - vfs_mount_error(mp, "illegal wsize: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_RSIZE; - } - if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) { - if (opt == NULL) { - vfs_mount_error(mp, "illegal retrans"); - error = EINVAL; - goto out; - } - ret = sscanf(opt, "%d", &args.retrans); - if (ret != 1 || args.retrans <= 0) { - vfs_mount_error(mp, "illegal retrans: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_RETRANS; - } - if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.acregmin); - if (ret != 1 || args.acregmin < 0) { - vfs_mount_error(mp, "illegal acregmin: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_ACREGMIN; - } - if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.acregmax); - if (ret != 1 || args.acregmax < 0) { - vfs_mount_error(mp, "illegal acregmax: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_ACREGMAX; - } - if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.acdirmin); - if (ret != 1 || args.acdirmin < 0) { - vfs_mount_error(mp, "illegal acdirmin: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_ACDIRMIN; - } - if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.acdirmax); - if (ret != 1 || args.acdirmax < 0) { - vfs_mount_error(mp, "illegal acdirmax: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_ACDIRMAX; - } - if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.wcommitsize); - if (ret != 1 || args.wcommitsize < 0) { - vfs_mount_error(mp, "illegal wcommitsize: %s", opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_WCOMMITSIZE; - } - if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.deadthresh); - if (ret != 1 || args.deadthresh <= 0) { - vfs_mount_error(mp, "illegal deadthresh: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_DEADTHRESH; - } - if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.timeo); - if (ret != 1 || args.timeo <= 0) { - vfs_mount_error(mp, "illegal timeout: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_TIMEO; - } - if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &args.maxgrouplist); - if (ret != 1 || args.maxgrouplist <= 0) { - vfs_mount_error(mp, "illegal maxgroups: %s", - opt); - error = EINVAL; - goto out; - } - args.flags |= NFSMNT_MAXGRPS; - } - if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) { - ret = sscanf(opt, "%d", &nametimeo); - if (ret != 1 || nametimeo < 0) { - vfs_mount_error(mp, "illegal nametimeo: %s", opt); - error = EINVAL; - goto out; - } - } - if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL) - == 0) { - ret = sscanf(opt, "%d", &negnametimeo); - if (ret != 1 || negnametimeo < 0) { - vfs_mount_error(mp, "illegal negnametimeo: %s", - opt); - error = EINVAL; - goto out; - } - } - if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr, - &args.addrlen) == 0) { - has_addr_opt = 1; - if (args.addrlen > SOCK_MAXADDRLEN) { - error = ENAMETOOLONG; - goto out; - } - nam = malloc(args.addrlen, M_SONAME, - M_WAITOK); - bcopy(args.addr, nam, args.addrlen); - nam->sa_len = args.addrlen; - } - if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh, - &args.fhsize) == 0) { - has_fh_opt = 1; - } - if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname, - NULL) == 0) { - has_hostname_opt = 1; - } - if (args.hostname == NULL) { - vfs_mount_error(mp, "Invalid hostname"); - error = EINVAL; - goto out; - } - if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) { - vfs_mount_error(mp, "Bad file handle"); - error = EINVAL; - goto out; - } - - if (mp->mnt_flag & MNT_UPDATE) { - struct nfsmount *nmp = VFSTONFS(mp); - - if (nmp == NULL) { - error = EIO; - goto out; - } - - /* - * If a change from TCP->UDP is done and there are thread(s) - * that have I/O RPC(s) in progress with a tranfer size - * greater than NFS_MAXDGRAMDATA, those thread(s) will be - * hung, retrying the RPC(s) forever. Usually these threads - * will be seen doing an uninterruptible sleep on wait channel - * "newnfsreq" (truncated to "newnfsre" by procstat). - */ - if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM) - tprintf(curthread->td_proc, LOG_WARNING, - "Warning: mount -u that changes TCP->UDP can result in hung threads\n"); - - /* - * When doing an update, we can't change from or to - * v3, switch lockd strategies or change cookie translation - */ - args.flags = (args.flags & - ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) | - (nmp->nm_flag & - (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)); - nfs_decode_args(mp, nmp, &args, NULL); - goto out; - } - - /* - * Make the nfs_ip_paranoia sysctl serve as the default connection - * or no-connection mode for those protocols that support - * no-connection mode (the flag will be cleared later for protocols - * that do not support no-connection mode). This will allow a client - * to receive replies from a different IP then the request was - * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid), - * not 0. - */ - if (nfs_ip_paranoia == 0) - args.flags |= NFSMNT_NOCONN; - - if (has_nfs_args_opt) { - /* - * In the 'nfs_args' case, the pointers in the args - * structure are in userland - we copy them in here. - */ - if (!has_fh_opt) { - error = copyin((caddr_t)args.fh, (caddr_t)nfh, - args.fhsize); - if (error) { - goto out; - } - args.fh = nfh; - } - if (!has_hostname_opt) { - error = copyinstr(args.hostname, hst, MNAMELEN-1, &len); - if (error) { - goto out; - } - bzero(&hst[len], MNAMELEN - len); - args.hostname = hst; - } - if (!has_addr_opt) { - /* sockargs() call must be after above copyin() calls */ - error = getsockaddr(&nam, (caddr_t)args.addr, - args.addrlen); - if (error) { - goto out; - } - } - } else if (has_addr_opt == 0) { - vfs_mount_error(mp, "No server address"); - error = EINVAL; - goto out; - } - error = mountnfs(&args, mp, nam, args.hostname, &vp, - curthread->td_ucred, nametimeo, negnametimeo); -out: - if (!error) { - MNT_ILOCK(mp); - mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED; - MNT_IUNLOCK(mp); - } - return (error); -} - - -/* - * VFS Operations. - * - * mount system call - * It seems a bit dumb to copyinstr() the host and path here and then - * bcopy() them in mountnfs(), but I wanted to detect errors before - * doing the sockargs() call because sockargs() allocates an mbuf and - * an error after that means that I have to release the mbuf. - */ -/* ARGSUSED */ -static int -nfs_cmount(struct mntarg *ma, void *data, uint64_t flags) -{ - int error; - struct nfs_args args; - - error = copyin(data, &args, sizeof (struct nfs_args)); - if (error) - return error; - - ma = mount_arg(ma, "nfs_args", &args, sizeof args); - - error = kernel_mount(ma, flags); - return (error); -} - -/* - * Common code for mount and mountroot - */ -static int -mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, - char *hst, struct vnode **vpp, struct ucred *cred, int nametimeo, - int negnametimeo) -{ - struct nfsmount *nmp; - struct nfsnode *np; - int error; - struct vattr attrs; - - if (mp->mnt_flag & MNT_UPDATE) { - nmp = VFSTONFS(mp); - printf("%s: MNT_UPDATE is no longer handled here\n", __func__); - free(nam, M_SONAME); - return (0); - } else { - nmp = uma_zalloc(nfsmount_zone, M_WAITOK); - bzero((caddr_t)nmp, sizeof (struct nfsmount)); - TAILQ_INIT(&nmp->nm_bufq); - mp->mnt_data = nmp; - nmp->nm_getinfo = nfs_getnlminfo; - nmp->nm_vinvalbuf = nfs_vinvalbuf; - } - vfs_getnewfsid(mp); - nmp->nm_mountp = mp; - mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF); - - /* - * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too - * high, depending on whether we end up with negative offsets in - * the client or server somewhere. 2GB-1 may be safer. - * - * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum - * that we can handle until we find out otherwise. - */ - if ((argp->flags & NFSMNT_NFSV3) == 0) - nmp->nm_maxfilesize = 0xffffffffLL; - else - nmp->nm_maxfilesize = OFF_MAX; - - nmp->nm_timeo = NFS_TIMEO; - nmp->nm_retry = NFS_RETRANS; - if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) { - nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA; - } else { - nmp->nm_wsize = NFS_WSIZE; - nmp->nm_rsize = NFS_RSIZE; - } - nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000); - nmp->nm_readdirsize = NFS_READDIRSIZE; - nmp->nm_numgrps = NFS_MAXGRPS; - nmp->nm_readahead = NFS_DEFRAHEAD; - nmp->nm_deadthresh = NFS_MAXDEADTHRESH; - nmp->nm_nametimeo = nametimeo; - nmp->nm_negnametimeo = negnametimeo; - nmp->nm_tprintf_delay = nfs_tprintf_delay; - if (nmp->nm_tprintf_delay < 0) - nmp->nm_tprintf_delay = 0; - nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay; - if (nmp->nm_tprintf_initial_delay < 0) - nmp->nm_tprintf_initial_delay = 0; - nmp->nm_fhsize = argp->fhsize; - bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize); - bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN); - nmp->nm_nam = nam; - /* Set up the sockets and per-host congestion */ - nmp->nm_sotype = argp->sotype; - nmp->nm_soproto = argp->proto; - nmp->nm_rpcops = &nfs_rpcops; - - nfs_decode_args(mp, nmp, argp, hst); - - /* - * For Connection based sockets (TCP,...) defer the connect until - * the first request, in case the server is not responding. - */ - if (nmp->nm_sotype == SOCK_DGRAM && - (error = nfs_connect(nmp))) - goto bad; - - /* - * This is silly, but it has to be set so that vinifod() works. - * We do not want to do an nfs_statfs() here since we can get - * stuck on a dead server and we are holding a lock on the mount - * point. - */ - mtx_lock(&nmp->nm_mtx); - mp->mnt_stat.f_iosize = nfs_iosize(nmp); - mtx_unlock(&nmp->nm_mtx); - /* - * A reference count is needed on the nfsnode representing the - * remote root. If this object is not persistent, then backward - * traversals of the mount point (i.e. "..") will not work if - * the nfsnode gets flushed out of the cache. Ufs does not have - * this problem, because one can identify root inodes by their - * number == ROOTINO (2). - */ - error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE); - if (error) - goto bad; - *vpp = NFSTOV(np); - - /* - * Get file attributes and transfer parameters for the - * mountpoint. This has the side effect of filling in - * (*vpp)->v_type with the correct value. - */ - if (argp->flags & NFSMNT_NFSV3) - nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread); - else - VOP_GETATTR(*vpp, &attrs, curthread->td_ucred); - - /* - * Lose the lock but keep the ref. - */ - VOP_UNLOCK(*vpp, 0); - - return (0); -bad: - nfs_disconnect(nmp); - mtx_destroy(&nmp->nm_mtx); - uma_zfree(nfsmount_zone, nmp); - free(nam, M_SONAME); - return (error); -} - -/* - * unmount system call - */ -static int -nfs_unmount(struct mount *mp, int mntflags) -{ - struct nfsmount *nmp; - int error, flags = 0, i; - - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - nmp = VFSTONFS(mp); - /* - * Goes something like this.. - * - Call vflush() to clear out vnodes for this filesystem - * - Close the socket - * - Free up the data structures - */ - /* In the forced case, cancel any outstanding requests. */ - if (flags & FORCECLOSE) { - error = nfs_nmcancelreqs(nmp); - if (error) - goto out; - } - /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */ - error = vflush(mp, 1, flags, curthread); - if (error) - goto out; - - /* - * We are now committed to the unmount. - */ - /* Make sure no nfsiods are assigned to this mount. */ - mtx_lock(&nfs_iod_mtx); - for (i = 0; i < NFS_MAXASYNCDAEMON; i++) - if (nfs_iodmount[i] == nmp) { - nfs_iodwant[i] = NFSIOD_AVAILABLE; - nfs_iodmount[i] = NULL; - } - mtx_unlock(&nfs_iod_mtx); - nfs_disconnect(nmp); - free(nmp->nm_nam, M_SONAME); - - mtx_destroy(&nmp->nm_mtx); - uma_zfree(nfsmount_zone, nmp); -out: - return (error); -} - -/* - * Return root of a filesystem - */ -static int -nfs_root(struct mount *mp, int flags, struct vnode **vpp) -{ - struct vnode *vp; - struct nfsmount *nmp; - struct nfsnode *np; - int error; - - nmp = VFSTONFS(mp); - error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags); - if (error) - return error; - vp = NFSTOV(np); - /* - * Get transfer parameters and attributes for root vnode once. - */ - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 && - (nmp->nm_flag & NFSMNT_NFSV3)) { - mtx_unlock(&nmp->nm_mtx); - nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread); - } else - mtx_unlock(&nmp->nm_mtx); - if (vp->v_type == VNON) - vp->v_type = VDIR; - vp->v_vflag |= VV_ROOT; - *vpp = vp; - return (0); -} - -/* - * Flush out the buffer cache - */ -/* ARGSUSED */ -static int -nfs_sync(struct mount *mp, int waitfor) -{ - struct vnode *vp, *mvp; - struct thread *td; - int error, allerror = 0; - - td = curthread; - - MNT_ILOCK(mp); - /* - * If a forced dismount is in progress, return from here so that - * the umount(2) syscall doesn't get stuck in VFS_SYNC() before - * calling VFS_UNMOUNT(). - */ - if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) { - MNT_IUNLOCK(mp); - return (EBADF); - } - MNT_IUNLOCK(mp); - - /* - * Force stale buffer cache information to be flushed. - */ -loop: - MNT_VNODE_FOREACH_ALL(vp, mp, mvp) { - /* XXX Racy bv_cnt check. */ - if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 || - waitfor == MNT_LAZY) { - VI_UNLOCK(vp); - continue; - } - if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) { - MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); - goto loop; - } - error = VOP_FSYNC(vp, waitfor, td); - if (error) - allerror = error; - VOP_UNLOCK(vp, 0); - vrele(vp); - } - return (allerror); -} - -static int -nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req) -{ - struct nfsmount *nmp = VFSTONFS(mp); - struct vfsquery vq; - int error; - - bzero(&vq, sizeof(vq)); - switch (op) { -#if 0 - case VFS_CTL_NOLOCKS: - val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0; - if (req->oldptr != NULL) { - error = SYSCTL_OUT(req, &val, sizeof(val)); - if (error) - return (error); - } - if (req->newptr != NULL) { - error = SYSCTL_IN(req, &val, sizeof(val)); - if (error) - return (error); - if (val) - nmp->nm_flag |= NFSMNT_NOLOCKS; - else - nmp->nm_flag &= ~NFSMNT_NOLOCKS; - } - break; -#endif - case VFS_CTL_QUERY: - mtx_lock(&nmp->nm_mtx); - if (nmp->nm_state & NFSSTA_TIMEO) - vq.vq_flags |= VQ_NOTRESP; - mtx_unlock(&nmp->nm_mtx); -#if 0 - if (!(nmp->nm_flag & NFSMNT_NOLOCKS) && - (nmp->nm_state & NFSSTA_LOCKTIMEO)) - vq.vq_flags |= VQ_NOTRESPLOCK; -#endif - error = SYSCTL_OUT(req, &vq, sizeof(vq)); - break; - case VFS_CTL_TIMEO: - if (req->oldptr != NULL) { - error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay, - sizeof(nmp->nm_tprintf_initial_delay)); - if (error) - return (error); - } - if (req->newptr != NULL) { - error = vfs_suser(mp, req->td); - if (error) - return (error); - error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay, - sizeof(nmp->nm_tprintf_initial_delay)); - if (error) - return (error); - if (nmp->nm_tprintf_initial_delay < 0) - nmp->nm_tprintf_initial_delay = 0; - } - break; - default: - return (ENOTSUP); - } - return (0); -} - -/* - * Extract the information needed by the nlm from the nfs vnode. - */ -static void -nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp, - struct sockaddr_storage *sp, int *is_v3p, off_t *sizep, - struct timeval *timeop) -{ - struct nfsmount *nmp; - struct nfsnode *np = VTONFS(vp); - - nmp = VFSTONFS(vp->v_mount); - if (fhlenp != NULL) - *fhlenp = (size_t)np->n_fhsize; - if (fhp != NULL) - bcopy(np->n_fhp, fhp, np->n_fhsize); - if (sp != NULL) - bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp))); - if (is_v3p != NULL) - *is_v3p = NFS_ISV3(vp); - if (sizep != NULL) - *sizep = np->n_size; - if (timeop != NULL) { - timeop->tv_sec = nmp->nm_timeo / NFS_HZ; - timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ); - } -} - diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c deleted file mode 100644 index 2516d7db94c..00000000000 --- a/sys/nfsclient/nfs_vnops.c +++ /dev/null @@ -1,3544 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * vnode op calls for Sun NFS version 2 and 3 - */ - -#include "opt_inet.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#ifdef KDTRACE_HOOKS -#include - -dtrace_nfsclient_accesscache_flush_probe_func_t - dtrace_nfsclient_accesscache_flush_done_probe; -uint32_t nfsclient_accesscache_flush_done_id; - -dtrace_nfsclient_accesscache_get_probe_func_t - dtrace_nfsclient_accesscache_get_hit_probe, - dtrace_nfsclient_accesscache_get_miss_probe; -uint32_t nfsclient_accesscache_get_hit_id; -uint32_t nfsclient_accesscache_get_miss_id; - -dtrace_nfsclient_accesscache_load_probe_func_t - dtrace_nfsclient_accesscache_load_done_probe; -uint32_t nfsclient_accesscache_load_done_id; -#endif /* !KDTRACE_HOOKS */ - -/* Defs */ -#define TRUE 1 -#define FALSE 0 - -/* - * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these - * calls are not in getblk() and brelse() so that they would not be necessary - * here. - */ -#ifndef B_VMIO -#define vfs_busy_pages(bp, f) -#endif - -static vop_read_t nfsfifo_read; -static vop_write_t nfsfifo_write; -static vop_close_t nfsfifo_close; -static int nfs_flush(struct vnode *, int, int); -static int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *); -static vop_lookup_t nfs_lookup; -static vop_create_t nfs_create; -static vop_mknod_t nfs_mknod; -static vop_open_t nfs_open; -static vop_close_t nfs_close; -static vop_access_t nfs_access; -static vop_getattr_t nfs_getattr; -static vop_setattr_t nfs_setattr; -static vop_read_t nfs_read; -static vop_fsync_t nfs_fsync; -static vop_remove_t nfs_remove; -static vop_link_t nfs_link; -static vop_rename_t nfs_rename; -static vop_mkdir_t nfs_mkdir; -static vop_rmdir_t nfs_rmdir; -static vop_symlink_t nfs_symlink; -static vop_readdir_t nfs_readdir; -static vop_strategy_t nfs_strategy; -static int nfs_lookitup(struct vnode *, const char *, int, - struct ucred *, struct thread *, struct nfsnode **); -static int nfs_sillyrename(struct vnode *, struct vnode *, - struct componentname *); -static vop_access_t nfsspec_access; -static vop_readlink_t nfs_readlink; -static vop_print_t nfs_print; -static vop_advlock_t nfs_advlock; -static vop_advlockasync_t nfs_advlockasync; - -/* - * Global vfs data structures for nfs - */ -struct vop_vector nfs_vnodeops = { - .vop_default = &default_vnodeops, - .vop_access = nfs_access, - .vop_advlock = nfs_advlock, - .vop_advlockasync = nfs_advlockasync, - .vop_close = nfs_close, - .vop_create = nfs_create, - .vop_fsync = nfs_fsync, - .vop_getattr = nfs_getattr, - .vop_getpages = nfs_getpages, - .vop_putpages = nfs_putpages, - .vop_inactive = nfs_inactive, - .vop_link = nfs_link, - .vop_lookup = nfs_lookup, - .vop_mkdir = nfs_mkdir, - .vop_mknod = nfs_mknod, - .vop_open = nfs_open, - .vop_print = nfs_print, - .vop_read = nfs_read, - .vop_readdir = nfs_readdir, - .vop_readlink = nfs_readlink, - .vop_reclaim = nfs_reclaim, - .vop_remove = nfs_remove, - .vop_rename = nfs_rename, - .vop_rmdir = nfs_rmdir, - .vop_setattr = nfs_setattr, - .vop_strategy = nfs_strategy, - .vop_symlink = nfs_symlink, - .vop_write = nfs_write, -}; - -struct vop_vector nfs_fifoops = { - .vop_default = &fifo_specops, - .vop_access = nfsspec_access, - .vop_close = nfsfifo_close, - .vop_fsync = nfs_fsync, - .vop_getattr = nfs_getattr, - .vop_inactive = nfs_inactive, - .vop_print = nfs_print, - .vop_read = nfsfifo_read, - .vop_reclaim = nfs_reclaim, - .vop_setattr = nfs_setattr, - .vop_write = nfsfifo_write, -}; - -static int nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, - struct componentname *cnp, struct vattr *vap); -static int nfs_removerpc(struct vnode *dvp, const char *name, int namelen, - struct ucred *cred, struct thread *td); -static int nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, - int fnamelen, struct vnode *tdvp, - const char *tnameptr, int tnamelen, - struct ucred *cred, struct thread *td); -static int nfs_renameit(struct vnode *sdvp, struct componentname *scnp, - struct sillyrename *sp); - -/* - * Global variables - */ -struct mtx nfs_iod_mtx; -enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON]; -struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; -int nfs_numasync = 0; -#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) - -SYSCTL_DECL(_vfs_oldnfs); - -static int nfsaccess_cache_timeout = NFS_MAXATTRTIMO; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW, - &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout"); - -static int nfs_prime_access_cache = 0; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, prime_access_cache, CTLFLAG_RW, - &nfs_prime_access_cache, 0, - "Prime NFS ACCESS cache when fetching attributes"); - -static int nfsv3_commit_on_close = 0; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, - &nfsv3_commit_on_close, 0, "write+commit on close, else only write"); - -static int nfs_clean_pages_on_close = 1; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, clean_pages_on_close, CTLFLAG_RW, - &nfs_clean_pages_on_close, 0, "NFS clean dirty pages on close"); - -int nfs_directio_enable = 0; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_directio_enable, CTLFLAG_RW, - &nfs_directio_enable, 0, "Enable NFS directio"); - -/* - * This sysctl allows other processes to mmap a file that has been opened - * O_DIRECT by a process. In general, having processes mmap the file while - * Direct IO is in progress can lead to Data Inconsistencies. But, we allow - * this by default to prevent DoS attacks - to prevent a malicious user from - * opening up files O_DIRECT preventing other users from mmap'ing these - * files. "Protected" environments where stricter consistency guarantees are - * required can disable this knob. The process that opened the file O_DIRECT - * cannot mmap() the file, because mmap'ed IO on an O_DIRECT open() is not - * meaningful. - */ -int nfs_directio_allow_mmap = 1; -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW, - &nfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens"); - -#if 0 -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, access_cache_hits, CTLFLAG_RD, - &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); - -SYSCTL_INT(_vfs_oldnfs, OID_AUTO, access_cache_misses, CTLFLAG_RD, - &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count"); -#endif - -#define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \ - | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \ - | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP) - -/* - * SMP Locking Note : - * The list of locks after the description of the lock is the ordering - * of other locks acquired with the lock held. - * np->n_mtx : Protects the fields in the nfsnode. - VM Object Lock - VI_MTX (acquired indirectly) - * nmp->nm_mtx : Protects the fields in the nfsmount. - rep->r_mtx - * nfs_iod_mtx : Global lock, protects shared nfsiod state. - * nfs_reqq_mtx : Global lock, protects the nfs_reqq list. - nmp->nm_mtx - rep->r_mtx - * rep->r_mtx : Protects the fields in an nfsreq. - */ - -static int -nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td, - struct ucred *cred, uint32_t *retmode) -{ - const int v3 = 1; - u_int32_t *tl; - int error = 0, attrflag, i, lrupos; - - struct mbuf *mreq, *mrep, *md, *mb; - caddr_t bpos, dpos; - u_int32_t rmode; - struct nfsnode *np = VTONFS(vp); - - nfsstats.rpccnt[NFSPROC_ACCESS]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED, M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(wmode); - nfsm_request(vp, NFSPROC_ACCESS, td, cred); - nfsm_postop_attr(vp, attrflag); - if (!error) { - lrupos = 0; - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - rmode = fxdr_unsigned(u_int32_t, *tl); - mtx_lock(&np->n_mtx); - for (i = 0; i < NFS_ACCESSCACHESIZE; i++) { - if (np->n_accesscache[i].uid == cred->cr_uid) { - np->n_accesscache[i].mode = rmode; - np->n_accesscache[i].stamp = time_second; - break; - } - if (i > 0 && np->n_accesscache[i].stamp < - np->n_accesscache[lrupos].stamp) - lrupos = i; - } - if (i == NFS_ACCESSCACHESIZE) { - np->n_accesscache[lrupos].uid = cred->cr_uid; - np->n_accesscache[lrupos].mode = rmode; - np->n_accesscache[lrupos].stamp = time_second; - } - mtx_unlock(&np->n_mtx); - if (retmode != NULL) - *retmode = rmode; - KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, cred->cr_uid, rmode, 0); - } - m_freem(mrep); -nfsmout: -#ifdef KDTRACE_HOOKS - if (error) { - KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, cred->cr_uid, 0, - error); - } -#endif - return (error); -} - -/* - * nfs access vnode op. - * For nfs version 2, just return ok. File accesses may fail later. - * For nfs version 3, use the access rpc to check accessibility. If file modes - * are changed on the server, accesses might still fail later. - */ -static int -nfs_access(struct vop_access_args *ap) -{ - struct vnode *vp = ap->a_vp; - int error = 0, i, gotahit; - u_int32_t mode, rmode, wmode; - int v3 = NFS_ISV3(vp); - struct nfsnode *np = VTONFS(vp); - - /* - * Disallow write attempts on filesystems mounted read-only; - * unless the file is a socket, fifo, or a block or character - * device resident on the filesystem. - */ - if ((ap->a_accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { - switch (vp->v_type) { - case VREG: - case VDIR: - case VLNK: - return (EROFS); - default: - break; - } - } - /* - * For nfs v3, check to see if we have done this recently, and if - * so return our cached result instead of making an ACCESS call. - * If not, do an access rpc, otherwise you are stuck emulating - * ufs_access() locally using the vattr. This may not be correct, - * since the server may apply other access criteria such as - * client uid-->server uid mapping that we do not know about. - */ - if (v3) { - if (ap->a_accmode & VREAD) - mode = NFSV3ACCESS_READ; - else - mode = 0; - if (vp->v_type != VDIR) { - if (ap->a_accmode & VWRITE) - mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); - if (ap->a_accmode & VEXEC) - mode |= NFSV3ACCESS_EXECUTE; - } else { - if (ap->a_accmode & VWRITE) - mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | - NFSV3ACCESS_DELETE); - if (ap->a_accmode & VEXEC) - mode |= NFSV3ACCESS_LOOKUP; - } - /* XXX safety belt, only make blanket request if caching */ - if (nfsaccess_cache_timeout > 0) { - wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | - NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | - NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP; - } else { - wmode = mode; - } - - /* - * Does our cached result allow us to give a definite yes to - * this request? - */ - gotahit = 0; - mtx_lock(&np->n_mtx); - for (i = 0; i < NFS_ACCESSCACHESIZE; i++) { - if (ap->a_cred->cr_uid == np->n_accesscache[i].uid) { - if (time_second < (np->n_accesscache[i].stamp + - nfsaccess_cache_timeout) && - (np->n_accesscache[i].mode & mode) == mode) { - nfsstats.accesscache_hits++; - gotahit = 1; - } - break; - } - } - mtx_unlock(&np->n_mtx); -#ifdef KDTRACE_HOOKS - if (gotahit) - KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp, - ap->a_cred->cr_uid, mode); - else - KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp, - ap->a_cred->cr_uid, mode); -#endif - if (gotahit == 0) { - /* - * Either a no, or a don't know. Go to the wire. - */ - nfsstats.accesscache_misses++; - error = nfs3_access_otw(vp, wmode, ap->a_td, ap->a_cred, - &rmode); - if (!error) { - if ((rmode & mode) != mode) - error = EACCES; - } - } - return (error); - } else { - if ((error = nfsspec_access(ap)) != 0) { - return (error); - } - /* - * Attempt to prevent a mapped root from accessing a file - * which it shouldn't. We try to read a byte from the file - * if the user is root and the file is not zero length. - * After calling nfsspec_access, we should have the correct - * file size cached. - */ - mtx_lock(&np->n_mtx); - if (ap->a_cred->cr_uid == 0 && (ap->a_accmode & VREAD) - && VTONFS(vp)->n_size > 0) { - struct iovec aiov; - struct uio auio; - char buf[1]; - - mtx_unlock(&np->n_mtx); - aiov.iov_base = buf; - aiov.iov_len = 1; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = 0; - auio.uio_resid = 1; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_READ; - auio.uio_td = ap->a_td; - - if (vp->v_type == VREG) - error = nfs_readrpc(vp, &auio, ap->a_cred); - else if (vp->v_type == VDIR) { - char* bp; - bp = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK); - aiov.iov_base = bp; - aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ; - error = nfs_readdirrpc(vp, &auio, ap->a_cred); - free(bp, M_TEMP); - } else if (vp->v_type == VLNK) - error = nfs_readlinkrpc(vp, &auio, ap->a_cred); - else - error = EACCES; - } else - mtx_unlock(&np->n_mtx); - return (error); - } -} - -int nfs_otw_getattr_avoid = 0; - -/* - * nfs open vnode op - * Check to see if the type is ok - * and that deletion is not in progress. - * For paged in text files, you will need to flush the page cache - * if consistency is lost. - */ -/* ARGSUSED */ -static int -nfs_open(struct vop_open_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct vattr vattr; - int error; - int fmode = ap->a_mode; - struct ucred *cred; - - if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK) - return (EOPNOTSUPP); - - /* - * Get a valid lease. If cached data is stale, flush it. - */ - mtx_lock(&np->n_mtx); - if (np->n_flag & NMODIFIED) { - mtx_unlock(&np->n_mtx); - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1); - if (error == EINTR || error == EIO) - return (error); - mtx_lock(&np->n_mtx); - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - if (vp->v_type == VDIR) - np->n_direofoffset = 0; - mtx_unlock(&np->n_mtx); - error = VOP_GETATTR(vp, &vattr, ap->a_cred); - if (error) - return (error); - mtx_lock(&np->n_mtx); - np->n_mtime = vattr.va_mtime; - } else { - mtx_unlock(&np->n_mtx); - error = VOP_GETATTR(vp, &vattr, ap->a_cred); - if (error) - return (error); - mtx_lock(&np->n_mtx); - if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { - if (vp->v_type == VDIR) - np->n_direofoffset = 0; - mtx_unlock(&np->n_mtx); - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1); - if (error == EINTR || error == EIO) { - return (error); - } - mtx_lock(&np->n_mtx); - np->n_mtime = vattr.va_mtime; - } - } - /* - * If the object has >= 1 O_DIRECT active opens, we disable caching. - */ - if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) { - if (np->n_directio_opens == 0) { - mtx_unlock(&np->n_mtx); - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1); - if (error) - return (error); - mtx_lock(&np->n_mtx); - np->n_flag |= NNONCACHE; - } - np->n_directio_opens++; - } - - /* - * If this is an open for writing, capture a reference to the - * credentials, so they can be used by nfs_putpages(). Using - * these write credentials is preferable to the credentials of - * whatever thread happens to be doing the VOP_PUTPAGES() since - * the write RPCs are less likely to fail with EACCES. - */ - if ((fmode & FWRITE) != 0) { - cred = np->n_writecred; - np->n_writecred = crhold(ap->a_cred); - } else - cred = NULL; - mtx_unlock(&np->n_mtx); - if (cred != NULL) - crfree(cred); - vnode_create_vobject(vp, vattr.va_size, ap->a_td); - return (0); -} - -/* - * nfs close vnode op - * What an NFS client should do upon close after writing is a debatable issue. - * Most NFS clients push delayed writes to the server upon close, basically for - * two reasons: - * 1 - So that any write errors may be reported back to the client process - * doing the close system call. By far the two most likely errors are - * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure. - * 2 - To put a worst case upper bound on cache inconsistency between - * multiple clients for the file. - * There is also a consistency problem for Version 2 of the protocol w.r.t. - * not being able to tell if other clients are writing a file concurrently, - * since there is no way of knowing if the changed modify time in the reply - * is only due to the write for this client. - * (NFS Version 3 provides weak cache consistency data in the reply that - * should be sufficient to detect and handle this case.) - * - * The current code does the following: - * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers - * for NFS Version 3 - flush dirty buffers to the server but don't invalidate - * or commit them (this satisfies 1 and 2 except for the - * case where the server crashes after this close but - * before the commit RPC, which is felt to be "good - * enough". Changing the last argument to nfs_flush() to - * a 1 would force a commit operation, if it is felt a - * commit is necessary now. - */ -/* ARGSUSED */ -static int -nfs_close(struct vop_close_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - int error = 0; - int fmode = ap->a_fflag; - - if (vp->v_type == VREG) { - /* - * Examine and clean dirty pages, regardless of NMODIFIED. - * This closes a major hole in close-to-open consistency. - * We want to push out all dirty pages (and buffers) on - * close, regardless of whether they were dirtied by - * mmap'ed writes or via write(). - */ - if (nfs_clean_pages_on_close && vp->v_object) { - VM_OBJECT_WLOCK(vp->v_object); - vm_object_page_clean(vp->v_object, 0, 0, 0); - VM_OBJECT_WUNLOCK(vp->v_object); - } - mtx_lock(&np->n_mtx); - if (np->n_flag & NMODIFIED) { - mtx_unlock(&np->n_mtx); - if (NFS_ISV3(vp)) { - /* - * Under NFSv3 we have dirty buffers to dispose of. We - * must flush them to the NFS server. We have the option - * of waiting all the way through the commit rpc or just - * waiting for the initial write. The default is to only - * wait through the initial write so the data is in the - * server's cache, which is roughly similar to the state - * a standard disk subsystem leaves the file in on close(). - * - * We cannot clear the NMODIFIED bit in np->n_flag due to - * potential races with other processes, and certainly - * cannot clear it if we don't commit. - */ - int cm = nfsv3_commit_on_close ? 1 : 0; - error = nfs_flush(vp, MNT_WAIT, cm); - /* np->n_flag &= ~NMODIFIED; */ - } else - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1); - mtx_lock(&np->n_mtx); - } - if (np->n_flag & NWRITEERR) { - np->n_flag &= ~NWRITEERR; - error = np->n_error; - } - mtx_unlock(&np->n_mtx); - } - if (nfs_directio_enable) - KASSERT((np->n_directio_asyncwr == 0), - ("nfs_close: dirty unflushed (%d) directio buffers\n", - np->n_directio_asyncwr)); - if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) { - mtx_lock(&np->n_mtx); - KASSERT((np->n_directio_opens > 0), - ("nfs_close: unexpectedly value (0) of n_directio_opens\n")); - np->n_directio_opens--; - if (np->n_directio_opens == 0) - np->n_flag &= ~NNONCACHE; - mtx_unlock(&np->n_mtx); - } - return (error); -} - -/* - * nfs getattr call from vfs. - */ -static int -nfs_getattr(struct vop_getattr_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct thread *td = curthread; - struct vattr *vap = ap->a_vap; - struct vattr vattr; - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep, *md, *mb; - int v3 = NFS_ISV3(vp); - - /* - * Update local times for special files. - */ - mtx_lock(&np->n_mtx); - if (np->n_flag & (NACC | NUPD)) - np->n_flag |= NCHG; - mtx_unlock(&np->n_mtx); - /* - * First look in the cache. - */ - if (nfs_getattrcache(vp, &vattr) == 0) - goto nfsmout; - if (v3 && nfs_prime_access_cache && nfsaccess_cache_timeout > 0) { - nfsstats.accesscache_misses++; - nfs3_access_otw(vp, NFSV3ACCESS_ALL, td, ap->a_cred, NULL); - if (nfs_getattrcache(vp, &vattr) == 0) - goto nfsmout; - } - nfsstats.rpccnt[NFSPROC_GETATTR]++; - mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - nfsm_request(vp, NFSPROC_GETATTR, td, ap->a_cred); - if (!error) { - nfsm_loadattr(vp, &vattr); - } - m_freem(mrep); -nfsmout: - vap->va_type = vattr.va_type; - vap->va_mode = vattr.va_mode; - vap->va_nlink = vattr.va_nlink; - vap->va_uid = vattr.va_uid; - vap->va_gid = vattr.va_gid; - vap->va_fsid = vattr.va_fsid; - vap->va_fileid = vattr.va_fileid; - vap->va_size = vattr.va_size; - vap->va_blocksize = vattr.va_blocksize; - vap->va_atime = vattr.va_atime; - vap->va_mtime = vattr.va_mtime; - vap->va_ctime = vattr.va_ctime; - vap->va_gen = vattr.va_gen; - vap->va_flags = vattr.va_flags; - vap->va_rdev = vattr.va_rdev; - vap->va_bytes = vattr.va_bytes; - vap->va_filerev = vattr.va_filerev; - - return (error); -} - -/* - * nfs setattr call. - */ -static int -nfs_setattr(struct vop_setattr_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct vattr *vap = ap->a_vap; - struct thread *td = curthread; - int error = 0; - u_quad_t tsize; - -#ifndef nolint - tsize = (u_quad_t)0; -#endif - - /* - * Setting of flags is not supported. - */ - if (vap->va_flags != VNOVAL) - return (EOPNOTSUPP); - - /* - * Disallow write attempts if the filesystem is mounted read-only. - */ - if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || - vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || - vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && - (vp->v_mount->mnt_flag & MNT_RDONLY)) { - error = EROFS; - goto out; - } - if (vap->va_size != VNOVAL) { - switch (vp->v_type) { - case VDIR: - return (EISDIR); - case VCHR: - case VBLK: - case VSOCK: - case VFIFO: - if (vap->va_mtime.tv_sec == VNOVAL && - vap->va_atime.tv_sec == VNOVAL && - vap->va_mode == (mode_t)VNOVAL && - vap->va_uid == (uid_t)VNOVAL && - vap->va_gid == (gid_t)VNOVAL) - return (0); - vap->va_size = VNOVAL; - break; - default: - /* - * Disallow write attempts if the filesystem is - * mounted read-only. - */ - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - /* - * We run vnode_pager_setsize() early (why?), - * we must set np->n_size now to avoid vinvalbuf - * V_SAVE races that might setsize a lower - * value. - */ - mtx_lock(&np->n_mtx); - tsize = np->n_size; - mtx_unlock(&np->n_mtx); - error = nfs_meta_setsize(vp, ap->a_cred, td, - vap->va_size); - mtx_lock(&np->n_mtx); - if (np->n_flag & NMODIFIED) { - tsize = np->n_size; - mtx_unlock(&np->n_mtx); - if (vap->va_size == 0) - error = nfs_vinvalbuf(vp, 0, td, 1); - else - error = nfs_vinvalbuf(vp, V_SAVE, td, 1); - if (error) { - vnode_pager_setsize(vp, tsize); - goto out; - } - } else - mtx_unlock(&np->n_mtx); - /* - * np->n_size has already been set to vap->va_size - * in nfs_meta_setsize(). We must set it again since - * nfs_loadattrcache() could be called through - * nfs_meta_setsize() and could modify np->n_size. - */ - mtx_lock(&np->n_mtx); - np->n_vattr.va_size = np->n_size = vap->va_size; - mtx_unlock(&np->n_mtx); - }; - } else { - mtx_lock(&np->n_mtx); - if ((vap->va_mtime.tv_sec != VNOVAL || vap->va_atime.tv_sec != VNOVAL) && - (np->n_flag & NMODIFIED) && vp->v_type == VREG) { - mtx_unlock(&np->n_mtx); - if ((error = nfs_vinvalbuf(vp, V_SAVE, td, 1)) != 0 && - (error == EINTR || error == EIO)) - return error; - } else - mtx_unlock(&np->n_mtx); - } - error = nfs_setattrrpc(vp, vap, ap->a_cred); - if (error && vap->va_size != VNOVAL) { - mtx_lock(&np->n_mtx); - np->n_size = np->n_vattr.va_size = tsize; - vnode_pager_setsize(vp, tsize); - mtx_unlock(&np->n_mtx); - } -out: - return (error); -} - -/* - * Do an nfs setattr rpc. - */ -static int -nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred) -{ - struct nfsv2_sattr *sp; - struct nfsnode *np = VTONFS(vp); - caddr_t bpos, dpos; - u_int32_t *tl; - int error = 0, i, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb; - int v3 = NFS_ISV3(vp); - - nfsstats.rpccnt[NFSPROC_SETATTR]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - if (v3) { - nfsm_v3attrbuild(vap, TRUE); - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } else { - sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); - if (vap->va_mode == (mode_t)VNOVAL) - sp->sa_mode = nfs_xdrneg1; - else - sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode); - if (vap->va_uid == (uid_t)VNOVAL) - sp->sa_uid = nfs_xdrneg1; - else - sp->sa_uid = txdr_unsigned(vap->va_uid); - if (vap->va_gid == (gid_t)VNOVAL) - sp->sa_gid = nfs_xdrneg1; - else - sp->sa_gid = txdr_unsigned(vap->va_gid); - sp->sa_size = txdr_unsigned(vap->va_size); - txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); - txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); - } - nfsm_request(vp, NFSPROC_SETATTR, curthread, cred); - if (v3) { - mtx_lock(&np->n_mtx); - for (i = 0; i < NFS_ACCESSCACHESIZE; i++) - np->n_accesscache[i].stamp = 0; - mtx_unlock(&np->n_mtx); - KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp); - nfsm_wcc_data(vp, wccflag); - } else - nfsm_loadattr(vp, NULL); - m_freem(mrep); -nfsmout: - return (error); -} - -/* - * nfs lookup call, one step at a time... - * First look in cache - * If not found, unlock the directory nfsnode and do the rpc - */ -static int -nfs_lookup(struct vop_lookup_args *ap) -{ - struct componentname *cnp = ap->a_cnp; - struct vnode *dvp = ap->a_dvp; - struct vnode **vpp = ap->a_vpp; - struct mount *mp = dvp->v_mount; - struct vattr dvattr, vattr; - struct timespec nctime; - int flags = cnp->cn_flags; - struct vnode *newvp; - struct nfsmount *nmp; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep, *md, *mb; - long len; - nfsfh_t *fhp; - struct nfsnode *np, *newnp; - int error = 0, attrflag, dattrflag, fhsize, ltype, ncticks; - int v3 = NFS_ISV3(dvp); - struct thread *td = cnp->cn_thread; - - *vpp = NULLVP; - if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) && - (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) - return (EROFS); - if (dvp->v_type != VDIR) - return (ENOTDIR); - nmp = VFSTONFS(mp); - np = VTONFS(dvp); - if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) { - *vpp = NULLVP; - return (error); - } - error = cache_lookup(dvp, vpp, cnp, &nctime, &ncticks); - if (error > 0 && error != ENOENT) - return (error); - if (error == -1) { - /* - * Lookups of "." are special and always return the - * current directory. cache_lookup() already handles - * associated locking bookkeeping, etc. - */ - if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') { - /* XXX: Is this really correct? */ - if (cnp->cn_nameiop != LOOKUP && - (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - return (0); - } - - /* - * We only accept a positive hit in the cache if the - * change time of the file matches our cached copy. - * Otherwise, we discard the cache entry and fallback - * to doing a lookup RPC. We also only trust cache - * entries for less than nm_nametimeo seconds. - * - * To better handle stale file handles and attributes, - * clear the attribute cache of this node if it is a - * leaf component, part of an open() call, and not - * locally modified before fetching the attributes. - * This should allow stale file handles to be detected - * here where we can fall back to a LOOKUP RPC to - * recover rather than having nfs_open() detect the - * stale file handle and failing open(2) with ESTALE. - */ - newvp = *vpp; - newnp = VTONFS(newvp); - if (!(nmp->nm_flag & NFSMNT_NOCTO) && - (flags & (ISLASTCN | ISOPEN)) == (ISLASTCN | ISOPEN) && - !(newnp->n_flag & NMODIFIED)) { - mtx_lock(&newnp->n_mtx); - newnp->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp); - mtx_unlock(&newnp->n_mtx); - } - if ((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) && - VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 && - timespeccmp(&vattr.va_ctime, &nctime, ==)) { - nfsstats.lookupcache_hits++; - if (cnp->cn_nameiop != LOOKUP && - (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - return (0); - } - cache_purge(newvp); - if (dvp != newvp) - vput(newvp); - else - vrele(newvp); - *vpp = NULLVP; - } else if (error == ENOENT) { - if (dvp->v_iflag & VI_DOOMED) - return (ENOENT); - /* - * We only accept a negative hit in the cache if the - * modification time of the parent directory matches - * the cached copy in the name cache entry. - * Otherwise, we discard all of the negative cache - * entries for this directory. We also only trust - * negative cache entries for up to nm_negnametimeo - * seconds. - */ - if ((u_int)(ticks - ncticks) < (nmp->nm_negnametimeo * hz) && - VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 && - timespeccmp(&vattr.va_mtime, &nctime, ==)) { - nfsstats.lookupcache_hits++; - return (ENOENT); - } - cache_purge_negative(dvp); - } - - attrflag = dattrflag = 0; - error = 0; - newvp = NULLVP; - nfsstats.lookupcache_misses++; - nfsstats.rpccnt[NFSPROC_LOOKUP]++; - len = cnp->cn_namelen; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len), M_WAITOK, - MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_thread, cnp->cn_cred); - if (error) { - if (v3) { - nfsm_postop_attr_va(dvp, dattrflag, &vattr); - m_freem(mrep); - } - goto nfsmout; - } - nfsm_getfh(fhp, fhsize, v3); - - /* - * Handle RENAME case... - */ - if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) { - if (NFS_CMPFH(np, fhp, fhsize)) { - m_freem(mrep); - return (EISDIR); - } - error = nfs_nget(mp, fhp, fhsize, &np, LK_EXCLUSIVE); - if (error) { - m_freem(mrep); - return (error); - } - newvp = NFSTOV(np); - if (v3) { - nfsm_postop_attr(newvp, attrflag); - nfsm_postop_attr(dvp, attrflag); - } else - nfsm_loadattr(newvp, NULL); - *vpp = newvp; - m_freem(mrep); - cnp->cn_flags |= SAVENAME; - return (0); - } - - if (flags & ISDOTDOT) { - ltype = VOP_ISLOCKED(dvp); - error = vfs_busy(mp, MBF_NOWAIT); - if (error != 0) { - vfs_ref(mp); - VOP_UNLOCK(dvp, 0); - error = vfs_busy(mp, 0); - vn_lock(dvp, ltype | LK_RETRY); - vfs_rel(mp); - if (error == 0 && (dvp->v_iflag & VI_DOOMED)) { - vfs_unbusy(mp); - error = ENOENT; - } - if (error != 0) { - m_freem(mrep); - return (error); - } - } - VOP_UNLOCK(dvp, 0); - error = nfs_nget(mp, fhp, fhsize, &np, cnp->cn_lkflags); - if (error == 0) - newvp = NFSTOV(np); - vfs_unbusy(mp); - if (newvp != dvp) - vn_lock(dvp, ltype | LK_RETRY); - if (dvp->v_iflag & VI_DOOMED) { - if (error == 0) { - if (newvp == dvp) - vrele(newvp); - else - vput(newvp); - } - error = ENOENT; - } - if (error) { - m_freem(mrep); - return (error); - } - } else if (NFS_CMPFH(np, fhp, fhsize)) { - VREF(dvp); - newvp = dvp; - } else { - error = nfs_nget(mp, fhp, fhsize, &np, cnp->cn_lkflags); - if (error) { - m_freem(mrep); - return (error); - } - newvp = NFSTOV(np); - - /* - * Flush the attribute cache when opening a leaf node - * to ensure that fresh attributes are fetched in - * nfs_open() if we are unable to fetch attributes - * from the LOOKUP reply. - */ - if ((flags & (ISLASTCN | ISOPEN)) == (ISLASTCN | ISOPEN) && - !(np->n_flag & NMODIFIED)) { - mtx_lock(&np->n_mtx); - np->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp); - mtx_unlock(&np->n_mtx); - } - } - if (v3) { - nfsm_postop_attr_va(newvp, attrflag, &vattr); - nfsm_postop_attr_va(dvp, dattrflag, &dvattr); - } else { - nfsm_loadattr(newvp, &vattr); - attrflag = 1; - } - if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - if ((cnp->cn_flags & MAKEENTRY) && - (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) && - attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0)) - cache_enter_time(dvp, newvp, cnp, &vattr.va_ctime, - newvp->v_type != VDIR ? NULL : &dvattr.va_ctime); - *vpp = newvp; - m_freem(mrep); -nfsmout: - if (error) { - if (newvp != NULLVP) { - vput(newvp); - *vpp = NULLVP; - } - - if (error != ENOENT) - goto done; - - /* The requested file was not found. */ - if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && - (flags & ISLASTCN)) { - /* - * XXX: UFS does a full VOP_ACCESS(dvp, - * VWRITE) here instead of just checking - * MNT_RDONLY. - */ - if (mp->mnt_flag & MNT_RDONLY) - return (EROFS); - cnp->cn_flags |= SAVENAME; - return (EJUSTRETURN); - } - - if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) { - /* - * Cache the modification time of the parent - * directory from the post-op attributes in - * the name cache entry. The negative cache - * entry will be ignored once the directory - * has changed. Don't bother adding the entry - * if the directory has already changed. - */ - mtx_lock(&np->n_mtx); - if (timespeccmp(&np->n_vattr.va_mtime, - &vattr.va_mtime, ==)) { - mtx_unlock(&np->n_mtx); - cache_enter_time(dvp, NULL, cnp, - &vattr.va_mtime, NULL); - } else - mtx_unlock(&np->n_mtx); - } - return (ENOENT); - } -done: - return (error); -} - -/* - * nfs read call. - * Just call nfs_bioread() to do the work. - */ -static int -nfs_read(struct vop_read_args *ap) -{ - struct vnode *vp = ap->a_vp; - - switch (vp->v_type) { - case VREG: - return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); - case VDIR: - return (EISDIR); - default: - return (EOPNOTSUPP); - } -} - -/* - * nfs readlink call - */ -static int -nfs_readlink(struct vop_readlink_args *ap) -{ - struct vnode *vp = ap->a_vp; - - if (vp->v_type != VLNK) - return (EINVAL); - return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); -} - -/* - * Do a readlink rpc. - * Called by nfs_doio() from below the buffer cache. - */ -int -nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - caddr_t bpos, dpos; - int error = 0, len, attrflag; - struct mbuf *mreq, *mrep, *md, *mb; - int v3 = NFS_ISV3(vp); - - nfsstats.rpccnt[NFSPROC_READLINK]++; - mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, cred); - if (v3) - nfsm_postop_attr(vp, attrflag); - if (!error) { - nfsm_strsiz(len, NFS_MAXPATHLEN); - if (len == NFS_MAXPATHLEN) { - struct nfsnode *np = VTONFS(vp); - mtx_lock(&np->n_mtx); - if (np->n_size && np->n_size < NFS_MAXPATHLEN) - len = np->n_size; - mtx_unlock(&np->n_mtx); - } - nfsm_mtouio(uiop, len); - } - m_freem(mrep); -nfsmout: - return (error); -} - -/* - * nfs read rpc call - * Ditto above - */ -int -nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - u_int32_t *tl; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep, *md, *mb; - struct nfsmount *nmp; - off_t end; - int error = 0, len, retlen, tsiz, eof, attrflag; - int v3 = NFS_ISV3(vp); - int rsize; - -#ifndef nolint - eof = 0; -#endif - nmp = VFSTONFS(vp->v_mount); - tsiz = uiop->uio_resid; - mtx_lock(&nmp->nm_mtx); - end = uiop->uio_offset + tsiz; - if (end > nmp->nm_maxfilesize || end < uiop->uio_offset) { - mtx_unlock(&nmp->nm_mtx); - return (EFBIG); - } - rsize = nmp->nm_rsize; - mtx_unlock(&nmp->nm_mtx); - while (tsiz > 0) { - nfsstats.rpccnt[NFSPROC_READ]++; - len = (tsiz > rsize) ? rsize : tsiz; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED * 3, M_WAITOK, - MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED * 3); - if (v3) { - txdr_hyper(uiop->uio_offset, tl); - *(tl + 2) = txdr_unsigned(len); - } else { - *tl++ = txdr_unsigned(uiop->uio_offset); - *tl++ = txdr_unsigned(len); - *tl = 0; - } - nfsm_request(vp, NFSPROC_READ, uiop->uio_td, cred); - if (v3) { - nfsm_postop_attr(vp, attrflag); - if (error) { - m_freem(mrep); - goto nfsmout; - } - tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED); - eof = fxdr_unsigned(int, *(tl + 1)); - } else { - nfsm_loadattr(vp, NULL); - } - nfsm_strsiz(retlen, rsize); - nfsm_mtouio(uiop, retlen); - m_freem(mrep); - tsiz -= retlen; - if (v3) { - if (eof || retlen == 0) { - tsiz = 0; - } - } else if (retlen < len) { - tsiz = 0; - } - } -nfsmout: - return (error); -} - -/* - * nfs write call - */ -int -nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, - int *iomode, int *must_commit) -{ - u_int32_t *tl; - int32_t backup; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep, *md, *mb; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - off_t end; - int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; - int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC; - int wsize; - - KASSERT(uiop->uio_iovcnt == 1, ("nfs: writerpc iovcnt > 1")); - *must_commit = 0; - tsiz = uiop->uio_resid; - mtx_lock(&nmp->nm_mtx); - end = uiop->uio_offset + tsiz; - if (end > nmp->nm_maxfilesize || end < uiop->uio_offset) { - mtx_unlock(&nmp->nm_mtx); - return (EFBIG); - } - wsize = nmp->nm_wsize; - mtx_unlock(&nmp->nm_mtx); - while (tsiz > 0) { - nfsstats.rpccnt[NFSPROC_WRITE]++; - len = (tsiz > wsize) ? wsize : tsiz; - mreq = m_get2(NFSX_FH(v3) + 5 * NFSX_UNSIGNED, M_WAITOK, - MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - if (v3) { - tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED); - txdr_hyper(uiop->uio_offset, tl); - tl += 2; - *tl++ = txdr_unsigned(len); - *tl++ = txdr_unsigned(*iomode); - *tl = txdr_unsigned(len); - } else { - u_int32_t x; - - tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED); - /* Set both "begin" and "current" to non-garbage. */ - x = txdr_unsigned((u_int32_t)uiop->uio_offset); - *tl++ = x; /* "begin offset" */ - *tl++ = x; /* "current offset" */ - x = txdr_unsigned(len); - *tl++ = x; /* total to this offset */ - *tl = x; /* size of this write */ - } - nfsm_uiotom(uiop, len); - nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, cred); - if (v3) { - wccflag = NFSV3_WCCCHK; - nfsm_wcc_data(vp, wccflag); - if (!error) { - tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED - + NFSX_V3WRITEVERF); - rlen = fxdr_unsigned(int, *tl++); - if (rlen == 0) { - error = NFSERR_IO; - m_freem(mrep); - break; - } else if (rlen < len) { - backup = len - rlen; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base - - backup; - uiop->uio_iov->iov_len += backup; - uiop->uio_offset -= backup; - uiop->uio_resid += backup; - len = rlen; - } - commit = fxdr_unsigned(int, *tl++); - - /* - * Return the lowest committment level - * obtained by any of the RPCs. - */ - if (committed == NFSV3WRITE_FILESYNC) - committed = commit; - else if (committed == NFSV3WRITE_DATASYNC && - commit == NFSV3WRITE_UNSTABLE) - committed = commit; - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){ - bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, - NFSX_V3WRITEVERF); - nmp->nm_state |= NFSSTA_HASWRITEVERF; - } else if (bcmp((caddr_t)tl, - (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) { - *must_commit = 1; - bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, - NFSX_V3WRITEVERF); - } - mtx_unlock(&nmp->nm_mtx); - } - } else { - nfsm_loadattr(vp, NULL); - } - if (wccflag) { - mtx_lock(&(VTONFS(vp))->n_mtx); - VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime; - mtx_unlock(&(VTONFS(vp))->n_mtx); - } - m_freem(mrep); - if (error) - break; - tsiz -= len; - } -nfsmout: - if (DOINGASYNC(vp)) - committed = NFSV3WRITE_FILESYNC; - *iomode = committed; - if (error) - uiop->uio_resid = tsiz; - return (error); -} - -/* - * nfs mknod rpc - * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the - * mode set to specify the file type and the size field for rdev. - */ -static int -nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, - struct vattr *vap) -{ - struct nfsv2_sattr *sp; - u_int32_t *tl; - struct vnode *newvp = NULL; - struct nfsnode *np = NULL; - struct vattr vattr; - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; - struct mbuf *mreq, *mrep, *md, *mb; - u_int32_t rdev; - int v3 = NFS_ISV3(dvp); - - if (vap->va_type == VCHR || vap->va_type == VBLK) - rdev = txdr_unsigned(vap->va_rdev); - else if (vap->va_type == VFIFO || vap->va_type == VSOCK) - rdev = nfs_xdrneg1; - else { - return (EOPNOTSUPP); - } - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) - return (error); - nfsstats.rpccnt[NFSPROC_MKNOD]++; - mreq = m_get2(NFSX_FH(v3) + 4 * NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - if (v3) { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl++ = vtonfsv3_type(vap->va_type); - nfsm_v3attrbuild(vap, FALSE); - if (vap->va_type == VCHR || vap->va_type == VBLK) { - tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(major(vap->va_rdev)); - *tl = txdr_unsigned(minor(vap->va_rdev)); - } - } else { - sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); - sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); - sp->sa_uid = nfs_xdrneg1; - sp->sa_gid = nfs_xdrneg1; - sp->sa_size = rdev; - txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); - txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); - } - nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_thread, cnp->cn_cred); - if (!error) { - nfsm_mtofh(dvp, newvp, v3, gotvp); - if (!gotvp) { - if (newvp) { - vput(newvp); - newvp = NULL; - } - error = nfs_lookitup(dvp, cnp->cn_nameptr, - cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np); - if (!error) - newvp = NFSTOV(np); - } - } - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); -nfsmout: - if (error) { - if (newvp) - vput(newvp); - } else { - *vpp = newvp; - } - mtx_lock(&(VTONFS(dvp))->n_mtx); - VTONFS(dvp)->n_flag |= NMODIFIED; - if (!wccflag) { - VTONFS(dvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); - } - mtx_unlock(&(VTONFS(dvp))->n_mtx); - return (error); -} - -/* - * nfs mknod vop - * just call nfs_mknodrpc() to do the work. - */ -/* ARGSUSED */ -static int -nfs_mknod(struct vop_mknod_args *ap) -{ - return (nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap)); -} - -static u_long create_verf; -/* - * nfs file create call - */ -static int -nfs_create(struct vop_create_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vattr *vap = ap->a_vap; - struct componentname *cnp = ap->a_cnp; - struct nfsv2_sattr *sp; - u_int32_t *tl; - struct nfsnode *np = NULL; - struct vnode *newvp = NULL; - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; - struct mbuf *mreq, *mrep, *md, *mb; - struct vattr vattr; - int v3 = NFS_ISV3(dvp); - - /* - * Oops, not for me.. - */ - if (vap->va_type == VSOCK) { - error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap); - return (error); - } - - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) { - return (error); - } - if (vap->va_vaflags & VA_EXCLUSIVE) - fmode |= O_EXCL; -again: - nfsstats.rpccnt[NFSPROC_CREATE]++; - mreq = m_get2(NFSX_FH(v3) + 2 * NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - if (v3) { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - if (fmode & O_EXCL) { - *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); - tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF); -#ifdef INET - CURVNET_SET(CRED_TO_VNET(cnp->cn_cred)); - IN_IFADDR_RLOCK(); - if (!TAILQ_EMPTY(&V_in_ifaddrhead)) - *tl++ = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr; - else -#endif - *tl++ = create_verf; -#ifdef INET - IN_IFADDR_RUNLOCK(); - CURVNET_RESTORE(); -#endif - *tl = ++create_verf; - } else { - *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); - nfsm_v3attrbuild(vap, FALSE); - } - } else { - sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); - sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); - sp->sa_uid = nfs_xdrneg1; - sp->sa_gid = nfs_xdrneg1; - sp->sa_size = 0; - txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); - txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); - } - nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_thread, cnp->cn_cred); - if (!error) { - nfsm_mtofh(dvp, newvp, v3, gotvp); - if (!gotvp) { - if (newvp) { - vput(newvp); - newvp = NULL; - } - error = nfs_lookitup(dvp, cnp->cn_nameptr, - cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np); - if (!error) - newvp = NFSTOV(np); - } - } - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); -nfsmout: - if (error) { - if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) { - fmode &= ~O_EXCL; - goto again; - } - if (newvp) - vput(newvp); - } else if (v3 && (fmode & O_EXCL)) { - /* - * We are normally called with only a partially initialized - * VAP. Since the NFSv3 spec says that server may use the - * file attributes to store the verifier, the spec requires - * us to do a SETATTR RPC. FreeBSD servers store the verifier - * in atime, but we can't really assume that all servers will - * so we ensure that our SETATTR sets both atime and mtime. - */ - if (vap->va_mtime.tv_sec == VNOVAL) - vfs_timestamp(&vap->va_mtime); - if (vap->va_atime.tv_sec == VNOVAL) - vap->va_atime = vap->va_mtime; - error = nfs_setattrrpc(newvp, vap, cnp->cn_cred); - if (error) - vput(newvp); - } - if (!error) { - *ap->a_vpp = newvp; - } - mtx_lock(&(VTONFS(dvp))->n_mtx); - VTONFS(dvp)->n_flag |= NMODIFIED; - if (!wccflag) { - VTONFS(dvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); - } - mtx_unlock(&(VTONFS(dvp))->n_mtx); - return (error); -} - -/* - * nfs file remove call - * To try and make nfs semantics closer to ufs semantics, a file that has - * other processes using the vnode is renamed instead of removed and then - * removed later on the last close. - * - If v_usecount > 1 - * If a rename is not already in the works - * call nfs_sillyrename() to set it up - * else - * do the remove rpc - */ -static int -nfs_remove(struct vop_remove_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct nfsnode *np = VTONFS(vp); - int error = 0; - struct vattr vattr; - - KASSERT((cnp->cn_flags & HASBUF) != 0, ("nfs_remove: no name")); - KASSERT(vrefcnt(vp) > 0, ("nfs_remove: bad v_usecount")); - if (vp->v_type == VDIR) - error = EPERM; - else if (vrefcnt(vp) == 1 || (np->n_sillyrename && - !VOP_GETATTR(vp, &vattr, cnp->cn_cred) && vattr.va_nlink > 1)) { - /* - * Purge the name cache so that the chance of a lookup for - * the name succeeding while the remove is in progress is - * minimized. Without node locking it can still happen, such - * that an I/O op returns ESTALE, but since you get this if - * another host removes the file.. - */ - cache_purge(vp); - /* - * throw away biocache buffers, mainly to avoid - * unnecessary delayed writes later. - */ - error = nfs_vinvalbuf(vp, 0, cnp->cn_thread, 1); - /* Do the rpc */ - if (error != EINTR && error != EIO) - error = nfs_removerpc(dvp, cnp->cn_nameptr, - cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread); - /* - * Kludge City: If the first reply to the remove rpc is lost.. - * the reply to the retransmitted request will be ENOENT - * since the file was in fact removed - * Therefore, we cheat and return success. - */ - if (error == ENOENT) - error = 0; - } else if (!np->n_sillyrename) - error = nfs_sillyrename(dvp, vp, cnp); - mtx_lock(&np->n_mtx); - np->n_attrstamp = 0; - mtx_unlock(&np->n_mtx); - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - return (error); -} - -/* - * nfs file remove rpc called from nfs_inactive - */ -int -nfs_removeit(struct sillyrename *sp) -{ - /* - * Make sure that the directory vnode is still valid. - * XXX we should lock sp->s_dvp here. - */ - if (sp->s_dvp->v_type == VBAD) - return (0); - return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred, - NULL)); -} - -/* - * Nfs remove rpc, called from nfs_remove() and nfs_removeit(). - */ -static int -nfs_removerpc(struct vnode *dvp, const char *name, int namelen, - struct ucred *cred, struct thread *td) -{ - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb; - int v3 = NFS_ISV3(dvp); - - nfsstats.rpccnt[NFSPROC_REMOVE]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen), - M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(name, namelen, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_REMOVE, td, cred); - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); -nfsmout: - mtx_lock(&(VTONFS(dvp))->n_mtx); - VTONFS(dvp)->n_flag |= NMODIFIED; - if (!wccflag) { - VTONFS(dvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); - } - mtx_unlock(&(VTONFS(dvp))->n_mtx); - return (error); -} - -/* - * nfs file rename call - */ -static int -nfs_rename(struct vop_rename_args *ap) -{ - struct vnode *fvp = ap->a_fvp; - struct vnode *tvp = ap->a_tvp; - struct vnode *fdvp = ap->a_fdvp; - struct vnode *tdvp = ap->a_tdvp; - struct componentname *tcnp = ap->a_tcnp; - struct componentname *fcnp = ap->a_fcnp; - int error; - - KASSERT((tcnp->cn_flags & HASBUF) != 0 && - (fcnp->cn_flags & HASBUF) != 0, ("nfs_rename: no name")); - /* Check for cross-device rename */ - if ((fvp->v_mount != tdvp->v_mount) || - (tvp && (fvp->v_mount != tvp->v_mount))) { - error = EXDEV; - goto out; - } - - if (fvp == tvp) { - nfs_printf("nfs_rename: fvp == tvp (can't happen)\n"); - error = 0; - goto out; - } - if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) - goto out; - - /* - * We have to flush B_DELWRI data prior to renaming - * the file. If we don't, the delayed-write buffers - * can be flushed out later after the file has gone stale - * under NFSV3. NFSV2 does not have this problem because - * ( as far as I can tell ) it flushes dirty buffers more - * often. - * - * Skip the rename operation if the fsync fails, this can happen - * due to the server's volume being full, when we pushed out data - * that was written back to our cache earlier. Not checking for - * this condition can result in potential (silent) data loss. - */ - error = VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_thread); - VOP_UNLOCK(fvp, 0); - if (!error && tvp) - error = VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_thread); - if (error) - goto out; - - /* - * If the tvp exists and is in use, sillyrename it before doing the - * rename of the new file over it. - * XXX Can't sillyrename a directory. - */ - if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename && - tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { - vput(tvp); - tvp = NULL; - } - - error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, - tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, - tcnp->cn_thread); - - if (fvp->v_type == VDIR) { - if (tvp != NULL && tvp->v_type == VDIR) - cache_purge(tdvp); - cache_purge(fdvp); - } - -out: - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - vrele(fdvp); - vrele(fvp); - /* - * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. - */ - if (error == ENOENT) - error = 0; - return (error); -} - -/* - * nfs file rename rpc called from nfs_remove() above - */ -static int -nfs_renameit(struct vnode *sdvp, struct componentname *scnp, - struct sillyrename *sp) -{ - - return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp, - sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread)); -} - -/* - * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit(). - */ -static int -nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, - struct vnode *tdvp, const char *tnameptr, int tnamelen, struct ucred *cred, - struct thread *td) -{ - caddr_t bpos, dpos; - int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb; - int v3 = NFS_ISV3(fdvp); - - nfsstats.rpccnt[NFSPROC_RENAME]++; - mreq = m_get2((NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) + - nfsm_rndup(tnamelen), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(fdvp, v3); - nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); - nfsm_fhtom(tdvp, v3); - nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); - nfsm_request(fdvp, NFSPROC_RENAME, td, cred); - if (v3) { - nfsm_wcc_data(fdvp, fwccflag); - nfsm_wcc_data(tdvp, twccflag); - } - m_freem(mrep); -nfsmout: - mtx_lock(&(VTONFS(fdvp))->n_mtx); - VTONFS(fdvp)->n_flag |= NMODIFIED; - mtx_unlock(&(VTONFS(fdvp))->n_mtx); - mtx_lock(&(VTONFS(tdvp))->n_mtx); - VTONFS(tdvp)->n_flag |= NMODIFIED; - mtx_unlock(&(VTONFS(tdvp))->n_mtx); - if (!fwccflag) { - VTONFS(fdvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(fdvp); - } - if (!twccflag) { - VTONFS(tdvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(tdvp); - } - return (error); -} - -/* - * nfs hard link create call - */ -static int -nfs_link(struct vop_link_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *tdvp = ap->a_tdvp; - struct componentname *cnp = ap->a_cnp; - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; - struct mbuf *mreq, *mrep, *md, *mb; - int v3; - - if (vp->v_mount != tdvp->v_mount) { - return (EXDEV); - } - - /* - * Push all writes to the server, so that the attribute cache - * doesn't get "out of sync" with the server. - * XXX There should be a better way! - */ - VOP_FSYNC(vp, MNT_WAIT, cnp->cn_thread); - - v3 = NFS_ISV3(vp); - nfsstats.rpccnt[NFSPROC_LINK]++; - mreq = m_get2(NFSX_FH(v3)*2 + NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - nfsm_fhtom(tdvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - nfsm_request(vp, NFSPROC_LINK, cnp->cn_thread, cnp->cn_cred); - if (v3) { - nfsm_postop_attr(vp, attrflag); - nfsm_wcc_data(tdvp, wccflag); - } - m_freem(mrep); -nfsmout: - mtx_lock(&(VTONFS(tdvp))->n_mtx); - VTONFS(tdvp)->n_flag |= NMODIFIED; - mtx_unlock(&(VTONFS(tdvp))->n_mtx); - if (!attrflag) { - VTONFS(vp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp); - } - if (!wccflag) { - VTONFS(tdvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(tdvp); - } - return (error); -} - -/* - * nfs symbolic link create call - */ -static int -nfs_symlink(struct vop_symlink_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vattr *vap = ap->a_vap; - struct componentname *cnp = ap->a_cnp; - struct nfsv2_sattr *sp; - caddr_t bpos, dpos; - int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; - struct mbuf *mreq, *mrep, *md, *mb; - struct vnode *newvp = NULL; - int v3 = NFS_ISV3(dvp); - - nfsstats.rpccnt[NFSPROC_SYMLINK]++; - slen = strlen(ap->a_target); - mreq = m_get2(NFSX_FH(v3) + 2*NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3), - M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - if (v3) { - nfsm_v3attrbuild(vap, FALSE); - } - nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); - if (!v3) { - sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); - sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); - sp->sa_uid = nfs_xdrneg1; - sp->sa_gid = nfs_xdrneg1; - sp->sa_size = nfs_xdrneg1; - txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); - txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); - } - - /* - * Issue the NFS request and get the rpc response. - * - * Only NFSv3 responses returning an error of 0 actually return - * a file handle that can be converted into newvp without having - * to do an extra lookup rpc. - */ - nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_thread, cnp->cn_cred); - if (v3) { - if (error == 0) - nfsm_mtofh(dvp, newvp, v3, gotvp); - nfsm_wcc_data(dvp, wccflag); - } - - /* - * out code jumps -> here, mrep is also freed. - */ - - m_freem(mrep); -nfsmout: - - /* - * If we do not have an error and we could not extract the newvp from - * the response due to the request being NFSv2, we have to do a - * lookup in order to obtain a newvp to return. - */ - if (error == 0 && newvp == NULL) { - struct nfsnode *np = NULL; - - error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, - cnp->cn_cred, cnp->cn_thread, &np); - if (!error) - newvp = NFSTOV(np); - } - if (error) { - if (newvp) - vput(newvp); - } else { - *ap->a_vpp = newvp; - } - mtx_lock(&(VTONFS(dvp))->n_mtx); - VTONFS(dvp)->n_flag |= NMODIFIED; - mtx_unlock(&(VTONFS(dvp))->n_mtx); - if (!wccflag) { - VTONFS(dvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); - } - return (error); -} - -/* - * nfs make dir call - */ -static int -nfs_mkdir(struct vop_mkdir_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vattr *vap = ap->a_vap; - struct componentname *cnp = ap->a_cnp; - struct nfsv2_sattr *sp; - int len; - struct nfsnode *np = NULL; - struct vnode *newvp = NULL; - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR; - int gotvp = 0; - struct mbuf *mreq, *mrep, *md, *mb; - struct vattr vattr; - int v3 = NFS_ISV3(dvp); - - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) - return (error); - len = cnp->cn_namelen; - nfsstats.rpccnt[NFSPROC_MKDIR]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) + - NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); - if (v3) { - nfsm_v3attrbuild(vap, FALSE); - } else { - sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR); - sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); - sp->sa_uid = nfs_xdrneg1; - sp->sa_gid = nfs_xdrneg1; - sp->sa_size = nfs_xdrneg1; - txdr_nfsv2time(&vap->va_atime, &sp->sa_atime); - txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime); - } - nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_thread, cnp->cn_cred); - if (!error) - nfsm_mtofh(dvp, newvp, v3, gotvp); - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); -nfsmout: - mtx_lock(&(VTONFS(dvp))->n_mtx); - VTONFS(dvp)->n_flag |= NMODIFIED; - mtx_unlock(&(VTONFS(dvp))->n_mtx); - if (!wccflag) { - VTONFS(dvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); - } - if (error == 0 && newvp == NULL) { - error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, - cnp->cn_thread, &np); - if (!error) { - newvp = NFSTOV(np); - if (newvp->v_type != VDIR) - error = EEXIST; - } - } - if (error) { - if (newvp) - vput(newvp); - } else - *ap->a_vpp = newvp; - return (error); -} - -/* - * nfs remove directory call - */ -static int -nfs_rmdir(struct vop_rmdir_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb; - int v3 = NFS_ISV3(dvp); - - if (dvp == vp) - return (EINVAL); - nfsstats.rpccnt[NFSPROC_RMDIR]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + - nfsm_rndup(cnp->cn_namelen), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_thread, cnp->cn_cred); - if (v3) - nfsm_wcc_data(dvp, wccflag); - m_freem(mrep); -nfsmout: - mtx_lock(&(VTONFS(dvp))->n_mtx); - VTONFS(dvp)->n_flag |= NMODIFIED; - mtx_unlock(&(VTONFS(dvp))->n_mtx); - if (!wccflag) { - VTONFS(dvp)->n_attrstamp = 0; - KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp); - } - cache_purge(dvp); - cache_purge(vp); - /* - * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry. - */ - if (error == ENOENT) - error = 0; - return (error); -} - -/* - * nfs readdir call - */ -static int -nfs_readdir(struct vop_readdir_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct uio *uio = ap->a_uio; - int tresid, error = 0; - struct vattr vattr; - - if (vp->v_type != VDIR) - return(EPERM); - - /* - * First, check for hit on the EOF offset cache - */ - if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && - (np->n_flag & NMODIFIED) == 0) { - if (VOP_GETATTR(vp, &vattr, ap->a_cred) == 0) { - mtx_lock(&np->n_mtx); - if (!NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { - mtx_unlock(&np->n_mtx); - nfsstats.direofcache_hits++; - goto out; - } else - mtx_unlock(&np->n_mtx); - } - } - - /* - * Call nfs_bioread() to do the real work. - */ - tresid = uio->uio_resid; - error = nfs_bioread(vp, uio, 0, ap->a_cred); - - if (!error && uio->uio_resid == tresid) { - nfsstats.direofcache_misses++; - } -out: - return (error); -} - -/* - * Readdir rpc call. - * Called from below the buffer cache by nfs_doio(). - */ -int -nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - int len, left; - struct dirent *dp = NULL; - u_int32_t *tl; - caddr_t cp; - nfsuint64 *cookiep; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep, *md, *mb; - nfsuint64 cookie; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - struct nfsnode *dnp = VTONFS(vp); - u_quad_t fileno; - int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; - int attrflag; - int v3 = NFS_ISV3(vp); - - KASSERT(uiop->uio_iovcnt == 1 && - (uiop->uio_offset & (DIRBLKSIZ - 1)) == 0 && - (uiop->uio_resid & (DIRBLKSIZ - 1)) == 0, - ("nfs readdirrpc bad uio")); - - /* - * If there is no cookie, assume directory was stale. - */ - nfs_dircookie_lock(dnp); - cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); - if (cookiep) { - cookie = *cookiep; - nfs_dircookie_unlock(dnp); - } else { - nfs_dircookie_unlock(dnp); - return (NFSERR_BAD_COOKIE); - } - - /* - * Loop around doing readdir rpc's of size nm_readdirsize - * truncated to a multiple of DIRBLKSIZ. - * The stopping criteria is EOF or buffer full. - */ - while (more_dirs && bigenough) { - nfsstats.rpccnt[NFSPROC_READDIR]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_READDIR(v3), M_WAITOK, - MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - if (v3) { - tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED); - *tl++ = cookie.nfsuquad[0]; - *tl++ = cookie.nfsuquad[1]; - mtx_lock(&dnp->n_mtx); - *tl++ = dnp->n_cookieverf.nfsuquad[0]; - *tl++ = dnp->n_cookieverf.nfsuquad[1]; - mtx_unlock(&dnp->n_mtx); - } else { - tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = cookie.nfsuquad[0]; - } - *tl = txdr_unsigned(nmp->nm_readdirsize); - nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, cred); - if (v3) { - nfsm_postop_attr(vp, attrflag); - if (!error) { - tl = nfsm_dissect(u_int32_t *, - 2 * NFSX_UNSIGNED); - mtx_lock(&dnp->n_mtx); - dnp->n_cookieverf.nfsuquad[0] = *tl++; - dnp->n_cookieverf.nfsuquad[1] = *tl; - mtx_unlock(&dnp->n_mtx); - } else { - m_freem(mrep); - goto nfsmout; - } - } - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - more_dirs = fxdr_unsigned(int, *tl); - - /* loop thru the dir entries, doctoring them to 4bsd form */ - while (more_dirs && bigenough) { - if (v3) { - tl = nfsm_dissect(u_int32_t *, - 3 * NFSX_UNSIGNED); - fileno = fxdr_hyper(tl); - len = fxdr_unsigned(int, *(tl + 2)); - } else { - tl = nfsm_dissect(u_int32_t *, - 2 * NFSX_UNSIGNED); - fileno = fxdr_unsigned(u_quad_t, *tl++); - len = fxdr_unsigned(int, *tl); - } - if (len <= 0 || len > NFS_MAXNAMLEN) { - error = EBADRPC; - m_freem(mrep); - goto nfsmout; - } - tlen = nfsm_rndup(len); - if (tlen == len) - tlen += 4; /* To ensure null termination */ - left = DIRBLKSIZ - blksiz; - if ((tlen + DIRHDSIZ) > left) { - dp->d_reclen += left; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + left; - uiop->uio_iov->iov_len -= left; - uiop->uio_offset += left; - uiop->uio_resid -= left; - blksiz = 0; - } - if ((tlen + DIRHDSIZ) > uiop->uio_resid) - bigenough = 0; - if (bigenough) { - dp = (struct dirent *)uiop->uio_iov->iov_base; - dp->d_fileno = (int)fileno; - dp->d_namlen = len; - dp->d_reclen = tlen + DIRHDSIZ; - dp->d_type = DT_UNKNOWN; - blksiz += dp->d_reclen; - if (blksiz == DIRBLKSIZ) - blksiz = 0; - uiop->uio_offset += DIRHDSIZ; - uiop->uio_resid -= DIRHDSIZ; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + DIRHDSIZ; - uiop->uio_iov->iov_len -= DIRHDSIZ; - nfsm_mtouio(uiop, len); - cp = uiop->uio_iov->iov_base; - tlen -= len; - *cp = '\0'; /* null terminate */ - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + tlen; - uiop->uio_iov->iov_len -= tlen; - uiop->uio_offset += tlen; - uiop->uio_resid -= tlen; - } else - nfsm_adv(nfsm_rndup(len)); - if (v3) { - tl = nfsm_dissect(u_int32_t *, - 3 * NFSX_UNSIGNED); - } else { - tl = nfsm_dissect(u_int32_t *, - 2 * NFSX_UNSIGNED); - } - if (bigenough) { - cookie.nfsuquad[0] = *tl++; - if (v3) - cookie.nfsuquad[1] = *tl++; - } else if (v3) - tl += 2; - else - tl++; - more_dirs = fxdr_unsigned(int, *tl); - } - /* - * If at end of rpc data, get the eof boolean - */ - if (!more_dirs) { - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - more_dirs = (fxdr_unsigned(int, *tl) == 0); - } - m_freem(mrep); - } - /* - * Fill last record, iff any, out to a multiple of DIRBLKSIZ - * by increasing d_reclen for the last record. - */ - if (blksiz > 0) { - left = DIRBLKSIZ - blksiz; - dp->d_reclen += left; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + left; - uiop->uio_iov->iov_len -= left; - uiop->uio_offset += left; - uiop->uio_resid -= left; - } - - /* - * We are now either at the end of the directory or have filled the - * block. - */ - if (bigenough) - dnp->n_direofoffset = uiop->uio_offset; - else { - if (uiop->uio_resid > 0) - nfs_printf("EEK! readdirrpc resid > 0\n"); - nfs_dircookie_lock(dnp); - cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); - *cookiep = cookie; - nfs_dircookie_unlock(dnp); - } -nfsmout: - return (error); -} - -/* - * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc(). - */ -int -nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - int len, left; - struct dirent *dp; - u_int32_t *tl; - caddr_t cp; - struct vnode *newvp; - nfsuint64 *cookiep; - caddr_t bpos, dpos, dpossav1, dpossav2; - struct mbuf *mreq, *mrep, *md, *mb, *mdsav1, *mdsav2; - struct nameidata nami, *ndp = &nami; - struct componentname *cnp = &ndp->ni_cnd; - nfsuint64 cookie; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - struct nfsnode *dnp = VTONFS(vp), *np; - struct vattr vattr, dvattr; - nfsfh_t *fhp; - u_quad_t fileno; - int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i; - int attrflag, dattrflag, fhsize; - -#ifndef nolint - dp = NULL; -#endif - KASSERT(uiop->uio_iovcnt == 1 && - (uiop->uio_offset & (DIRBLKSIZ - 1)) == 0 && - (uiop->uio_resid & (DIRBLKSIZ - 1)) == 0, - ("nfs readdirplusrpc bad uio")); - ndp->ni_dvp = vp; - newvp = NULLVP; - - /* - * If there is no cookie, assume directory was stale. - */ - nfs_dircookie_lock(dnp); - cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0); - if (cookiep) { - cookie = *cookiep; - nfs_dircookie_unlock(dnp); - } else { - nfs_dircookie_unlock(dnp); - return (NFSERR_BAD_COOKIE); - } - /* - * Loop around doing readdir rpc's of size nm_readdirsize - * truncated to a multiple of DIRBLKSIZ. - * The stopping criteria is EOF or buffer full. - */ - while (more_dirs && bigenough) { - nfsstats.rpccnt[NFSPROC_READDIRPLUS]++; - mreq = m_get2(NFSX_FH(1) + 6 * NFSX_UNSIGNED, M_WAITOK, - MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, 1); - tl = nfsm_build(u_int32_t *, 6 * NFSX_UNSIGNED); - *tl++ = cookie.nfsuquad[0]; - *tl++ = cookie.nfsuquad[1]; - mtx_lock(&dnp->n_mtx); - *tl++ = dnp->n_cookieverf.nfsuquad[0]; - *tl++ = dnp->n_cookieverf.nfsuquad[1]; - mtx_unlock(&dnp->n_mtx); - *tl++ = txdr_unsigned(nmp->nm_readdirsize); - *tl = txdr_unsigned(nmp->nm_rsize); - nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, cred); - nfsm_postop_attr_va(vp, dattrflag, &dvattr); - if (error) { - m_freem(mrep); - goto nfsmout; - } - tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED); - mtx_lock(&dnp->n_mtx); - dnp->n_cookieverf.nfsuquad[0] = *tl++; - dnp->n_cookieverf.nfsuquad[1] = *tl++; - mtx_unlock(&dnp->n_mtx); - more_dirs = fxdr_unsigned(int, *tl); - - /* loop thru the dir entries, doctoring them to 4bsd form */ - while (more_dirs && bigenough) { - tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED); - fileno = fxdr_hyper(tl); - len = fxdr_unsigned(int, *(tl + 2)); - if (len <= 0 || len > NFS_MAXNAMLEN) { - error = EBADRPC; - m_freem(mrep); - goto nfsmout; - } - tlen = nfsm_rndup(len); - if (tlen == len) - tlen += 4; /* To ensure null termination*/ - left = DIRBLKSIZ - blksiz; - if ((tlen + DIRHDSIZ) > left) { - dp->d_reclen += left; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + left; - uiop->uio_iov->iov_len -= left; - uiop->uio_offset += left; - uiop->uio_resid -= left; - blksiz = 0; - } - if ((tlen + DIRHDSIZ) > uiop->uio_resid) - bigenough = 0; - if (bigenough) { - dp = (struct dirent *)uiop->uio_iov->iov_base; - dp->d_fileno = (int)fileno; - dp->d_namlen = len; - dp->d_reclen = tlen + DIRHDSIZ; - dp->d_type = DT_UNKNOWN; - blksiz += dp->d_reclen; - if (blksiz == DIRBLKSIZ) - blksiz = 0; - uiop->uio_offset += DIRHDSIZ; - uiop->uio_resid -= DIRHDSIZ; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + DIRHDSIZ; - uiop->uio_iov->iov_len -= DIRHDSIZ; - cnp->cn_nameptr = uiop->uio_iov->iov_base; - cnp->cn_namelen = len; - nfsm_mtouio(uiop, len); - cp = uiop->uio_iov->iov_base; - tlen -= len; - *cp = '\0'; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + tlen; - uiop->uio_iov->iov_len -= tlen; - uiop->uio_offset += tlen; - uiop->uio_resid -= tlen; - } else - nfsm_adv(nfsm_rndup(len)); - tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED); - if (bigenough) { - cookie.nfsuquad[0] = *tl++; - cookie.nfsuquad[1] = *tl++; - } else - tl += 2; - - /* - * Since the attributes are before the file handle - * (sigh), we must skip over the attributes and then - * come back and get them. - */ - attrflag = fxdr_unsigned(int, *tl); - if (attrflag) { - dpossav1 = dpos; - mdsav1 = md; - nfsm_adv(NFSX_V3FATTR); - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - doit = fxdr_unsigned(int, *tl); - /* - * Skip loading the attrs for "..". There's a - * race between loading the attrs here and - * lookups that look for the directory currently - * being read (in the parent). We try to acquire - * the exclusive lock on ".." here, owning the - * lock on the directory being read. Lookup will - * hold the lock on ".." and try to acquire the - * lock on the directory being read. - * - * There are other ways of fixing this, one would - * be to do a trylock on the ".." vnode and skip - * loading the attrs on ".." if it happens to be - * locked by another process. But skipping the - * attrload on ".." seems the easiest option. - */ - if (strcmp(dp->d_name, "..") == 0) { - doit = 0; - /* - * We've already skipped over the attrs, - * skip over the filehandle. And store d_type - * as VDIR. - */ - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - i = fxdr_unsigned(int, *tl); - nfsm_adv(nfsm_rndup(i)); - dp->d_type = IFTODT(VTTOIF(VDIR)); - } - if (doit) { - nfsm_getfh(fhp, fhsize, 1); - if (NFS_CMPFH(dnp, fhp, fhsize)) { - VREF(vp); - newvp = vp; - np = dnp; - } else { - error = nfs_nget(vp->v_mount, fhp, - fhsize, &np, LK_EXCLUSIVE); - if (error) - doit = 0; - else - newvp = NFSTOV(np); - } - } - if (doit && bigenough) { - dpossav2 = dpos; - dpos = dpossav1; - mdsav2 = md; - md = mdsav1; - nfsm_loadattr(newvp, &vattr); - dpos = dpossav2; - md = mdsav2; - dp->d_type = IFTODT(VTTOIF(vattr.va_type)); - ndp->ni_vp = newvp; - if (newvp->v_type != VDIR || dattrflag != 0) - cache_enter_time(ndp->ni_dvp, ndp->ni_vp, - cnp, &vattr.va_ctime, - newvp->v_type != VDIR ? NULL : - &dvattr.va_ctime); - } - } else { - /* Just skip over the file handle */ - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - i = fxdr_unsigned(int, *tl); - if (i) { - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - fhsize = fxdr_unsigned(int, *tl); - nfsm_adv(nfsm_rndup(fhsize)); - } - } - if (newvp != NULLVP) { - if (newvp == vp) - vrele(newvp); - else - vput(newvp); - newvp = NULLVP; - } - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - more_dirs = fxdr_unsigned(int, *tl); - } - /* - * If at end of rpc data, get the eof boolean - */ - if (!more_dirs) { - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - more_dirs = (fxdr_unsigned(int, *tl) == 0); - } - m_freem(mrep); - } - /* - * Fill last record, iff any, out to a multiple of DIRBLKSIZ - * by increasing d_reclen for the last record. - */ - if (blksiz > 0) { - left = DIRBLKSIZ - blksiz; - dp->d_reclen += left; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + left; - uiop->uio_iov->iov_len -= left; - uiop->uio_offset += left; - uiop->uio_resid -= left; - } - - /* - * We are now either at the end of the directory or have filled the - * block. - */ - if (bigenough) - dnp->n_direofoffset = uiop->uio_offset; - else { - if (uiop->uio_resid > 0) - nfs_printf("EEK! readdirplusrpc resid > 0\n"); - nfs_dircookie_lock(dnp); - cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1); - *cookiep = cookie; - nfs_dircookie_unlock(dnp); - } -nfsmout: - if (newvp != NULLVP) { - if (newvp == vp) - vrele(newvp); - else - vput(newvp); - newvp = NULLVP; - } - return (error); -} - -/* - * Silly rename. To make the NFS filesystem that is stateless look a little - * more like the "ufs" a remove of an active vnode is translated to a rename - * to a funny looking filename that is removed by nfs_inactive on the - * nfsnode. There is the potential for another process on a different client - * to create the same funny name between the nfs_lookitup() fails and the - * nfs_rename() completes, but... - */ -static int -nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) -{ - struct sillyrename *sp; - struct nfsnode *np; - int error; - short pid; - unsigned int lticks; - - cache_purge(dvp); - np = VTONFS(vp); - KASSERT(vp->v_type != VDIR, ("nfs: sillyrename dir")); - sp = malloc(sizeof (struct sillyrename), - M_NFSREQ, M_WAITOK); - sp->s_cred = crhold(cnp->cn_cred); - sp->s_dvp = dvp; - sp->s_removeit = nfs_removeit; - VREF(dvp); - - /* - * Fudge together a funny name. - * Changing the format of the funny name to accomodate more - * sillynames per directory. - * The name is now changed to .nfs...4, where ticks is - * CPU ticks since boot. - */ - pid = cnp->cn_thread->td_proc->p_pid; - lticks = (unsigned int)ticks; - for ( ; ; ) { - sp->s_namlen = sprintf(sp->s_name, - ".nfs.%08x.%04x4.4", lticks, - pid); - if (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, - cnp->cn_thread, NULL)) - break; - lticks++; - } - error = nfs_renameit(dvp, cnp, sp); - if (error) - goto bad; - error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, - cnp->cn_thread, &np); - np->n_sillyrename = sp; - return (0); -bad: - vrele(sp->s_dvp); - crfree(sp->s_cred); - free((caddr_t)sp, M_NFSREQ); - return (error); -} - -/* - * Look up a file name and optionally either update the file handle or - * allocate an nfsnode, depending on the value of npp. - * npp == NULL --> just do the lookup - * *npp == NULL --> allocate a new nfsnode and make sure attributes are - * handled too - * *npp != NULL --> update the file handle in the vnode - */ -static int -nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, - struct thread *td, struct nfsnode **npp) -{ - struct vnode *newvp = NULL; - struct nfsnode *np, *dnp = VTONFS(dvp); - caddr_t bpos, dpos; - int error = 0, fhlen, attrflag; - struct mbuf *mreq, *mrep, *md, *mb; - nfsfh_t *nfhp; - int v3 = NFS_ISV3(dvp); - - nfsstats.rpccnt[NFSPROC_LOOKUP]++; - mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len), - M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(dvp, v3); - nfsm_strtom(name, len, NFS_MAXNAMLEN); - nfsm_request(dvp, NFSPROC_LOOKUP, td, cred); - if (npp && !error) { - nfsm_getfh(nfhp, fhlen, v3); - if (*npp) { - np = *npp; - if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { - free((caddr_t)np->n_fhp, M_NFSBIGFH); - np->n_fhp = &np->n_fh; - } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) - np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK); - bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); - np->n_fhsize = fhlen; - newvp = NFSTOV(np); - } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { - VREF(dvp); - newvp = dvp; - } else { - error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE); - if (error) { - m_freem(mrep); - return (error); - } - newvp = NFSTOV(np); - } - if (v3) { - nfsm_postop_attr(newvp, attrflag); - if (!attrflag && *npp == NULL) { - m_freem(mrep); - if (newvp == dvp) - vrele(newvp); - else - vput(newvp); - return (ENOENT); - } - } else - nfsm_loadattr(newvp, NULL); - } - m_freem(mrep); -nfsmout: - if (npp && *npp == NULL) { - if (error) { - if (newvp) { - if (newvp == dvp) - vrele(newvp); - else - vput(newvp); - } - } else - *npp = np; - } - return (error); -} - -/* - * Nfs Version 3 commit rpc - */ -int -nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred, - struct thread *td) -{ - u_int32_t *tl; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - caddr_t bpos, dpos; - int error = 0, wccflag = NFSV3_WCCRATTR; - struct mbuf *mreq, *mrep, *md, *mb; - - mtx_lock(&nmp->nm_mtx); - if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) { - mtx_unlock(&nmp->nm_mtx); - return (0); - } - mtx_unlock(&nmp->nm_mtx); - nfsstats.rpccnt[NFSPROC_COMMIT]++; - mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, 1); - tl = nfsm_build(u_int32_t *, 3 * NFSX_UNSIGNED); - txdr_hyper(offset, tl); - tl += 2; - *tl = txdr_unsigned(cnt); - nfsm_request(vp, NFSPROC_COMMIT, td, cred); - nfsm_wcc_data(vp, wccflag); - if (!error) { - tl = nfsm_dissect(u_int32_t *, NFSX_V3WRITEVERF); - if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl, - NFSX_V3WRITEVERF)) { - bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf, - NFSX_V3WRITEVERF); - error = NFSERR_STALEWRITEVERF; - } - } - m_freem(mrep); -nfsmout: - return (error); -} - -/* - * Strategy routine. - * For async requests when nfsiod(s) are running, queue the request by - * calling nfs_asyncio(), otherwise just all nfs_doio() to do the - * request. - */ -static int -nfs_strategy(struct vop_strategy_args *ap) -{ - struct buf *bp = ap->a_bp; - struct ucred *cr; - - KASSERT(!(bp->b_flags & B_DONE), - ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp)); - BUF_ASSERT_HELD(bp); - - if (bp->b_iocmd == BIO_READ) - cr = bp->b_rcred; - else - cr = bp->b_wcred; - - /* - * If the op is asynchronous and an i/o daemon is waiting - * queue the request, wake it up and wait for completion - * otherwise just do it ourselves. - */ - if ((bp->b_flags & B_ASYNC) == 0 || - nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread)) - (void)nfs_doio(ap->a_vp, bp, cr, curthread); - return (0); -} - -/* - * fsync vnode op. Just call nfs_flush() with commit == 1. - */ -/* ARGSUSED */ -static int -nfs_fsync(struct vop_fsync_args *ap) -{ - - return (nfs_flush(ap->a_vp, ap->a_waitfor, 1)); -} - -/* - * Flush all the blocks associated with a vnode. - * Walk through the buffer pool and push any dirty pages - * associated with the vnode. - */ -static int -nfs_flush(struct vnode *vp, int waitfor, int commit) -{ - struct nfsnode *np = VTONFS(vp); - struct buf *bp; - int i; - struct buf *nbp; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - int error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos; - int passone = 1; - u_quad_t off, endoff, toff; - struct ucred* wcred = NULL; - struct buf **bvec = NULL; - struct bufobj *bo; - struct thread *td = curthread; -#ifndef NFS_COMMITBVECSIZ -#define NFS_COMMITBVECSIZ 20 -#endif - struct buf *bvec_on_stack[NFS_COMMITBVECSIZ]; - int bvecsize = 0, bveccount; - - if (nmp->nm_flag & NFSMNT_INT) - slpflag = PCATCH; - if (!commit) - passone = 0; - bo = &vp->v_bufobj; - /* - * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the - * server, but has not been committed to stable storage on the server - * yet. On the first pass, the byte range is worked out and the commit - * rpc is done. On the second pass, nfs_writebp() is called to do the - * job. - */ -again: - off = (u_quad_t)-1; - endoff = 0; - bvecpos = 0; - if (NFS_ISV3(vp) && commit) { - if (bvec != NULL && bvec != bvec_on_stack) - free(bvec, M_TEMP); - /* - * Count up how many buffers waiting for a commit. - */ - bveccount = 0; - BO_LOCK(bo); - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (!BUF_ISLOCKED(bp) && - (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) - == (B_DELWRI | B_NEEDCOMMIT)) - bveccount++; - } - /* - * Allocate space to remember the list of bufs to commit. It is - * important to use M_NOWAIT here to avoid a race with nfs_write. - * If we can't get memory (for whatever reason), we will end up - * committing the buffers one-by-one in the loop below. - */ - if (bveccount > NFS_COMMITBVECSIZ) { - /* - * Release the vnode interlock to avoid a lock - * order reversal. - */ - BO_UNLOCK(bo); - bvec = (struct buf **) - malloc(bveccount * sizeof(struct buf *), - M_TEMP, M_NOWAIT); - BO_LOCK(bo); - if (bvec == NULL) { - bvec = bvec_on_stack; - bvecsize = NFS_COMMITBVECSIZ; - } else - bvecsize = bveccount; - } else { - bvec = bvec_on_stack; - bvecsize = NFS_COMMITBVECSIZ; - } - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (bvecpos >= bvecsize) - break; - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { - nbp = TAILQ_NEXT(bp, b_bobufs); - continue; - } - if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != - (B_DELWRI | B_NEEDCOMMIT)) { - BUF_UNLOCK(bp); - nbp = TAILQ_NEXT(bp, b_bobufs); - continue; - } - BO_UNLOCK(bo); - bremfree(bp); - /* - * Work out if all buffers are using the same cred - * so we can deal with them all with one commit. - * - * NOTE: we are not clearing B_DONE here, so we have - * to do it later on in this routine if we intend to - * initiate I/O on the bp. - * - * Note: to avoid loopback deadlocks, we do not - * assign b_runningbufspace. - */ - if (wcred == NULL) - wcred = bp->b_wcred; - else if (wcred != bp->b_wcred) - wcred = NOCRED; - vfs_busy_pages(bp, 1); - - BO_LOCK(bo); - /* - * bp is protected by being locked, but nbp is not - * and vfs_busy_pages() may sleep. We have to - * recalculate nbp. - */ - nbp = TAILQ_NEXT(bp, b_bobufs); - - /* - * A list of these buffers is kept so that the - * second loop knows which buffers have actually - * been committed. This is necessary, since there - * may be a race between the commit rpc and new - * uncommitted writes on the file. - */ - bvec[bvecpos++] = bp; - toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + - bp->b_dirtyoff; - if (toff < off) - off = toff; - toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff); - if (toff > endoff) - endoff = toff; - } - BO_UNLOCK(bo); - } - if (bvecpos > 0) { - /* - * Commit data on the server, as required. - * If all bufs are using the same wcred, then use that with - * one call for all of them, otherwise commit each one - * separately. - */ - if (wcred != NOCRED) - retv = nfs_commit(vp, off, (int)(endoff - off), - wcred, td); - else { - retv = 0; - for (i = 0; i < bvecpos; i++) { - off_t off, size; - bp = bvec[i]; - off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + - bp->b_dirtyoff; - size = (u_quad_t)(bp->b_dirtyend - - bp->b_dirtyoff); - retv = nfs_commit(vp, off, (int)size, - bp->b_wcred, td); - if (retv) break; - } - } - - if (retv == NFSERR_STALEWRITEVERF) - nfs_clearcommit(vp->v_mount); - - /* - * Now, either mark the blocks I/O done or mark the - * blocks dirty, depending on whether the commit - * succeeded. - */ - for (i = 0; i < bvecpos; i++) { - bp = bvec[i]; - bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); - if (retv) { - /* - * Error, leave B_DELWRI intact - */ - vfs_unbusy_pages(bp); - brelse(bp); - } else { - /* - * Success, remove B_DELWRI ( bundirty() ). - * - * b_dirtyoff/b_dirtyend seem to be NFS - * specific. We should probably move that - * into bundirty(). XXX - */ - bufobj_wref(bo); - bp->b_flags |= B_ASYNC; - bundirty(bp); - bp->b_flags &= ~B_DONE; - bp->b_ioflags &= ~BIO_ERROR; - bp->b_dirtyoff = bp->b_dirtyend = 0; - bufdone(bp); - } - } - } - - /* - * Start/do any write(s) that are required. - */ -loop: - BO_LOCK(bo); - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { - if (waitfor != MNT_WAIT || passone) - continue; - - error = BUF_TIMELOCK(bp, - LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, - BO_LOCKPTR(bo), "nfsfsync", slpflag, slptimeo); - if (error == 0) { - BUF_UNLOCK(bp); - goto loop; - } - if (error == ENOLCK) { - error = 0; - goto loop; - } - if (nfs_sigintr(nmp, td)) { - error = EINTR; - goto done; - } - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - goto loop; - } - if ((bp->b_flags & B_DELWRI) == 0) - panic("nfs_fsync: not dirty"); - if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) { - BUF_UNLOCK(bp); - continue; - } - BO_UNLOCK(bo); - bremfree(bp); - if (passone || !commit) - bp->b_flags |= B_ASYNC; - else - bp->b_flags |= B_ASYNC; - bwrite(bp); - if (nfs_sigintr(nmp, td)) { - error = EINTR; - goto done; - } - goto loop; - } - if (passone) { - passone = 0; - BO_UNLOCK(bo); - goto again; - } - if (waitfor == MNT_WAIT) { - while (bo->bo_numoutput) { - error = bufobj_wwait(bo, slpflag, slptimeo); - if (error) { - BO_UNLOCK(bo); - error = nfs_sigintr(nmp, td); - if (error) - goto done; - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - BO_LOCK(bo); - } - } - if (bo->bo_dirty.bv_cnt != 0 && commit) { - BO_UNLOCK(bo); - goto loop; - } - /* - * Wait for all the async IO requests to drain - */ - BO_UNLOCK(bo); - mtx_lock(&np->n_mtx); - while (np->n_directio_asyncwr > 0) { - np->n_flag |= NFSYNCWAIT; - error = nfs_msleep(td, (caddr_t)&np->n_directio_asyncwr, - &np->n_mtx, slpflag | (PRIBIO + 1), - "nfsfsync", 0); - if (error) { - if (nfs_sigintr(nmp, td)) { - mtx_unlock(&np->n_mtx); - error = EINTR; - goto done; - } - } - } - mtx_unlock(&np->n_mtx); - } else - BO_UNLOCK(bo); - mtx_lock(&np->n_mtx); - if (np->n_flag & NWRITEERR) { - error = np->n_error; - np->n_flag &= ~NWRITEERR; - } - if (commit && bo->bo_dirty.bv_cnt == 0 && - bo->bo_numoutput == 0 && np->n_directio_asyncwr == 0) - np->n_flag &= ~NMODIFIED; - mtx_unlock(&np->n_mtx); -done: - if (bvec != NULL && bvec != bvec_on_stack) - free(bvec, M_TEMP); - return (error); -} - -/* - * NFS advisory byte-level locks. - */ -static int -nfs_advlock(struct vop_advlock_args *ap) -{ - struct vnode *vp = ap->a_vp; - u_quad_t size; - int error; - - error = vn_lock(vp, LK_SHARED); - if (error) - return (error); - if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { - size = VTONFS(vp)->n_size; - VOP_UNLOCK(vp, 0); - error = lf_advlock(ap, &(vp->v_lockf), size); - } else { - if (nfs_advlock_p) - error = nfs_advlock_p(ap); - else - error = ENOLCK; - } - - return (error); -} - -/* - * NFS advisory byte-level locks. - */ -static int -nfs_advlockasync(struct vop_advlockasync_args *ap) -{ - struct vnode *vp = ap->a_vp; - u_quad_t size; - int error; - - error = vn_lock(vp, LK_SHARED); - if (error) - return (error); - if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { - size = VTONFS(vp)->n_size; - VOP_UNLOCK(vp, 0); - error = lf_advlockasync(ap, &(vp->v_lockf), size); - } else { - VOP_UNLOCK(vp, 0); - error = EOPNOTSUPP; - } - return (error); -} - -/* - * Print out the contents of an nfsnode. - */ -static int -nfs_print(struct vop_print_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - - nfs_printf("\tfileid %ld fsid 0x%x", - np->n_vattr.va_fileid, np->n_vattr.va_fsid); - if (vp->v_type == VFIFO) - fifo_printinfo(vp); - printf("\n"); - return (0); -} - -/* - * This is the "real" nfs::bwrite(struct buf*). - * We set B_CACHE if this is a VMIO buffer. - */ -int -nfs_writebp(struct buf *bp, int force __unused, struct thread *td) -{ - int s; - int oldflags = bp->b_flags; -#if 0 - int retv = 1; - off_t off; -#endif - - BUF_ASSERT_HELD(bp); - - if (bp->b_flags & B_INVAL) { - brelse(bp); - return(0); - } - - bp->b_flags |= B_CACHE; - - /* - * Undirty the bp. We will redirty it later if the I/O fails. - */ - - s = splbio(); - bundirty(bp); - bp->b_flags &= ~B_DONE; - bp->b_ioflags &= ~BIO_ERROR; - bp->b_iocmd = BIO_WRITE; - - bufobj_wref(bp->b_bufobj); - curthread->td_ru.ru_oublock++; - splx(s); - - /* - * Note: to avoid loopback deadlocks, we do not - * assign b_runningbufspace. - */ - vfs_busy_pages(bp, 1); - - BUF_KERNPROC(bp); - bp->b_iooffset = dbtob(bp->b_blkno); - bstrategy(bp); - - if( (oldflags & B_ASYNC) == 0) { - int rtval = bufwait(bp); - - if (oldflags & B_DELWRI) { - s = splbio(); - reassignbuf(bp); - splx(s); - } - brelse(bp); - return (rtval); - } - - return (0); -} - -/* - * nfs special file access vnode op. - * Essentially just get vattr and then imitate iaccess() since the device is - * local to the client. - */ -static int -nfsspec_access(struct vop_access_args *ap) -{ - struct vattr *vap; - struct ucred *cred = ap->a_cred; - struct vnode *vp = ap->a_vp; - accmode_t accmode = ap->a_accmode; - struct vattr vattr; - int error; - - /* - * Disallow write attempts on filesystems mounted read-only; - * unless the file is a socket, fifo, or a block or character - * device resident on the filesystem. - */ - if ((accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { - switch (vp->v_type) { - case VREG: - case VDIR: - case VLNK: - return (EROFS); - default: - break; - } - } - vap = &vattr; - error = VOP_GETATTR(vp, vap, cred); - if (error) - goto out; - error = vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid, - accmode, cred, NULL); -out: - return error; -} - -/* - * Read wrapper for fifos. - */ -static int -nfsfifo_read(struct vop_read_args *ap) -{ - struct nfsnode *np = VTONFS(ap->a_vp); - int error; - - /* - * Set access flag. - */ - mtx_lock(&np->n_mtx); - np->n_flag |= NACC; - vfs_timestamp(&np->n_atim); - mtx_unlock(&np->n_mtx); - error = fifo_specops.vop_read(ap); - return error; -} - -/* - * Write wrapper for fifos. - */ -static int -nfsfifo_write(struct vop_write_args *ap) -{ - struct nfsnode *np = VTONFS(ap->a_vp); - - /* - * Set update flag. - */ - mtx_lock(&np->n_mtx); - np->n_flag |= NUPD; - vfs_timestamp(&np->n_mtim); - mtx_unlock(&np->n_mtx); - return(fifo_specops.vop_write(ap)); -} - -/* - * Close wrapper for fifos. - * - * Update the times on the nfsnode then do fifo close. - */ -static int -nfsfifo_close(struct vop_close_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct vattr vattr; - struct timespec ts; - - mtx_lock(&np->n_mtx); - if (np->n_flag & (NACC | NUPD)) { - vfs_timestamp(&ts); - if (np->n_flag & NACC) - np->n_atim = ts; - if (np->n_flag & NUPD) - np->n_mtim = ts; - np->n_flag |= NCHG; - if (vrefcnt(vp) == 1 && - (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { - VATTR_NULL(&vattr); - if (np->n_flag & NACC) - vattr.va_atime = np->n_atim; - if (np->n_flag & NUPD) - vattr.va_mtime = np->n_mtim; - mtx_unlock(&np->n_mtx); - (void)VOP_SETATTR(vp, &vattr, ap->a_cred); - goto out; - } - } - mtx_unlock(&np->n_mtx); -out: - return (fifo_specops.vop_close(ap)); -} - -/* - * Just call nfs_writebp() with the force argument set to 1. - * - * NOTE: B_DONE may or may not be set in a_bp on call. - */ -static int -nfs_bwrite(struct buf *bp) -{ - - return (nfs_writebp(bp, 1, curthread)); -} - -struct buf_ops buf_ops_nfs = { - .bop_name = "buf_ops_nfs", - .bop_write = nfs_bwrite, - .bop_strategy = bufstrategy, - .bop_sync = bufsync, - .bop_bdflush = bufbdflush, -}; diff --git a/sys/nfsserver/nfs_fha_old.c b/sys/nfsserver/nfs_fha_old.c deleted file mode 100644 index a9282785fef..00000000000 --- a/sys/nfsserver/nfs_fha_old.c +++ /dev/null @@ -1,265 +0,0 @@ -/*- - * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ - * Copyright (c) 2013 Spectra Logic Corporation - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static void fhaold_init(void *foo); -static void fhaold_uninit(void *foo); -rpcproc_t fhaold_get_procnum(rpcproc_t procnum); -int fhaold_realign(struct mbuf **mb, int malloc_flags); -int fhaold_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos); -int fhaold_is_read(rpcproc_t procnum); -int fhaold_is_write(rpcproc_t procnum); -int fhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3, - struct fha_info *info); -int fhaold_no_offset(rpcproc_t procnum); -void fhaold_set_locktype(rpcproc_t procnum, struct fha_info *info); -static int fheold_stats_sysctl(SYSCTL_HANDLER_ARGS); - -static struct fha_params fhaold_softc; - -SYSCTL_DECL(_vfs_nfsrv); - -extern SVCPOOL *nfsrv_pool; - -SYSINIT(nfs_fhaold, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhaold_init, NULL); -SYSUNINIT(nfs_fhaold, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhaold_uninit, NULL); - -static void -fhaold_init(void *foo) -{ - struct fha_params *softc; - - softc = &fhaold_softc; - - bzero(softc, sizeof(*softc)); - - /* - * Setup the callbacks for this FHA personality. - */ - softc->callbacks.get_procnum = fhaold_get_procnum; - softc->callbacks.realign = fhaold_realign; - softc->callbacks.get_fh = fhaold_get_fh; - softc->callbacks.is_read = fhaold_is_read; - softc->callbacks.is_write = fhaold_is_write; - softc->callbacks.get_offset = fhaold_get_offset; - softc->callbacks.no_offset = fhaold_no_offset; - softc->callbacks.set_locktype = fhaold_set_locktype; - softc->callbacks.fhe_stats_sysctl = fheold_stats_sysctl; - - snprintf(softc->server_name, sizeof(softc->server_name), - FHAOLD_SERVER_NAME); - - softc->pool = &nfsrv_pool; - - /* - * Initialize the sysctl context list for the fha module. - */ - sysctl_ctx_init(&softc->sysctl_ctx); - softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, - SYSCTL_STATIC_CHILDREN(_vfs_nfsrv), OID_AUTO, "fha", CTLFLAG_RD, - 0, "fha node"); - if (softc->sysctl_tree == NULL) { - printf("%s: unable to allocate sysctl tree\n", __func__); - return; - } - fha_init(softc); -} - -static void -fhaold_uninit(void *foo) -{ - struct fha_params *softc; - - softc = &fhaold_softc; - - fha_uninit(softc); -} - - -rpcproc_t -fhaold_get_procnum(rpcproc_t procnum) -{ - if (procnum > NFSV2PROC_STATFS) - return (-1); - - return (nfsrv_nfsv3_procid[procnum]); -} - -int -fhaold_realign(struct mbuf **mb, int malloc_flags) -{ - return (nfs_realign(mb, malloc_flags)); -} - -int -fhaold_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - uint8_t *buf; - uint64_t t; - int fhlen, i; - - if (v3) { - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - fhlen = fxdr_unsigned(int, *tl); - if (fhlen != 0 && fhlen != NFSX_V3FH) - return EBADRPC; - } else { - fhlen = NFSX_V2FH; - } - t = 0; - if (fhlen != 0) { - buf = nfsm_dissect_xx_nonblock(fhlen, md, dpos); - if (buf == NULL) - return EBADRPC; - for (i = 0; i < fhlen; i++) - t ^= ((uint64_t)buf[i] << (i & 7) * 8); - } - *fh = t; - return 0; -} - -int -fhaold_is_read(rpcproc_t procnum) -{ - if (procnum == NFSPROC_READ) - return (1); - else - return (0); -} - -int -fhaold_is_write(rpcproc_t procnum) -{ - if (procnum == NFSPROC_WRITE) - return (1); - else - return (0); -} - -int -fhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3, - struct fha_info *info) -{ - uint32_t *tl; - - if (v3) { - tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - goto out; - info->offset = fxdr_hyper(tl); - } else { - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - goto out; - info->offset = fxdr_unsigned(uint32_t, *tl); - } - - return (0); -out: - return (-1); -} - -int -fhaold_no_offset(rpcproc_t procnum) -{ - if (procnum == NFSPROC_FSSTAT || - procnum == NFSPROC_FSINFO || - procnum == NFSPROC_PATHCONF || - procnum == NFSPROC_NOOP || - procnum == NFSPROC_NULL) - return (1); - else - return (0); -} - -void -fhaold_set_locktype(rpcproc_t procnum, struct fha_info *info) -{ - switch (procnum) { - case NFSPROC_NULL: - case NFSPROC_GETATTR: - case NFSPROC_LOOKUP: - case NFSPROC_ACCESS: - case NFSPROC_READLINK: - case NFSPROC_READ: - case NFSPROC_READDIR: - case NFSPROC_READDIRPLUS: - case NFSPROC_WRITE: - info->locktype = LK_SHARED; - break; - case NFSPROC_SETATTR: - case NFSPROC_CREATE: - case NFSPROC_MKDIR: - case NFSPROC_SYMLINK: - case NFSPROC_MKNOD: - case NFSPROC_REMOVE: - case NFSPROC_RMDIR: - case NFSPROC_RENAME: - case NFSPROC_LINK: - case NFSPROC_FSSTAT: - case NFSPROC_FSINFO: - case NFSPROC_PATHCONF: - case NFSPROC_COMMIT: - case NFSPROC_NOOP: - info->locktype = LK_EXCLUSIVE; - break; - } -} - -static int -fheold_stats_sysctl(SYSCTL_HANDLER_ARGS) -{ - return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhaold_softc)); -} - -SVCTHREAD * -fhaold_assign(SVCTHREAD *this_thread, struct svc_req *req) -{ - return (fha_assign(this_thread, req, &fhaold_softc)); -} diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c deleted file mode 100644 index 32fd3f59029..00000000000 --- a/sys/nfsserver/nfs_serv.c +++ /dev/null @@ -1,3767 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * nfs version 2 and 3 server calls to vnode ops - * - these routines generally have 3 phases - * 1 - break down and validate rpc request in mbuf list - * 2 - do the vnode ops for the request - * (surprisingly ?? many are very similar to syscalls in vfs_syscalls.c) - * 3 - build the rpc reply in an mbuf list - * nb: - * - do not mix the phases, since the nfsm_?? macros can return failures - * on a bad rpc or similar and do not do any vrele() or vput()'s - * - * - the nfsm_reply() macro generates an nfs rpc reply with the nfs - * error number iff error != 0 whereas - * returning an error from the server function implies a fatal error - * such as a badly constructed rpc request that should be dropped without - * a reply. - * For nfsm_reply(), the case where error == EBADRPC is treated - * specially; after constructing a reply, it does an immediate - * `goto nfsmout' to avoid getting any V3 post-op status appended. - * - * Other notes: - * Warning: always pay careful attention to resource cleanup on return - * and note that nfsm_*() macros can terminate a procedure on certain - * errors. - * - * lookup() and namei() - * may return garbage in various structural fields/return elements - * if an error is returned, and may garbage up nd.ni_dvp even if no - * error is returned and you did not request LOCKPARENT or WANTPARENT. - * - * We use the ni_cnd.cn_flags 'HASBUF' flag to track whether the name - * buffer has been freed or not. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -FEATURE(nfsserver, "NFS server"); - -#ifdef NFSRV_DEBUG -#define nfsdbprintf(info) printf info -#else -#define nfsdbprintf(info) -#endif - -#define MAX_COMMIT_COUNT (1024 * 1024) - -#define MAX_REORDERED_RPC 16 -#define NUM_HEURISTIC 1031 -#define NHUSE_INIT 64 -#define NHUSE_INC 16 -#define NHUSE_MAX 2048 - -static struct nfsheur { - struct vnode *nh_vp; /* vp to match (unreferenced pointer) */ - off_t nh_nextoff; /* next offset for sequential detection */ - int nh_use; /* use count for selection */ - int nh_seqcount; /* heuristic */ -} nfsheur[NUM_HEURISTIC]; - -/* Global vars */ - -int nfsrvw_procrastinate = NFS_GATHERDELAY * 1000; -int nfsrvw_procrastinate_v3 = 0; - -static struct timeval nfsver = { 0 }; - -SYSCTL_NODE(_vfs, OID_AUTO, nfsrv, CTLFLAG_RW, 0, "NFS server"); - -static int nfs_async; -static int nfs_commit_blks; -static int nfs_commit_miss; -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, async, CTLFLAG_RW, &nfs_async, 0, - "Tell client that writes were synced even though they were not"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks, 0, - "Number of completed commits"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, 0, ""); - -struct nfsrvstats nfsrvstats; -SYSCTL_STRUCT(_vfs_nfsrv, NFS_NFSRVSTATS, nfsrvstats, CTLFLAG_RW, - &nfsrvstats, nfsrvstats, "S,nfsrvstats"); - -static int nfsrv_access(struct vnode *, accmode_t, struct ucred *, - int, int); - -/* - * Clear nameidata fields that are tested in nsfmout cleanup code prior - * to using first nfsm macro (that might jump to the cleanup code). - */ - -static __inline void -ndclear(struct nameidata *nd) -{ - - nd->ni_cnd.cn_flags = 0; - nd->ni_vp = NULL; - nd->ni_dvp = NULL; - nd->ni_startdir = NULL; - nd->ni_strictrelative = 0; -} - -/* - * Heuristic to detect sequential operation. - */ -static struct nfsheur * -nfsrv_sequential_heuristic(struct uio *uio, struct vnode *vp) -{ - struct nfsheur *nh; - int hi, try; - - /* Locate best candidate. */ - try = 32; - hi = ((int)(vm_offset_t)vp / sizeof(struct vnode)) % NUM_HEURISTIC; - nh = &nfsheur[hi]; - while (try--) { - if (nfsheur[hi].nh_vp == vp) { - nh = &nfsheur[hi]; - break; - } - if (nfsheur[hi].nh_use > 0) - --nfsheur[hi].nh_use; - hi = (hi + 1) % NUM_HEURISTIC; - if (nfsheur[hi].nh_use < nh->nh_use) - nh = &nfsheur[hi]; - } - - /* Initialize hint if this is a new file. */ - if (nh->nh_vp != vp) { - nh->nh_vp = vp; - nh->nh_nextoff = uio->uio_offset; - nh->nh_use = NHUSE_INIT; - if (uio->uio_offset == 0) - nh->nh_seqcount = 4; - else - nh->nh_seqcount = 1; - } - - /* Calculate heuristic. */ - if ((uio->uio_offset == 0 && nh->nh_seqcount > 0) || - uio->uio_offset == nh->nh_nextoff) { - /* See comments in vfs_vnops.c:sequential_heuristic(). */ - nh->nh_seqcount += howmany(uio->uio_resid, 16384); - if (nh->nh_seqcount > IO_SEQMAX) - nh->nh_seqcount = IO_SEQMAX; - } else if (qabs(uio->uio_offset - nh->nh_nextoff) <= MAX_REORDERED_RPC * - imax(vp->v_mount->mnt_stat.f_iosize, uio->uio_resid)) { - /* Probably a reordered RPC, leave seqcount alone. */ - } else if (nh->nh_seqcount > 1) { - nh->nh_seqcount /= 2; - } else { - nh->nh_seqcount = 0; - } - nh->nh_use += NHUSE_INC; - if (nh->nh_use > NHUSE_MAX) - nh->nh_use = NHUSE_MAX; - return (nh); -} - -/* - * nfs v3 access service - */ -int -nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct vnode *vp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - u_int32_t *tl; - caddr_t bpos; - int error = 0, rdonly, getret; - struct mbuf *mb, *mreq; - struct vattr vattr, *vap = &vattr; - u_long testmode, nfsmode; - int v3 = (nfsd->nd_flag & ND_NFSV3); - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (!v3) - panic("nfsrv3_access: v3 proc called on a v2 connection"); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(1, NULL); - error = 0; - goto nfsmout; - } - nfsmode = fxdr_unsigned(u_int32_t, *tl); - if ((nfsmode & NFSV3ACCESS_READ) && - nfsrv_access(vp, VREAD, cred, rdonly, 0)) - nfsmode &= ~NFSV3ACCESS_READ; - if (vp->v_type == VDIR) - testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | - NFSV3ACCESS_DELETE); - else - testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); - if ((nfsmode & testmode) && - nfsrv_access(vp, VWRITE, cred, rdonly, 0)) - nfsmode &= ~testmode; - if (vp->v_type == VDIR) - testmode = NFSV3ACCESS_LOOKUP; - else - testmode = NFSV3ACCESS_EXECUTE; - if ((nfsmode & testmode) && - nfsrv_access(vp, VEXEC, cred, rdonly, 0)) - nfsmode &= ~testmode; - getret = VOP_GETATTR(vp, vap, cred); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, vap); - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(nfsmode); -nfsmout: - if (vp) - vput(vp); - return(error); -} - -/* - * nfs getattr service - */ -int -nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nfs_fattr *fp; - struct vattr va; - struct vattr *vap = &va; - struct vnode *vp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - caddr_t bpos; - int error = 0, rdonly; - struct mbuf *mb, *mreq; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(0); - error = 0; - goto nfsmout; - } - error = VOP_GETATTR(vp, vap, cred); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)); - if (error) { - error = 0; - goto nfsmout; - } - fp = nfsm_build(struct nfs_fattr *, - NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)); - nfsm_srvfillattr(vap, fp); - /* fall through */ - -nfsmout: - if (vp) - vput(vp); - return(error); -} - -/* - * nfs setattr service - */ -int -nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct vattr va, preat; - struct vattr *vap = &va; - struct nfsv2_sattr *sp; - struct nfs_fattr *fp; - struct vnode *vp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - u_int32_t *tl; - caddr_t bpos; - int error = 0, rdonly, preat_ret = 1, postat_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0; - struct mbuf *mb, *mreq; - struct timespec guard = { 0, 0 }; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto out; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - VATTR_NULL(vap); - if (v3) { - nfsm_srvsattr(vap); - tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); - gcheck = fxdr_unsigned(int, *tl); - if (gcheck) { - tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED); - fxdr_nfsv3time(tl, &guard); - } - } else { - sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR); - /* - * Nah nah nah nah na nah - * There is a bug in the Sun client that puts 0xffff in the mode - * field of sattr when it should put in 0xffffffff. The u_short - * doesn't sign extend. - * --> check the low order 2 bytes for 0xffff - */ - if ((fxdr_unsigned(int, sp->sa_mode) & 0xffff) != 0xffff) - vap->va_mode = nfstov_mode(sp->sa_mode); - if (sp->sa_uid != nfsrv_nfs_xdrneg1) - vap->va_uid = fxdr_unsigned(uid_t, sp->sa_uid); - if (sp->sa_gid != nfsrv_nfs_xdrneg1) - vap->va_gid = fxdr_unsigned(gid_t, sp->sa_gid); - if (sp->sa_size != nfsrv_nfs_xdrneg1) - vap->va_size = fxdr_unsigned(u_quad_t, sp->sa_size); - if (sp->sa_atime.nfsv2_sec != nfsrv_nfs_xdrneg1) { -#ifdef notyet - fxdr_nfsv2time(&sp->sa_atime, &vap->va_atime); -#else - vap->va_atime.tv_sec = - fxdr_unsigned(int32_t, sp->sa_atime.nfsv2_sec); - vap->va_atime.tv_nsec = 0; -#endif - } - if (sp->sa_mtime.nfsv2_sec != nfsrv_nfs_xdrneg1) - fxdr_nfsv2time(&sp->sa_mtime, &vap->va_mtime); - - } - - /* - * Now that we have all the fields, lets do it. - */ - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); - if (v3) - nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); - error = 0; - goto nfsmout; - } - - /* - * vp now an active resource, pay careful attention to cleanup - */ - if (v3) { - error = preat_ret = VOP_GETATTR(vp, &preat, cred); - if (!error && gcheck && - (preat.va_ctime.tv_sec != guard.tv_sec || - preat.va_ctime.tv_nsec != guard.tv_nsec)) - error = NFSERR_NOT_SYNC; - if (error) { - vput(vp); - vp = NULL; - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) - nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); - error = 0; - goto nfsmout; - } - } - - /* - * If the size is being changed write acces is required, otherwise - * just check for a read only filesystem. - */ - if (vap->va_size == ((u_quad_t)((quad_t) -1))) { - if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) { - error = EROFS; - goto out; - } - } else { - if (vp->v_type == VDIR) { - error = EISDIR; - goto out; - } else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly, - 0)) != 0) - goto out; - } - error = VOP_SETATTR(vp, vap, cred); - postat_ret = VOP_GETATTR(vp, vap, cred); - if (!error) - error = postat_ret; -out: - if (vp != NULL) - vput(vp); - - vp = NULL; - nfsm_reply(NFSX_WCCORFATTR(v3)); - if (v3) { - nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap); - } else if (!error) { - /* v2 non-error case. */ - fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); - } - error = 0; - /* fall through */ - -nfsmout: - if (vp) - vput(vp); - vn_finished_write(mp); - return(error); -} - -/* - * nfs lookup rpc - */ -int -nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nfs_fattr *fp; - struct nameidata nd, ind, *ndp = &nd; - struct vnode *vp, *dirp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - caddr_t bpos; - int error = 0, len, dirattr_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag; - struct mbuf *mb, *mreq; - struct vattr va, dirattr, *vap = &va; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); - - pubflag = nfs_ispublicfh(fhp); - - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART; - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirattr, &dirattr_ret, pubflag); - - /* - * namei failure, only dirp to cleanup. Clear out garbarge from - * structure in case macros jump to nfsmout. - */ - - if (error) { - if (dirp) { - vrele(dirp); - dirp = NULL; - } - nfsm_reply(NFSX_POSTOPATTR(v3)); - if (v3) - nfsm_srvpostop_attr(dirattr_ret, &dirattr); - error = 0; - goto nfsmout; - } - - /* - * Locate index file for public filehandle - * - * error is 0 on entry and 0 on exit from this block. - */ - - if (pubflag) { - if (nd.ni_vp->v_type == VDIR && nfs_pub.np_index != NULL) { - /* - * Setup call to lookup() to see if we can find - * the index file. Arguably, this doesn't belong - * in a kernel.. Ugh. If an error occurs, do not - * try to install an index file and then clear the - * error. - * - * When we replace nd with ind and redirect ndp, - * maintenance of ni_startdir and ni_vp shift to - * ind and we have to clean them up in the old nd. - * However, the cnd resource continues to be maintained - * via the original nd. Confused? You aren't alone! - */ - ind = nd; - VOP_UNLOCK(nd.ni_vp, 0); - ind.ni_pathlen = strlen(nfs_pub.np_index); - ind.ni_cnd.cn_nameptr = ind.ni_cnd.cn_pnbuf = - nfs_pub.np_index; - ind.ni_startdir = nd.ni_vp; - VREF(ind.ni_startdir); - error = lookup(&ind); - ind.ni_dvp = NULL; - - if (error == 0) { - /* - * Found an index file. Get rid of - * the old references. transfer nd.ni_vp' - */ - if (dirp) - vrele(dirp); - dirp = nd.ni_vp; - nd.ni_vp = NULL; - vrele(nd.ni_startdir); - nd.ni_startdir = NULL; - ndp = &ind; - } - error = 0; - } - /* - * If the public filehandle was used, check that this lookup - * didn't result in a filehandle outside the publicly exported - * filesystem. We clear the poor vp here to avoid lockups due - * to NFS I/O. - */ - - if (ndp->ni_vp->v_mount != nfs_pub.np_mount) { - vput(nd.ni_vp); - nd.ni_vp = NULL; - error = EPERM; - } - } - - /* - * Resources at this point: - * ndp->ni_vp may not be NULL - */ - - if (error) { - nfsm_reply(NFSX_POSTOPATTR(v3)); - if (v3) - nfsm_srvpostop_attr(dirattr_ret, &dirattr); - error = 0; - goto nfsmout; - } - - /* - * Get underlying attribute, then release remaining resources ( for - * the same potential blocking reason ) and reply. - */ - vp = ndp->ni_vp; - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fhp->fh_fid); - if (!error) - error = VOP_GETATTR(vp, vap, cred); - - vput(vp); - vrele(ndp->ni_startdir); - vrele(dirp); - ndp->ni_vp = NULL; - ndp->ni_startdir = NULL; - dirp = NULL; - nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3)); - if (error) { - if (v3) - nfsm_srvpostop_attr(dirattr_ret, &dirattr); - error = 0; - goto nfsmout; - } - nfsm_srvfhtom(fhp, v3); - if (v3) { - nfsm_srvpostop_attr(0, vap); - nfsm_srvpostop_attr(dirattr_ret, &dirattr); - } else { - fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); - } - -nfsmout: - if (ndp->ni_vp || dirp || ndp->ni_startdir) { - if (ndp->ni_vp) - vput(ndp->ni_vp); - if (dirp) - vrele(dirp); - if (ndp->ni_startdir) - vrele(ndp->ni_startdir); - } - NDFREE(&nd, NDF_ONLY_PNBUF); - return (error); -} - -/* - * nfs readlink service - */ -int -nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN]; - struct iovec *ivp = iv; - struct mbuf *mp; - u_int32_t *tl; - caddr_t bpos; - int error = 0, rdonly, i, tlen, len, getret; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mp3, *nmp, *mreq; - struct vnode *vp = NULL; - struct vattr attr; - nfsfh_t nfh; - fhandle_t *fhp; - struct uio io, *uiop = &io; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); -#ifndef nolint - mp = NULL; -#endif - mp3 = NULL; - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - len = 0; - i = 0; - while (len < NFS_MAXPATHLEN) { - MGET(nmp, M_WAITOK, MT_DATA); - MCLGET(nmp, M_WAITOK); - nmp->m_len = NFSMSIZ(nmp); - if (len == 0) - mp3 = mp = nmp; - else { - mp->m_next = nmp; - mp = nmp; - } - if ((len + mp->m_len) > NFS_MAXPATHLEN) { - mp->m_len = NFS_MAXPATHLEN - len; - len = NFS_MAXPATHLEN; - } else - len += mp->m_len; - ivp->iov_base = mtod(mp, caddr_t); - ivp->iov_len = mp->m_len; - i++; - ivp++; - } - uiop->uio_iov = iv; - uiop->uio_iovcnt = i; - uiop->uio_offset = 0; - uiop->uio_resid = len; - uiop->uio_rw = UIO_READ; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_td = NULL; - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); - if (v3) - nfsm_srvpostop_attr(1, NULL); - error = 0; - goto nfsmout; - } - if (vp->v_type != VLNK) { - if (v3) - error = EINVAL; - else - error = ENXIO; - } else - error = VOP_READLINK(vp, uiop, cred); - getret = VOP_GETATTR(vp, &attr, cred); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED); - if (v3) - nfsm_srvpostop_attr(getret, &attr); - if (error) { - error = 0; - goto nfsmout; - } - if (uiop->uio_resid > 0) { - len -= uiop->uio_resid; - tlen = nfsm_rndup(len); - nfsm_adj(mp3, NFS_MAXPATHLEN-tlen, tlen-len); - } - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(len); - mb->m_next = mp3; - mp3 = NULL; -nfsmout: - if (mp3) - m_freem(mp3); - if (vp) - vput(vp); - return(error); -} - -/* - * nfs read service - */ -int -nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct iovec *iv; - struct iovec *iv2; - struct mbuf *m; - struct nfs_fattr *fp; - u_int32_t *tl; - int i; - caddr_t bpos; - int error = 0, rdonly, cnt, len, left, siz, tlen, getret; - int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen; - struct mbuf *mb, *mreq; - struct mbuf *m2; - struct vnode *vp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - struct uio io, *uiop = &io; - struct vattr va, *vap = &va; - struct nfsheur *nh; - off_t off; - int ioflag = 0; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if (v3) { - tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED); - off = fxdr_hyper(tl); - } else { - tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); - off = (off_t)fxdr_unsigned(u_int32_t, *tl); - } - nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd)); - - /* - * Reference vp. If an error occurs, vp will be invalid, but we - * have to NULL it just in case. The macros might goto nfsmout - * as well. - */ - - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - vp = NULL; - nfsm_reply(2 * NFSX_UNSIGNED); - if (v3) - nfsm_srvpostop_attr(1, NULL); - error = 0; - goto nfsmout; - } - - if (vp->v_type != VREG) { - if (v3) - error = EINVAL; - else - error = (vp->v_type == VDIR) ? EISDIR : EACCES; - } - if (!error) { - if ((error = nfsrv_access(vp, VREAD, cred, rdonly, 1)) != 0) - error = nfsrv_access(vp, VEXEC, cred, rdonly, 1); - } - getret = VOP_GETATTR(vp, vap, cred); - if (!error) - error = getret; - if (error) { - vput(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3)); - if (v3) - nfsm_srvpostop_attr(getret, vap); - error = 0; - goto nfsmout; - } - - /* - * Calculate byte count to read - */ - if (off >= vap->va_size) - cnt = 0; - else if ((off + reqlen) > vap->va_size) - cnt = vap->va_size - off; - else - cnt = reqlen; - - nfsm_reply(NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt)); - if (v3) { - tl = nfsm_build(u_int32_t *, NFSX_V3FATTR + 4 * NFSX_UNSIGNED); - *tl++ = nfsrv_nfs_true; - fp = (struct nfs_fattr *)tl; - tl += (NFSX_V3FATTR / sizeof (u_int32_t)); - } else { - tl = nfsm_build(u_int32_t *, NFSX_V2FATTR + NFSX_UNSIGNED); - fp = (struct nfs_fattr *)tl; - tl += (NFSX_V2FATTR / sizeof (u_int32_t)); - } - len = left = nfsm_rndup(cnt); - if (cnt > 0) { - /* - * Generate the mbuf list with the uio_iov ref. to it. - */ - i = 0; - m = m2 = mb; - while (left > 0) { - siz = min(M_TRAILINGSPACE(m), left); - if (siz > 0) { - left -= siz; - i++; - } - if (left > 0) { - MGET(m, M_WAITOK, MT_DATA); - MCLGET(m, M_WAITOK); - m->m_len = 0; - m2->m_next = m; - m2 = m; - } - } - iv = malloc(i * sizeof (struct iovec), - M_TEMP, M_WAITOK); - uiop->uio_iov = iv2 = iv; - m = mb; - left = len; - i = 0; - while (left > 0) { - if (m == NULL) - panic("nfsrv_read iov"); - siz = min(M_TRAILINGSPACE(m), left); - if (siz > 0) { - iv->iov_base = mtod(m, caddr_t) + m->m_len; - iv->iov_len = siz; - m->m_len += siz; - left -= siz; - iv++; - i++; - } - m = m->m_next; - } - uiop->uio_iovcnt = i; - uiop->uio_offset = off; - uiop->uio_resid = len; - uiop->uio_rw = UIO_READ; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_td = NULL; - nh = nfsrv_sequential_heuristic(uiop, vp); - ioflag |= nh->nh_seqcount << IO_SEQSHIFT; - error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred); - if (error == 0) - nh->nh_nextoff = uiop->uio_offset; - free((caddr_t)iv2, M_TEMP); - if (error || (getret = VOP_GETATTR(vp, vap, cred))) { - if (!error) - error = getret; - m_freem(mreq); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3)); - if (v3) - nfsm_srvpostop_attr(getret, vap); - error = 0; - goto nfsmout; - } - } else - uiop->uio_resid = 0; - vput(vp); - vp = NULL; - nfsm_srvfillattr(vap, fp); - tlen = len - uiop->uio_resid; - cnt = cnt < tlen ? cnt : tlen; - tlen = nfsm_rndup(cnt); - if (len != tlen || tlen != cnt) - nfsm_adj(mb, len - tlen, tlen - cnt); - if (v3) { - *tl++ = txdr_unsigned(cnt); - if (cnt < reqlen) - *tl++ = nfsrv_nfs_true; - else - *tl++ = nfsrv_nfs_false; - } - *tl = txdr_unsigned(cnt); -nfsmout: - if (vp) - vput(vp); - return(error); -} - -/* - * nfs write service - */ -int -nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct iovec *ivp; - int i, cnt; - struct mbuf *mp; - struct nfs_fattr *fp; - struct iovec *iv; - struct vattr va, forat; - struct vattr *vap = &va; - u_int32_t *tl; - caddr_t bpos; - int error = 0, rdonly, len, forat_ret = 1; - int ioflags, aftat_ret = 1, retlen = 0, zeroing, adjust; - int stable = NFSV3WRITE_FILESYNC; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *vp = NULL; - struct nfsheur *nh; - nfsfh_t nfh; - fhandle_t *fhp; - struct uio io, *uiop = &io; - off_t off; - struct mount *mntp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (mrep == NULL) { - *mrq = NULL; - error = 0; - goto nfsmout; - } - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mntp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto ereply; - } - (void) vn_start_write(NULL, &mntp, V_WAIT); - vfs_rel(mntp); /* The write holds a ref. */ - if (v3) { - tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED); - off = fxdr_hyper(tl); - tl += 3; - stable = fxdr_unsigned(int, *tl++); - } else { - tl = nfsm_dissect_nonblock(u_int32_t *, 4 * NFSX_UNSIGNED); - off = (off_t)fxdr_unsigned(u_int32_t, *++tl); - tl += 2; - if (nfs_async) - stable = NFSV3WRITE_UNSTABLE; - } - retlen = len = fxdr_unsigned(int32_t, *tl); - cnt = i = 0; - - /* - * For NFS Version 2, it is not obvious what a write of zero length - * should do, but I might as well be consistent with Version 3, - * which is to return ok so long as there are no permission problems. - */ - if (len > 0) { - zeroing = 1; - mp = mrep; - while (mp) { - if (mp == md) { - zeroing = 0; - adjust = dpos - mtod(mp, caddr_t); - mp->m_len -= adjust; - if (mp->m_len > 0 && adjust > 0) - mp->m_data += adjust; - } - if (zeroing) - mp->m_len = 0; - else if (mp->m_len > 0) { - i += mp->m_len; - if (i > len) { - mp->m_len -= (i - len); - zeroing = 1; - } - if (mp->m_len > 0) - cnt++; - } - mp = mp->m_next; - } - } - if (len > NFS_MAXDATA || len < 0 || i < len) { - error = EIO; - nfsm_reply(2 * NFSX_UNSIGNED); - if (v3) - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); - error = 0; - goto nfsmout; - } - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - vp = NULL; - nfsm_reply(2 * NFSX_UNSIGNED); - if (v3) - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); - error = 0; - goto nfsmout; - } - if (v3) - forat_ret = VOP_GETATTR(vp, &forat, cred); - if (vp->v_type != VREG) { - if (v3) - error = EINVAL; - else - error = (vp->v_type == VDIR) ? EISDIR : EACCES; - } - if (!error) - error = nfsrv_access(vp, VWRITE, cred, rdonly, 1); - if (error) { - vput(vp); - vp = NULL; - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); - error = 0; - goto nfsmout; - } - - if (len > 0) { - ivp = malloc(cnt * sizeof (struct iovec), M_TEMP, - M_WAITOK); - uiop->uio_iov = iv = ivp; - uiop->uio_iovcnt = cnt; - mp = mrep; - while (mp) { - if (mp->m_len > 0) { - ivp->iov_base = mtod(mp, caddr_t); - ivp->iov_len = mp->m_len; - ivp++; - } - mp = mp->m_next; - } - - /* - * XXX - * The IO_METASYNC flag indicates that all metadata (and not just - * enough to ensure data integrity) mus be written to stable storage - * synchronously. - * (IO_METASYNC is not yet implemented in 4.4BSD-Lite.) - */ - if (stable == NFSV3WRITE_UNSTABLE) - ioflags = IO_NODELOCKED; - else if (stable == NFSV3WRITE_DATASYNC) - ioflags = (IO_SYNC | IO_NODELOCKED); - else - ioflags = (IO_METASYNC | IO_SYNC | IO_NODELOCKED); - uiop->uio_resid = len; - uiop->uio_rw = UIO_WRITE; - uiop->uio_segflg = UIO_SYSSPACE; - uiop->uio_td = NULL; - uiop->uio_offset = off; - nh = nfsrv_sequential_heuristic(uiop, vp); - ioflags |= nh->nh_seqcount << IO_SEQSHIFT; - error = VOP_WRITE(vp, uiop, ioflags, cred); - if (error == 0) - nh->nh_nextoff = uiop->uio_offset; - /* Unlocked write. */ - nfsrvstats.srvvop_writes++; - free((caddr_t)iv, M_TEMP); - } - aftat_ret = VOP_GETATTR(vp, vap, cred); - vput(vp); - vp = NULL; - if (!error) - error = aftat_ret; -ereply: - nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) + - 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3)); - if (v3) { - nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap); - if (error) { - error = 0; - goto nfsmout; - } - tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(retlen); - /* - * If nfs_async is set, then pretend the write was FILESYNC. - */ - if (stable == NFSV3WRITE_UNSTABLE && !nfs_async) - *tl++ = txdr_unsigned(stable); - else - *tl++ = txdr_unsigned(NFSV3WRITE_FILESYNC); - /* - * Actually, there is no need to txdr these fields, - * but it may make the values more human readable, - * for debugging purposes. - */ - if (nfsver.tv_sec == 0) - nfsver = boottime; - *tl++ = txdr_unsigned(nfsver.tv_sec); - *tl = txdr_unsigned(nfsver.tv_usec); - } else if (!error) { - /* v2 non-error case. */ - fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); - } - error = 0; -nfsmout: - if (vp) - vput(vp); - vn_finished_write(mntp); - return(error); -} - -/* - * nfs create service - * now does a truncate to 0 length via. setattr if it already exists - */ -int -nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nfs_fattr *fp; - struct vattr va, dirfor, diraft; - struct vattr *vap = &va; - struct nfsv2_sattr *sp; - u_int32_t *tl; - struct nameidata nd; - caddr_t bpos; - int error = 0, rdev, len, tsize, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0; - struct mbuf *mb, *mreq; - struct vnode *dirp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - u_quad_t tempsize; - struct timespec cverf; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); -#ifndef nolint - rdev = 0; -#endif - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto ereply; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE; - - /* - * Call namei and do initial cleanup to get a few things - * out of the way. If we get an initial error we cleanup - * and return here to avoid special-casing the invalid nd - * structure through the rest of the case. dirp may be - * set even if an error occurs, but the nd structure will not - * be valid at all if an error occurs so we have to invalidate it - * prior to calling nfsm_reply ( which might goto nfsmout ). - */ - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (dirp && !v3) { - vrele(dirp); - dirp = NULL; - } - if (error) { - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; - goto nfsmout; - } - - /* - * No error. Continue. State: - * - * startdir is valid ( we release this immediately ) - * dirp may be valid - * nd.ni_vp may be valid - * nd.ni_dvp is valid - * - * The error state is set through the code and we may also do some - * opportunistic releasing of vnodes to avoid holding locks through - * NFS I/O. The cleanup at the end is a catch-all - */ - - VATTR_NULL(vap); - if (v3) { - tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); - how = fxdr_unsigned(int, *tl); - switch (how) { - case NFSV3CREATE_GUARDED: - if (nd.ni_vp) { - error = EEXIST; - break; - } - /* fall through */ - case NFSV3CREATE_UNCHECKED: - nfsm_srvsattr(vap); - break; - case NFSV3CREATE_EXCLUSIVE: - tl = nfsm_dissect_nonblock(u_int32_t *, - NFSX_V3CREATEVERF); - /* Unique bytes, endianness is not important. */ - cverf.tv_sec = (int32_t)tl[0]; - cverf.tv_nsec = tl[1]; - exclusive_flag = 1; - break; - }; - vap->va_type = VREG; - } else { - sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR); - vap->va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode)); - if (vap->va_type == VNON) - vap->va_type = VREG; - vap->va_mode = nfstov_mode(sp->sa_mode); - switch (vap->va_type) { - case VREG: - tsize = fxdr_unsigned(int32_t, sp->sa_size); - if (tsize != -1) - vap->va_size = (u_quad_t)tsize; - break; - case VCHR: - case VBLK: - case VFIFO: - rdev = fxdr_unsigned(long, sp->sa_size); - break; - default: - break; - }; - } - - /* - * Iff doesn't exist, create it - * otherwise just truncate to 0 length - * should I set the mode too ? - * - * The only possible error we can have at this point is EEXIST. - * nd.ni_vp will also be non-NULL in that case. - */ - if (nd.ni_vp == NULL) { - if (vap->va_mode == (mode_t)VNOVAL) - vap->va_mode = 0; - if (vap->va_type == VREG || vap->va_type == VSOCK) { - error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); - if (error) - NDFREE(&nd, NDF_ONLY_PNBUF); - else { - if (exclusive_flag) { - exclusive_flag = 0; - VATTR_NULL(vap); - vap->va_atime = cverf; - error = VOP_SETATTR(nd.ni_vp, vap, - cred); - } - } - } else if (vap->va_type == VCHR || vap->va_type == VBLK || - vap->va_type == VFIFO) { - /* - * NFSv2-specific code for creating device nodes - * and fifos. - * - * Handle SysV FIFO node special cases. All other - * devices require super user to access. - */ - if (vap->va_type == VCHR && rdev == 0xffffffff) - vap->va_type = VFIFO; - if (vap->va_type != VFIFO && - (error = priv_check_cred(cred, PRIV_VFS_MKNOD_DEV, - 0))) { - goto ereply; - } - vap->va_rdev = rdev; - error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); - if (error) { - NDFREE(&nd, NDF_ONLY_PNBUF); - goto ereply; - } - vput(nd.ni_vp); - nd.ni_vp = NULL; - - /* - * release dvp prior to lookup - */ - vput(nd.ni_dvp); - nd.ni_dvp = NULL; - /* - * Setup for lookup. - * - * Even though LOCKPARENT was cleared, ni_dvp may - * be garbage. - */ - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags &= ~(LOCKPARENT); - nd.ni_cnd.cn_thread = curthread; - nd.ni_cnd.cn_cred = cred; - error = lookup(&nd); - nd.ni_dvp = NULL; - if (error) - goto ereply; - - if (nd.ni_cnd.cn_flags & ISSYMLINK) { - error = EINVAL; - goto ereply; - } - } else { - error = ENXIO; - } - } else { - if (vap->va_size != -1) { - error = nfsrv_access(nd.ni_vp, VWRITE, - cred, (nd.ni_cnd.cn_flags & RDONLY), 0); - if (!error) { - tempsize = vap->va_size; - VATTR_NULL(vap); - vap->va_size = tempsize; - error = VOP_SETATTR(nd.ni_vp, vap, cred); - } - } - } - - if (!error) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid); - if (!error) - error = VOP_GETATTR(nd.ni_vp, vap, cred); - } - if (v3) { - if (exclusive_flag && !error && - bcmp(&cverf, &vap->va_atime, sizeof (cverf))) - error = EEXIST; - if (dirp == nd.ni_dvp) - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - else { - /* Drop the other locks to avoid deadlock. */ - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - nd.ni_dvp = NULL; - nd.ni_vp = NULL; - - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - VOP_UNLOCK(dirp, 0); - } - } -ereply: - nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { - if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); - } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - } else if (!error) { - /* v2 non-error case. */ - nfsm_srvfhtom(fhp, v3); - fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); - } - error = 0; - -nfsmout: - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - if (nd.ni_startdir) { - vrele(nd.ni_startdir); - nd.ni_startdir = NULL; - } - if (dirp) - vrele(dirp); - NDFREE(&nd, NDF_ONLY_PNBUF); - vn_finished_write(mp); - return (error); -} - -/* - * nfs v3 mknod service - */ -int -nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct vattr va, dirfor, diraft; - struct vattr *vap = &va; - struct thread *td = curthread; - u_int32_t *tl; - struct nameidata nd; - caddr_t bpos; - int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - u_int32_t major, minor; - enum vtype vtyp; - struct mbuf *mb, *mreq; - struct vnode *vp, *dirp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - struct mount *mp = NULL; - int v3 = (nfsd->nd_flag & ND_NFSV3); - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (!v3) - panic("nfsrv_mknod: v3 proc called on a v2 connection"); - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto ereply; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE; - - /* - * Handle nfs_namei() call. If an error occurs, the nd structure - * is not valid. However, nfsm_*() routines may still jump to - * nfsmout. - */ - - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (error) { - nfsm_reply(NFSX_WCCDATA(1)); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; - goto nfsmout; - } - tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); - vtyp = nfsv3tov_type(*tl); - if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) { - error = NFSERR_BADTYPE; - goto out; - } - VATTR_NULL(vap); - nfsm_srvsattr(vap); - if (vtyp == VCHR || vtyp == VBLK) { - tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED); - major = fxdr_unsigned(u_int32_t, *tl++); - minor = fxdr_unsigned(u_int32_t, *tl); - vap->va_rdev = makedev(major, minor); - } - - /* - * Iff doesn't exist, create it. - */ - if (nd.ni_vp) { - error = EEXIST; - goto out; - } - vap->va_type = vtyp; - if (vap->va_mode == (mode_t)VNOVAL) - vap->va_mode = 0; - if (vtyp == VSOCK) { - vrele(nd.ni_startdir); - nd.ni_startdir = NULL; - error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); - if (error) - NDFREE(&nd, NDF_ONLY_PNBUF); - } else { - if (vtyp != VFIFO && (error = priv_check_cred(cred, - PRIV_VFS_MKNOD_DEV, 0))) - goto out; - error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); - if (error) { - NDFREE(&nd, NDF_ONLY_PNBUF); - goto out; - } - vput(nd.ni_vp); - nd.ni_vp = NULL; - - /* - * Release dvp prior to lookup - */ - vput(nd.ni_dvp); - nd.ni_dvp = NULL; - - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags &= ~(LOCKPARENT); - nd.ni_cnd.cn_thread = td; - nd.ni_cnd.cn_cred = td->td_ucred; - error = lookup(&nd); - nd.ni_dvp = NULL; - - if (error) - goto out; - if (nd.ni_cnd.cn_flags & ISSYMLINK) - error = EINVAL; - } - - /* - * send response, cleanup, return. - */ -out: - vp = nd.ni_vp; - if (!error) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(vp, &fhp->fh_fid); - if (!error) - error = VOP_GETATTR(vp, vap, cred); - } - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - nd.ni_dvp = NULL; - } - if (vp) { - vput(vp); - vp = NULL; - nd.ni_vp = NULL; - } - if (nd.ni_startdir) { - vrele(nd.ni_startdir); - nd.ni_startdir = NULL; - } - NDFREE(&nd, NDF_ONLY_PNBUF); - if (dirp) { - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - vput(dirp); - } -ereply: - nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)); - if (v3) { - if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); - } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - } - vn_finished_write(mp); - return (0); -nfsmout: - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - if (dirp) - vrele(dirp); - if (nd.ni_startdir) - vrele(nd.ni_startdir); - NDFREE(&nd, NDF_ONLY_PNBUF); - vn_finished_write(mp); - return (error); -} - -/* - * nfs remove service - */ -int -nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nameidata nd; - caddr_t bpos; - int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *dirp; - struct vattr dirfor, diraft; - nfsfh_t nfh; - fhandle_t *fhp; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto ereply; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = DELETE; - nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF; - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (dirp && !v3) { - vrele(dirp); - dirp = NULL; - } - if (error == 0) { - if (nd.ni_vp->v_type == VDIR) { - error = EPERM; /* POSIX */ - goto out; - } - /* - * The root of a mounted filesystem cannot be deleted. - */ - if (nd.ni_vp->v_vflag & VV_ROOT) { - error = EBUSY; - goto out; - } -out: - if (!error) { - error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); - NDFREE(&nd, NDF_ONLY_PNBUF); - } - } - if (dirp && v3) { - if (dirp == nd.ni_dvp) - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - else { - /* Drop the other locks to avoid deadlock. */ - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - nd.ni_dvp = NULL; - nd.ni_vp = NULL; - - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - VOP_UNLOCK(dirp, 0); - } - vrele(dirp); - dirp = NULL; - } -ereply: - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; -nfsmout: - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - vn_finished_write(mp); - return(error); -} - -/* - * nfs rename service - */ -int -nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - caddr_t bpos; - int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1; - int tdirfor_ret = 1, tdiraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct nameidata fromnd, tond; - struct vnode *fvp, *tvp, *tdvp, *fdirp = NULL; - struct vnode *tdirp = NULL; - struct vattr fdirfor, fdiraft, tdirfor, tdiraft; - nfsfh_t fnfh, tnfh; - fhandle_t *ffhp, *tfhp; - uid_t saved_uid; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); -#ifndef nolint - fvp = NULL; -#endif - ffhp = &fnfh.fh_generic; - tfhp = &tnfh.fh_generic; - - /* - * Clear fields incase goto nfsmout occurs from macro. - */ - - ndclear(&fromnd); - ndclear(&tond); - - nfsm_srvmtofh(ffhp); - if ((mp = vfs_getvfs(&ffhp->fh_fsid)) == NULL) { - error = ESTALE; - goto out1; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - /* - * Remember our original uid so that we can reset cr_uid before - * the second nfs_namei() call, in case it is remapped. - */ - saved_uid = cred->cr_uid; - fromnd.ni_cnd.cn_cred = cred; - fromnd.ni_cnd.cn_nameiop = DELETE; - fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART; - error = nfs_namei(&fromnd, nfsd, ffhp, len, slp, nam, &md, - &dpos, &fdirp, v3, &fdirfor, &fdirfor_ret, FALSE); - if (fdirp && !v3) { - vrele(fdirp); - fdirp = NULL; - } - if (error) { - nfsm_reply(2 * NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft); - nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft); - } - error = 0; - goto nfsmout; - } - fvp = fromnd.ni_vp; - nfsm_srvmtofh(tfhp); - nfsm_srvnamesiz(len2); - cred->cr_uid = saved_uid; - tond.ni_cnd.cn_cred = cred; - tond.ni_cnd.cn_nameiop = RENAME; - tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART; - error = nfs_namei(&tond, nfsd, tfhp, len2, slp, nam, &md, - &dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, FALSE); - if (tdirp && !v3) { - vrele(tdirp); - tdirp = NULL; - } - if (error) - goto out1; - - tdvp = tond.ni_dvp; - tvp = tond.ni_vp; - if (tvp != NULL) { - if (fvp->v_type == VDIR && tvp->v_type != VDIR) { - if (v3) - error = EEXIST; - else - error = EISDIR; - goto out; - } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) { - if (v3) - error = EEXIST; - else - error = ENOTDIR; - goto out; - } - if (tvp->v_type == VDIR && tvp->v_mountedhere) { - if (v3) - error = EXDEV; - else - error = ENOTEMPTY; - goto out; - } - } - if (fvp->v_type == VDIR && fvp->v_mountedhere) { - if (v3) - error = EXDEV; - else - error = ENOTEMPTY; - goto out; - } - if (fvp->v_mount != tdvp->v_mount) { - if (v3) - error = EXDEV; - else - error = ENOTEMPTY; - goto out; - } - if (fvp == tdvp) { - if (v3) - error = EINVAL; - else - error = ENOTEMPTY; - } - /* - * If source is the same as the destination (that is the - * same vnode with the same name in the same directory), - * then there is nothing to do. - */ - if (fvp == tvp && fromnd.ni_dvp == tdvp && - fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen && - !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr, - fromnd.ni_cnd.cn_namelen)) - error = -1; -out: - if (!error) { - /* - * The VOP_RENAME function releases all vnode references & - * locks prior to returning so we need to clear the pointers - * to bypass cleanup code later on. - */ - error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, - tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); - fromnd.ni_dvp = NULL; - fromnd.ni_vp = NULL; - tond.ni_dvp = NULL; - tond.ni_vp = NULL; - if (error) { - NDFREE(&fromnd, NDF_ONLY_PNBUF); - NDFREE(&tond, NDF_ONLY_PNBUF); - } - } else { - if (error == -1) - error = 0; - } - /* fall through */ -out1: - nfsm_reply(2 * NFSX_WCCDATA(v3)); - if (v3) { - /* Release existing locks to prevent deadlock. */ - if (tond.ni_dvp) { - if (tond.ni_dvp == tond.ni_vp) - vrele(tond.ni_dvp); - else - vput(tond.ni_dvp); - } - if (tond.ni_vp) - vput(tond.ni_vp); - tond.ni_dvp = NULL; - tond.ni_vp = NULL; - - if (fdirp) { - vn_lock(fdirp, LK_EXCLUSIVE | LK_RETRY); - fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred); - VOP_UNLOCK(fdirp, 0); - } - if (tdirp) { - vn_lock(tdirp, LK_EXCLUSIVE | LK_RETRY); - tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred); - VOP_UNLOCK(tdirp, 0); - } - nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft); - nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft); - } - error = 0; - /* fall through */ - -nfsmout: - /* - * Clear out tond related fields - */ - if (tond.ni_dvp) { - if (tond.ni_dvp == tond.ni_vp) - vrele(tond.ni_dvp); - else - vput(tond.ni_dvp); - } - if (tond.ni_vp) - vput(tond.ni_vp); - if (tdirp) - vrele(tdirp); - if (tond.ni_startdir) - vrele(tond.ni_startdir); - NDFREE(&tond, NDF_ONLY_PNBUF); - /* - * Clear out fromnd related fields - */ - if (fdirp) - vrele(fdirp); - if (fromnd.ni_startdir) - vrele(fromnd.ni_startdir); - NDFREE(&fromnd, NDF_ONLY_PNBUF); - if (fromnd.ni_dvp) - vrele(fromnd.ni_dvp); - if (fromnd.ni_vp) - vrele(fromnd.ni_vp); - - vn_finished_write(mp); - return (error); -} - -/* - * nfs link service - */ -int -nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nameidata nd; - caddr_t bpos; - int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1; - int getret = 1, v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *vp = NULL, *xp, *dirp = NULL; - struct vattr dirfor, diraft, at; - nfsfh_t nfh, dnfh; - fhandle_t *fhp, *dfhp; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - ndclear(&nd); - - fhp = &nfh.fh_generic; - dfhp = &dnfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto ereply; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvmtofh(dfhp); - nfsm_srvnamesiz(len); - - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - } - vp = NULL; - error = 0; - goto nfsmout; - } - if (v3) - getret = VOP_GETATTR(vp, &at, cred); - if (vp->v_type == VDIR) { - error = EPERM; /* POSIX */ - goto out1; - } - VOP_UNLOCK(vp, 0); - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE; - error = nfs_namei(&nd, nfsd, dfhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (dirp && !v3) { - vrele(dirp); - dirp = NULL; - } - if (error) { - vrele(vp); - vp = NULL; - goto out2; - } - xp = nd.ni_vp; - if (xp != NULL) { - error = EEXIST; - vrele(vp); - vp = NULL; - goto out2; - } - xp = nd.ni_dvp; - if (vp->v_mount != xp->v_mount) { - error = EXDEV; - vrele(vp); - vp = NULL; - goto out2; - } - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd); - NDFREE(&nd, NDF_ONLY_PNBUF); - /* fall through */ - -out1: - if (v3) - getret = VOP_GETATTR(vp, &at, cred); -out2: - if (dirp) { - if (dirp == nd.ni_dvp) - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - else { - /* Release existing locks to prevent deadlock. */ - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vrele(nd.ni_vp); - nd.ni_dvp = NULL; - nd.ni_vp = NULL; - - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - VOP_UNLOCK(dirp, 0); - } - } -ereply: - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - } - error = 0; - /* fall through */ - -nfsmout: - NDFREE(&nd, NDF_ONLY_PNBUF); - if (vp) - vput(vp); - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (dirp) - vrele(dirp); - if (nd.ni_vp) - vrele(nd.ni_vp); - vn_finished_write(mp); - return(error); -} - -/* - * nfs symbolic link service - */ -int -nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct vattr va, dirfor, diraft; - struct nameidata nd; - struct vattr *vap = &va; - struct nfsv2_sattr *sp; - char *bpos, *pathcp = NULL; - struct uio io; - struct iovec iv; - int error = 0, len, len2, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *dirp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto out; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | NOCACHE; - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (error == 0) { - VATTR_NULL(vap); - if (v3) - nfsm_srvsattr(vap); - nfsm_srvpathsiz(len2); - } - if (dirp && !v3) { - vrele(dirp); - dirp = NULL; - } - if (error) - goto out; - pathcp = malloc(len2 + 1, M_TEMP, M_WAITOK); - iv.iov_base = pathcp; - iv.iov_len = len2; - io.uio_resid = len2; - io.uio_offset = 0; - io.uio_iov = &iv; - io.uio_iovcnt = 1; - io.uio_segflg = UIO_SYSSPACE; - io.uio_rw = UIO_READ; - io.uio_td = NULL; - nfsm_mtouio(&io, len2); - if (!v3) { - sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR); - vap->va_mode = nfstov_mode(sp->sa_mode); - } - *(pathcp + len2) = '\0'; - if (nd.ni_vp) { - error = EEXIST; - goto out; - } - - /* - * issue symlink op. SAVESTART is set so the underlying path component - * is only freed by the VOP if an error occurs. - */ - if (vap->va_mode == (mode_t)VNOVAL) - vap->va_mode = 0; - error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp); - if (error) - NDFREE(&nd, NDF_ONLY_PNBUF); - else - vput(nd.ni_vp); - nd.ni_vp = NULL; - /* - * releases directory prior to potential lookup op. - */ - vput(nd.ni_dvp); - nd.ni_dvp = NULL; - - if (error == 0) { - if (v3) { - /* - * Issue lookup. Leave SAVESTART set so we can easily free - * the name buffer later on. - * - * since LOCKPARENT is not set, ni_dvp will be garbage on - * return whether an error occurs or not. - */ - nd.ni_cnd.cn_nameiop = LOOKUP; - nd.ni_cnd.cn_flags &= ~(LOCKPARENT | FOLLOW); - nd.ni_cnd.cn_flags |= (NOFOLLOW | LOCKLEAF); - nd.ni_cnd.cn_thread = curthread; - nd.ni_cnd.cn_cred = cred; - error = lookup(&nd); - nd.ni_dvp = NULL; - - if (error == 0) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid); - if (!error) - error = VOP_GETATTR(nd.ni_vp, vap, cred); - vput(nd.ni_vp); - nd.ni_vp = NULL; - } - } - } -out: - /* - * These releases aren't strictly required, does even doing them - * make any sense? XXX can nfsm_reply() block? - */ - if (pathcp) { - free(pathcp, M_TEMP); - pathcp = NULL; - } - if (dirp) { - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - VOP_UNLOCK(dirp, 0); - } - if (nd.ni_startdir) { - vrele(nd.ni_startdir); - nd.ni_startdir = NULL; - } - nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { - if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); - } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - } - error = 0; - /* fall through */ - -nfsmout: - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vrele(nd.ni_vp); - if (nd.ni_startdir) - vrele(nd.ni_startdir); - if (dirp) - vrele(dirp); - if (pathcp) - free(pathcp, M_TEMP); - - vn_finished_write(mp); - return (error); -} - -/* - * nfs mkdir service - */ -int -nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct vattr va, dirfor, diraft; - struct vattr *vap = &va; - struct nfs_fattr *fp; - struct nameidata nd; - u_int32_t *tl; - caddr_t bpos; - int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *dirp = NULL; - int vpexcl = 0; - nfsfh_t nfh; - fhandle_t *fhp; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto out; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = CREATE; - nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE; - - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (dirp && !v3) { - vrele(dirp); - dirp = NULL; - } - if (error) { - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; - goto nfsmout; - } - VATTR_NULL(vap); - if (v3) { - nfsm_srvsattr(vap); - } else { - tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED); - vap->va_mode = nfstov_mode(*tl++); - } - - /* - * At this point nd.ni_dvp is referenced and exclusively locked and - * nd.ni_vp, if it exists, is referenced but not locked. - */ - - vap->va_type = VDIR; - if (nd.ni_vp != NULL) { - NDFREE(&nd, NDF_ONLY_PNBUF); - error = EEXIST; - goto out; - } - - /* - * Issue mkdir op. Since SAVESTART is not set, the pathname - * component is freed by the VOP call. This will fill-in - * nd.ni_vp, reference, and exclusively lock it. - */ - if (vap->va_mode == (mode_t)VNOVAL) - vap->va_mode = 0; - error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap); - NDFREE(&nd, NDF_ONLY_PNBUF); - vpexcl = 1; - - vput(nd.ni_dvp); - nd.ni_dvp = NULL; - - if (!error) { - bzero((caddr_t)fhp, sizeof(nfh)); - fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid; - error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid); - if (!error) - error = VOP_GETATTR(nd.ni_vp, vap, cred); - } -out: - if (dirp) { - if (dirp == nd.ni_dvp) { - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - } else { - /* Release existing locks to prevent deadlock. */ - if (nd.ni_dvp) { - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == nd.ni_vp && vpexcl) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) { - if (vpexcl) - vput(nd.ni_vp); - else - vrele(nd.ni_vp); - } - nd.ni_dvp = NULL; - nd.ni_vp = NULL; - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - VOP_UNLOCK(dirp, 0); - } - } - nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3)); - if (v3) { - if (!error) { - nfsm_srvpostop_fh(fhp); - nfsm_srvpostop_attr(0, vap); - } - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - } else if (!error) { - /* v2 non-error case. */ - nfsm_srvfhtom(fhp, v3); - fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR); - nfsm_srvfillattr(vap, fp); - } - error = 0; - /* fall through */ - -nfsmout: - if (nd.ni_dvp) { - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == nd.ni_vp && vpexcl) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) { - if (vpexcl) - vput(nd.ni_vp); - else - vrele(nd.ni_vp); - } - if (dirp) - vrele(dirp); - vn_finished_write(mp); - return (error); -} - -/* - * nfs rmdir service - */ -int -nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - caddr_t bpos; - int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *vp, *dirp = NULL; - struct vattr dirfor, diraft; - nfsfh_t nfh; - fhandle_t *fhp; - struct nameidata nd; - struct mount *mp = NULL; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - ndclear(&nd); - - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto out; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - nfsm_srvnamesiz(len); - nd.ni_cnd.cn_cred = cred; - nd.ni_cnd.cn_nameiop = DELETE; - nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF; - error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos, - &dirp, v3, &dirfor, &dirfor_ret, FALSE); - if (dirp && !v3) { - vrele(dirp); - dirp = NULL; - } - if (error) { - nfsm_reply(NFSX_WCCDATA(v3)); - if (v3) - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - error = 0; - goto nfsmout; - } - vp = nd.ni_vp; - if (vp->v_type != VDIR) { - error = ENOTDIR; - goto out; - } - /* - * No rmdir "." please. - */ - if (nd.ni_dvp == vp) { - error = EINVAL; - goto out; - } - /* - * The root of a mounted filesystem cannot be deleted. - */ - if (vp->v_vflag & VV_ROOT) - error = EBUSY; -out: - /* - * Issue or abort op. Since SAVESTART is not set, path name - * component is freed by the VOP after either. - */ - if (!error) - error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); - NDFREE(&nd, NDF_ONLY_PNBUF); - - if (dirp) { - if (dirp == nd.ni_dvp) - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - else { - /* Release existing locks to prevent deadlock. */ - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - nd.ni_dvp = NULL; - nd.ni_vp = NULL; - vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY); - diraft_ret = VOP_GETATTR(dirp, &diraft, cred); - VOP_UNLOCK(dirp, 0); - } - } - nfsm_reply(NFSX_WCCDATA(v3)); - error = 0; - if (v3) - nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft); - /* fall through */ - -nfsmout: - NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp) { - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - } - if (nd.ni_vp) - vput(nd.ni_vp); - if (dirp) - vrele(dirp); - - vn_finished_write(mp); - return(error); -} - -/* - * nfs readdir service - * - mallocs what it thinks is enough to read - * count rounded up to a multiple of NFS_DIRBLKSIZ <= NFS_MAXREADDIR - * - calls VOP_READDIR() - * - loops around building the reply - * if the output generated exceeds count break out of loop - * The nfsm_clget macro is used here so that the reply will be packed - * tightly in mbuf clusters. - * - it only knows that it has encountered eof when the VOP_READDIR() - * reads nothing - * - as such one readdir rpc will return eof false although you are there - * and then the next will return eof - * - it trims out records with d_fileno == 0 - * this doesn't matter for Unix clients, but they might confuse clients - * for other os'. - * NB: It is tempting to set eof to true if the VOP_READDIR() reads less - * than requested, but this may not apply to all filesystems. For - * example, client NFS does not { although it is never remote mounted - * anyhow } - * The alternate call nfsrv_readdirplus() does lookups as well. - * PS: The NFS protocol spec. does not clarify what the "count" byte - * argument is a count of.. just name strings and file id's or the - * entire reply rpc or ... - * I tried just file name and id sizes and it confused the Sun client, - * so I am using the full rpc size now. The "paranoia.." comment refers - * to including the status longwords that are not a part of the dir. - * "entry" structures, but are in the rpc. - */ -struct flrep { - nfsuint64 fl_off; - u_int32_t fl_postopok; - u_int32_t fl_fattr[NFSX_V3FATTR / sizeof (u_int32_t)]; - u_int32_t fl_fhok; - u_int32_t fl_fhsize; - u_int32_t fl_nfh[NFSX_V3FH / sizeof (u_int32_t)]; -}; - -int -nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - char *bp, *be; - struct mbuf *mp; - struct dirent *dp; - caddr_t cp; - u_int32_t *tl; - caddr_t bpos; - struct mbuf *mb, *mreq; - char *cpos, *cend, *rbuf; - struct vnode *vp = NULL; - struct vattr at; - nfsfh_t nfh; - fhandle_t *fhp; - struct uio io; - struct iovec iv; - int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1; - int siz, cnt, fullsiz, eofflag, rdonly, ncookies; - int v3 = (nfsd->nd_flag & ND_NFSV3); - u_quad_t off, toff, verf; - u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */ - int is_ufs; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if (v3) { - tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED); - toff = fxdr_hyper(tl); - tl += 2; - verf = fxdr_hyper(tl); - tl += 2; - } else { - tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED); - toff = fxdr_unsigned(u_quad_t, *tl++); - verf = 0; /* shut up gcc */ - } - off = toff; - cnt = fxdr_unsigned(int, *tl); - siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); - xfer = NFS_SRVMAXDATA(nfsd); - if (cnt > xfer) - cnt = xfer; - if (siz > xfer) - siz = xfer; - fullsiz = siz; - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (!error && vp->v_type != VDIR) { - error = ENOTDIR; - vput(vp); - vp = NULL; - } - if (error) { - nfsm_reply(NFSX_UNSIGNED); - if (v3) - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - - /* - * Obtain lock on vnode for this section of the code - */ - if (v3) { - error = getret = VOP_GETATTR(vp, &at, cred); -#if 0 - /* - * XXX This check may be too strict for Solaris 2.5 clients. - */ - if (!error && toff && verf && verf != at.va_filerev) - error = NFSERR_BAD_COOKIE; -#endif - } - if (!error) - error = nfsrv_access(vp, VEXEC, cred, rdonly, 0); - if (error) { - vput(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3)); - if (v3) - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - is_ufs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "ufs") == 0; - VOP_UNLOCK(vp, 0); - - /* - * end section. Allocate rbuf and continue - */ - rbuf = malloc(siz, M_TEMP, M_WAITOK); -again: - iv.iov_base = rbuf; - iv.iov_len = fullsiz; - io.uio_iov = &iv; - io.uio_iovcnt = 1; - io.uio_offset = (off_t)off; - io.uio_resid = fullsiz; - io.uio_segflg = UIO_SYSSPACE; - io.uio_rw = UIO_READ; - io.uio_td = NULL; - eofflag = 0; - if (cookies) { - free((caddr_t)cookies, M_TEMP); - cookies = NULL; - } - vn_lock(vp, LK_SHARED | LK_RETRY); - error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies); - off = (off_t)io.uio_offset; - if (!cookies && !error) - error = NFSERR_PERM; - if (v3) { - getret = VOP_GETATTR(vp, &at, cred); - if (!error) - error = getret; - } - VOP_UNLOCK(vp, 0); - if (error) { - vrele(vp); - vp = NULL; - free((caddr_t)rbuf, M_TEMP); - if (cookies) - free((caddr_t)cookies, M_TEMP); - nfsm_reply(NFSX_POSTOPATTR(v3)); - if (v3) - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - if (io.uio_resid) { - siz -= io.uio_resid; - - /* - * If nothing read, return eof - * rpc reply - */ - if (siz == 0) { - vrele(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + - 2 * NFSX_UNSIGNED); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED); - txdr_hyper(at.va_filerev, tl); - tl += 2; - } else - tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nfsrv_nfs_false; - *tl = nfsrv_nfs_true; - free((caddr_t)rbuf, M_TEMP); - free((caddr_t)cookies, M_TEMP); - error = 0; - goto nfsmout; - } - } - - /* - * Check for degenerate cases of nothing useful read. - * If so go try again - */ - cpos = rbuf; - cend = rbuf + siz; - dp = (struct dirent *)cpos; - cookiep = cookies; - /* - * For some reason FreeBSD's ufs_readdir() chooses to back the - * directory offset up to a block boundary, so it is necessary to - * skip over the records that precede the requested offset. This - * requires the assumption that file offset cookies monotonically - * increase. - */ - while (cpos < cend && ncookies > 0 && - (dp->d_fileno == 0 || dp->d_type == DT_WHT || - (is_ufs == 1 && ((u_quad_t)(*cookiep)) <= toff))) { - cpos += dp->d_reclen; - dp = (struct dirent *)cpos; - cookiep++; - ncookies--; - } - if (cpos >= cend || ncookies == 0) { - toff = off; - siz = fullsiz; - goto again; - } - - len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */ - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz); - if (v3) { - nfsm_srvpostop_attr(getret, &at); - tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); - txdr_hyper(at.va_filerev, tl); - } - mp = mb; - bp = bpos; - be = bp + M_TRAILINGSPACE(mp); - - /* Loop through the records and build reply */ - while (cpos < cend && ncookies > 0) { - if (dp->d_fileno != 0 && dp->d_type != DT_WHT) { - nlen = dp->d_namlen; - rem = nfsm_rndup(nlen) - nlen; - len += (4 * NFSX_UNSIGNED + nlen + rem); - if (v3) - len += 2 * NFSX_UNSIGNED; - if (len > cnt) { - eofflag = 0; - break; - } - /* - * Build the directory record xdr from - * the dirent entry. - */ - nfsm_clget; - *tl = nfsrv_nfs_true; - bp += NFSX_UNSIGNED; - if (v3) { - nfsm_clget; - *tl = 0; - bp += NFSX_UNSIGNED; - } - nfsm_clget; - *tl = txdr_unsigned(dp->d_fileno); - bp += NFSX_UNSIGNED; - nfsm_clget; - *tl = txdr_unsigned(nlen); - bp += NFSX_UNSIGNED; - - /* And loop around copying the name */ - xfer = nlen; - cp = dp->d_name; - while (xfer > 0) { - nfsm_clget; - if ((bp+xfer) > be) - tsiz = be-bp; - else - tsiz = xfer; - bcopy(cp, bp, tsiz); - bp += tsiz; - xfer -= tsiz; - if (xfer > 0) - cp += tsiz; - } - /* And null pad to an int32_t boundary. */ - for (i = 0; i < rem; i++) - *bp++ = '\0'; - nfsm_clget; - - /* Finish off the record */ - if (v3) { - *tl = 0; - bp += NFSX_UNSIGNED; - nfsm_clget; - } - *tl = txdr_unsigned(*cookiep); - bp += NFSX_UNSIGNED; - } - cpos += dp->d_reclen; - dp = (struct dirent *)cpos; - cookiep++; - ncookies--; - } - vrele(vp); - vp = NULL; - nfsm_clget; - *tl = nfsrv_nfs_false; - bp += NFSX_UNSIGNED; - nfsm_clget; - if (eofflag) - *tl = nfsrv_nfs_true; - else - *tl = nfsrv_nfs_false; - bp += NFSX_UNSIGNED; - if (mp != mb) { - if (bp < be) - mp->m_len = bp - mtod(mp, caddr_t); - } else - mp->m_len += bp - bpos; - free((caddr_t)rbuf, M_TEMP); - free((caddr_t)cookies, M_TEMP); - -nfsmout: - if (vp) - vrele(vp); - return(error); -} - -int -nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - char *bp, *be; - struct mbuf *mp; - struct dirent *dp; - caddr_t cp; - u_int32_t *tl; - caddr_t bpos; - struct mbuf *mb, *mreq; - char *cpos, *cend, *rbuf; - struct vnode *vp = NULL, *nvp; - struct flrep fl; - nfsfh_t nfh; - fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh; - struct uio io; - struct iovec iv; - struct vattr va, at, *vap = &va; - struct nfs_fattr *fp; - int len, nlen, rem, xfer, tsiz, i, error = 0, error1, getret = 1; - int vp_locked; - int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies; - u_quad_t off, toff, verf; - u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */ - int v3 = (nfsd->nd_flag & ND_NFSV3); - int usevget = 1; - struct componentname cn; - struct mount *mntp = NULL; - int is_ufs; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - vp_locked = 0; - if (!v3) - panic("nfsrv_readdirplus: v3 proc called on a v2 connection"); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - tl = nfsm_dissect_nonblock(u_int32_t *, 6 * NFSX_UNSIGNED); - toff = fxdr_hyper(tl); - tl += 2; - verf = fxdr_hyper(tl); - tl += 2; - siz = fxdr_unsigned(int, *tl++); - cnt = fxdr_unsigned(int, *tl); - off = toff; - siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1)); - xfer = NFS_SRVMAXDATA(nfsd); - if (cnt > xfer) - cnt = xfer; - if (siz > xfer) - siz = xfer; - fullsiz = siz; - error = nfsrv_fhtovp(fhp, NFSRV_FLAG_BUSY, &vp, nfsd, slp, - nam, &rdonly); - if (!error) { - vp_locked = 1; - mntp = vp->v_mount; - if (vp->v_type != VDIR) { - error = ENOTDIR; - vput(vp); - vp = NULL; - vp_locked = 0; - } - } - if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - error = getret = VOP_GETATTR(vp, &at, cred); -#if 0 - /* - * XXX This check may be too strict for Solaris 2.5 clients. - */ - if (!error && toff && verf && verf != at.va_filerev) - error = NFSERR_BAD_COOKIE; -#endif - if (!error) - error = nfsrv_access(vp, VEXEC, cred, rdonly, 0); - if (error) { - vput(vp); - vp_locked = 0; - vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR); - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - is_ufs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "ufs") == 0; - VOP_UNLOCK(vp, 0); - vp_locked = 0; - rbuf = malloc(siz, M_TEMP, M_WAITOK); -again: - iv.iov_base = rbuf; - iv.iov_len = fullsiz; - io.uio_iov = &iv; - io.uio_iovcnt = 1; - io.uio_offset = (off_t)off; - io.uio_resid = fullsiz; - io.uio_segflg = UIO_SYSSPACE; - io.uio_rw = UIO_READ; - io.uio_td = NULL; - eofflag = 0; - vp_locked = 1; - if (cookies) { - free((caddr_t)cookies, M_TEMP); - cookies = NULL; - } - vn_lock(vp, LK_SHARED | LK_RETRY); - error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies); - off = (u_quad_t)io.uio_offset; - getret = VOP_GETATTR(vp, &at, cred); - VOP_UNLOCK(vp, 0); - vp_locked = 0; - if (!cookies && !error) - error = NFSERR_PERM; - if (!error) - error = getret; - if (error) { - vrele(vp); - vp = NULL; - if (cookies) - free((caddr_t)cookies, M_TEMP); - free((caddr_t)rbuf, M_TEMP); - nfsm_reply(NFSX_V3POSTOPATTR); - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - if (io.uio_resid) { - siz -= io.uio_resid; - - /* - * If nothing read, return eof - * rpc reply - */ - if (siz == 0) { - vrele(vp); - vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + - 2 * NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); - tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED); - txdr_hyper(at.va_filerev, tl); - tl += 2; - *tl++ = nfsrv_nfs_false; - *tl = nfsrv_nfs_true; - free((caddr_t)cookies, M_TEMP); - free((caddr_t)rbuf, M_TEMP); - error = 0; - goto nfsmout; - } - } - - /* - * Check for degenerate cases of nothing useful read. - * If so go try again - */ - cpos = rbuf; - cend = rbuf + siz; - dp = (struct dirent *)cpos; - cookiep = cookies; - /* - * For some reason FreeBSD's ufs_readdir() chooses to back the - * directory offset up to a block boundary, so it is necessary to - * skip over the records that precede the requested offset. This - * requires the assumption that file offset cookies monotonically - * increase. - */ - while (cpos < cend && ncookies > 0 && - (dp->d_fileno == 0 || dp->d_type == DT_WHT || - (is_ufs == 1 && ((u_quad_t)(*cookiep)) <= toff))) { - cpos += dp->d_reclen; - dp = (struct dirent *)cpos; - cookiep++; - ncookies--; - } - if (cpos >= cend || ncookies == 0) { - toff = off; - siz = fullsiz; - goto again; - } - - dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + - 2 * NFSX_UNSIGNED; - nfsm_reply(cnt); - nfsm_srvpostop_attr(getret, &at); - tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED); - txdr_hyper(at.va_filerev, tl); - mp = mb; - bp = bpos; - be = bp + M_TRAILINGSPACE(mp); - - /* Loop through the records and build reply */ - while (cpos < cend && ncookies > 0) { - if (dp->d_fileno != 0 && dp->d_type != DT_WHT) { - nlen = dp->d_namlen; - rem = nfsm_rndup(nlen)-nlen; - - if (usevget) { - /* - * For readdir_and_lookup get the vnode using - * the file number. - */ - error = VFS_VGET(mntp, dp->d_fileno, LK_SHARED, - &nvp); - if (error != 0 && error != EOPNOTSUPP) { - error = 0; - goto invalid; - } else if (error == EOPNOTSUPP) { - /* - * VFS_VGET() not supported? - * Let's switch to VOP_LOOKUP(). - */ - error = 0; - usevget = 0; - cn.cn_nameiop = LOOKUP; - cn.cn_flags = ISLASTCN | NOFOLLOW | \ - LOCKSHARED | LOCKLEAF; - cn.cn_lkflags = LK_SHARED | LK_RETRY; - cn.cn_cred = cred; - cn.cn_thread = curthread; - } - } - if (!usevget) { - cn.cn_nameptr = dp->d_name; - cn.cn_namelen = dp->d_namlen; - if (dp->d_namlen == 2 && - dp->d_name[0] == '.' && - dp->d_name[1] == '.') { - cn.cn_flags |= ISDOTDOT; - } else { - cn.cn_flags &= ~ISDOTDOT; - } - if (!vp_locked) { - vn_lock(vp, LK_SHARED | LK_RETRY); - vp_locked = 1; - } - if ((vp->v_vflag & VV_ROOT) != 0 && - (cn.cn_flags & ISDOTDOT) != 0) { - vref(vp); - nvp = vp; - } else if (VOP_LOOKUP(vp, &nvp, &cn) != 0) - goto invalid; - } - - bzero((caddr_t)nfhp, NFSX_V3FH); - nfhp->fh_fsid = nvp->v_mount->mnt_stat.f_fsid; - if ((error1 = VOP_VPTOFH(nvp, &nfhp->fh_fid)) == 0) - error1 = VOP_GETATTR(nvp, vap, cred); - if (!usevget && vp == nvp) - vunref(nvp); - else - vput(nvp); - nvp = NULL; - if (error1 != 0) - goto invalid; - - /* - * If either the dircount or maxcount will be - * exceeded, get out now. Both of these lengths - * are calculated conservatively, including all - * XDR overheads. - */ - len += (8 * NFSX_UNSIGNED + nlen + rem + NFSX_V3FH + - NFSX_V3POSTOPATTR); - dirlen += (6 * NFSX_UNSIGNED + nlen + rem); - if (len > cnt || dirlen > fullsiz) { - eofflag = 0; - break; - } - - /* - * Build the directory record xdr from - * the dirent entry. - */ - fp = (struct nfs_fattr *)&fl.fl_fattr; - nfsm_srvfillattr(vap, fp); - fl.fl_fhsize = txdr_unsigned(NFSX_V3FH); - fl.fl_fhok = nfsrv_nfs_true; - fl.fl_postopok = nfsrv_nfs_true; - fl.fl_off.nfsuquad[0] = 0; - fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep); - - nfsm_clget; - *tl = nfsrv_nfs_true; - bp += NFSX_UNSIGNED; - nfsm_clget; - *tl = 0; - bp += NFSX_UNSIGNED; - nfsm_clget; - *tl = txdr_unsigned(dp->d_fileno); - bp += NFSX_UNSIGNED; - nfsm_clget; - *tl = txdr_unsigned(nlen); - bp += NFSX_UNSIGNED; - - /* And loop around copying the name */ - xfer = nlen; - cp = dp->d_name; - while (xfer > 0) { - nfsm_clget; - if ((bp + xfer) > be) - tsiz = be - bp; - else - tsiz = xfer; - bcopy(cp, bp, tsiz); - bp += tsiz; - xfer -= tsiz; - if (xfer > 0) - cp += tsiz; - } - /* And null pad to an int32_t boundary. */ - for (i = 0; i < rem; i++) - *bp++ = '\0'; - - /* - * Now copy the flrep structure out. - */ - xfer = sizeof (struct flrep); - cp = (caddr_t)&fl; - while (xfer > 0) { - nfsm_clget; - if ((bp + xfer) > be) - tsiz = be - bp; - else - tsiz = xfer; - bcopy(cp, bp, tsiz); - bp += tsiz; - xfer -= tsiz; - if (xfer > 0) - cp += tsiz; - } - } -invalid: - cpos += dp->d_reclen; - dp = (struct dirent *)cpos; - cookiep++; - ncookies--; - } - if (!usevget && vp_locked) - vput(vp); - else - vrele(vp); - vp = NULL; - nfsm_clget; - *tl = nfsrv_nfs_false; - bp += NFSX_UNSIGNED; - nfsm_clget; - if (eofflag) - *tl = nfsrv_nfs_true; - else - *tl = nfsrv_nfs_false; - bp += NFSX_UNSIGNED; - if (mp != mb) { - if (bp < be) - mp->m_len = bp - mtod(mp, caddr_t); - } else - mp->m_len += bp - bpos; - free((caddr_t)cookies, M_TEMP); - free((caddr_t)rbuf, M_TEMP); -nfsmout: - if (vp) - vrele(vp); - if (mntp) - vfs_unbusy(mntp); - return(error); -} - -/* - * nfs commit service - */ -int -nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct vattr bfor, aft; - struct vnode *vp = NULL; - nfsfh_t nfh; - fhandle_t *fhp; - u_int32_t *tl; - caddr_t bpos; - int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt; - struct mbuf *mb, *mreq; - u_quad_t off; - struct mount *mp = NULL; - int v3 = (nfsd->nd_flag & ND_NFSV3); - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (!v3) - panic("nfsrv_commit: v3 proc called on a v2 connection"); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) { - error = ESTALE; - goto ereply; - } - (void) vn_start_write(NULL, &mp, V_WAIT); - vfs_rel(mp); /* The write holds a ref. */ - tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED); - - /* - * XXX At this time VOP_FSYNC() does not accept offset and byte - * count parameters, so these arguments are useless (someday maybe). - */ - off = fxdr_hyper(tl); - tl += 2; - cnt = fxdr_unsigned(int, *tl); - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); - nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft); - error = 0; - goto nfsmout; - } - for_ret = VOP_GETATTR(vp, &bfor, cred); - - /* - * RFC 1813 3.3.21: if count is 0, a flush from offset to the end of file - * is done. At this time VOP_FSYNC does not accept offset and byte count - * parameters so call VOP_FSYNC the whole file for now. - */ - if (cnt == 0 || cnt > MAX_COMMIT_COUNT) { - /* - * Give up and do the whole thing - */ - if (vp->v_object && - (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - VM_OBJECT_WLOCK(vp->v_object); - vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC); - VM_OBJECT_WUNLOCK(vp->v_object); - } - error = VOP_FSYNC(vp, MNT_WAIT, curthread); - } else { - /* - * Locate and synchronously write any buffers that fall - * into the requested range. Note: we are assuming that - * f_iosize is a power of 2. - */ - int iosize = vp->v_mount->mnt_stat.f_iosize; - int iomask = iosize - 1; - struct bufobj *bo; - daddr_t lblkno; - - /* - * Align to iosize boundry, super-align to page boundry. - */ - if (off & iomask) { - cnt += off & iomask; - off &= ~(u_quad_t)iomask; - } - if (off & PAGE_MASK) { - cnt += off & PAGE_MASK; - off &= ~(u_quad_t)PAGE_MASK; - } - lblkno = off / iosize; - - if (vp->v_object && - (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) { - VM_OBJECT_WLOCK(vp->v_object); - vm_object_page_clean(vp->v_object, off, off + cnt, - OBJPC_SYNC); - VM_OBJECT_WUNLOCK(vp->v_object); - } - - bo = &vp->v_bufobj; - BO_LOCK(bo); - while (cnt > 0) { - struct buf *bp; - - /* - * If we have a buffer and it is marked B_DELWRI we - * have to lock and write it. Otherwise the prior - * write is assumed to have already been committed. - * - * gbincore() can return invalid buffers now so we - * have to check that bit as well (though B_DELWRI - * should not be set if B_INVAL is set there could be - * a race here since we haven't locked the buffer). - */ - if ((bp = gbincore(&vp->v_bufobj, lblkno)) != NULL) { - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL | - LK_INTERLOCK, BO_LOCKPTR(bo)) == ENOLCK) { - BO_LOCK(bo); - continue; /* retry */ - } - if ((bp->b_flags & (B_DELWRI|B_INVAL)) == - B_DELWRI) { - bremfree(bp); - bp->b_flags &= ~B_ASYNC; - bwrite(bp); - ++nfs_commit_miss; - } else - BUF_UNLOCK(bp); - BO_LOCK(bo); - } - ++nfs_commit_blks; - if (cnt < iosize) - break; - cnt -= iosize; - ++lblkno; - } - BO_UNLOCK(bo); - } - - aft_ret = VOP_GETATTR(vp, &aft, cred); - vput(vp); - vp = NULL; -ereply: - nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF); - nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft); - if (!error) { - tl = nfsm_build(u_int32_t *, NFSX_V3WRITEVERF); - if (nfsver.tv_sec == 0) - nfsver = boottime; - *tl++ = txdr_unsigned(nfsver.tv_sec); - *tl = txdr_unsigned(nfsver.tv_usec); - } else { - error = 0; - } -nfsmout: - if (vp) - vput(vp); - vn_finished_write(mp); - return(error); -} - -/* - * nfs statfs service - */ -int -nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct statfs *sf; - struct nfs_statfs *sfp; - caddr_t bpos; - int error = 0, rdonly, getret = 1; - int v3 = (nfsd->nd_flag & ND_NFSV3); - struct mbuf *mb, *mreq; - struct vnode *vp = NULL; - struct vattr at; - nfsfh_t nfh; - fhandle_t *fhp; - struct statfs statfs; - u_quad_t tval; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(NFSX_UNSIGNED); - if (v3) - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - sf = &statfs; - error = VFS_STATFS(vp->v_mount, sf); - getret = VOP_GETATTR(vp, &at, cred); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3)); - if (v3) - nfsm_srvpostop_attr(getret, &at); - if (error) { - error = 0; - goto nfsmout; - } - sfp = nfsm_build(struct nfs_statfs *, NFSX_STATFS(v3)); - if (v3) { - tval = (u_quad_t)sf->f_blocks; - tval *= (u_quad_t)sf->f_bsize; - txdr_hyper(tval, &sfp->sf_tbytes); - tval = (u_quad_t)sf->f_bfree; - tval *= (u_quad_t)sf->f_bsize; - txdr_hyper(tval, &sfp->sf_fbytes); - /* - * Don't send negative values for available space, - * since this field is unsigned in the NFS protocol. - * Otherwise, the client would see absurdly high - * numbers for free space. - */ - if (sf->f_bavail < 0) - tval = 0; - else - tval = (u_quad_t)sf->f_bavail; - tval *= (u_quad_t)sf->f_bsize; - txdr_hyper(tval, &sfp->sf_abytes); - sfp->sf_tfiles.nfsuquad[0] = 0; - sfp->sf_tfiles.nfsuquad[1] = txdr_unsigned(sf->f_files); - sfp->sf_ffiles.nfsuquad[0] = 0; - sfp->sf_ffiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree); - sfp->sf_afiles.nfsuquad[0] = 0; - sfp->sf_afiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree); - sfp->sf_invarsec = 0; - } else { - sfp->sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA); - sfp->sf_bsize = txdr_unsigned(sf->f_bsize); - sfp->sf_blocks = txdr_unsigned(sf->f_blocks); - sfp->sf_bfree = txdr_unsigned(sf->f_bfree); - if (sf->f_bavail < 0) - sfp->sf_bavail = 0; - else - sfp->sf_bavail = txdr_unsigned(sf->f_bavail); - } -nfsmout: - if (vp) - vput(vp); - return(error); -} - -/* - * nfs fsinfo service - */ -int -nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nfsv3_fsinfo *sip; - caddr_t bpos; - int error = 0, rdonly, getret = 1, pref; - struct mbuf *mb, *mreq; - struct vnode *vp = NULL; - struct vattr at; - nfsfh_t nfh; - fhandle_t *fhp; - u_quad_t maxfsize; - struct statfs sb; - int v3 = (nfsd->nd_flag & ND_NFSV3); - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (!v3) - panic("nfsrv_fsinfo: v3 proc called on a v2 connection"); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - - /* XXX Try to make a guess on the max file size. */ - VFS_STATFS(vp->v_mount, &sb); - maxfsize = (u_quad_t)0x80000000 * sb.f_bsize - 1; - - getret = VOP_GETATTR(vp, &at, cred); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO); - nfsm_srvpostop_attr(getret, &at); - sip = nfsm_build(struct nfsv3_fsinfo *, NFSX_V3FSINFO); - - /* - * XXX - * There should be filesystem VFS OP(s) to get this information. - * For now, assume ufs. - */ - pref = NFS_SRVMAXDATA(nfsd); - sip->fs_rtmax = txdr_unsigned(pref); - sip->fs_rtpref = txdr_unsigned(pref); - sip->fs_rtmult = txdr_unsigned(NFS_FABLKSIZE); - sip->fs_wtmax = txdr_unsigned(pref); - sip->fs_wtpref = txdr_unsigned(pref); - sip->fs_wtmult = txdr_unsigned(NFS_FABLKSIZE); - sip->fs_dtpref = txdr_unsigned(pref); - txdr_hyper(maxfsize, &sip->fs_maxfilesize); - sip->fs_timedelta.nfsv3_sec = 0; - sip->fs_timedelta.nfsv3_nsec = txdr_unsigned(1); - sip->fs_properties = txdr_unsigned(NFSV3FSINFO_LINK | - NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS | - NFSV3FSINFO_CANSETTIME); -nfsmout: - if (vp) - vput(vp); - return(error); -} - -/* - * nfs pathconf service - */ -int -nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md; - struct sockaddr *nam = nfsd->nd_nam; - caddr_t dpos = nfsd->nd_dpos; - struct ucred *cred = nfsd->nd_cr; - struct nfsv3_pathconf *pc; - caddr_t bpos; - int error = 0, rdonly, getret = 1; - register_t linkmax, namemax, chownres, notrunc; - struct mbuf *mb, *mreq; - struct vnode *vp = NULL; - struct vattr at; - nfsfh_t nfh; - fhandle_t *fhp; - int v3 = (nfsd->nd_flag & ND_NFSV3); - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (!v3) - panic("nfsrv_pathconf: v3 proc called on a v2 connection"); - fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly); - if (error) { - nfsm_reply(NFSX_UNSIGNED); - nfsm_srvpostop_attr(getret, &at); - error = 0; - goto nfsmout; - } - error = VOP_PATHCONF(vp, _PC_LINK_MAX, &linkmax); - if (!error) - error = VOP_PATHCONF(vp, _PC_NAME_MAX, &namemax); - if (!error) - error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &chownres); - if (!error) - error = VOP_PATHCONF(vp, _PC_NO_TRUNC, ¬runc); - getret = VOP_GETATTR(vp, &at, cred); - vput(vp); - vp = NULL; - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF); - nfsm_srvpostop_attr(getret, &at); - if (error) { - error = 0; - goto nfsmout; - } - pc = nfsm_build(struct nfsv3_pathconf *, NFSX_V3PATHCONF); - - pc->pc_linkmax = txdr_unsigned(linkmax); - pc->pc_namemax = txdr_unsigned(namemax); - pc->pc_notrunc = txdr_unsigned(notrunc); - pc->pc_chownrestricted = txdr_unsigned(chownres); - - /* - * These should probably be supported by VOP_PATHCONF(), but - * until msdosfs is exportable (why would you want to?), the - * Unix defaults should be ok. - */ - pc->pc_caseinsensitive = nfsrv_nfs_false; - pc->pc_casepreserving = nfsrv_nfs_true; -nfsmout: - if (vp) - vput(vp); - return(error); -} - -/* - * Null operation, used by clients to ping server - */ -/* ARGSUSED */ -int -nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep; - caddr_t bpos; - int error = NFSERR_RETVOID; - struct mbuf *mb, *mreq; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - nfsm_reply(0); -nfsmout: - return (error); -} - -/* - * No operation, used for obsolete procedures - */ -/* ARGSUSED */ -int -nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct mbuf **mrq) -{ - struct mbuf *mrep = nfsd->nd_mrep; - caddr_t bpos; - int error; - struct mbuf *mb, *mreq; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - if (nfsd->nd_repstat) - error = nfsd->nd_repstat; - else - error = EPROCUNAVAIL; - nfsm_reply(0); - error = 0; -nfsmout: - return (error); -} - -/* - * Perform access checking for vnodes obtained from file handles that would - * refer to files already opened by a Unix client. You cannot just use - * vn_writechk() and VOP_ACCESS() for two reasons. - * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write - * case. - * 2 - The owner is to be given access irrespective of mode bits for some - * operations, so that processes that chmod after opening a file don't - * break. I don't like this because it opens a security hole, but since - * the nfs server opens a security hole the size of a barn door anyhow, - * what the heck. - * - * The exception to rule 2 is EPERM. If a file is IMMUTABLE, VOP_ACCESS() - * will return EPERM instead of EACCES. EPERM is always an error. - */ -static int -nfsrv_access(struct vnode *vp, accmode_t accmode, struct ucred *cred, - int rdonly, int override) -{ - struct vattr vattr; - int error; - - nfsdbprintf(("%s %d\n", __FILE__, __LINE__)); - - if (accmode & VWRITE) { - /* Just vn_writechk() changed to check rdonly */ - /* - * Disallow write attempts on read-only filesystems; - * unless the file is a socket or a block or character - * device resident on the filesystem. - */ - if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) { - switch (vp->v_type) { - case VREG: - case VDIR: - case VLNK: - return (EROFS); - default: - break; - } - } - /* - * If there's shared text associated with - * the inode, we can't allow writing. - */ - if (VOP_IS_TEXT(vp)) - return (ETXTBSY); - } - - error = VOP_GETATTR(vp, &vattr, cred); - if (error) - return (error); - error = VOP_ACCESS(vp, accmode, cred, curthread); - /* - * Allow certain operations for the owner (reads and writes - * on files that are already open). - */ - if (override && error == EACCES && cred->cr_uid == vattr.va_uid) - error = 0; - return (error); -} diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c deleted file mode 100644 index 8bd045a3278..00000000000 --- a/sys/nfsserver/nfs_srvkrpc.c +++ /dev/null @@ -1,545 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_inet6.h" -#include "opt_kgssapi.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef INET6 -#include -#include /* XXX: for in6_var.h */ -#include /* XXX: for ip6_sprintf */ -#endif - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -static MALLOC_DEFINE(M_NFSSVC, "nfss_srvsock", "Nfs server structure"); - -MALLOC_DEFINE(M_NFSRVDESC, "nfss_srvdesc", "NFS server socket descriptor"); -MALLOC_DEFINE(M_NFSD, "nfss_daemon", "Nfs server daemon structure"); - -#define TRUE 1 -#define FALSE 0 - -SYSCTL_DECL(_vfs_nfsrv); - -SVCPOOL *nfsrv_pool; -int nfsd_waiting = 0; -int nfsrv_numnfsd = 0; -struct callout nfsrv_callout; -static eventhandler_tag nfsrv_nmbclusters_tag; - -static int nfs_privport = 0; -SYSCTL_INT(_vfs_nfsrv, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW, - &nfs_privport, 0, - "Only allow clients using a privileged port"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay, CTLFLAG_RW, - &nfsrvw_procrastinate, 0, - "Delay value for write gathering"); -SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay_v3, CTLFLAG_RW, - &nfsrvw_procrastinate_v3, 0, - "Delay in seconds for NFSv3 write gathering"); - -static int nfssvc_addsock(struct file *, struct thread *); -static int nfssvc_nfsd(struct thread *, struct nfsd_nfsd_args *); - -extern u_long sb_max_adj; - -int32_t (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd, - struct nfssvc_sock *slp, struct mbuf **mreqp) = { - nfsrv_null, - nfsrv_getattr, - nfsrv_setattr, - nfsrv_lookup, - nfsrv3_access, - nfsrv_readlink, - nfsrv_read, - nfsrv_write, - nfsrv_create, - nfsrv_mkdir, - nfsrv_symlink, - nfsrv_mknod, - nfsrv_remove, - nfsrv_rmdir, - nfsrv_rename, - nfsrv_link, - nfsrv_readdir, - nfsrv_readdirplus, - nfsrv_statfs, - nfsrv_fsinfo, - nfsrv_pathconf, - nfsrv_commit, - nfsrv_noop -}; - -/* - * NFS server system calls - */ -/* - * This is now called from nfssvc() in nfs/nfs_nfssvc.c. - */ - -/* - * Nfs server psuedo system call for the nfsd's - * Based on the flag value it either: - * - adds a socket to the selection list - * - remains in the kernel as an nfsd - * - remains in the kernel as an nfsiod - * For INET6 we suppose that nfsd provides only IN6P_IPV6_V6ONLY sockets - * and that mountd provides - * - sockaddr with no IPv4-mapped addresses - * - mask for both INET and INET6 families if there is IPv4-mapped overlap - */ -int -nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap) -{ - struct file *fp; - struct nfsd_addsock_args addsockarg; - struct nfsd_nfsd_args nfsdarg; - cap_rights_t rights; - int error; - - if (uap->flag & NFSSVC_ADDSOCK) { - error = copyin(uap->argp, (caddr_t)&addsockarg, - sizeof(addsockarg)); - if (error) - return (error); - error = fget(td, addsockarg.sock, - cap_rights_init(&rights, CAP_SOCK_SERVER), &fp); - if (error) - return (error); - if (fp->f_type != DTYPE_SOCKET) { - fdrop(fp, td); - return (error); /* XXXRW: Should be EINVAL? */ - } - error = nfssvc_addsock(fp, td); - fdrop(fp, td); - } else if (uap->flag & NFSSVC_OLDNFSD) - error = nfssvc_nfsd(td, NULL); - else if (uap->flag & NFSSVC_NFSD) { - if (!uap->argp) - return (EINVAL); - error = copyin(uap->argp, (caddr_t)&nfsdarg, - sizeof(nfsdarg)); - if (error) - return (error); - error = nfssvc_nfsd(td, &nfsdarg); - } else - error = ENXIO; - return (error); -} - -/* - * Generate the rpc reply header - * siz arg. is used to decide if adding a cluster is worthwhile - */ -struct mbuf * -nfs_rephead(int siz, struct nfsrv_descript *nd, int err, - struct mbuf **mbp, caddr_t *bposp) -{ - u_int32_t *tl; - struct mbuf *mreq; - caddr_t bpos; - struct mbuf *mb; - - if (err == EBADRPC) - return (NULL); - - nd->nd_repstat = err; - if (err && (nd->nd_flag & ND_NFSV3) == 0) /* XXX recheck */ - siz = 0; - - MGET(mreq, M_WAITOK, MT_DATA); - - /* - * If this is a big reply, use a cluster - */ - mreq->m_len = 0; - if (siz >= MINCLSIZE) { - MCLGET(mreq, M_WAITOK); - } - mb = mreq; - bpos = mtod(mb, caddr_t); - - if (err != NFSERR_RETVOID) { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - if (err) - *tl = txdr_unsigned(nfsrv_errmap(nd, err)); - else - *tl = 0; - } - - *mbp = mb; - *bposp = bpos; - if (err != 0 && err != NFSERR_RETVOID) - nfsrvstats.srvrpc_errs++; - - return (mreq); -} - -static void -nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) -{ - rpcproc_t procnum; - int32_t (*proc)(struct nfsrv_descript *nd, struct nfssvc_sock *slp, - struct mbuf **mreqp); - int flag; - struct nfsrv_descript nd; - struct mbuf *mreq, *mrep; - int error; - - if (rqst->rq_vers == NFS_VER2) { - if (rqst->rq_proc > NFSV2PROC_STATFS) { - svcerr_noproc(rqst); - svc_freereq(rqst); - return; - } - procnum = nfsrv_nfsv3_procid[rqst->rq_proc]; - flag = 0; - } else { - if (rqst->rq_proc >= NFS_NPROCS) { - svcerr_noproc(rqst); - svc_freereq(rqst); - return; - } - procnum = rqst->rq_proc; - flag = ND_NFSV3; - } - proc = nfsrv3_procs[procnum]; - - mreq = mrep = NULL; - mreq = rqst->rq_args; - rqst->rq_args = NULL; - (void)nfs_realign(&mreq, M_WAITOK); - - /* - * Note: we want rq_addr, not svc_getrpccaller for nd_nam2 - - * NFS_SRVMAXDATA uses a NULL value for nd_nam2 to detect TCP - * mounts. - */ - memset(&nd, 0, sizeof(nd)); - nd.nd_md = nd.nd_mrep = mreq; - nd.nd_dpos = mtod(mreq, caddr_t); - nd.nd_nam = svc_getrpccaller(rqst); - nd.nd_nam2 = rqst->rq_addr; - nd.nd_procnum = procnum; - nd.nd_cr = NULL; - nd.nd_flag = flag; - - if (nfs_privport) { - /* Check if source port is privileged */ - u_short port; - struct sockaddr *nam = nd.nd_nam; - struct sockaddr_in *sin; - - sin = (struct sockaddr_in *)nam; - /* - * INET/INET6 - same code: - * sin_port and sin6_port are at same offset - */ - port = ntohs(sin->sin_port); - if (port >= IPPORT_RESERVED && - nd.nd_procnum != NFSPROC_NULL) { -#ifdef INET6 - char b6[INET6_ADDRSTRLEN]; -#if defined(KLD_MODULE) - /* Do not use ip6_sprintf: the nfs module should work without INET6. */ -#define ip6_sprintf(buf, a) \ - (sprintf((buf), "%x:%x:%x:%x:%x:%x:%x:%x", \ - (a)->s6_addr16[0], (a)->s6_addr16[1], \ - (a)->s6_addr16[2], (a)->s6_addr16[3], \ - (a)->s6_addr16[4], (a)->s6_addr16[5], \ - (a)->s6_addr16[6], (a)->s6_addr16[7]), \ - (buf)) -#endif -#endif - printf("NFS request from unprivileged port (%s:%d)\n", -#ifdef INET6 - sin->sin_family == AF_INET6 ? - ip6_sprintf(b6, &satosin6(sin)->sin6_addr) : -#if defined(KLD_MODULE) -#undef ip6_sprintf -#endif -#endif - inet_ntoa(sin->sin_addr), port); - m_freem(mreq); - svcerr_weakauth(rqst); - svc_freereq(rqst); - return; - } - } - - if (proc != nfsrv_null) { - if (!svc_getcred(rqst, &nd.nd_cr, &nd.nd_credflavor)) { - m_freem(mreq); - svcerr_weakauth(rqst); - svc_freereq(rqst); - return; - } -#ifdef MAC - mac_cred_associate_nfsd(nd.nd_cr); -#endif - } - nfsrvstats.srvrpccnt[nd.nd_procnum]++; - - error = proc(&nd, NULL, &mrep); - - if (nd.nd_cr) - crfree(nd.nd_cr); - - if (mrep == NULL) { - svcerr_decode(rqst); - svc_freereq(rqst); - return; - } - if (error && error != NFSERR_RETVOID) { - svcerr_systemerr(rqst); - svc_freereq(rqst); - return; - } - if (nd.nd_repstat & NFSERR_AUTHERR) { - svcerr_auth(rqst, nd.nd_repstat & ~NFSERR_AUTHERR); - m_freem(mrep); - } else { - if (!svc_sendreply_mbuf(rqst, mrep)) - svcerr_systemerr(rqst); - } - svc_freereq(rqst); -} - -/* - * Adds a socket to the list for servicing by nfsds. - */ -static int -nfssvc_addsock(struct file *fp, struct thread *td) -{ - int siz; - struct socket *so; - int error; - SVCXPRT *xprt; - - so = fp->f_data; - - siz = sb_max_adj; - error = soreserve(so, siz, siz); - if (error) - return (error); - - /* - * Steal the socket from userland so that it doesn't close - * unexpectedly. - */ - if (so->so_type == SOCK_DGRAM) - xprt = svc_dg_create(nfsrv_pool, so, 0, 0); - else - xprt = svc_vc_create(nfsrv_pool, so, 0, 0); - if (xprt) { - fp->f_ops = &badfileops; - fp->f_data = NULL; - svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, NULL); - svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, NULL); - SVC_RELEASE(xprt); - } - - return (0); -} - -/* - * Called by nfssvc() for nfsds. Just loops around servicing rpc requests - * until it is killed by a signal. - */ -static int -nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args) -{ - char principal[128]; - int error; - - if (args) { - error = copyinstr(args->principal, principal, - sizeof(principal), NULL); - if (error) - return (error); - } else { - memcpy(principal, "nfs@", 4); - getcredhostname(td->td_ucred, principal + 4, - sizeof(principal) - 4); - } - - /* - * Only the first nfsd actually does any work. The RPC code - * adds threads to it as needed. Any extra processes offered - * by nfsd just exit. If nfsd is new enough, it will call us - * once with a structure that specifies how many threads to - * use. - */ - NFSD_LOCK(); - if (nfsrv_numnfsd == 0) { - nfsrv_numnfsd++; - - NFSD_UNLOCK(); - - rpc_gss_set_svc_name_call(principal, "kerberosv5", - GSS_C_INDEFINITE, NFS_PROG, NFS_VER2); - rpc_gss_set_svc_name_call(principal, "kerberosv5", - GSS_C_INDEFINITE, NFS_PROG, NFS_VER3); - - if (args) { - nfsrv_pool->sp_minthreads = args->minthreads; - nfsrv_pool->sp_maxthreads = args->maxthreads; - } else { - nfsrv_pool->sp_minthreads = 4; - nfsrv_pool->sp_maxthreads = 4; - } - - svc_run(nfsrv_pool); - - rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER2); - rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER3); - - NFSD_LOCK(); - nfsrv_numnfsd--; - nfsrv_init(TRUE); - } - NFSD_UNLOCK(); - - return (0); -} - -/* - * Size the NFS server's duplicate request cache at 1/2 the - * nmbclusters, floating within a (64, 2048) range. This is to - * prevent all mbuf clusters being tied up in the NFS dupreq - * cache for small values of nmbclusters. - */ -static size_t -nfsrv_replay_size(void) -{ - size_t replaysiz; - - replaysiz = nmbclusters / 2; - if (replaysiz > NFSRVCACHE_MAX_SIZE) - replaysiz = NFSRVCACHE_MAX_SIZE; - if (replaysiz < NFSRVCACHE_MIN_SIZE) - replaysiz = NFSRVCACHE_MIN_SIZE; - replaysiz *= MCLBYTES; - - return (replaysiz); -} - -/* - * Called when nmbclusters changes - we resize the replay cache - * accordingly. - */ -static void -nfsrv_nmbclusters_change(void *tag) -{ - - if (nfsrv_pool) - replay_setsize(nfsrv_pool->sp_rcache, nfsrv_replay_size()); -} - -/* - * Initialize the data structures for the server. - * Handshake with any new nfsds starting up to avoid any chance of - * corruption. - */ -void -nfsrv_init(int terminating) -{ - - NFSD_LOCK_ASSERT(); - - if (terminating) { - NFSD_UNLOCK(); - EVENTHANDLER_DEREGISTER(nmbclusters_change, - nfsrv_nmbclusters_tag); - svcpool_destroy(nfsrv_pool); - nfsrv_pool = NULL; - NFSD_LOCK(); - } else - nfs_pub.np_valid = 0; - - NFSD_UNLOCK(); - - nfsrv_pool = svcpool_create("nfsd", SYSCTL_STATIC_CHILDREN(_vfs_nfsrv)); - nfsrv_pool->sp_rcache = replay_newcache(nfsrv_replay_size()); - nfsrv_pool->sp_assign = fhaold_assign; - nfsrv_pool->sp_done = fha_nd_complete; - nfsrv_nmbclusters_tag = EVENTHANDLER_REGISTER(nmbclusters_change, - nfsrv_nmbclusters_change, NULL, EVENTHANDLER_PRI_FIRST); - - NFSD_LOCK(); -} diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c deleted file mode 100644 index 04371da91cc..00000000000 --- a/sys/nfsserver/nfs_srvsubs.c +++ /dev/null @@ -1,1418 +0,0 @@ -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * These functions support the macros and help fiddle mbuf chains for - * the nfs op functions. They do things like create the rpc header and - * copy data between mbuf chains and uio lists. - */ - -#include "opt_inet6.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -/* - * Data items converted to xdr at startup, since they are constant - * This is kinda hokey, but may save a little time doing byte swaps - */ -u_int32_t nfsrv_nfs_xdrneg1; -u_int32_t nfsrv_nfs_true, nfsrv_nfs_false; - -/* And other global data */ -static const nfstype nfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, - NFLNK, NFNON, NFCHR, NFNON }; -#define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))]) -#define vtonfsv3_mode(m) txdr_unsigned((m) & ALLPERMS) - -int nfsrv_ticks; - -struct mtx nfsd_mtx; - -/* - * Mapping of old NFS Version 2 RPC numbers to generic numbers. - */ -const int nfsrv_nfsv3_procid[NFS_NPROCS] = { - NFSPROC_NULL, - NFSPROC_GETATTR, - NFSPROC_SETATTR, - NFSPROC_NOOP, - NFSPROC_LOOKUP, - NFSPROC_READLINK, - NFSPROC_READ, - NFSPROC_NOOP, - NFSPROC_WRITE, - NFSPROC_CREATE, - NFSPROC_REMOVE, - NFSPROC_RENAME, - NFSPROC_LINK, - NFSPROC_SYMLINK, - NFSPROC_MKDIR, - NFSPROC_RMDIR, - NFSPROC_READDIR, - NFSPROC_FSSTAT, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, - NFSPROC_NOOP, -}; - -/* - * and the reverse mapping from generic to Version 2 procedure numbers - */ -const int nfsrvv2_procid[NFS_NPROCS] = { - NFSV2PROC_NULL, - NFSV2PROC_GETATTR, - NFSV2PROC_SETATTR, - NFSV2PROC_LOOKUP, - NFSV2PROC_NOOP, - NFSV2PROC_READLINK, - NFSV2PROC_READ, - NFSV2PROC_WRITE, - NFSV2PROC_CREATE, - NFSV2PROC_MKDIR, - NFSV2PROC_SYMLINK, - NFSV2PROC_CREATE, - NFSV2PROC_REMOVE, - NFSV2PROC_RMDIR, - NFSV2PROC_RENAME, - NFSV2PROC_LINK, - NFSV2PROC_READDIR, - NFSV2PROC_NOOP, - NFSV2PROC_STATFS, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, - NFSV2PROC_NOOP, -}; - -/* - * Maps errno values to nfs error numbers. - * Use 0 (which gets converted to NFSERR_IO) as the catch all for ones not - * specifically defined in RFC 1094. - */ -static const u_char nfsrv_v2errmap[ELAST] = { - NFSERR_PERM, NFSERR_NOENT, 0, 0, 0, - NFSERR_NXIO, 0, 0, 0, 0, - 0, 0, NFSERR_ACCES, 0, 0, - 0, NFSERR_EXIST, 0, NFSERR_NODEV, NFSERR_NOTDIR, - NFSERR_ISDIR, 0, 0, 0, 0, - 0, NFSERR_FBIG, NFSERR_NOSPC, 0, NFSERR_ROFS, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, NFSERR_NAMETOL, 0, 0, - NFSERR_NOTEMPTY, 0, 0, NFSERR_DQUOT, NFSERR_STALE, - 0 -}; - -/* - * Maps errno values to nfs error numbers. - * Although it is not obvious whether or not NFS clients really care if - * a returned error value is in the specified list for the procedure, the - * safest thing to do is filter them appropriately. For Version 2, the - * X/Open XNFS document is the only specification that defines error values - * for each RPC (The RFC simply lists all possible error values for all RPCs), - * so I have decided to not do this for Version 2. - * The first entry is the default error return and the rest are the valid - * errors for that RPC in increasing numeric order. - */ -static const short nfsv3err_null[] = { - 0, - 0, -}; - -static const short nfsv3err_getattr[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_setattr[] = { - NFSERR_IO, - NFSERR_PERM, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOT_SYNC, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_lookup[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_NAMETOL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_access[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_readlink[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_read[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_NXIO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_write[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_INVAL, - NFSERR_FBIG, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_create[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_mkdir[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_symlink[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_mknod[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - NFSERR_BADTYPE, - 0, -}; - -static const short nfsv3err_remove[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_rmdir[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_NOTDIR, - NFSERR_INVAL, - NFSERR_ROFS, - NFSERR_NAMETOL, - NFSERR_NOTEMPTY, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_rename[] = { - NFSERR_IO, - NFSERR_NOENT, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_XDEV, - NFSERR_NOTDIR, - NFSERR_ISDIR, - NFSERR_INVAL, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_MLINK, - NFSERR_NAMETOL, - NFSERR_NOTEMPTY, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_link[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_EXIST, - NFSERR_XDEV, - NFSERR_NOTDIR, - NFSERR_INVAL, - NFSERR_NOSPC, - NFSERR_ROFS, - NFSERR_MLINK, - NFSERR_NAMETOL, - NFSERR_DQUOT, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_NOTSUPP, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_readdir[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_BAD_COOKIE, - NFSERR_TOOSMALL, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_readdirplus[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_ACCES, - NFSERR_NOTDIR, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_BAD_COOKIE, - NFSERR_NOTSUPP, - NFSERR_TOOSMALL, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_fsstat[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_fsinfo[] = { - NFSERR_STALE, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_pathconf[] = { - NFSERR_STALE, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short nfsv3err_commit[] = { - NFSERR_IO, - NFSERR_IO, - NFSERR_STALE, - NFSERR_BADHANDLE, - NFSERR_SERVERFAULT, - 0, -}; - -static const short *nfsrv_v3errmap[] = { - nfsv3err_null, - nfsv3err_getattr, - nfsv3err_setattr, - nfsv3err_lookup, - nfsv3err_access, - nfsv3err_readlink, - nfsv3err_read, - nfsv3err_write, - nfsv3err_create, - nfsv3err_mkdir, - nfsv3err_symlink, - nfsv3err_mknod, - nfsv3err_remove, - nfsv3err_rmdir, - nfsv3err_rename, - nfsv3err_link, - nfsv3err_readdir, - nfsv3err_readdirplus, - nfsv3err_fsstat, - nfsv3err_fsinfo, - nfsv3err_pathconf, - nfsv3err_commit, -}; - -extern int (*nfsd_call_nfsserver)(struct thread *, struct nfssvc_args *); - -/* - * Called once to initialize data structures... - */ -static int -nfsrv_modevent(module_t mod, int type, void *data) -{ - int error = 0; - - switch (type) { - case MOD_LOAD: - mtx_init(&nfsd_mtx, "nfsd_mtx", NULL, MTX_DEF); - nfsrv_nfs_true = txdr_unsigned(TRUE); - nfsrv_nfs_false = txdr_unsigned(FALSE); - nfsrv_nfs_xdrneg1 = txdr_unsigned(-1); - nfsrv_ticks = (hz * NFS_TICKINTVL + 500) / 1000; - if (nfsrv_ticks < 1) - nfsrv_ticks = 1; - - NFSD_LOCK(); - nfsrv_init(0); /* Init server data structures */ - NFSD_UNLOCK(); - - nfsd_call_nfsserver = nfssvc_nfsserver; - break; - - case MOD_UNLOAD: - if (nfsrv_numnfsd != 0) { - error = EBUSY; - break; - } - - nfsd_call_nfsserver = NULL; - callout_drain(&nfsrv_callout); - mtx_destroy(&nfsd_mtx); - break; - default: - error = EOPNOTSUPP; - break; - } - return error; -} -static moduledata_t nfsserver_mod = { - "nfsserver", - nfsrv_modevent, - NULL, -}; -DECLARE_MODULE(nfsserver, nfsserver_mod, SI_SUB_VFS, SI_ORDER_ANY); - -/* So that loader and kldload(2) can find us, wherever we are.. */ -MODULE_VERSION(nfsserver, 1); -MODULE_DEPEND(nfsserver, nfssvc, 1, 1, 1); -MODULE_DEPEND(nfsserver, krpc, 1, 1, 1); -MODULE_DEPEND(nfsserver, nfs_common, 1, 1, 1); - -/* - * Set up nameidata for a lookup() call and do it. - * - * If pubflag is set, this call is done for a lookup operation on the - * public filehandle. In that case we allow crossing mountpoints and - * absolute pathnames. However, the caller is expected to check that - * the lookup result is within the public fs, and deny access if - * it is not. - * - * nfs_namei() clears out garbage fields that namei() might leave garbage. - * This is mainly ni_vp and ni_dvp when an error occurs, and ni_dvp when no - * error occurs but the parent was not requested. - * - * dirp may be set whether an error is returned or not, and must be - * released by the caller. - */ -int -nfs_namei(struct nameidata *ndp, struct nfsrv_descript *nfsd, - fhandle_t *fhp, int len, struct nfssvc_sock *slp, - struct sockaddr *nam, struct mbuf **mdp, - caddr_t *dposp, struct vnode **retdirp, int v3, struct vattr *retdirattrp, - int *retdirattr_retp, int pubflag) -{ - int i, rem; - struct mbuf *md; - char *fromcp, *tocp, *cp; - struct iovec aiov; - struct uio auio; - struct vnode *dp; - int error, rdonly, linklen; - struct componentname *cnp = &ndp->ni_cnd; - int lockleaf = (cnp->cn_flags & LOCKLEAF) != 0; - - *retdirp = NULL; - cnp->cn_flags |= NOMACCHECK; - cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK); - - /* - * Copy the name from the mbuf list to ndp->ni_pnbuf - * and set the various ndp fields appropriately. - */ - fromcp = *dposp; - tocp = cnp->cn_pnbuf; - md = *mdp; - rem = mtod(md, caddr_t) + md->m_len - fromcp; - for (i = 0; i < len; i++) { - while (rem == 0) { - md = md->m_next; - if (md == NULL) { - error = EBADRPC; - goto out; - } - fromcp = mtod(md, caddr_t); - rem = md->m_len; - } - if (*fromcp == '\0' || (!pubflag && *fromcp == '/')) { - error = EACCES; - goto out; - } - *tocp++ = *fromcp++; - rem--; - } - *tocp = '\0'; - *mdp = md; - *dposp = fromcp; - len = nfsm_rndup(len)-len; - if (len > 0) { - if (rem >= len) - *dposp += len; - else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0) - goto out; - } - - if (!pubflag && nfs_ispublicfh(fhp)) - return (ESTALE); - - /* - * Extract and set starting directory. - */ - error = nfsrv_fhtovp(fhp, 0, &dp, nfsd, slp, nam, &rdonly); - if (error) - goto out; - if (dp->v_type != VDIR) { - vput(dp); - error = ENOTDIR; - goto out; - } - - if (rdonly) - cnp->cn_flags |= RDONLY; - - /* - * Set return directory. Reference to dp is implicitly transfered - * to the returned pointer - */ - *retdirp = dp; - if (v3) { - *retdirattr_retp = VOP_GETATTR(dp, retdirattrp, - ndp->ni_cnd.cn_cred); - } - - VOP_UNLOCK(dp, 0); - - if (pubflag) { - /* - * Oh joy. For WebNFS, handle those pesky '%' escapes, - * and the 'native path' indicator. - */ - cp = uma_zalloc(namei_zone, M_WAITOK); - fromcp = cnp->cn_pnbuf; - tocp = cp; - if ((unsigned char)*fromcp >= WEBNFS_SPECCHAR_START) { - switch ((unsigned char)*fromcp) { - case WEBNFS_NATIVE_CHAR: - /* - * 'Native' path for us is the same - * as a path according to the NFS spec, - * just skip the escape char. - */ - fromcp++; - break; - /* - * More may be added in the future, range 0x80-0xff - */ - default: - error = EIO; - uma_zfree(namei_zone, cp); - goto out; - } - } - /* - * Translate the '%' escapes, URL-style. - */ - while (*fromcp != '\0') { - if (*fromcp == WEBNFS_ESC_CHAR) { - if (fromcp[1] != '\0' && fromcp[2] != '\0') { - fromcp++; - *tocp++ = HEXSTRTOI(fromcp); - fromcp += 2; - continue; - } else { - error = ENOENT; - uma_zfree(namei_zone, cp); - goto out; - } - } else - *tocp++ = *fromcp++; - } - *tocp = '\0'; - uma_zfree(namei_zone, cnp->cn_pnbuf); - cnp->cn_pnbuf = cp; - } - - ndp->ni_pathlen = (tocp - cnp->cn_pnbuf) + 1; - ndp->ni_segflg = UIO_SYSSPACE; - - if (pubflag) { - ndp->ni_rootdir = rootvnode; - ndp->ni_loopcnt = 0; - - if (cnp->cn_pnbuf[0] == '/') - dp = rootvnode; - } else { - cnp->cn_flags |= NOCROSSMOUNT; - } - - /* - * Initialize for scan, set ni_startdir and bump ref on dp again - * because lookup() will dereference ni_startdir. - */ - - cnp->cn_thread = curthread; - VREF(dp); - ndp->ni_startdir = dp; - - if (!lockleaf) - cnp->cn_flags |= LOCKLEAF; - for (;;) { - cnp->cn_nameptr = cnp->cn_pnbuf; - /* - * Call lookup() to do the real work. If an error occurs, - * ndp->ni_vp and ni_dvp are left uninitialized or NULL and - * we do not have to dereference anything before returning. - * In either case ni_startdir will be dereferenced and NULLed - * out. - */ - error = lookup(ndp); - if (error) - break; - - /* - * Check for encountering a symbolic link. Trivial - * termination occurs if no symlink encountered. - * Note: zfree is safe because error is 0, so we will - * not zfree it again when we break. - */ - if ((cnp->cn_flags & ISSYMLINK) == 0) { - if (cnp->cn_flags & (SAVENAME | SAVESTART)) - cnp->cn_flags |= HASBUF; - else - uma_zfree(namei_zone, cnp->cn_pnbuf); - if (ndp->ni_vp && !lockleaf) - VOP_UNLOCK(ndp->ni_vp, 0); - break; - } - - /* - * Validate symlink - */ - if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1) - VOP_UNLOCK(ndp->ni_dvp, 0); - if (!pubflag) { - error = EINVAL; - goto badlink2; - } - - if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { - error = ELOOP; - goto badlink2; - } - if (ndp->ni_pathlen > 1) - cp = uma_zalloc(namei_zone, M_WAITOK); - else - cp = cnp->cn_pnbuf; - aiov.iov_base = cp; - aiov.iov_len = MAXPATHLEN; - auio.uio_iov = &aiov; - auio.uio_iovcnt = 1; - auio.uio_offset = 0; - auio.uio_rw = UIO_READ; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_td = NULL; - auio.uio_resid = MAXPATHLEN; - error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred); - if (error) { - badlink1: - if (ndp->ni_pathlen > 1) - uma_zfree(namei_zone, cp); - badlink2: - vput(ndp->ni_vp); - vrele(ndp->ni_dvp); - break; - } - linklen = MAXPATHLEN - auio.uio_resid; - if (linklen == 0) { - error = ENOENT; - goto badlink1; - } - if (linklen + ndp->ni_pathlen >= MAXPATHLEN) { - error = ENAMETOOLONG; - goto badlink1; - } - - /* - * Adjust or replace path - */ - if (ndp->ni_pathlen > 1) { - bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen); - uma_zfree(namei_zone, cnp->cn_pnbuf); - cnp->cn_pnbuf = cp; - } else - cnp->cn_pnbuf[linklen] = '\0'; - ndp->ni_pathlen += linklen; - - /* - * Cleanup refs for next loop and check if root directory - * should replace current directory. Normally ni_dvp - * becomes the new base directory and is cleaned up when - * we loop. Explicitly null pointers after invalidation - * to clarify operation. - */ - vput(ndp->ni_vp); - ndp->ni_vp = NULL; - - if (cnp->cn_pnbuf[0] == '/') { - vrele(ndp->ni_dvp); - ndp->ni_dvp = ndp->ni_rootdir; - VREF(ndp->ni_dvp); - } - ndp->ni_startdir = ndp->ni_dvp; - ndp->ni_dvp = NULL; - } - if (!lockleaf) - cnp->cn_flags &= ~LOCKLEAF; - - /* - * nfs_namei() guarentees that fields will not contain garbage - * whether an error occurs or not. This allows the caller to track - * cleanup state trivially. - */ -out: - if (error) { - uma_zfree(namei_zone, cnp->cn_pnbuf); - ndp->ni_vp = NULL; - ndp->ni_dvp = NULL; - ndp->ni_startdir = NULL; - cnp->cn_flags &= ~HASBUF; - } else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) { - ndp->ni_dvp = NULL; - } - return (error); -} - -/* - * A fiddled version of m_adj() that ensures null fill to a long - * boundary and only trims off the back end - */ -void -nfsm_adj(struct mbuf *mp, int len, int nul) -{ - struct mbuf *m; - int count, i; - char *cp; - - /* - * Trim from tail. Scan the mbuf chain, - * calculating its length and finding the last mbuf. - * If the adjustment only affects this mbuf, then just - * adjust and return. Otherwise, rescan and truncate - * after the remaining size. - */ - count = 0; - m = mp; - for (;;) { - count += m->m_len; - if (m->m_next == NULL) - break; - m = m->m_next; - } - if (m->m_len > len) { - m->m_len -= len; - if (nul > 0) { - cp = mtod(m, caddr_t)+m->m_len-nul; - for (i = 0; i < nul; i++) - *cp++ = '\0'; - } - return; - } - count -= len; - if (count < 0) - count = 0; - /* - * Correct length for chain is "count". - * Find the mbuf with last data, adjust its length, - * and toss data from remaining mbufs on chain. - */ - for (m = mp; m; m = m->m_next) { - if (m->m_len >= count) { - m->m_len = count; - if (nul > 0) { - cp = mtod(m, caddr_t)+m->m_len-nul; - for (i = 0; i < nul; i++) - *cp++ = '\0'; - } - if (m->m_next != NULL) { - m_freem(m->m_next); - m->m_next = NULL; - } - break; - } - count -= m->m_len; - } -} - -/* - * Make these functions instead of macros, so that the kernel text size - * doesn't get too big... - */ -void -nfsm_srvwcc(struct nfsrv_descript *nfsd, int before_ret, - struct vattr *before_vap, int after_ret, struct vattr *after_vap, - struct mbuf **mbp, char **bposp) -{ - struct mbuf *mb = *mbp; - char *bpos = *bposp; - u_int32_t *tl; - - if (before_ret) { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = nfsrv_nfs_false; - } else { - tl = nfsm_build(u_int32_t *, 7 * NFSX_UNSIGNED); - *tl++ = nfsrv_nfs_true; - txdr_hyper(before_vap->va_size, tl); - tl += 2; - txdr_nfsv3time(&(before_vap->va_mtime), tl); - tl += 2; - txdr_nfsv3time(&(before_vap->va_ctime), tl); - } - *bposp = bpos; - *mbp = mb; - nfsm_srvpostopattr(nfsd, after_ret, after_vap, mbp, bposp); -} - -void -nfsm_srvpostopattr(struct nfsrv_descript *nfsd, int after_ret, - struct vattr *after_vap, struct mbuf **mbp, char **bposp) -{ - struct mbuf *mb = *mbp; - char *bpos = *bposp; - u_int32_t *tl; - struct nfs_fattr *fp; - - if (after_ret) { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = nfsrv_nfs_false; - } else { - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED + NFSX_V3FATTR); - *tl++ = nfsrv_nfs_true; - fp = (struct nfs_fattr *)tl; - nfsm_srvfattr(nfsd, after_vap, fp); - } - *mbp = mb; - *bposp = bpos; -} - -void -nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap, - struct nfs_fattr *fp) -{ - - fp->fa_nlink = txdr_unsigned(vap->va_nlink); - fp->fa_uid = txdr_unsigned(vap->va_uid); - fp->fa_gid = txdr_unsigned(vap->va_gid); - if (nfsd->nd_flag & ND_NFSV3) { - fp->fa_type = vtonfsv3_type(vap->va_type); - fp->fa_mode = vtonfsv3_mode(vap->va_mode); - txdr_hyper(vap->va_size, &fp->fa3_size); - txdr_hyper(vap->va_bytes, &fp->fa3_used); - fp->fa3_rdev.specdata1 = txdr_unsigned(major(vap->va_rdev)); - fp->fa3_rdev.specdata2 = txdr_unsigned(minor(vap->va_rdev)); - fp->fa3_fsid.nfsuquad[0] = 0; - fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(vap->va_fsid); - fp->fa3_fileid.nfsuquad[0] = 0; - fp->fa3_fileid.nfsuquad[1] = txdr_unsigned(vap->va_fileid); - txdr_nfsv3time(&vap->va_atime, &fp->fa3_atime); - txdr_nfsv3time(&vap->va_mtime, &fp->fa3_mtime); - txdr_nfsv3time(&vap->va_ctime, &fp->fa3_ctime); - } else { - fp->fa_type = vtonfsv2_type(vap->va_type); - fp->fa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode); - fp->fa2_size = txdr_unsigned(vap->va_size); - fp->fa2_blocksize = txdr_unsigned(vap->va_blocksize); - if (vap->va_type == VFIFO) - fp->fa2_rdev = 0xffffffff; - else - fp->fa2_rdev = txdr_unsigned(vap->va_rdev); - fp->fa2_blocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE); - fp->fa2_fsid = txdr_unsigned(vap->va_fsid); - fp->fa2_fileid = txdr_unsigned(vap->va_fileid); - txdr_nfsv2time(&vap->va_atime, &fp->fa2_atime); - txdr_nfsv2time(&vap->va_mtime, &fp->fa2_mtime); - txdr_nfsv2time(&vap->va_ctime, &fp->fa2_ctime); - } -} - -/* - * nfsrv_fhtovp() - convert a fh to a vnode ptr (optionally locked) - * - look up fsid in mount list (if not found ret error) - * - get vp and export rights by calling VFS_FHTOVP() - * - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon - */ -int -nfsrv_fhtovp(fhandle_t *fhp, int flags, struct vnode **vpp, - struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, - struct sockaddr *nam, int *rdonlyp) -{ - struct mount *mp; - int i; - struct ucred *cred, *credanon; - int error, exflags; -#ifdef MNT_EXNORESPORT /* XXX needs mountd and /etc/exports help yet */ - struct sockaddr_int *saddr; -#endif - int credflavor; - int numsecflavors, *secflavors; - int authsys; - int v3 = nfsd->nd_flag & ND_NFSV3; - int mountreq; - - *vpp = NULL; - - if (nfs_ispublicfh(fhp)) { - if (!nfs_pub.np_valid) - return (ESTALE); - fhp = &nfs_pub.np_handle; - } - - mp = vfs_busyfs(&fhp->fh_fsid); - if (!mp) - return (ESTALE); - error = VFS_CHECKEXP(mp, nam, &exflags, &credanon, - &numsecflavors, &secflavors); - if (error) { - vfs_unbusy(mp); - goto out; - } - if (numsecflavors == 0) { - /* - * This can happen if the system is running with an - * old mountd that doesn't pass in a secflavor list. - */ - numsecflavors = 1; - authsys = AUTH_SYS; - secflavors = &authsys; - } - credflavor = nfsd->nd_credflavor; - for (i = 0; i < numsecflavors; i++) { - if (secflavors[i] == credflavor) - break; - } - if (i == numsecflavors) { - /* - * RFC 2623 section 2.3.2 - allow certain procedures - * used at NFS client mount time even if they have - * weak authentication. - */ - mountreq = FALSE; - if (v3) { - if (nfsd->nd_procnum == NFSPROC_FSINFO - || nfsd->nd_procnum == NFSPROC_GETATTR) - mountreq = TRUE; - } else { - if (nfsd->nd_procnum == NFSPROC_FSSTAT - || nfsd->nd_procnum == NFSPROC_GETATTR) - mountreq = TRUE; - } - if (!mountreq) { - error = NFSERR_AUTHERR | AUTH_TOOWEAK; - vfs_unbusy(mp); - goto out; - } - } - error = VFS_FHTOVP(mp, &fhp->fh_fid, LK_EXCLUSIVE, vpp); - if (error) { - /* Make sure the server replies ESTALE to the client. */ - error = ESTALE; - vfs_unbusy(mp); - goto out; - } -#ifdef MNT_EXNORESPORT - if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) { - saddr = (struct sockaddr_in *)nam; - if ((saddr->sin_family == AF_INET || - saddr->sin_family == AF_INET6) && - /* same code for INET and INET6: sin*_port at same offet */ - ntohs(saddr->sin_port) >= IPPORT_RESERVED) { - vput(*vpp); - *vpp = NULL; - error = NFSERR_AUTHERR | AUTH_TOOWEAK; - vfs_unbusy(mp); - goto out; - } - } -#endif - /* - * Check/setup credentials. - */ - cred = nfsd->nd_cr; - if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { - cred->cr_uid = credanon->cr_uid; - crsetgroups(cred, credanon->cr_ngroups, credanon->cr_groups); - } - if (exflags & MNT_EXRDONLY) - *rdonlyp = 1; - else - *rdonlyp = 0; - - if (!(flags & NFSRV_FLAG_BUSY)) - vfs_unbusy(mp); -out: - if (credanon != NULL) - crfree(credanon); - - return (error); -} - - -/* - * WebNFS: check if a filehandle is a public filehandle. For v3, this - * means a length of 0, for v2 it means all zeroes. nfsm_srvmtofh has - * transformed this to all zeroes in both cases, so check for it. - */ -int -nfs_ispublicfh(fhandle_t *fhp) -{ - char *cp = (char *)fhp; - int i; - - NFSD_LOCK_DONTCARE(); - - for (i = 0; i < NFSX_V3FH; i++) - if (*cp++ != 0) - return (FALSE); - return (TRUE); -} - -/* - * Map errnos to NFS error numbers. For Version 3 also filter out error - * numbers not specified for the associated procedure. - */ -int -nfsrv_errmap(struct nfsrv_descript *nd, int err) -{ - const short *defaulterrp, *errp; - int e; - - - if (nd->nd_flag & ND_NFSV3) { - if (nd->nd_procnum <= NFSPROC_COMMIT) { - errp = defaulterrp = nfsrv_v3errmap[nd->nd_procnum]; - while (*++errp) { - if (*errp == err) - return (err); - else if (*errp > err) - break; - } - return ((int)*defaulterrp); - } else - return (err & 0xffff); - } - e = 0; - if (err <= ELAST) - e = nfsrv_v2errmap[err - 1]; - if (e != 0) - return (e); - return (NFSERR_IO); -} - -/* - * Sort the group list in increasing numerical order. - * (Insertion sort by Chris Torek, who was grossed out by the bubble sort - * that used to be here.) - */ -void -nfsrvw_sort(gid_t *list, int num) -{ - int i, j; - gid_t v; - - /* Insertion sort. */ - for (i = 1; i < num; i++) { - v = list[i]; - /* find correct slot for value v, moving others up */ - for (j = i; --j >= 0 && v < list[j];) - list[j + 1] = list[j]; - list[j + 1] = v; - } -} - -/* - * Helper functions for macros. - */ - -void -nfsm_srvfhtom_xx(fhandle_t *f, int v3, struct mbuf **mb, caddr_t *bpos) -{ - u_int32_t *tl; - - if (v3) { - tl = nfsm_build_xx(NFSX_UNSIGNED + NFSX_V3FH, mb, bpos); - *tl++ = txdr_unsigned(NFSX_V3FH); - bcopy(f, tl, NFSX_V3FH); - } else { - tl = nfsm_build_xx(NFSX_V2FH, mb, bpos); - bcopy(f, tl, NFSX_V2FH); - } -} - -void -nfsm_srvpostop_fh_xx(fhandle_t *f, struct mbuf **mb, caddr_t *bpos) -{ - u_int32_t *tl; - - tl = nfsm_build_xx(2 * NFSX_UNSIGNED + NFSX_V3FH, mb, bpos); - *tl++ = nfsrv_nfs_true; - *tl++ = txdr_unsigned(NFSX_V3FH); - bcopy(f, tl, NFSX_V3FH); -} - -int -nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - *s = fxdr_unsigned(int32_t, *tl); - if (*s > m || *s <= 0) - return EBADRPC; - return 0; -} - -int -nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - - NFSD_LOCK_DONTCARE(); - - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - *s = fxdr_unsigned(int32_t, *tl); - if (*s > m) - return NFSERR_NAMETOL; - if (*s <= 0) - return EBADRPC; - return 0; -} - -int -nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - *s = fxdr_unsigned(int32_t, *tl); - if (*s > m) - return NFSERR_NAMETOL; - if (*s < 0) - return EBADRPC; - return 0; -} - -void -nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp, - char **bp, char **be, caddr_t bpos) -{ - struct mbuf *nmp; - - NFSD_UNLOCK_ASSERT(); - - if (*bp >= *be) { - if (*mp == mb) - (*mp)->m_len += *bp - bpos; - MGET(nmp, M_WAITOK, MT_DATA); - MCLGET(nmp, M_WAITOK); - nmp->m_len = NFSMSIZ(nmp); - (*mp)->m_next = nmp; - *mp = nmp; - *bp = mtod(*mp, caddr_t); - *be = *bp + (*mp)->m_len; - } - *tl = (u_int32_t *)*bp; -} - -int -nfsm_srvmtofh_xx(fhandle_t *f, int v3, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - int fhlen; - - if (v3) { - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - fhlen = fxdr_unsigned(int, *tl); - if (fhlen != 0 && fhlen != NFSX_V3FH) - return EBADRPC; - } else { - fhlen = NFSX_V2FH; - } - if (fhlen != 0) { - tl = nfsm_dissect_xx_nonblock(fhlen, md, dpos); - if (tl == NULL) - return EBADRPC; - bcopy((caddr_t)tl, (caddr_t)(f), fhlen); - } else { - bzero((caddr_t)(f), NFSX_V3FH); - } - return 0; -} - -int -nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos) -{ - u_int32_t *tl; - int toclient = 0; - - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - if (*tl == nfsrv_nfs_true) { - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - (a)->va_mode = nfstov_mode(*tl); - } - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - if (*tl == nfsrv_nfs_true) { - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - (a)->va_uid = fxdr_unsigned(uid_t, *tl); - } - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - if (*tl == nfsrv_nfs_true) { - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - (a)->va_gid = fxdr_unsigned(gid_t, *tl); - } - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - if (*tl == nfsrv_nfs_true) { - tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - (a)->va_size = fxdr_hyper(tl); - } - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - switch (fxdr_unsigned(int, *tl)) { - case NFSV3SATTRTIME_TOCLIENT: - tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - fxdr_nfsv3time(tl, &(a)->va_atime); - toclient = 1; - break; - case NFSV3SATTRTIME_TOSERVER: - vfs_timestamp(&a->va_atime); - a->va_vaflags |= VA_UTIMES_NULL; - break; - } - tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - switch (fxdr_unsigned(int, *tl)) { - case NFSV3SATTRTIME_TOCLIENT: - tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return EBADRPC; - fxdr_nfsv3time(tl, &(a)->va_mtime); - a->va_vaflags &= ~VA_UTIMES_NULL; - break; - case NFSV3SATTRTIME_TOSERVER: - vfs_timestamp(&a->va_mtime); - if (toclient == 0) - a->va_vaflags |= VA_UTIMES_NULL; - break; - } - return 0; -} diff --git a/sys/sys/param.h b/sys/sys/param.h index d25cdef6946..a4922f1a8cb 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1100050 /* Master, propagated to newvers */ +#define __FreeBSD_version 1100051 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, From 0b327b634a6fc79050f4c5801c647cad1ae4e351 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 23 Dec 2014 01:32:18 +0000 Subject: [PATCH 105/207] Add an UPDATING entry for r276096, which removed the kernel sources for the old NFS client and server. --- UPDATING | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/UPDATING b/UPDATING index 89a2de7deb1..c84be39d822 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20141222: + The old NFS client and server (kernel options NFSCLIENT, NFSSERVER) + kernel sources have been removed. The .h files remain, since some + utilities include them. This will need to be fixed later. + If "mount -t oldnfs ..." is attempted, it will fail. + If the "-o" option on mountd(8), nfsd(8) or nfsstat(1) is used, + the utilities will report errors. + 20141121: The handling of LOCAL_LIB_DIRS has been altered to skip addition of directories to top level SUBDIR variable when their parent From b053814333808bd3c86dc6a5f1fa3a7ec6ac2368 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Tue, 23 Dec 2014 02:14:49 +0000 Subject: [PATCH 106/207] Allow ktr(4) tracing of all guest exceptions via the tunable "hw.vmm.trace_guest_exceptions". To enable this feature set the tunable to "1" before loading vmm.ko. Tracing the guest exceptions can be useful when debugging guest triple faults. Note that there is a performance impact when exception tracing is enabled since every exception will now trigger a VM-exit. Also, handle machine check exceptions that happen during guest execution by vectoring to the host's machine check handler via "int $18". Discussed with: grehan MFC after: 2 weeks --- sys/amd64/include/vmm.h | 2 + sys/amd64/vmm/amd/svm.c | 96 ++++++++++++++++++++++++++++++++++++-- sys/amd64/vmm/intel/vmcs.c | 6 --- sys/amd64/vmm/intel/vmcs.h | 2 +- sys/amd64/vmm/intel/vmx.c | 76 +++++++++++++++++++++++++++--- sys/amd64/vmm/vmm.c | 12 +++++ 6 files changed, 177 insertions(+), 17 deletions(-) diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 0f191102ca5..8a8c3f47183 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -358,6 +358,8 @@ void vm_copyin(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo, void *kaddr, size_t len); void vm_copyout(struct vm *vm, int vcpuid, const void *kaddr, struct vm_copyinfo *copyinfo, size_t len); + +int vcpu_trace_exceptions(struct vm *vm, int vcpuid); #endif /* KERNEL */ #define VM_MAXCPU 16 /* maximum virtual cpus */ diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index 753799af6d2..7d7504619e9 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "vmm_lapic.h" @@ -429,8 +430,24 @@ vmcb_init(struct svm_softc *sc, int vcpu, uint64_t iopm_base_pa, svm_enable_intercept(sc, vcpu, VMCB_CR_INTCPT, mask); } - /* Intercept Machine Check exceptions. */ - svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(IDT_MC)); + + /* + * Intercept everything when tracing guest exceptions otherwise + * just intercept machine check exception. + */ + if (vcpu_trace_exceptions(sc->vm, vcpu)) { + for (n = 0; n < 32; n++) { + /* + * Skip unimplemented vectors in the exception bitmap. + */ + if (n == 2 || n == 9) { + continue; + } + svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(n)); + } + } else { + svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(IDT_MC)); + } /* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */ svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_IO); @@ -1176,9 +1193,10 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit) struct vmcb_state *state; struct vmcb_ctrl *ctrl; struct svm_regctx *ctx; + struct vm_exception exception; uint64_t code, info1, info2, val; uint32_t eax, ecx, edx; - int handled; + int error, errcode_valid, handled, idtvec, reflect; bool retu; ctx = svm_get_guest_regctx(svm_sc, vcpu); @@ -1237,8 +1255,78 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit) case VMCB_EXIT_NMI: /* external NMI */ handled = 1; break; - case VMCB_EXIT_MC: /* machine check */ + case 0x40 ... 0x5F: vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_EXCEPTION, 1); + reflect = 1; + idtvec = code - 0x40; + switch (idtvec) { + case IDT_MC: + /* + * Call the machine check handler by hand. Also don't + * reflect the machine check back into the guest. + */ + reflect = 0; + VCPU_CTR0(svm_sc->vm, vcpu, "Vectoring to MCE handler"); + __asm __volatile("int $18"); + break; + case IDT_PF: + error = svm_setreg(svm_sc, vcpu, VM_REG_GUEST_CR2, + info2); + KASSERT(error == 0, ("%s: error %d updating cr2", + __func__, error)); + /* fallthru */ + case IDT_NP: + case IDT_SS: + case IDT_GP: + case IDT_AC: + case IDT_TS: + errcode_valid = 1; + break; + + case IDT_DF: + errcode_valid = 1; + info1 = 0; + break; + + case IDT_BP: + case IDT_OF: + case IDT_BR: + /* + * The 'nrip' field is populated for INT3, INTO and + * BOUND exceptions and this also implies that + * 'inst_length' is non-zero. + * + * Reset 'inst_length' to zero so the guest %rip at + * event injection is identical to what it was when + * the exception originally happened. + */ + VCPU_CTR2(svm_sc->vm, vcpu, "Reset inst_length from %d " + "to zero before injecting exception %d", + vmexit->inst_length, idtvec); + vmexit->inst_length = 0; + /* fallthru */ + default: + errcode_valid = 0; + break; + } + KASSERT(vmexit->inst_length == 0, ("invalid inst_length (%d) " + "when reflecting exception %d into guest", + vmexit->inst_length, idtvec)); + + if (reflect) { + /* Reflect the exception back into the guest */ + exception.vector = idtvec; + exception.error_code_valid = errcode_valid; + exception.error_code = errcode_valid ? info1 : 0; + VCPU_CTR2(svm_sc->vm, vcpu, "Reflecting exception " + "%d/%#x into the guest", exception.vector, + exception.error_code); + error = vm_inject_exception(svm_sc->vm, vcpu, + &exception); + KASSERT(error == 0, ("%s: vm_inject_exception error %d", + __func__, error)); + } + handled = 1; break; case VMCB_EXIT_MSR: /* MSR access. */ eax = state->rax; diff --git a/sys/amd64/vmm/intel/vmcs.c b/sys/amd64/vmm/intel/vmcs.c index 51e5c2c06f0..ae4d9db3274 100644 --- a/sys/amd64/vmm/intel/vmcs.c +++ b/sys/amd64/vmm/intel/vmcs.c @@ -332,7 +332,6 @@ vmcs_init(struct vmcs *vmcs) int error, codesel, datasel, tsssel; u_long cr0, cr4, efer; uint64_t pat, fsbase, idtrbase; - uint32_t exc_bitmap; codesel = vmm_get_host_codesel(); datasel = vmm_get_host_datasel(); @@ -417,11 +416,6 @@ vmcs_init(struct vmcs *vmcs) if ((error = vmwrite(VMCS_HOST_RIP, (u_long)vmx_exit_guest)) != 0) goto done; - /* exception bitmap */ - exc_bitmap = 1 << IDT_MC; - if ((error = vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap)) != 0) - goto done; - /* link pointer */ if ((error = vmwrite(VMCS_LINK_POINTER, ~0)) != 0) goto done; diff --git a/sys/amd64/vmm/intel/vmcs.h b/sys/amd64/vmm/intel/vmcs.h index 6122de581fa..6d78a6928e2 100644 --- a/sys/amd64/vmm/intel/vmcs.h +++ b/sys/amd64/vmm/intel/vmcs.h @@ -321,7 +321,7 @@ vmcs_write(uint32_t encoding, uint64_t val) #define EXIT_REASON_MTF 37 #define EXIT_REASON_MONITOR 39 #define EXIT_REASON_PAUSE 40 -#define EXIT_REASON_MCE 41 +#define EXIT_REASON_MCE_DURING_ENTRY 41 #define EXIT_REASON_TPR 43 #define EXIT_REASON_APIC_ACCESS 44 #define EXIT_REASON_VIRTUALIZED_EOI 45 diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index c855697c6c0..c3dd04e66e1 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -283,8 +283,8 @@ exit_reason_to_str(int reason) return "monitor"; case EXIT_REASON_PAUSE: return "pause"; - case EXIT_REASON_MCE: - return "mce"; + case EXIT_REASON_MCE_DURING_ENTRY: + return "mce-during-entry"; case EXIT_REASON_TPR: return "tpr"; case EXIT_REASON_APIC_ACCESS: @@ -821,6 +821,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap) int i, error; struct vmx *vmx; struct vmcs *vmcs; + uint32_t exc_bitmap; vmx = malloc(sizeof(struct vmx), M_VMX, M_WAITOK | M_ZERO); if ((uintptr_t)vmx & PAGE_MASK) { @@ -911,6 +912,14 @@ vmx_vminit(struct vm *vm, pmap_t pmap) error += vmwrite(VMCS_ENTRY_CTLS, entry_ctls); error += vmwrite(VMCS_MSR_BITMAP, vtophys(vmx->msr_bitmap)); error += vmwrite(VMCS_VPID, vpid[i]); + + /* exception bitmap */ + if (vcpu_trace_exceptions(vm, i)) + exc_bitmap = 0xffffffff; + else + exc_bitmap = 1 << IDT_MC; + error += vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap); + if (virtual_interrupt_delivery) { error += vmwrite(VMCS_APIC_ACCESS, APIC_ACCESS_ADDRESS); error += vmwrite(VMCS_VIRTUAL_APIC, @@ -2056,8 +2065,9 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) struct vlapic *vlapic; struct vm_inout_str *vis; struct vm_task_switch *ts; + struct vm_exception vmexc; uint32_t eax, ecx, edx, idtvec_info, idtvec_err, intr_info, inst_info; - uint32_t intr_type, reason; + uint32_t intr_type, intr_vec, reason; uint64_t exitintinfo, qual, gpa; bool retu; @@ -2073,6 +2083,18 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) vmm_stat_incr(vmx->vm, vcpu, VMEXIT_COUNT, 1); + /* + * VM-entry failures during or after loading guest state. + * + * These VM-exits are uncommon but must be handled specially + * as most VM-exit fields are not populated as usual. + */ + if (__predict_false(reason == EXIT_REASON_MCE_DURING_ENTRY)) { + VCPU_CTR0(vmx->vm, vcpu, "Handling MCE during VM-entry"); + __asm __volatile("int $18"); + return (1); + } + /* * VM exits that can be triggered during event delivery need to * be handled specially by re-injecting the event if the IDT @@ -2305,6 +2327,9 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) KASSERT((intr_info & VMCS_INTR_VALID) != 0, ("VM exit interruption info invalid: %#x", intr_info)); + intr_vec = intr_info & 0xff; + intr_type = intr_info & VMCS_INTR_T_MASK; + /* * If Virtual NMIs control is 1 and the VM-exit is due to a * fault encountered during the execution of IRET then we must @@ -2315,16 +2340,55 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) * See "Information for VM Exits Due to Vectored Events". */ if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 && - (intr_info & 0xff) != IDT_DF && + (intr_vec != IDT_DF) && (intr_info & EXIT_QUAL_NMIUDTI) != 0) vmx_restore_nmi_blocking(vmx, vcpu); /* * The NMI has already been handled in vmx_exit_handle_nmi(). */ - if ((intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_NMI) + if (intr_type == VMCS_INTR_T_NMI) return (1); - break; + + /* + * Call the machine check handler by hand. Also don't reflect + * the machine check back into the guest. + */ + if (intr_vec == IDT_MC) { + VCPU_CTR0(vmx->vm, vcpu, "Vectoring to MCE handler"); + __asm __volatile("int $18"); + return (1); + } + + if (intr_vec == IDT_PF) { + error = vmxctx_setreg(vmxctx, VM_REG_GUEST_CR2, qual); + KASSERT(error == 0, ("%s: vmxctx_setreg(cr2) error %d", + __func__, error)); + } + + /* + * Software exceptions exhibit trap-like behavior. This in + * turn requires populating the VM-entry instruction length + * so that the %rip in the trap frame is past the INT3/INTO + * instruction. + */ + if (intr_type == VMCS_INTR_T_SWEXCEPTION) + vmcs_write(VMCS_ENTRY_INST_LENGTH, vmexit->inst_length); + + /* Reflect all other exceptions back into the guest */ + bzero(&vmexc, sizeof(struct vm_exception)); + vmexc.vector = intr_vec; + if (intr_info & VMCS_INTR_DEL_ERRCODE) { + vmexc.error_code_valid = 1; + vmexc.error_code = vmcs_read(VMCS_EXIT_INTR_ERRCODE); + } + VCPU_CTR2(vmx->vm, vcpu, "Reflecting exception %d/%#x into " + "the guest", vmexc.vector, vmexc.error_code); + error = vm_inject_exception(vmx->vm, vcpu, &vmexc); + KASSERT(error == 0, ("%s: vm_inject_exception error %d", + __func__, error)); + return (1); + case EXIT_REASON_EPT_FAULT: /* * If 'gpa' lies within the address space allocated to diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index e7fbada39fc..d9cb6f3c125 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -207,6 +207,11 @@ static int vmm_ipinum; SYSCTL_INT(_hw_vmm, OID_AUTO, ipinum, CTLFLAG_RD, &vmm_ipinum, 0, "IPI vector used for vcpu notifications"); +static int trace_guest_exceptions; +SYSCTL_INT(_hw_vmm, OID_AUTO, trace_guest_exceptions, CTLFLAG_RDTUN, + &trace_guest_exceptions, 0, + "Trap into hypervisor on all guest exceptions and reflect them back"); + static void vcpu_cleanup(struct vm *vm, int i, bool destroy) { @@ -250,6 +255,13 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create) vmm_stat_init(vcpu->stats); } +int +vcpu_trace_exceptions(struct vm *vm, int vcpuid) +{ + + return (trace_guest_exceptions); +} + struct vm_exit * vm_exitinfo(struct vm *vm, int cpuid) { From df90fb1f9fa08772683a0d1ffe59b3f320731613 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Tue, 23 Dec 2014 03:00:18 +0000 Subject: [PATCH 107/207] Temporarily disable the cpus directive until I figure out what's wrong. --- sys/boot/fdt/dts/arm/rpi.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/boot/fdt/dts/arm/rpi.dts b/sys/boot/fdt/dts/arm/rpi.dts index 08d9d24bb4e..5ded2af8856 100644 --- a/sys/boot/fdt/dts/arm/rpi.dts +++ b/sys/boot/fdt/dts/arm/rpi.dts @@ -35,6 +35,7 @@ memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */ + /* cpus { #address-cells = <1>; #size-cells = <0>; @@ -45,6 +46,7 @@ clock-frequency = <700000000>; /* 700MHz */ }; }; + */ memory { device_type = "memory"; From 3e834dd35d5411f54368671925bad9bd55082b42 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 23 Dec 2014 05:50:53 +0000 Subject: [PATCH 108/207] Always select the card before we do the 4.x specific stuff and deselect it after setting the block size. This is a similar bug that was fixed elsewhere, but not here. This makes sure that we leave the card deselected at the end of the loop, and we don't send any commands to the card without it selected. Reviewed by: ian@ --- sys/dev/mmc/mmc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c index 4d6c2db6a28..ec4d358a15a 100644 --- a/sys/dev/mmc/mmc.c +++ b/sys/dev/mmc/mmc.c @@ -1446,10 +1446,10 @@ mmc_discover_cards(struct mmc_softc *sc) break; } + mmc_select_card(sc, ivar->rca); + /* Only MMC >= 4.x cards support EXT_CSD. */ if (ivar->csd.spec_vers >= 4) { - /* Card must be selected to fetch EXT_CSD. */ - mmc_select_card(sc, ivar->rca); mmc_send_ext_csd(sc, ivar->raw_ext_csd); /* Handle extended capacity from EXT_CSD */ sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] + @@ -1479,7 +1479,6 @@ mmc_discover_cards(struct mmc_softc *sc) mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_ERASE_GRP_DEF, 1); } - mmc_select_card(sc, 0); } else { ivar->bus_width = bus_width_1; ivar->timing = bus_timing_normal; @@ -1506,6 +1505,7 @@ mmc_discover_cards(struct mmc_softc *sc) child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); } + mmc_select_card(sc, 0); } } From 51f529b50b17fead1f6c33698a78c20dc0ccfca4 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Tue, 23 Dec 2014 09:31:24 +0000 Subject: [PATCH 109/207] Always sync the global ZFS config cache to reflect the new mosconfig This fixes out of date zpool.cache for root pools, which can cause issues such as confusion of zdb etc. MFC after: 1 month --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c index 2d0cf230932..c4ee741e9a7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c @@ -536,8 +536,7 @@ spa_config_update(spa_t *spa, int what) /* * Update the global config cache to reflect the new mosconfig. */ - if (!spa->spa_is_root) - spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL); + spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL); if (what == SPA_CONFIG_UPDATE_POOL) spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS); From 1f69310e70788b89f11729b1d8bfe687f474d1a1 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 23 Dec 2014 10:18:42 +0000 Subject: [PATCH 110/207] Fix potential division by zero after r275920. Reported by: Coverity Scan CID: 1260387 MFC after: 3 days --- sys/cam/ctl/ctl_backend_ramdisk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c index 6c62b4bdc2d..d43cb6032d3 100644 --- a/sys/cam/ctl/ctl_backend_ramdisk.c +++ b/sys/cam/ctl/ctl_backend_ramdisk.c @@ -569,6 +569,8 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, be_lun->size_bytes = be_lun->size_blocks * blocksize; be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1; + be_lun->ctl_be_lun.atomicblock = UINT32_MAX; + be_lun->ctl_be_lun.opttxferlen = softc->rd_size / blocksize; } else { be_lun->ctl_be_lun.maxlba = 0; blocksize = 0; @@ -595,8 +597,6 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc, be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY; if (unmap) be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP; - be_lun->ctl_be_lun.atomicblock = UINT32_MAX; - be_lun->ctl_be_lun.opttxferlen = softc->rd_size / blocksize; be_lun->ctl_be_lun.be_lun = be_lun; if (params->flags & CTL_LUN_FLAG_ID_REQ) { From 70d099afe03f2b75a908381332d7275187b6a593 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Tue, 23 Dec 2014 10:43:35 +0000 Subject: [PATCH 111/207] Fix build with recent binutils Recent binutils considered the .gnu.warning.symbol section as a fatal error when run with --fatal-warnings which makes any users of "insecure" functions from libc failing to build with recent binutils. Introduce a new macro: LD_FATAL_WARNINGS=no to run ld(1) with --no-fatal-warnings for the users of "insecure" functions Differential Revision: https://reviews.freebsd.org/D1320 --- gnu/lib/libssp/Makefile | 1 + lib/libbsnmp/libbsnmp/Makefile | 1 + share/mk/bsd.lib.mk | 7 ++++++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/gnu/lib/libssp/Makefile b/gnu/lib/libssp/Makefile index 6e8977169bb..5a41298360e 100644 --- a/gnu/lib/libssp/Makefile +++ b/gnu/lib/libssp/Makefile @@ -15,6 +15,7 @@ SRCDIR= ${GCCLIB}/libssp LIB= ssp SHLIB_MAJOR= 0 +LD_FATAL_WARNINGS= no SRCS= ssp.c gets-chk.c memcpy-chk.c memmove-chk.c mempcpy-chk.c \ memset-chk.c snprintf-chk.c sprintf-chk.c stpcpy-chk.c \ diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile index cc294cf57ee..ef6e35b9726 100644 --- a/lib/libbsnmp/libbsnmp/Makefile +++ b/lib/libbsnmp/libbsnmp/Makefile @@ -9,6 +9,7 @@ CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib LIB= bsnmp SHLIB_MAJOR= 6 +LD_FATAL_WARNINGS= no CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"' diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index f0acf16772d..6a6f3f214cd 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -207,7 +207,12 @@ _LIBS+= ${SHLIB_NAME} SOLINKOPTS= -shared -Wl,-x .if !defined(ALLOW_SHARED_TEXTREL) -SOLINKOPTS+= -Wl,--fatal-warnings -Wl,--warn-shared-textrel +.if defined(LD_FATAL_WARNINGS) && ${LD_FATAL_WARNINGS} == "no" +SOLINKOPTS+= -Wl,--no-fatal-warnings +.else +SOLINKOPTS+= -Wl,--fatal-warnings +.endif +SOLINKOPTS+= -Wl,--warn-shared-textrel .endif .if target(beforelinking) From 502e440349c07960b23fb621f9e3e5a99730c344 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 23 Dec 2014 12:26:35 +0000 Subject: [PATCH 112/207] m_clrprotoflags() is designed to cleanup M_PROTO flags when mbufs cross protocol and facility boundaries. However, now it cleans up only the first mbuf, while intent clearly means all mbufs in a possible chain. Differential Revision: https://reviews.freebsd.org/D1352 Reviewed by: rpaulo, gnn, adrian Sponsored by: Nginx, Inc. --- sys/sys/mbuf.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index ac3cfb2d0ce..cbb2a1850c2 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -757,7 +757,10 @@ static __inline void m_clrprotoflags(struct mbuf *m) { - m->m_flags &= ~M_PROTOFLAGS; + while (m) { + m->m_flags &= ~M_PROTOFLAGS; + m = m->m_next; + } } static __inline struct mbuf * From 62c23db947c945cdc423a726b725570e18ca3d64 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 23 Dec 2014 14:24:36 +0000 Subject: [PATCH 113/207] Fix kernel builds with "options NFS_DEBUG" that were broken by r276096. Also delete the two kernel options NFS_GATHERDELAY, NFS_WDELAYHASHSIZ which are no longer used. Reported by: bz --- sys/conf/NOTES | 2 -- sys/conf/options | 2 -- sys/fs/nfs/nfsport.h | 18 ------------------ sys/fs/nfsclient/nfs.h | 18 ++++++++++++++++++ sys/fs/nfsclient/nfs_clvfsops.c | 5 +++++ 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/sys/conf/NOTES b/sys/conf/NOTES index dfa3514aa03..70cffbead75 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1098,8 +1098,6 @@ options NFS_MINATTRTIMO=3 # VREG attrib cache timeout in sec options NFS_MAXATTRTIMO=60 options NFS_MINDIRATTRTIMO=30 # VDIR attrib cache timeout in sec options NFS_MAXDIRATTRTIMO=60 -options NFS_GATHERDELAY=10 # Default write gather delay (msec) -options NFS_WDELAYHASHSIZ=16 # and with this options NFS_DEBUG # Enable NFS Debugging # diff --git a/sys/conf/options b/sys/conf/options index 475d960d99a..52c44a10363 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -619,8 +619,6 @@ NFS_MINATTRTIMO opt_nfs.h NFS_MAXATTRTIMO opt_nfs.h NFS_MINDIRATTRTIMO opt_nfs.h NFS_MAXDIRATTRTIMO opt_nfs.h -NFS_GATHERDELAY opt_nfs.h -NFS_WDELAYHASHSIZ opt_nfs.h NFS_DEBUG opt_nfs.h # For the Bt848/Bt848A/Bt849/Bt878/Bt879 driver diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 88c7a34ae3f..9f08854c3a2 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -930,24 +930,6 @@ void nfsd_mntinit(void); int newnfs_iosize(struct nfsmount *); -#ifdef NFS_DEBUG - -extern int nfs_debug; -#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */ -#define NFS_DEBUG_WG 2 /* server write gathering */ -#define NFS_DEBUG_RC 4 /* server request caching */ - -#define NFS_DPF(cat, args) \ - do { \ - if (nfs_debug & NFS_DEBUG_##cat) printf args; \ - } while (0) - -#else - -#define NFS_DPF(cat, args) - -#endif - int newnfs_vncmpf(struct vnode *, void *); #ifndef NFS_MINDIRATTRTIMO diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h index 183515cc604..e05e5537342 100644 --- a/sys/fs/nfsclient/nfs.h +++ b/sys/fs/nfsclient/nfs.h @@ -55,6 +55,24 @@ #define NFS_ISV34(v) \ (VFSTONFS((v)->v_mount)->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) +#ifdef NFS_DEBUG + +extern int nfs_debug; +#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */ +#define NFS_DEBUG_WG 2 /* server write gathering */ +#define NFS_DEBUG_RC 4 /* server request caching */ + +#define NFS_DPF(cat, args) \ + do { \ + if (nfs_debug & NFS_DEBUG_##cat) printf args; \ + } while (0) + +#else + +#define NFS_DPF(cat, args) + +#endif + /* * NFS iod threads can be in one of these three states once spawned. * NFSIOD_NOT_AVAILABLE - Cannot be assigned an I/O operation at this time. diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 68122df4cff..9758b4c3a0a 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -100,6 +100,11 @@ SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY, static int nfs_tprintf_delay = NFS_TPRINTF_DELAY; SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY, downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, ""); +#ifdef NFS_DEBUG +int nfs_debug; +SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0, + "Toggle debug flag"); +#endif static int nfs_mountroot(struct mount *); static void nfs_sec_name(char *, int *); From 7a19455d223bcf956470de0b6677086df4f78446 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Tue, 23 Dec 2014 15:18:28 +0000 Subject: [PATCH 114/207] Hide block device VPD pages for non-block devices. MFC after: 2 weeks --- sys/cam/ctl/ctl.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 0c2524b02f9..e90a029b359 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -9599,6 +9599,7 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len) struct scsi_vpd_supported_pages *pages; int sup_page_size; struct ctl_lun *lun; + int p; lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; @@ -9632,27 +9633,30 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len) else pages->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; - pages->length = SCSI_EVPD_NUM_SUPPORTED_PAGES; + p = 0; /* Supported VPD pages */ - pages->page_list[0] = SVPD_SUPPORTED_PAGES; + pages->page_list[p++] = SVPD_SUPPORTED_PAGES; /* Serial Number */ - pages->page_list[1] = SVPD_UNIT_SERIAL_NUMBER; + pages->page_list[p++] = SVPD_UNIT_SERIAL_NUMBER; /* Device Identification */ - pages->page_list[2] = SVPD_DEVICE_ID; + pages->page_list[p++] = SVPD_DEVICE_ID; /* Extended INQUIRY Data */ - pages->page_list[3] = SVPD_EXTENDED_INQUIRY_DATA; + pages->page_list[p++] = SVPD_EXTENDED_INQUIRY_DATA; /* Mode Page Policy */ - pages->page_list[4] = SVPD_MODE_PAGE_POLICY; + pages->page_list[p++] = SVPD_MODE_PAGE_POLICY; /* SCSI Ports */ - pages->page_list[5] = SVPD_SCSI_PORTS; + pages->page_list[p++] = SVPD_SCSI_PORTS; /* Third-party Copy */ - pages->page_list[6] = SVPD_SCSI_TPC; - /* Block limits */ - pages->page_list[7] = SVPD_BLOCK_LIMITS; - /* Block Device Characteristics */ - pages->page_list[8] = SVPD_BDC; - /* Logical Block Provisioning */ - pages->page_list[9] = SVPD_LBP; + pages->page_list[p++] = SVPD_SCSI_TPC; + if (lun != NULL && lun->be_lun->lun_type == T_DIRECT) { + /* Block limits */ + pages->page_list[p++] = SVPD_BLOCK_LIMITS; + /* Block Device Characteristics */ + pages->page_list[p++] = SVPD_BDC; + /* Logical Block Provisioning */ + pages->page_list[p++] = SVPD_LBP; + } + pages->length = p; ctl_set_success(ctsio); ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; @@ -10234,13 +10238,12 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) static int ctl_inquiry_evpd(struct ctl_scsiio *ctsio) { + struct ctl_lun *lun; struct scsi_inquiry *cdb; int alloc_len, retval; + lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; cdb = (struct scsi_inquiry *)ctsio->cdb; - - retval = CTL_RETVAL_COMPLETE; - alloc_len = scsi_2btoul(cdb->length); switch (cdb->page_code) { @@ -10266,15 +10269,22 @@ ctl_inquiry_evpd(struct ctl_scsiio *ctsio) retval = ctl_inquiry_evpd_tpc(ctsio, alloc_len); break; case SVPD_BLOCK_LIMITS: + if (lun == NULL || lun->be_lun->lun_type != T_DIRECT) + goto err; retval = ctl_inquiry_evpd_block_limits(ctsio, alloc_len); break; case SVPD_BDC: + if (lun == NULL || lun->be_lun->lun_type != T_DIRECT) + goto err; retval = ctl_inquiry_evpd_bdc(ctsio, alloc_len); break; case SVPD_LBP: + if (lun == NULL || lun->be_lun->lun_type != T_DIRECT) + goto err; retval = ctl_inquiry_evpd_lbp(ctsio, alloc_len); break; default: +err: ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1, From cafe874475568bdd2f970b192ceb4185461b949d Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 23 Dec 2014 15:38:19 +0000 Subject: [PATCH 115/207] Restore the trap type argument to the DTrace trap hook, removed in r268600. It's redundant at the moment since it can be obtained from the trapframe on the architectures where DTrace is supported, but this won't be the case with ARM. --- sys/amd64/amd64/trap.c | 3 ++- sys/cddl/dev/dtrace/amd64/dtrace_subr.c | 4 ++-- sys/cddl/dev/dtrace/i386/dtrace_subr.c | 4 ++-- sys/cddl/dev/dtrace/mips/dtrace_subr.c | 5 +---- sys/cddl/dev/dtrace/powerpc/dtrace_subr.c | 5 +++-- sys/i386/i386/trap.c | 2 +- sys/mips/mips/trap.c | 3 ++- sys/powerpc/aim/trap.c | 2 +- sys/sys/dtrace_bsd.h | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 4880c913552..67842cfc4a1 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -614,7 +614,8 @@ trap_check(struct trapframe *frame) { #ifdef KDTRACE_HOOKS - if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame)) + if (dtrace_trap_func != NULL && + (*dtrace_trap_func)(frame, frame->tf_trapno) != 0) return; #endif trap(frame); diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c index c123cc6aa5b..805add208cd 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c @@ -464,7 +464,7 @@ dtrace_gethrestime(void) /* Function to handle DTrace traps during probes. See amd64/amd64/trap.c. */ int -dtrace_trap(struct trapframe *frame) +dtrace_trap(struct trapframe *frame, u_int type) { /* * A trap can occur while DTrace executes a probe. Before @@ -480,7 +480,7 @@ dtrace_trap(struct trapframe *frame) * There are only a couple of trap types that are expected. * All the rest will be handled in the usual way. */ - switch (frame->tf_trapno) { + switch (type) { /* General protection fault. */ case T_PROTFLT: /* Flag an illegal operation. */ diff --git a/sys/cddl/dev/dtrace/i386/dtrace_subr.c b/sys/cddl/dev/dtrace/i386/dtrace_subr.c index e620a8fe611..4073317e165 100644 --- a/sys/cddl/dev/dtrace/i386/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/i386/dtrace_subr.c @@ -473,7 +473,7 @@ dtrace_gethrestime(void) /* Function to handle DTrace traps during probes. See i386/i386/trap.c */ int -dtrace_trap(struct trapframe *frame) +dtrace_trap(struct trapframe *frame, u_int type) { /* * A trap can occur while DTrace executes a probe. Before @@ -489,7 +489,7 @@ dtrace_trap(struct trapframe *frame) * There are only a couple of trap types that are expected. * All the rest will be handled in the usual way. */ - switch (frame->tf_trapno) { + switch (type) { /* General protection fault. */ case T_PROTFLT: /* Flag an illegal operation. */ diff --git a/sys/cddl/dev/dtrace/mips/dtrace_subr.c b/sys/cddl/dev/dtrace/mips/dtrace_subr.c index 5565a616a17..4f13b986934 100644 --- a/sys/cddl/dev/dtrace/mips/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/mips/dtrace_subr.c @@ -137,11 +137,8 @@ dtrace_gethrestime(void) /* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */ int -dtrace_trap(struct trapframe *frame) +dtrace_trap(struct trapframe *frame, u_int type) { - u_int type; - - type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT; /* * A trap can occur while DTrace executes a probe. Before diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c index 5411ece1f33..a89f1d32adf 100644 --- a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c @@ -262,8 +262,9 @@ dtrace_gethrestime(void) /* Function to handle DTrace traps during probes. See powerpc/powerpc/trap.c */ int -dtrace_trap(struct trapframe *frame) +dtrace_trap(struct trapframe *frame, u_int type) { + /* * A trap can occur while DTrace executes a probe. Before * executing the probe, DTrace blocks re-scheduling and sets @@ -278,7 +279,7 @@ dtrace_trap(struct trapframe *frame) * There are only a couple of trap types that are expected. * All the rest will be handled in the usual way. */ - switch (frame->exc) { + switch (type) { /* Page fault. */ case EXC_DSI: case EXC_DSE: diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 490d4815c7d..6d35c3af454 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -246,7 +246,7 @@ trap(struct trapframe *frame) * flag is cleared and finally re-scheduling is enabled. */ if ((type == T_PROTFLT || type == T_PAGEFLT) && - dtrace_trap_func != NULL && (*dtrace_trap_func)(frame)) + dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type)) goto out; #endif diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index a4405ae5941..98fe812dc93 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -617,7 +617,8 @@ trap(struct trapframe *trapframe) * XXXDTRACE: add pid probe handler here (if ever) */ if (!usermode) { - if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe)) + if (dtrace_trap_func != NULL && + (*dtrace_trap_func)(trapframe, type) != 0) return (trapframe->pc); } #endif diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 354c63be4f6..2f30d6d5a5b 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -177,7 +177,7 @@ trap(struct trapframe *frame) * handled the trap and modified the trap frame so that this * function can return normally. */ - if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame)) + if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type) != 0) return; #endif diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h index 6bcaf296396..f46b900e160 100644 --- a/sys/sys/dtrace_bsd.h +++ b/sys/sys/dtrace_bsd.h @@ -39,14 +39,14 @@ struct vattr; struct vnode; struct reg; -int dtrace_trap(struct trapframe *); +int dtrace_trap(struct trapframe *, u_int); /* * The dtrace module handles traps that occur during a DTrace probe. * This type definition is used in the trap handler to provide a * hook for the dtrace module to register its handler with. */ -typedef int (*dtrace_trap_func_t)(struct trapframe *); +typedef int (*dtrace_trap_func_t)(struct trapframe *, u_int); extern dtrace_trap_func_t dtrace_trap_func; /* From 3f1cbdbeb190dc15a4602a55e7d100461e20643e Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 23 Dec 2014 15:40:57 +0000 Subject: [PATCH 116/207] Fix a memory leak that occured when looking up CTF info for a symbol. --- lib/libproc/proc_sym.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c index 766ff73446e..e52f8ff563e 100644 --- a/lib/libproc/proc_sym.c +++ b/lib/libproc/proc_sym.c @@ -501,13 +501,16 @@ ctf_file_t * proc_name2ctf(struct proc_handle *p, const char *name) { #ifndef NO_CTF + ctf_file_t *ctf; prmap_t *map; int error; if ((map = proc_name2map(p, name)) == NULL) return (NULL); - return (ctf_open(map->pr_mapname, &error)); + ctf = ctf_open(map->pr_mapname, &error); + free(map); + return (ctf); #else (void)p; (void)name; From 2f6cde8eb465d459b8276d6a1436e50dcf7ed11d Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 23 Dec 2014 15:42:33 +0000 Subject: [PATCH 117/207] We can stop iterating once we've found the DOF section. Submitted by: Fedor Indutny --- cddl/contrib/opensolaris/lib/libdtrace/common/drti.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index fc86eb79522..d7b34907e4b 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -171,6 +171,7 @@ dtrace_dof_init(void) if (s != NULL && strcmp(s, ".SUNW_dof") == 0) { dofdata = elf_getdata(scn, NULL); dof = dofdata->d_buf; + break; } } } From 48eb0b8512e4cc654687351d10c7f8b205ac6cd6 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Tue, 23 Dec 2014 15:42:34 +0000 Subject: [PATCH 118/207] Convert a couple lingering NO_FORTH conditionals to test MK_FORTH. --- sys/boot/arm/uboot/Makefile | 2 +- sys/boot/powerpc/uboot/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/arm/uboot/Makefile b/sys/boot/arm/uboot/Makefile index 743f1897d05..c69d8aaabb6 100644 --- a/sys/boot/arm/uboot/Makefile +++ b/sys/boot/arm/uboot/Makefile @@ -76,7 +76,7 @@ LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -.if !defined(NO_FORTH) +.if ${MK_FORTH} != "no" # Enable BootForth BOOT_FORTH= yes CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/arm diff --git a/sys/boot/powerpc/uboot/Makefile b/sys/boot/powerpc/uboot/Makefile index a5a06a9d84f..681249aca78 100644 --- a/sys/boot/powerpc/uboot/Makefile +++ b/sys/boot/powerpc/uboot/Makefile @@ -66,7 +66,7 @@ LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a .endif -.if !defined(NO_FORTH) +.if ${MK_FORTH} != "no" # Enable BootForth BOOT_FORTH= yes CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc From 8f2fdc72adccc3bfd9db416a8ae9cd8df4e10d3e Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 23 Dec 2014 15:58:45 +0000 Subject: [PATCH 119/207] Use explicit --output-target to set EFI file format According to objcopy(1) --target is for use where the input and output formats are the same ("no translation"). In practice it does detect the input format in any case, but be explicit that we're specifying the output format as we are translating from ELF to EFI PE format. Sponsored by: The FreeBSD Foundation --- sys/boot/amd64/boot1.efi/Makefile | 2 +- sys/boot/amd64/efi/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/amd64/boot1.efi/Makefile b/sys/boot/amd64/boot1.efi/Makefile index 3e3bc9fcc82..dd8eaf9e4cd 100644 --- a/sys/boot/amd64/boot1.efi/Makefile +++ b/sys/boot/amd64/boot1.efi/Makefile @@ -51,7 +51,7 @@ boot1.efi: loader.sym ${OBJCOPY} -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ - --target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} + --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} CFLAGS+= -I${.CURDIR}/../../common diff --git a/sys/boot/amd64/efi/Makefile b/sys/boot/amd64/efi/Makefile index a9a213227d0..66b8cf86806 100644 --- a/sys/boot/amd64/efi/Makefile +++ b/sys/boot/amd64/efi/Makefile @@ -81,7 +81,7 @@ loader.efi: loader.sym ${OBJCOPY} -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel.dyn \ -j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \ - --target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} + --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET} LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a CFLAGS+= -I${.CURDIR}/../../common From 1a868688a49c8c1e9201aeb4b089f6ab1266b8e1 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 23 Dec 2014 16:00:25 +0000 Subject: [PATCH 120/207] Update comment: only one file in the FAT file system EFI boot image Sponsored by: The FreeBSD Foundation --- sys/boot/amd64/boot1.efi/generate-fat.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/amd64/boot1.efi/generate-fat.sh b/sys/boot/amd64/boot1.efi/generate-fat.sh index eafd3e00dfe..e8f9cdedd4b 100755 --- a/sys/boot/amd64/boot1.efi/generate-fat.sh +++ b/sys/boot/amd64/boot1.efi/generate-fat.sh @@ -34,10 +34,10 @@ umount stub mdconfig -d -u $DEVICE rmdir stub -# Locate the offsets of the two fake files +# Locate the offset of the fake file BOOT1_OFFSET=$(hd $OUTPUT_FILE | grep 'Boot1 START' | cut -f 1 -d ' ') -# Convert to numbers of blocks +# Convert to number of blocks BOOT1_OFFSET=$(echo 0x$BOOT1_OFFSET | awk '{printf("%x\n",$1/512);}') echo '# This file autogenerated by generate-fat.sh - DO NOT EDIT' > Makefile.fat From 132c449079aa5834921025145b0ae86bf72443d0 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 23 Dec 2014 16:17:37 +0000 Subject: [PATCH 121/207] Remove in_gif.h and in6_gif.h files. They only contain function declarations used by gif(4). Instead declare these functions in C files. Also make some variables static. --- ObsoleteFiles.inc | 3 +++ sys/net/if_gif.c | 12 ++++++++++-- sys/netinet/in_gif.c | 13 +++++++++---- sys/netinet/in_gif.h | 44 ------------------------------------------ sys/netinet6/in6_gif.c | 13 +++++++++---- sys/netinet6/in6_gif.h | 44 ------------------------------------------ 6 files changed, 31 insertions(+), 98 deletions(-) delete mode 100644 sys/netinet/in_gif.h delete mode 100644 sys/netinet6/in6_gif.h diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 71d2cc04b49..fff65dcafd1 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20141223: remove in6_gif.h and in_gif.h +OLD_FILES+=usr/include/netinet/in_gif.h +OLD_FILES+=usr/include/netinet6/in6_gif.h # 20141202: update to mandoc CVS 20141201 OLD_FILES+=usr.bin/preconv OLD_FILES+=share/man/man1/preconv.1.gz diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 674060dda21..421d1b34b8d 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$"); #include #ifdef INET #include -#include #include #endif /* INET */ @@ -85,7 +84,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #endif /* INET6 */ @@ -120,6 +118,16 @@ void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af); void (*ng_gif_attach_p)(struct ifnet *ifp); void (*ng_gif_detach_p)(struct ifnet *ifp); +#ifdef INET +extern int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +extern int in_gif_encapcheck(const struct mbuf *, int, int, void *); +extern int in_gif_attach(struct gif_softc *); +#endif +#ifdef INET6 +extern int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +extern int in6_gif_encapcheck(const struct mbuf *, int, int, void *); +extern int in6_gif_attach(struct gif_softc *); +#endif static int gif_set_tunnel(struct ifnet *, struct sockaddr *, struct sockaddr *); static void gif_delete_tunnel(struct ifnet *); diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index 46f68f5ffdc..261c88acf99 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -68,11 +67,16 @@ __FBSDID("$FreeBSD$"); #include +int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +int in_gif_encapcheck(const struct mbuf *, int, int, void *); +int in_gif_attach(struct gif_softc *); + static int gif_validate4(const struct ip *, struct gif_softc *, struct ifnet *); +static int in_gif_input(struct mbuf **, int *, int); extern struct domain inetdomain; -struct protosw in_gif_protosw = { +static struct protosw in_gif_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inetdomain, .pr_protocol = 0/* IPPROTO_IPV[46] */, @@ -83,7 +87,8 @@ struct protosw in_gif_protosw = { .pr_usrreqs = &rip_usrreqs }; -VNET_DEFINE(int, ip_gif_ttl) = GIF_TTL; +#define GIF_TTL 30 +static VNET_DEFINE(int, ip_gif_ttl) = GIF_TTL; #define V_ip_gif_ttl VNET(ip_gif_ttl) SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_gif_ttl), 0, ""); @@ -133,7 +138,7 @@ in_gif_output(struct ifnet *ifp, struct mbuf *m, int proto, uint8_t ecn) return (ip_output(m, NULL, NULL, 0, NULL, NULL)); } -int +static int in_gif_input(struct mbuf **mp, int *offp, int proto) { struct mbuf *m = *mp; diff --git a/sys/netinet/in_gif.h b/sys/netinet/in_gif.h deleted file mode 100644 index d48d8810917..00000000000 --- a/sys/netinet/in_gif.h +++ /dev/null @@ -1,44 +0,0 @@ -/* $FreeBSD$ */ -/* $KAME: in_gif.h,v 1.5 2000/04/14 08:36:02 itojun Exp $ */ - -/*- - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _NETINET_IN_GIF_H_ -#define _NETINET_IN_GIF_H_ - -#define GIF_TTL 30 - -struct gif_softc; -int in_gif_input(struct mbuf **, int *, int); -int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); -int in_gif_encapcheck(const struct mbuf *, int, int, void *); -int in_gif_attach(struct gif_softc *); - -#endif /*_NETINET_IN_GIF_H_*/ diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 10d5d7bc8cb..855315ed150 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$"); #ifdef INET6 #include #include -#include #include #endif #include @@ -74,18 +73,24 @@ __FBSDID("$FreeBSD$"); #include -VNET_DEFINE(int, ip6_gif_hlim) = GIF_HLIM; +#define GIF_HLIM 30 +static VNET_DEFINE(int, ip6_gif_hlim) = GIF_HLIM; #define V_ip6_gif_hlim VNET(ip6_gif_hlim) SYSCTL_DECL(_net_inet6_ip6); SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_gif_hlim), 0, ""); +int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +int in6_gif_encapcheck(const struct mbuf *, int, int, void *); +int in6_gif_attach(struct gif_softc *); + static int gif_validate6(const struct ip6_hdr *, struct gif_softc *, struct ifnet *); +static int in6_gif_input(struct mbuf **, int *, int); extern struct domain inet6domain; -struct protosw in6_gif_protosw = { +static struct protosw in6_gif_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = 0, /* IPPROTO_IPV[46] */ @@ -144,7 +149,7 @@ in6_gif_output(struct ifnet *ifp, struct mbuf *m, int proto, uint8_t ecn) return (ip6_output(m, 0, NULL, IPV6_MINMTU, 0, NULL, NULL)); } -int +static int in6_gif_input(struct mbuf **mp, int *offp, int proto) { struct mbuf *m = *mp; diff --git a/sys/netinet6/in6_gif.h b/sys/netinet6/in6_gif.h deleted file mode 100644 index 124617120fd..00000000000 --- a/sys/netinet6/in6_gif.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $KAME: in6_gif.h,v 1.5 2000/04/14 08:36:03 itojun Exp $ - * $FreeBSD$ - */ - -#ifndef _NETINET6_IN6_GIF_H_ -#define _NETINET6_IN6_GIF_H_ - -#define GIF_HLIM 30 - -struct gif_softc; -int in6_gif_input(struct mbuf **, int *, int); -int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); -int in6_gif_encapcheck(const struct mbuf *, int, int, void *); -int in6_gif_attach(struct gif_softc *); - -#endif /* _NETINET6_IN6_GIF_H_ */ From 70bd9518f1b732814a77c609a0401c6c4ee97f8e Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Tue, 23 Dec 2014 18:48:45 +0000 Subject: [PATCH 122/207] Bump the valid GPIO range for rfkill up from 8 to 16. AR5416 and later NICs have more than 8 (Well, more than 6) GPIO pins. So to support rfkill on these NICs we need to bump this up or the rfkill GPIO pin may get reset to the wrong value. Noticed by: Anthony Jenkins --- sys/dev/ath/if_ath_sysctl.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c index 40a34d479db..45c8ae4895e 100644 --- a/sys/dev/ath/if_ath_sysctl.c +++ b/sys/dev/ath/if_ath_sysctl.c @@ -446,7 +446,15 @@ ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS) return error; if (!ath_hal_setrfsilent(sc->sc_ah, rfsilent)) return EINVAL; - sc->sc_rfsilentpin = rfsilent & 0x1c; + /* + * Earlier chips (< AR5212) have up to 8 GPIO + * pins exposed. + * + * AR5416 and later chips have many more GPIO + * pins (up to 16) so the mask is expanded to + * four bits. + */ + sc->sc_rfsilentpin = rfsilent & 0x3c; sc->sc_rfsilentpol = (rfsilent & 0x2) != 0; return 0; } From 3b9e64af650c47babe6a3d2491d8fe6f8ec1f6c5 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Tue, 23 Dec 2014 19:31:56 +0000 Subject: [PATCH 123/207] Do not return the total number of available pins but the maximum pin number we can cope. Previously the returned value could prevent access to some of the pins. --- sys/arm/ti/ti_gpio.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index de88a48a21b..06faf112694 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -293,19 +293,8 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask) static int ti_gpio_pin_max(device_t dev, int *maxpin) { - struct ti_gpio_softc *sc = device_get_softc(dev); - unsigned int i; - unsigned int banks = 0; - /* Calculate how many valid banks we have and then multiply that by 32 to - * give use the total number of pins. - */ - for (i = 0; i < ti_max_gpio_banks(); i++) { - if (sc->sc_mem_res[i] != NULL) - banks++; - } - - *maxpin = (banks * PINS_PER_BANK) - 1; + *maxpin = ti_max_gpio_banks() * PINS_PER_BANK - 1; return (0); } From 06cd035ab6ee4d4ab08fb621d3af69ade673433d Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Tue, 23 Dec 2014 20:54:59 +0000 Subject: [PATCH 124/207] Remove if_stf.h. It contains only one function declaration used by if_stf(4). Also make in_stf_protosw structure static. --- ObsoleteFiles.inc | 3 ++- sys/net/if_stf.c | 6 +++--- sys/net/if_stf.h | 38 -------------------------------------- 3 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 sys/net/if_stf.h diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index fff65dcafd1..70b76b8dd62 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,7 +38,8 @@ # xargs -n1 | sort | uniq -d; # done -# 20141223: remove in6_gif.h and in_gif.h +# 20141223: remove in6_gif.h, in_gif.h and if_stf.h +OLD_FILES+=usr/include/net/if_stf.h OLD_FILES+=usr/include/netinet/in_gif.h OLD_FILES+=usr/include/netinet6/in6_gif.h # 20141202: update to mandoc CVS 20141201 diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index f3a604255dd..aed2a37379d 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -99,7 +99,6 @@ #include #include #include -#include #include #include @@ -156,7 +155,8 @@ static MALLOC_DEFINE(M_STF, stfname, "6to4 Tunnel Interface"); static const int ip_stf_ttl = 40; extern struct domain inetdomain; -struct protosw in_stf_protosw = { +static int in_stf_input(struct mbuf **, int *, int); +static struct protosw in_stf_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_IPV6, @@ -620,7 +620,7 @@ stf_checkaddr6(sc, in6, inifp) return 0; } -int +static int in_stf_input(struct mbuf **mp, int *offp, int proto) { struct stf_softc *sc; diff --git a/sys/net/if_stf.h b/sys/net/if_stf.h deleted file mode 100644 index 07f585b8c7a..00000000000 --- a/sys/net/if_stf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* $FreeBSD$ */ -/* $KAME: if_stf.h,v 1.5 2001/10/12 10:09:17 keiichi Exp $ */ - -/*- - * Copyright (C) 2000 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _NET_IF_STF_H_ -#define _NET_IF_STF_H_ - -int in_stf_input(struct mbuf **, int *, int); - -#endif /* _NET_IF_STF_H_ */ From 1dda8e90c989ad97a8dd3e8c9914c8100da1f3a5 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 01:10:53 +0000 Subject: [PATCH 125/207] Revert r276101, it didn't fix the problem and causes a compile error (nested comment blocks). --- sys/boot/fdt/dts/arm/rpi.dts | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/boot/fdt/dts/arm/rpi.dts b/sys/boot/fdt/dts/arm/rpi.dts index 5ded2af8856..08d9d24bb4e 100644 --- a/sys/boot/fdt/dts/arm/rpi.dts +++ b/sys/boot/fdt/dts/arm/rpi.dts @@ -35,7 +35,6 @@ memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */ - /* cpus { #address-cells = <1>; #size-cells = <0>; @@ -46,7 +45,6 @@ clock-frequency = <700000000>; /* 700MHz */ }; }; - */ memory { device_type = "memory"; From cbe686f7093b29ad1060178f78626e6ec5166af7 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 01:19:11 +0000 Subject: [PATCH 126/207] Don't assume required FDT properties are present. --- sys/dev/ofw/ofw_cpu.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sys/dev/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c index 226514059d5..1d01b63993e 100644 --- a/sys/dev/ofw/ofw_cpu.c +++ b/sys/dev/ofw/ofw_cpu.c @@ -171,7 +171,7 @@ ofw_cpu_probe(device_t dev) { const char *type = ofw_bus_get_type(dev); - if (strcmp(type, "cpu") != 0) + if (type == NULL || strcmp(type, "cpu") != 0) return (ENXIO); device_set_desc(dev, "Open Firmware CPU"); @@ -182,12 +182,20 @@ static int ofw_cpu_attach(device_t dev) { struct ofw_cpu_softc *sc; + phandle_t node; uint32_t cell; sc = device_get_softc(dev); - OF_getprop(ofw_bus_get_node(dev), "reg", &cell, sizeof(cell)); + node = ofw_bus_get_node(dev); + if (OF_getencprop(node, "reg", &cell, sizeof(cell)) < 0) { + cell = device_get_unit(dev); + device_printf(dev, "missing 'reg' property, using %u\n", cell); + } sc->sc_cpu_pcpu = pcpu_find(cell); - OF_getprop(ofw_bus_get_node(dev), "clock-frequency", &cell, sizeof(cell)); + if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) < 0) { + device_printf(dev, "missing 'clock-frequency' property\n"); + return (ENXIO); + } sc->sc_nominal_mhz = cell / 1000000; /* convert to MHz */ bus_generic_probe(dev); From 84cc2bcd19aba5bb0bbb8732b8bb96673748ca50 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Wed, 24 Dec 2014 01:50:44 +0000 Subject: [PATCH 127/207] Allow info to display correctly in for varying tabstop settings The SAMPLE message and notes where tab seperated for some parts and hence displayed incorrectly unless tabstop was set to 8. Switch to spaces to it displays correctly independent of the tabstop setting. Sponsored by: Multiplay --- etc/hosts.allow | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/etc/hosts.allow b/etc/hosts.allow index 95286d75cc7..3e19bc84040 100644 --- a/etc/hosts.allow +++ b/etc/hosts.allow @@ -4,15 +4,15 @@ # # NOTE: The hosts.deny file is deprecated. # Place both 'allow' and 'deny' rules in the hosts.allow file. -# See hosts_options(5) for the format of this file. -# hosts_access(5) no longer fully applies. - -# _____ _ _ -# | ____| __ __ __ _ _ __ ___ _ __ | | ___ | | -# | _| \ \/ / / _` | | '_ ` _ \ | '_ \ | | / _ \ | | -# | |___ > < | (_| | | | | | | | | |_) | | | | __/ |_| -# |_____| /_/\_\ \__,_| |_| |_| |_| | .__/ |_| \___| (_) -# |_| +# See hosts_options(5) for the format of this file. +# hosts_access(5) no longer fully applies. +# +# _____ _ _ +# | ____| __ __ __ _ _ __ ___ _ __ | | ___ | | +# | _| \ \/ / / _` | | '_ ` _ \ | '_ \ | | / _ \ | | +# | |___ > < | (_| | | | | | | | | |_) | | | | __/ |_| +# |_____| /_/\_\ \__,_| |_| |_| |_| | .__/ |_| \___| (_) +# |_| # !!! This is an example! You will need to modify it for your specific # !!! requirements! From 6783238b2deea7acaf2f83745b864263f701536c Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 03:02:12 +0000 Subject: [PATCH 128/207] Define the old-school arm arch constants we still use internally based on the somewhat newer constants predefined by the compiler. This will allow userland apps to use various machine/foo.h headers without CPUTYPE defined. --- sys/arm/include/cpuconf.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/sys/arm/include/cpuconf.h b/sys/arm/include/cpuconf.h index da35e576bbe..bc57d5967a7 100644 --- a/sys/arm/include/cpuconf.h +++ b/sys/arm/include/cpuconf.h @@ -85,20 +85,43 @@ #endif #if !defined(ARM_ARCH_6) -#if defined(CPU_ARM1136) || defined(CPU_ARM1176) +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_MV_PJ4B) #define ARM_ARCH_6 1 #else #define ARM_ARCH_6 0 #endif #endif -#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) || defined(CPU_MV_PJ4B) +#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) #define ARM_ARCH_7A 1 #else #define ARM_ARCH_7A 0 #endif #define ARM_NARCH (ARM_ARCH_4 + ARM_ARCH_5 + ARM_ARCH_6 | ARM_ARCH_7A) + +/* + * Compatibility for userland builds that have no CPUTYPE defined. Use the ARCH + * constants predefined by the compiler to define our old-school arch constants. + * This is a stopgap measure to tide us over until the conversion of all code + * to the newer ACLE constants defined by ARM (see acle-compat.h). + */ +#if ARM_NARCH == 0 +#if defined(__ARM_ARCH_4T__) +#undef ARM_ARCH_4 +#undef ARM_NARCH +#define ARM_ARCH_4 1 +#define ARM_NARCH 1 +#define CPU_ARM9 1 +#elif defined(__ARM_ARCH_6ZK__) +#undef ARM_ARCH_6 +#undef ARM_NARCH +#define ARM_ARCH_6 1 +#define ARM_NARCH 1 +#define CPU_ARM1176 1 +#endif +#endif + #if ARM_NARCH == 0 && !defined(KLD_MODULE) && defined(_KERNEL) #error ARM_NARCH is 0 #endif From 0236b3314fc11e041f52cccc0a4ed29724dc0542 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 03:09:55 +0000 Subject: [PATCH 129/207] Revert a glitched mismerge that got caught up in the prior commit. The PJ4B family is still armv7, not armv6. --- sys/arm/include/cpuconf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm/include/cpuconf.h b/sys/arm/include/cpuconf.h index bc57d5967a7..fb021539cae 100644 --- a/sys/arm/include/cpuconf.h +++ b/sys/arm/include/cpuconf.h @@ -85,14 +85,14 @@ #endif #if !defined(ARM_ARCH_6) -#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || defined(CPU_MV_PJ4B) +#if defined(CPU_ARM1136) || defined(CPU_ARM1176) #define ARM_ARCH_6 1 #else #define ARM_ARCH_6 0 #endif #endif -#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) +#if defined(CPU_CORTEXA) || defined(CPU_KRAIT) || defined(CPU_MV_PJ4B) #define ARM_ARCH_7A 1 #else #define ARM_ARCH_7A 0 From 0bac52c1cc1c4a0e100dd2eef865d7e9a4821c21 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Wed, 24 Dec 2014 03:24:50 +0000 Subject: [PATCH 130/207] Improves the GPIO API description a little bit. gpio_pin_max must return the maximum supported pin number and not the total number of pins on the system. PR: 157070 Submitted by: brix --- sys/dev/gpio/gpio_if.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/gpio/gpio_if.m b/sys/dev/gpio/gpio_if.m index f0ead651ce8..adc119e3d92 100644 --- a/sys/dev/gpio/gpio_if.m +++ b/sys/dev/gpio/gpio_if.m @@ -56,11 +56,11 @@ HEADER { }; # -# Get total number of pins +# Get maximum pin number # METHOD int pin_max { device_t dev; - int *npins; + int *maxpin; }; # From aa6b24dc9a675940c4a806d9a74c904e851028bc Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 24 Dec 2014 03:49:33 +0000 Subject: [PATCH 131/207] Add Intel vendor ID to the device table to make it more uniform so that all the pnp info to match the device is in the fxp_ident_table. --- sys/dev/fxp/if_fxp.c | 112 ++++++++++++++++++++-------------------- sys/dev/fxp/if_fxpreg.h | 2 - sys/dev/fxp/if_fxpvar.h | 3 +- 3 files changed, 58 insertions(+), 59 deletions(-) diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 947f057365d..cf0e6a249ff 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -157,52 +157,52 @@ static const u_char fxp_cb_config_template[] = { * them. */ static const struct fxp_ident fxp_ident_table[] = { - { 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" }, - { 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" }, - { 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" }, - { 0x1032, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" }, - { 0x1033, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, - { 0x1034, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, - { 0x1035, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, - { 0x1036, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, - { 0x1037, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, - { 0x1038, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, - { 0x1039, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" }, - { 0x103A, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" }, - { 0x103B, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" }, - { 0x103C, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" }, - { 0x103D, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" }, - { 0x103E, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" }, - { 0x1050, -1, 5, "Intel 82801BA (D865) Pro/100 VE Ethernet" }, - { 0x1051, -1, 5, "Intel 82562ET (ICH5/ICH5R) Pro/100 VE Ethernet" }, - { 0x1059, -1, 0, "Intel 82551QM Pro/100 M Mobile Connection" }, - { 0x1064, -1, 6, "Intel 82562EZ (ICH6)" }, - { 0x1065, -1, 6, "Intel 82562ET/EZ/GT/GZ PRO/100 VE Ethernet" }, - { 0x1068, -1, 6, "Intel 82801FBM (ICH6-M) Pro/100 VE Ethernet" }, - { 0x1069, -1, 6, "Intel 82562EM/EX/GX Pro/100 Ethernet" }, - { 0x1091, -1, 7, "Intel 82562GX Pro/100 Ethernet" }, - { 0x1092, -1, 7, "Intel Pro/100 VE Network Connection" }, - { 0x1093, -1, 7, "Intel Pro/100 VM Network Connection" }, - { 0x1094, -1, 7, "Intel Pro/100 946GZ (ICH7) Network Connection" }, - { 0x1209, -1, 0, "Intel 82559ER Embedded 10/100 Ethernet" }, - { 0x1229, 0x01, 0, "Intel 82557 Pro/100 Ethernet" }, - { 0x1229, 0x02, 0, "Intel 82557 Pro/100 Ethernet" }, - { 0x1229, 0x03, 0, "Intel 82557 Pro/100 Ethernet" }, - { 0x1229, 0x04, 0, "Intel 82558 Pro/100 Ethernet" }, - { 0x1229, 0x05, 0, "Intel 82558 Pro/100 Ethernet" }, - { 0x1229, 0x06, 0, "Intel 82559 Pro/100 Ethernet" }, - { 0x1229, 0x07, 0, "Intel 82559 Pro/100 Ethernet" }, - { 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" }, - { 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" }, - { 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" }, - { 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" }, - { 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" }, - { 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" }, - { 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" }, - { 0x1229, -1, 0, "Intel 82557/8/9 Pro/100 Ethernet" }, - { 0x2449, -1, 2, "Intel 82801BA/CAM (ICH2/3) Pro/100 Ethernet" }, - { 0x27dc, -1, 7, "Intel 82801GB (ICH7) 10/100 Ethernet" }, - { 0, -1, 0, NULL }, + { 0x8086, 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" }, + { 0x8086, 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" }, + { 0x8086, 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" }, + { 0x8086, 0x1032, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" }, + { 0x8086, 0x1033, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, + { 0x8086, 0x1034, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, + { 0x8086, 0x1035, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, + { 0x8086, 0x1036, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, + { 0x8086, 0x1037, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" }, + { 0x8086, 0x1038, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" }, + { 0x8086, 0x1039, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" }, + { 0x8086, 0x103A, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" }, + { 0x8086, 0x103B, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" }, + { 0x8086, 0x103C, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" }, + { 0x8086, 0x103D, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" }, + { 0x8086, 0x103E, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" }, + { 0x8086, 0x1050, -1, 5, "Intel 82801BA (D865) Pro/100 VE Ethernet" }, + { 0x8086, 0x1051, -1, 5, "Intel 82562ET (ICH5/ICH5R) Pro/100 VE Ethernet" }, + { 0x8086, 0x1059, -1, 0, "Intel 82551QM Pro/100 M Mobile Connection" }, + { 0x8086, 0x1064, -1, 6, "Intel 82562EZ (ICH6)" }, + { 0x8086, 0x1065, -1, 6, "Intel 82562ET/EZ/GT/GZ PRO/100 VE Ethernet" }, + { 0x8086, 0x1068, -1, 6, "Intel 82801FBM (ICH6-M) Pro/100 VE Ethernet" }, + { 0x8086, 0x1069, -1, 6, "Intel 82562EM/EX/GX Pro/100 Ethernet" }, + { 0x8086, 0x1091, -1, 7, "Intel 82562GX Pro/100 Ethernet" }, + { 0x8086, 0x1092, -1, 7, "Intel Pro/100 VE Network Connection" }, + { 0x8086, 0x1093, -1, 7, "Intel Pro/100 VM Network Connection" }, + { 0x8086, 0x1094, -1, 7, "Intel Pro/100 946GZ (ICH7) Network Connection" }, + { 0x8086, 0x1209, -1, 0, "Intel 82559ER Embedded 10/100 Ethernet" }, + { 0x8086, 0x1229, 0x01, 0, "Intel 82557 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x02, 0, "Intel 82557 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x03, 0, "Intel 82557 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x04, 0, "Intel 82558 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x05, 0, "Intel 82558 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x06, 0, "Intel 82559 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x07, 0, "Intel 82559 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" }, + { 0x8086, 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" }, + { 0x8086, 0x1229, -1, 0, "Intel 82557/8/9 Pro/100 Ethernet" }, + { 0x8086, 0x2449, -1, 2, "Intel 82801BA/CAM (ICH2/3) Pro/100 Ethernet" }, + { 0x8086, 0x27dc, -1, 7, "Intel 82801GB (ICH7) 10/100 Ethernet" }, + { 0, 0, -1, 0, NULL }, }; #ifdef FXP_IP_CSUM_WAR @@ -374,18 +374,18 @@ fxp_dma_wait(struct fxp_softc *sc, volatile uint16_t *status, static const struct fxp_ident * fxp_find_ident(device_t dev) { - uint16_t devid; + uint16_t vendor; + uint16_t device; uint8_t revid; const struct fxp_ident *ident; - if (pci_get_vendor(dev) == FXP_VENDORID_INTEL) { - devid = pci_get_device(dev); - revid = pci_get_revid(dev); - for (ident = fxp_ident_table; ident->name != NULL; ident++) { - if (ident->devid == devid && - (ident->revid == revid || ident->revid == -1)) { - return (ident); - } + vendor = pci_get_vendor(dev); + device = pci_get_device(dev); + revid = pci_get_revid(dev); + for (ident = fxp_ident_table; ident->name != NULL; ident++) { + if (ident->vendor == vendor && ident->device == device && + (ident->revid == revid || ident->revid == -1)) { + return (ident); } } return (NULL); @@ -628,7 +628,7 @@ fxp_attach(device_t dev) /* For 82559 or later chips, Rx checksum offload is supported. */ if (sc->revision >= FXP_REV_82559_A0) { /* 82559ER does not support Rx checksum offloading. */ - if (sc->ident->devid != 0x1209) + if (sc->ident->device != 0x1209) sc->flags |= FXP_FLAG_82559_RXCSUM; } /* diff --git a/sys/dev/fxp/if_fxpreg.h b/sys/dev/fxp/if_fxpreg.h index 7fd60afd170..7ee8588400a 100644 --- a/sys/dev/fxp/if_fxpreg.h +++ b/sys/dev/fxp/if_fxpreg.h @@ -28,8 +28,6 @@ * $FreeBSD$ */ -#define FXP_VENDORID_INTEL 0x8086 - #define FXP_PCI_MMBA 0x10 #define FXP_PCI_IOBA 0x14 diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h index e0097a158b0..78200ce3b3f 100644 --- a/sys/dev/fxp/if_fxpvar.h +++ b/sys/dev/fxp/if_fxpvar.h @@ -143,7 +143,8 @@ struct fxp_desc_list { }; struct fxp_ident { - uint16_t devid; + uint16_t vendor; + uint16_t device; int16_t revid; /* -1 matches anything */ uint8_t ich; const char *name; From e350f76c662d09a5c80c6d01b01949c678d2f947 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Wed, 24 Dec 2014 04:24:08 +0000 Subject: [PATCH 132/207] Bring in the last round of updates before adding the interrupt support. Fix the following issues: - Removed revision from device softc, it isn't used anywhere else out of device attach routine; - Move the duplicated code for verification of valid banks (and pins) to a single function; - Use some macros to simplify the handling of some constants; - Update some stale comments. --- sys/arm/ti/ti_gpio.c | 108 ++++++++++++++++++++++--------------------- sys/arm/ti/ti_gpio.h | 9 +--- 2 files changed, 58 insertions(+), 59 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index 06faf112694..45ce9594409 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -117,6 +117,8 @@ __FBSDID("$FreeBSD$"); #define AM335X_INTR_PER_BANK 2 #define AM335X_GPIO_REV 0x50600801 #define PINS_PER_BANK 32 +#define TI_GPIO_BANK(p) ((p) / PINS_PER_BANK) +#define TI_GPIO_MASK(p) (1U << ((p) % PINS_PER_BANK)) static u_int ti_max_gpio_banks(void) @@ -236,7 +238,7 @@ static struct resource_spec ti_gpio_irq_spec[] = { #define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED) /** - * ti_gpio_read_4 - reads a 16-bit value from one of the PADCONFS registers + * ti_gpio_read_4 - reads a 32-bit value from one of the GPIO registers * @sc: GPIO device context * @bank: The bank to read from * @off: The offset of a register from the GPIO register address range @@ -252,7 +254,7 @@ ti_gpio_read_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off) } /** - * ti_gpio_write_4 - writes a 32-bit value to one of the PADCONFS registers + * ti_gpio_write_4 - writes a 32-bit value to one of the GPIO registers * @sc: GPIO device context * @bank: The bank to write to * @off: The offset of a register from the GPIO register address range @@ -299,6 +301,19 @@ ti_gpio_pin_max(device_t dev, int *maxpin) return (0); } +static int +ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin) +{ + + if (pin > sc->sc_maxpin || + TI_GPIO_BANK(pin) >= ti_max_gpio_banks() || + sc->sc_mem_res[TI_GPIO_BANK(pin)] == NULL) { + return (EINVAL); + } + + return (0); +} + /** * ti_gpio_pin_getcaps - Gets the capabilties of a given pin * @dev: gpio device handle @@ -320,11 +335,10 @@ ti_gpio_pin_max(device_t dev, int *maxpin) static int ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); + struct ti_gpio_softc *sc; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP | @@ -352,11 +366,10 @@ ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) static int ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); + struct ti_gpio_softc *sc; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); /* Get the current pin state */ @@ -385,11 +398,10 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) static int ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); + struct ti_gpio_softc *sc; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); /* Set a very simple name */ @@ -421,13 +433,11 @@ ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name) static int ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); - uint32_t mask = (1UL << (pin % PINS_PER_BANK)); + struct ti_gpio_softc *sc; uint32_t oe; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); /* Set the GPIO mode and state */ @@ -438,12 +448,12 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) } /* If configuring as an output set the "output enable" bit */ - oe = ti_gpio_read_4(sc, bank, TI_GPIO_OE); + oe = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE); if (flags & GPIO_PIN_INPUT) - oe |= mask; + oe |= TI_GPIO_MASK(pin); else - oe &= ~mask; - ti_gpio_write_4(sc, bank, TI_GPIO_OE, oe); + oe &= ~TI_GPIO_MASK(pin); + ti_gpio_write_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE, oe); TI_GPIO_UNLOCK(sc); return (0); @@ -466,13 +476,11 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) static int ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); - uint32_t mask = (1UL << (pin % PINS_PER_BANK)); + struct ti_gpio_softc *sc; uint32_t reg; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); TI_GPIO_LOCK(sc); @@ -480,7 +488,7 @@ ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) reg = TI_GPIO_CLEARDATAOUT; else reg = TI_GPIO_SETDATAOUT; - ti_gpio_write_4(sc, bank, reg, mask); + ti_gpio_write_4(sc, TI_GPIO_BANK(pin), reg, TI_GPIO_MASK(pin)); TI_GPIO_UNLOCK(sc); return (0); @@ -504,13 +512,11 @@ ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) static int ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); - uint32_t mask = (1UL << (pin % PINS_PER_BANK)); - uint32_t oe, reg; + struct ti_gpio_softc *sc; + uint32_t oe, reg, val; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); /* @@ -518,12 +524,13 @@ ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) * input register otherwise. */ TI_GPIO_LOCK(sc); - oe = ti_gpio_read_4(sc, bank, TI_GPIO_OE); - if (oe & mask) + oe = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE); + if (oe & TI_GPIO_MASK(pin)) reg = TI_GPIO_DATAIN; else reg = TI_GPIO_DATAOUT; - *value = (ti_gpio_read_4(sc, bank, reg) & mask) ? 1 : 0; + val = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), reg); + *value = (val & TI_GPIO_MASK(pin)) ? 1 : 0; TI_GPIO_UNLOCK(sc); return (0); @@ -544,23 +551,21 @@ ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value) static int ti_gpio_pin_toggle(device_t dev, uint32_t pin) { - struct ti_gpio_softc *sc = device_get_softc(dev); - uint32_t bank = (pin / PINS_PER_BANK); - uint32_t mask = (1UL << (pin % PINS_PER_BANK)); + struct ti_gpio_softc *sc; uint32_t reg, val; - /* Sanity check the pin number is valid */ - if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, pin) != 0) return (EINVAL); /* Toggle the pin */ TI_GPIO_LOCK(sc); - val = ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT); - if (val & mask) + val = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_DATAOUT); + if (val & TI_GPIO_MASK(pin)) reg = TI_GPIO_CLEARDATAOUT; else reg = TI_GPIO_SETDATAOUT; - ti_gpio_write_4(sc, bank, reg, mask); + ti_gpio_write_4(sc, TI_GPIO_BANK(pin), reg, TI_GPIO_MASK(pin)); TI_GPIO_UNLOCK(sc); return (0); @@ -638,7 +643,7 @@ ti_gpio_bank_init(device_t dev, int bank) { int pin; struct ti_gpio_softc *sc; - uint32_t flags, reg_oe; + uint32_t flags, reg_oe, rev; sc = device_get_softc(dev); @@ -650,13 +655,12 @@ ti_gpio_bank_init(device_t dev, int bank) * actual revision numbers, so instead the values have been * determined by experimentation. */ - sc->sc_revision[bank] = ti_gpio_read_4(sc, bank, TI_GPIO_REVISION); + rev = ti_gpio_read_4(sc, bank, TI_GPIO_REVISION); /* Check the revision. */ - if (sc->sc_revision[bank] != ti_gpio_rev()) { + if (rev != ti_gpio_rev()) { device_printf(dev, "Warning: could not determine the revision " - "of %u GPIO module (revision:0x%08x)\n", - bank, sc->sc_revision[bank]); + "of GPIO module %d (revision:0x%08x)\n", bank, rev); return (EINVAL); } @@ -697,8 +701,8 @@ ti_gpio_attach(device_t dev) sc = device_get_softc(dev); sc->sc_dev = dev; - TI_GPIO_LOCK_INIT(sc); + ti_gpio_pin_max(dev, &sc->sc_maxpin); /* There are up to 6 different GPIO register sets located in different * memory areas on the chip. The memory range should have been set for diff --git a/sys/arm/ti/ti_gpio.h b/sys/arm/ti/ti_gpio.h index 0e1199f1927..6b6d79443c3 100644 --- a/sys/arm/ti/ti_gpio.h +++ b/sys/arm/ti/ti_gpio.h @@ -46,6 +46,8 @@ */ struct ti_gpio_softc { device_t sc_dev; + int sc_maxpin; + struct mtx sc_mtx; /* * The memory resource(s) for the PRCM register set, when the device is @@ -57,13 +59,6 @@ struct ti_gpio_softc { /* The handle for the register IRQ handlers. */ void *sc_irq_hdl[MAX_GPIO_INTRS]; - - /* - * The following describes the H/W revision of each of the GPIO banks. - */ - uint32_t sc_revision[MAX_GPIO_BANKS]; - - struct mtx sc_mtx; }; #endif /* TI_GPIO_H */ From 23059fc77f65beb33c08393cf81afcdc02f5bbd6 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Wed, 24 Dec 2014 07:04:04 +0000 Subject: [PATCH 133/207] Fix tunable and sysctl handling of the fail_on_task_timeout knob. Reviewed by: emax Obtained from: Netflix, Inc. MFC after: 3 days --- sys/dev/isci/isci_controller.c | 2 ++ sys/dev/isci/isci_sysctl.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/dev/isci/isci_controller.c b/sys/dev/isci/isci_controller.c index f3ff0825faf..b0f42852dda 100644 --- a/sys/dev/isci/isci_controller.c +++ b/sys/dev/isci/isci_controller.c @@ -373,6 +373,8 @@ SCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller) fail_on_timeout = 1; TUNABLE_INT_FETCH("hw.isci.fail_on_task_timeout", &fail_on_timeout); + controller->fail_on_task_timeout = fail_on_timeout; + /* Attach to CAM using xpt_bus_register now, then immediately freeze * the simq. It will get released later when initial domain discovery * is complete. diff --git a/sys/dev/isci/isci_sysctl.c b/sys/dev/isci/isci_sysctl.c index 62a10b95890..a7c56c63233 100644 --- a/sys/dev/isci/isci_sysctl.c +++ b/sys/dev/isci/isci_sysctl.c @@ -226,12 +226,13 @@ static int isci_sysctl_fail_on_task_timeout(SYSCTL_HANDLER_ARGS) { struct isci_softc *isci = (struct isci_softc *)arg1; - int32_t fail_on_timeout = 0; + int32_t fail_on_timeout; int error, i; + fail_on_timeout = isci->controllers[0].fail_on_task_timeout; error = sysctl_handle_int(oidp, &fail_on_timeout, 0, req); - if (error || fail_on_timeout == 0) + if (error || req->newptr == NULL) return (error); for (i = 0; i < isci->controller_count; i++) From c418933aeef4d8d3982a34060be611dc023d3613 Mon Sep 17 00:00:00 2001 From: Muhammad Moinur Rahman Date: Wed, 24 Dec 2014 09:25:16 +0000 Subject: [PATCH 134/207] Update Mentor and Mentee Information (bofh) Differential Revision: https://reviews.freebsd.org/D1363 Reviewed by: bapt Approved by: bapt --- share/misc/committers-ports.dot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index ae0390fe033..0e476b280b6 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -67,6 +67,7 @@ beech [label="Beech Rintoul\nbeech@FreeBSD.org\n2007/05/30"] bf [label="Brendan Fabeny\nbf@FreeBSD.org\n2010/06/02"] bland [label="Alexander Nedotsukov\nbland@FreeBSD.org\n2003/08/14"] bmah [label="Bruce A. Mah\nbmah@FreeBSD.org\n2000/08/23"] +bofh [label="Muhammad Moinur Rahman\bofh@FreeBSD.org\n2014/12/23"] brix [label="Henrik Brix Andersen\nbrix@FreeBSD.org\n2007/10/31"] brooks [label="Brooks Davies\nbrooks@FreeBSD.org\n2004/05/03"] bsam [label="Boris Samorodov\nbsam@FreeBSD.org\n2006/07/20"] @@ -263,6 +264,7 @@ bdrewery -> sbruno bdrewery -> trociny bapt -> bdrewery +bapt -> bofh bapt -> eadler bapt -> grembo bapt -> jlaffaye @@ -430,6 +432,7 @@ marcus -> bland marcus -> eik marcus -> jmallett +marino -> bofh marino -> robak makc -> alonso From 799cf446be2ca0ece3c501f23e47f0b646c5d569 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 24 Dec 2014 10:13:53 +0000 Subject: [PATCH 135/207] Clarify to explain that C99 conforming compilers don't need CMPLX*(). Discussed with: kargl@ --- lib/msun/src/math_private.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h index 083197e1b94..afaf201ae03 100644 --- a/lib/msun/src/math_private.h +++ b/lib/msun/src/math_private.h @@ -456,9 +456,8 @@ typedef union { * to -0.0+I*0.0. * * The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL() - * to construct complex values. The functions below are modelled after - * these macros, with the exception that they cannot be used to - * construct compile-time complex values. + * to construct complex values. Compilers that conform to the C99 + * standard require the following functions to avoid the above issues. */ #ifndef CMPLXF From ef7eac4353c913d185b7c9b51cf5e235c7c76759 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 24 Dec 2014 12:26:43 +0000 Subject: [PATCH 136/207] Switch i.MX to use the platform code to help with a single Freescale kernel. Differential Revision: https://reviews.freebsd.org/D1349 Reviewed by: ian, rpaulo --- sys/arm/conf/EFIKA_MX | 1 + sys/arm/conf/IMX53 | 1 + sys/arm/conf/IMX6 | 1 + sys/arm/freescale/imx/imx51_machdep.c | 37 +++++++++++++------------ sys/arm/freescale/imx/imx53_machdep.c | 37 +++++++++++++------------ sys/arm/freescale/imx/imx6_machdep.c | 40 +++++++++++++++++---------- 6 files changed, 66 insertions(+), 51 deletions(-) diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index b6351c8edc7..459cd799306 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -59,6 +59,7 @@ options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options PLATFORM options INCLUDE_CONFIG_FILE # Include this file in kernel options VFP # Enable floating point hardware support diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index a2db13b60f8..12cd4cfc0b0 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -56,6 +56,7 @@ options SYSVMSG # SYSV-style message queues options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options PLATFORM options INCLUDE_CONFIG_FILE # Include this file in kernel options VFP # Enable floating point hardware support diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 32807847032..bdaab26fb7f 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -53,6 +53,7 @@ options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev options INCLUDE_CONFIG_FILE # Include this file in kernel +options PLATFORM options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8) options VFP # Enable floating point hardware support options SMP # Enable multiple cores diff --git a/sys/arm/freescale/imx/imx51_machdep.c b/sys/arm/freescale/imx/imx51_machdep.c index 8ab6541e2e4..5d8f380fe43 100644 --- a/sys/arm/freescale/imx/imx51_machdep.c +++ b/sys/arm/freescale/imx/imx51_machdep.c @@ -39,36 +39,28 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include -vm_offset_t -platform_lastaddr(void) +#include "platform_if.h" + +static vm_offset_t +imx51_lastaddr(platform_t plat) { return (arm_devmap_lastaddr()); } -void -platform_probe_and_attach(void) +static int +imx51_attach(platform_t plat) { /* XXX - Get rid of this stuff soon. */ boothowto |= RB_VERBOSE|RB_MULTIPLE; bootverbose = 1; -} - -void -platform_gpio_init(void) -{ - -} - -void -platform_late_init(void) -{ + return (0); } /* @@ -78,8 +70,8 @@ platform_late_init(void) * * Notably missing are entries for GPU, IPU, in general anything video related. */ -int -platform_devmap_init(void) +static int +imx51_devmap_init(platform_t plat) { arm_devmap_add_entry(0x70000000, 0x00100000); @@ -101,3 +93,12 @@ u_int imx_soc_type() return (IMXSOC_51); } +static platform_method_t imx51_methods[] = { + PLATFORMMETHOD(platform_attach, imx51_attach), + PLATFORMMETHOD(platform_devmap_init, imx51_devmap_init), + PLATFORMMETHOD(platform_lastaddr, imx51_lastaddr), + + PLATFORMMETHOD_END, +}; + +FDT_PLATFORM_DEF(imx51, "i.MX51", 0, "fsl,imx51"); diff --git a/sys/arm/freescale/imx/imx53_machdep.c b/sys/arm/freescale/imx/imx53_machdep.c index ebf09d9af8b..92b59e4b493 100644 --- a/sys/arm/freescale/imx/imx53_machdep.c +++ b/sys/arm/freescale/imx/imx53_machdep.c @@ -39,36 +39,28 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include -vm_offset_t -platform_lastaddr(void) +#include "platform_if.h" + +static vm_offset_t +imx53_lastaddr(platform_t plat) { return (arm_devmap_lastaddr()); } -void -platform_probe_and_attach(void) +static int +imx53_attach(platform_t plat) { /* XXX - Get rid of this stuff soon. */ boothowto |= RB_VERBOSE|RB_MULTIPLE; bootverbose = 1; -} - -void -platform_gpio_init(void) -{ - -} - -void -platform_late_init(void) -{ + return (0); } /* @@ -78,8 +70,8 @@ platform_late_init(void) * * Notably missing are entries for GPU, IPU, in general anything video related. */ -int -platform_devmap_init(void) +static int +imx53_devmap_init(platform_t plat) { arm_devmap_add_entry(0x50000000, 0x00100000); @@ -101,4 +93,13 @@ u_int imx_soc_type() return (IMXSOC_53); } +static platform_method_t imx53_methods[] = { + PLATFORMMETHOD(platform_attach, imx53_attach), + PLATFORMMETHOD(platform_devmap_init, imx53_devmap_init), + PLATFORMMETHOD(platform_lastaddr, imx53_lastaddr), + + PLATFORMMETHOD_END, +}; + +FDT_PLATFORM_DEF(imx53, "i.MX53", 0, "fsl,imx53"); diff --git a/sys/arm/freescale/imx/imx6_machdep.c b/sys/arm/freescale/imx/imx6_machdep.c index 510a09b9833..2322cffab0d 100644 --- a/sys/arm/freescale/imx/imx6_machdep.c +++ b/sys/arm/freescale/imx/imx6_machdep.c @@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "platform_if.h" + struct fdt_fixup_entry fdt_fixup_table[] = { { NULL, NULL } }; @@ -90,29 +92,25 @@ fdt_pic_decode_t fdt_pic_table[] = { NULL }; -vm_offset_t -platform_lastaddr(void) +static vm_offset_t +imx6_lastaddr(platform_t plat) { return (arm_devmap_lastaddr()); } -void -platform_probe_and_attach(void) +static int +imx6_attach(platform_t plat) { /* Inform the MPCore timer driver that its clock is variable. */ arm_tmr_change_frequency(ARM_TMR_FREQUENCY_VARIES); + + return (0); } -void -platform_gpio_init(void) -{ - -} - -void -platform_late_init(void) +static void +imx6_late_init(platform_t plat) { /* Cache the gpio1 node handle for imx6_decode_fdt() workaround code. */ @@ -136,8 +134,8 @@ platform_late_init(void) * static map some of that area. Be careful with other things in that area such * as OCRAM that probably shouldn't be mapped as PTE_DEVICE memory. */ -int -platform_devmap_init(void) +static int +imx6_devmap_init(platform_t plat) { const uint32_t IMX6_ARMMP_PHYS = 0x00a00000; const uint32_t IMX6_ARMMP_SIZE = 0x00100000; @@ -271,3 +269,15 @@ imx6_early_putc(int c) early_putc_t *early_putc = imx6_early_putc; #endif +static platform_method_t imx6_methods[] = { + PLATFORMMETHOD(platform_attach, imx6_attach), + PLATFORMMETHOD(platform_lastaddr, imx6_lastaddr), + PLATFORMMETHOD(platform_devmap_init, imx6_devmap_init), + PLATFORMMETHOD(platform_late_init, imx6_late_init), + + PLATFORMMETHOD_END, +}; + +FDT_PLATFORM_DEF2(imx6, imx6s, "i.MX6 Solo", 0, "fsl,imx6s"); +FDT_PLATFORM_DEF2(imx6, imx6d, "i.MX6 Dual", 0, "fsl,imx6d"); +FDT_PLATFORM_DEF2(imx6, imx6q, "i.MX6 Quad", 0, "fsl,imx6q"); From 819d692b5e6693beaf28caf67ca38433ce452c2c Mon Sep 17 00:00:00 2001 From: Muhammad Moinur Rahman Date: Wed, 24 Dec 2014 13:25:22 +0000 Subject: [PATCH 137/207] Fix missing \n in committers-ports.dot while adding myself Differential Revision: https://reviews.freebsd.org/D1365 Submitted by: danfe Approved by: bapt(mentor) --- share/misc/committers-ports.dot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index 0e476b280b6..e97acba9584 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -67,7 +67,7 @@ beech [label="Beech Rintoul\nbeech@FreeBSD.org\n2007/05/30"] bf [label="Brendan Fabeny\nbf@FreeBSD.org\n2010/06/02"] bland [label="Alexander Nedotsukov\nbland@FreeBSD.org\n2003/08/14"] bmah [label="Bruce A. Mah\nbmah@FreeBSD.org\n2000/08/23"] -bofh [label="Muhammad Moinur Rahman\bofh@FreeBSD.org\n2014/12/23"] +bofh [label="Muhammad Moinur Rahman\nbofh@FreeBSD.org\n2014/12/23"] brix [label="Henrik Brix Andersen\nbrix@FreeBSD.org\n2007/10/31"] brooks [label="Brooks Davies\nbrooks@FreeBSD.org\n2004/05/03"] bsam [label="Boris Samorodov\nbsam@FreeBSD.org\n2006/07/20"] From ed600fa777e1f9157613bbe0d7857f5904a22e3d Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 24 Dec 2014 15:25:18 +0000 Subject: [PATCH 138/207] Rename pic_ipi_get to pic_ipi_read for intrng. --- sys/arm/arm/gic.c | 2 +- sys/arm/arm/mp_machdep.c | 4 ++-- sys/arm/include/smp.h | 2 +- sys/arm/mv/mpic.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index 10513a68151..af667ca07c4 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -436,7 +436,7 @@ pic_ipi_send(cpuset_t cpus, u_int ipi) } int -pic_ipi_get(int i) +pic_ipi_read(int i) { if (i != -1) { diff --git a/sys/arm/arm/mp_machdep.c b/sys/arm/arm/mp_machdep.c index a1b29c112cb..32dce4dcbff 100644 --- a/sys/arm/arm/mp_machdep.c +++ b/sys/arm/arm/mp_machdep.c @@ -266,7 +266,7 @@ ipi_handler(void *arg) cpu = PCPU_GET(cpuid); - ipi = pic_ipi_get((int)arg); + ipi = pic_ipi_read((int)arg); while ((ipi != 0x3ff)) { switch (ipi) { @@ -329,7 +329,7 @@ ipi_handler(void *arg) } pic_ipi_clear(ipi); - ipi = pic_ipi_get(-1); + ipi = pic_ipi_read(-1); } return (FILTER_HANDLED); diff --git a/sys/arm/include/smp.h b/sys/arm/include/smp.h index 6301c9a95ce..3803674dded 100644 --- a/sys/arm/include/smp.h +++ b/sys/arm/include/smp.h @@ -24,7 +24,7 @@ void ipi_selected(cpuset_t cpus, u_int ipi); /* PIC interface */ void pic_ipi_send(cpuset_t cpus, u_int ipi); void pic_ipi_clear(int ipi); -int pic_ipi_get(int arg); +int pic_ipi_read(int arg); /* Platform interface */ void platform_mp_setmaxid(void); diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c index 813caf48fa0..bfb55544ad7 100644 --- a/sys/arm/mv/mpic.c +++ b/sys/arm/mv/mpic.c @@ -375,7 +375,7 @@ pic_ipi_send(cpuset_t cpus, u_int ipi) } int -pic_ipi_get(int i __unused) +pic_ipi_read(int i __unused) { uint32_t val; From baa4417f37a2170ab8e53de77b3ffec791355799 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 17:12:51 +0000 Subject: [PATCH 139/207] Eliminate unnecessary references to pte.h internals by using the standard pmap_kenter_temporary() to map pages while dumping. Submitted by: Svatopluk Kraus , Michal Meloun --- sys/arm/arm/dump_machdep.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/arm/arm/dump_machdep.c b/sys/arm/arm/dump_machdep.c index 19c19c90f5c..61d6eb5e2b7 100644 --- a/sys/arm/arm/dump_machdep.c +++ b/sys/arm/arm/dump_machdep.c @@ -160,11 +160,13 @@ static int cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) { struct dumperinfo *di = (struct dumperinfo*)arg; - vm_paddr_t pa; + vm_paddr_t a, pa; + void *va; uint32_t pgs; size_t counter, sz, chunk; - int c, error; + int i, c, error; + va = 0; error = 0; /* catch case in which chunk size is 0 */ counter = 0; pgs = mdp->md_size / PAGE_SIZE; @@ -194,16 +196,14 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg) printf(" %d", pgs * PAGE_SIZE); counter &= (1<<24) - 1; } - if (pa == (pa & L1_ADDR_BITS)) { - pmap_kenter_section(0, pa & L1_ADDR_BITS, 0); - cpu_tlb_flushID_SE(0); - cpu_cpwait(); + for (i = 0; i < chunk; i++) { + a = pa + i * PAGE_SIZE; + va = pmap_kenter_temporary(trunc_page(a), i); } #ifdef SW_WATCHDOG wdog_kern_pat(WD_LASTVAL); #endif - error = dump_write(di, - (void *)(pa - (pa & L1_ADDR_BITS)),0, dumplo, sz); + error = dump_write(di, va, 0, dumplo, sz); if (error) break; dumplo += sz; From 93201211e94eba30a1171a818ebdfed10cb5838d Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Wed, 24 Dec 2014 18:34:56 +0000 Subject: [PATCH 140/207] Rename ip4_def_policy variable to def_policy. It is used by both IPv4 and IPv6. Initialize it only once in def_policy_init(). Remove its initialization from key_init() and make it static. Remove several fields from struct secpolicy: * lock - it isn't so useful having mutex in the structure, but the only thing we do with it is initialization and destroying. * state - it has only two values - DEAD and ALIVE. Instead of take a lock and change the state to DEAD, then take lock again in GC function and delete policy from the chain - keep in the chain only ALIVE policies. * scangen - it was used in GC function to protect from sending several SADB_SPDEXPIRE messages for one SPD entry. Now we don't keep DEAD entries in the chain and there is no need to have scangen variable. Use TAILQ to implement SPD entries chain. Use rmlock to protect access to SPD entries chain. Protect all SP lookup with RLOCK, and use WLOCK when we are inserting (or removing) SP entry in the chain. Instead of using pattern "LOCK(); refcnt++; UNLOCK();", use refcount(9) API to implement refcounting in SPD. Merge code from key_delsp() and _key_delsp() into _key_freesp(). And use KEY_FREESP() macro in all cases when we want to release reference or just delete SP entry. Obtained from: Yandex LLC Sponsored by: Yandex LLC --- sys/netipsec/ipsec.c | 27 ++-- sys/netipsec/ipsec.h | 23 +-- sys/netipsec/key.c | 295 ++++++++++++++++----------------------- sys/netipsec/key_debug.c | 4 +- 4 files changed, 140 insertions(+), 209 deletions(-) diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index 5e0cdbfd7df..8a79052677c 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -118,11 +118,12 @@ VNET_DEFINE(int, ip4_esp_trans_deflev) = IPSEC_LEVEL_USE; VNET_DEFINE(int, ip4_esp_net_deflev) = IPSEC_LEVEL_USE; VNET_DEFINE(int, ip4_ah_trans_deflev) = IPSEC_LEVEL_USE; VNET_DEFINE(int, ip4_ah_net_deflev) = IPSEC_LEVEL_USE; -VNET_DEFINE(struct secpolicy, ip4_def_policy); /* ECN ignore(-1)/forbidden(0)/allowed(1) */ VNET_DEFINE(int, ip4_ipsec_ecn) = 0; VNET_DEFINE(int, ip4_esp_randpad) = -1; +static VNET_DEFINE(struct secpolicy, def_policy); +#define V_def_policy VNET(def_policy) /* * Crypto support requirements: * @@ -141,7 +142,7 @@ SYSCTL_DECL(_net_inet_ipsec); /* net.inet.ipsec */ SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_def_policy).policy, 0, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0, "IPsec default policy."); SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_trans_deflev), 0, @@ -213,7 +214,7 @@ SYSCTL_DECL(_net_inet6_ipsec6); /* net.inet6.ipsec6 */ SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_def_policy).policy, 0, + CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0, "IPsec default policy."); SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_trans_deflev), 0, @@ -262,7 +263,7 @@ key_allocsp_default(const char* where, int tag) KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP key_allocsp_default from %s:%u\n", where, tag)); - sp = &V_ip4_def_policy; + sp = &V_def_policy; if (sp->policy != IPSEC_POLICY_DISCARD && sp->policy != IPSEC_POLICY_NONE) { ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n", @@ -828,17 +829,13 @@ ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp) ipsec_delpcbpolicy(new); return (ENOBUFS); } - new->sp_in->state = IPSEC_SPSTATE_ALIVE; new->sp_in->policy = IPSEC_POLICY_ENTRUST; - if ((new->sp_out = KEY_NEWSP()) == NULL) { KEY_FREESP(&new->sp_in); ipsec_delpcbpolicy(new); return (ENOBUFS); } - new->sp_out->state = IPSEC_SPSTATE_ALIVE; new->sp_out->policy = IPSEC_POLICY_ENTRUST; - *pcb_sp = new; return (0); @@ -927,7 +924,6 @@ ipsec_deepcopy_policy(struct secpolicy *src) } dst->req = newchain; - dst->state = src->state; dst->policy = src->policy; /* Do not touch the refcnt fields. */ @@ -979,8 +975,6 @@ ipsec_set_policy_internal(struct secpolicy **pcb_sp, int optname, if ((newsp = key_msg2sp(xpl, len, &error)) == NULL) return (error); - newsp->state = IPSEC_SPSTATE_ALIVE; - /* Clear old SP and set new SP. */ KEY_FREESP(pcb_sp); *pcb_sp = newsp; @@ -1693,14 +1687,15 @@ ipsec_dumpmbuf(struct mbuf *m) } static void -ipsec_init(const void *unused __unused) +def_policy_init(const void *unused __unused) { - SECPOLICY_LOCK_INIT(&V_ip4_def_policy); - V_ip4_def_policy.refcnt = 1; /* NB: disallow free. */ + bzero(&V_def_policy, sizeof(struct secpolicy)); + V_def_policy.policy = IPSEC_POLICY_NONE; + V_def_policy.refcnt = 1; } -VNET_SYSINIT(ipsec_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, ipsec_init, - NULL); +VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, + def_policy_init, NULL); /* XXX This stuff doesn't belong here... */ diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index 8ed39fbe93c..5e3e1c3b003 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -81,21 +81,15 @@ struct secpolicyindex { /* Security Policy Data Base */ struct secpolicy { - LIST_ENTRY(secpolicy) chain; - struct mtx lock; + TAILQ_ENTRY(secpolicy) chain; - u_int refcnt; /* reference count */ struct secpolicyindex spidx; /* selector */ - u_int32_t id; /* It's unique number on the system. */ - u_int state; /* 0: dead, others: alive */ -#define IPSEC_SPSTATE_DEAD 0 -#define IPSEC_SPSTATE_ALIVE 1 - u_int policy; /* policy_type per pfkeyv2.h */ - u_int16_t scangen; /* scan generation # */ struct ipsecrequest *req; /* pointer to the ipsec request tree, */ /* if policy == IPSEC else this value == NULL.*/ - + u_int refcnt; /* reference count */ + u_int policy; /* policy_type per pfkeyv2.h */ + u_int32_t id; /* It's unique number on the system. */ /* * lifetime handler. * the policy can be used without limitiation if both lifetime and @@ -109,13 +103,6 @@ struct secpolicy { long validtime; /* duration this policy is valid without use */ }; -#define SECPOLICY_LOCK_INIT(_sp) \ - mtx_init(&(_sp)->lock, "ipsec policy", NULL, MTX_DEF) -#define SECPOLICY_LOCK(_sp) mtx_lock(&(_sp)->lock) -#define SECPOLICY_UNLOCK(_sp) mtx_unlock(&(_sp)->lock) -#define SECPOLICY_LOCK_DESTROY(_sp) mtx_destroy(&(_sp)->lock) -#define SECPOLICY_LOCK_ASSERT(_sp) mtx_assert(&(_sp)->lock, MA_OWNED) - /* Request for IPsec */ struct ipsecrequest { struct ipsecrequest *next; @@ -279,7 +266,6 @@ VNET_DECLARE(int, ipsec_integrity); #endif VNET_PCPUSTAT_DECLARE(struct ipsecstat, ipsec4stat); -VNET_DECLARE(struct secpolicy, ip4_def_policy); VNET_DECLARE(int, ip4_esp_trans_deflev); VNET_DECLARE(int, ip4_esp_net_deflev); VNET_DECLARE(int, ip4_ah_trans_deflev); @@ -292,7 +278,6 @@ VNET_DECLARE(int, crypto_support); #define IPSECSTAT_INC(name) \ VNET_PCPUSTAT_ADD(struct ipsecstat, ipsec4stat, name, 1) -#define V_ip4_def_policy VNET(ip4_def_policy) #define V_ip4_esp_trans_deflev VNET(ip4_esp_trans_deflev) #define V_ip4_esp_net_deflev VNET(ip4_esp_net_deflev) #define V_ip4_ah_trans_deflev VNET(ip4_ah_trans_deflev) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 953f453ec76..5fdf83b2c09 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -141,16 +142,19 @@ static VNET_DEFINE(u_int32_t, acq_seq) = 0; #define V_acq_seq VNET(acq_seq) /* SPD */ -static VNET_DEFINE(LIST_HEAD(_sptree, secpolicy), sptree[IPSEC_DIR_MAX]); +static VNET_DEFINE(TAILQ_HEAD(_sptree, secpolicy), sptree[IPSEC_DIR_MAX]); +static struct rmlock sptree_lock; #define V_sptree VNET(sptree) -static struct mtx sptree_lock; -#define SPTREE_LOCK_INIT() \ - mtx_init(&sptree_lock, "sptree", \ - "fast ipsec security policy database", MTX_DEF) -#define SPTREE_LOCK_DESTROY() mtx_destroy(&sptree_lock) -#define SPTREE_LOCK() mtx_lock(&sptree_lock) -#define SPTREE_UNLOCK() mtx_unlock(&sptree_lock) -#define SPTREE_LOCK_ASSERT() mtx_assert(&sptree_lock, MA_OWNED) +#define SPTREE_LOCK_INIT() rm_init(&sptree_lock, "sptree") +#define SPTREE_LOCK_DESTROY() rm_destroy(&sptree_lock) +#define SPTREE_RLOCK_TRACKER struct rm_priotracker sptree_tracker +#define SPTREE_RLOCK() rm_rlock(&sptree_lock, &sptree_tracker) +#define SPTREE_RUNLOCK() rm_runlock(&sptree_lock, &sptree_tracker) +#define SPTREE_RLOCK_ASSERT() rm_assert(&sptree_lock, RA_RLOCKED) +#define SPTREE_WLOCK() rm_wlock(&sptree_lock) +#define SPTREE_WUNLOCK() rm_wunlock(&sptree_lock) +#define SPTREE_WLOCK_ASSERT() rm_assert(&sptree_lock, RA_WLOCKED) +#define SPTREE_UNLOCK_ASSERT() rm_assert(&sptree_lock, RA_UNLOCKED) static VNET_DEFINE(LIST_HEAD(_sahtree, secashead), sahtree); /* SAD */ #define V_sahtree VNET(sahtree) @@ -416,9 +420,8 @@ static struct callout key_timer; static struct secasvar *key_allocsa_policy(const struct secasindex *); static void key_freesp_so(struct secpolicy **); static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int); -static void key_delsp(struct secpolicy *); +static void key_unlink(struct secpolicy *); static struct secpolicy *key_getsp(struct secpolicyindex *); -static void _key_delsp(struct secpolicy *sp); static struct secpolicy *key_getspbyid(u_int32_t); static u_int32_t key_newreqid(void); static struct mbuf *key_gather_mbuf(struct mbuf *, @@ -575,15 +578,8 @@ sa_delref(struct secasvar *sav) return (refcount_release(&sav->refcnt)); } -#define SP_ADDREF(p) do { \ - (p)->refcnt++; \ - IPSEC_ASSERT((p)->refcnt != 0, ("SP refcnt overflow")); \ -} while (0) -#define SP_DELREF(p) do { \ - IPSEC_ASSERT((p)->refcnt > 0, ("SP refcnt underflow")); \ - (p)->refcnt--; \ -} while (0) - +#define SP_ADDREF(p) refcount_acquire(&(p)->refcnt) +#define SP_DELREF(p) refcount_release(&(p)->refcnt) /* * Update the refcnt while holding the SPTREE lock. @@ -591,9 +587,8 @@ sa_delref(struct secasvar *sav) void key_addref(struct secpolicy *sp) { - SPTREE_LOCK(); + SP_ADDREF(sp); - SPTREE_UNLOCK(); } /* @@ -606,7 +601,7 @@ key_havesp(u_int dir) { return (dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND ? - LIST_FIRST(&V_sptree[dir]) != NULL : 1); + TAILQ_FIRST(&V_sptree[dir]) != NULL : 1); } /* %%% IPsec policy management */ @@ -620,6 +615,7 @@ struct secpolicy * key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where, int tag) { + SPTREE_RLOCK_TRACKER; struct secpolicy *sp; IPSEC_ASSERT(spidx != NULL, ("null spidx")); @@ -634,14 +630,11 @@ key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where, printf("*** objects\n"); kdebug_secpolicyindex(spidx)); - SPTREE_LOCK(); - LIST_FOREACH(sp, &V_sptree[dir], chain) { + SPTREE_RLOCK(); + TAILQ_FOREACH(sp, &V_sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); kdebug_secpolicyindex(&sp->spidx)); - - if (sp->state == IPSEC_SPSTATE_DEAD) - continue; if (key_cmpspidx_withmask(&sp->spidx, spidx)) goto found; } @@ -655,7 +648,7 @@ found: sp->lastused = time_second; SP_ADDREF(sp); } - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__, @@ -673,6 +666,7 @@ struct secpolicy * key_allocsp2(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto, u_int dir, const char* where, int tag) { + SPTREE_RLOCK_TRACKER; struct secpolicy *sp; IPSEC_ASSERT(dst != NULL, ("null dst")); @@ -688,14 +682,11 @@ key_allocsp2(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto, printf("spi %u proto %u dir %u\n", spi, proto, dir); kdebug_sockaddr(&dst->sa)); - SPTREE_LOCK(); - LIST_FOREACH(sp, &V_sptree[dir], chain) { + SPTREE_RLOCK(); + TAILQ_FOREACH(sp, &V_sptree[dir], chain) { KEYDEBUG(KEYDEBUG_IPSEC_DATA, printf("*** in SPD\n"); kdebug_secpolicyindex(&sp->spidx)); - - if (sp->state == IPSEC_SPSTATE_DEAD) - continue; /* compare simple values, then dst address */ if (sp->spidx.ul_proto != proto) continue; @@ -715,7 +706,7 @@ found: sp->lastused = time_second; SP_ADDREF(sp); } - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__, @@ -1174,22 +1165,41 @@ done: void _key_freesp(struct secpolicy **spp, const char* where, int tag) { + struct ipsecrequest *isr, *nextisr; struct secpolicy *sp = *spp; IPSEC_ASSERT(sp != NULL, ("null sp")); - - SPTREE_LOCK(); - SP_DELREF(sp); - KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP %s SP:%p (ID=%u) from %s:%u; refcnt now %u\n", __func__, sp, sp->id, where, tag, sp->refcnt)); - if (sp->refcnt == 0) { - *spp = NULL; - key_delsp(sp); + if (SP_DELREF(sp) == 0) + return; + *spp = NULL; + for (isr = sp->req; isr != NULL; isr = nextisr) { + if (isr->sav != NULL) { + KEY_FREESAV(&isr->sav); + isr->sav = NULL; + } + nextisr = isr->next; + ipsec_delisr(isr); } - SPTREE_UNLOCK(); + free(sp, M_IPSEC_SP); +} + +static void +key_unlink(struct secpolicy *sp) +{ + + IPSEC_ASSERT(sp != NULL, ("null sp")); + IPSEC_ASSERT(sp->spidx.dir == IPSEC_DIR_INBOUND || + sp->spidx.dir == IPSEC_DIR_OUTBOUND, + ("invalid direction %u", sp->spidx.dir)); + SPTREE_UNLOCK_ASSERT(); + + SPTREE_WLOCK(); + TAILQ_REMOVE(&V_sptree[sp->spidx.dir], sp, chain); + SPTREE_WUNLOCK(); } /* @@ -1277,38 +1287,6 @@ key_freesav(struct secasvar **psav, const char* where, int tag) } /* %%% SPD management */ -/* - * free security policy entry. - */ -static void -key_delsp(struct secpolicy *sp) -{ - struct ipsecrequest *isr, *nextisr; - - IPSEC_ASSERT(sp != NULL, ("null sp")); - SPTREE_LOCK_ASSERT(); - - sp->state = IPSEC_SPSTATE_DEAD; - - IPSEC_ASSERT(sp->refcnt == 0, - ("SP with references deleted (refcnt %u)", sp->refcnt)); - - /* remove from SP index */ - if (__LIST_CHAINED(sp)) - LIST_REMOVE(sp, chain); - - for (isr = sp->req; isr != NULL; isr = nextisr) { - if (isr->sav != NULL) { - KEY_FREESAV(&isr->sav); - isr->sav = NULL; - } - - nextisr = isr->next; - ipsec_delisr(isr); - } - _key_delsp(sp); -} - /* * search SPD * OUT: NULL : not found @@ -1317,20 +1295,19 @@ key_delsp(struct secpolicy *sp) static struct secpolicy * key_getsp(struct secpolicyindex *spidx) { + SPTREE_RLOCK_TRACKER; struct secpolicy *sp; IPSEC_ASSERT(spidx != NULL, ("null spidx")); - SPTREE_LOCK(); - LIST_FOREACH(sp, &V_sptree[spidx->dir], chain) { - if (sp->state == IPSEC_SPSTATE_DEAD) - continue; + SPTREE_RLOCK(); + TAILQ_FOREACH(sp, &V_sptree[spidx->dir], chain) { if (key_cmpspidx_exactly(spidx, &sp->spidx)) { SP_ADDREF(sp); break; } } - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); return sp; } @@ -1343,28 +1320,25 @@ key_getsp(struct secpolicyindex *spidx) static struct secpolicy * key_getspbyid(u_int32_t id) { + SPTREE_RLOCK_TRACKER; struct secpolicy *sp; - SPTREE_LOCK(); - LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_INBOUND], chain) { - if (sp->state == IPSEC_SPSTATE_DEAD) - continue; + SPTREE_RLOCK(); + TAILQ_FOREACH(sp, &V_sptree[IPSEC_DIR_INBOUND], chain) { if (sp->id == id) { SP_ADDREF(sp); goto done; } } - LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_OUTBOUND], chain) { - if (sp->state == IPSEC_SPSTATE_DEAD) - continue; + TAILQ_FOREACH(sp, &V_sptree[IPSEC_DIR_OUTBOUND], chain) { if (sp->id == id) { SP_ADDREF(sp); goto done; } } done: - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); return sp; } @@ -1376,11 +1350,8 @@ key_newsp(const char* where, int tag) newsp = (struct secpolicy *) malloc(sizeof(struct secpolicy), M_IPSEC_SP, M_NOWAIT|M_ZERO); - if (newsp) { - SECPOLICY_LOCK_INIT(newsp); - newsp->refcnt = 1; - newsp->req = NULL; - } + if (newsp) + refcount_init(&newsp->refcnt, 1); KEYDEBUG(KEYDEBUG_IPSEC_STAMP, printf("DP %s from %s:%u return SP:%p\n", __func__, @@ -1388,13 +1359,6 @@ key_newsp(const char* where, int tag) return newsp; } -static void -_key_delsp(struct secpolicy *sp) -{ - SECPOLICY_LOCK_DESTROY(sp); - free(sp, M_IPSEC_SP); -} - /* * create secpolicy structure from sadb_x_policy structure. * NOTE: `state', `secpolicyindex' in secpolicy structure are not set, @@ -1874,9 +1838,7 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) newsp = key_getsp(&spidx); if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { if (newsp) { - SPTREE_LOCK(); - newsp->state = IPSEC_SPSTATE_DEAD; - SPTREE_UNLOCK(); + key_unlink(newsp); KEY_FREESP(&newsp); } } else { @@ -1888,13 +1850,15 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) } } + /* XXX: there is race between key_getsp and key_msg2sp. */ + /* allocation new SP entry */ if ((newsp = key_msg2sp(xpl0, PFKEY_EXTLEN(xpl0), &error)) == NULL) { return key_senderror(so, m, error); } if ((newsp->id = key_getnewspid()) == 0) { - _key_delsp(newsp); + KEY_FREESP(&newsp); return key_senderror(so, m, ENOBUFS); } @@ -1910,18 +1874,20 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) /* sanity check on addr pair */ if (((struct sockaddr *)(src0 + 1))->sa_family != ((struct sockaddr *)(dst0+ 1))->sa_family) { - _key_delsp(newsp); + KEY_FREESP(&newsp); return key_senderror(so, m, EINVAL); } if (((struct sockaddr *)(src0 + 1))->sa_len != ((struct sockaddr *)(dst0+ 1))->sa_len) { - _key_delsp(newsp); + KEY_FREESP(&newsp); return key_senderror(so, m, EINVAL); } #if 1 - if (newsp->req && newsp->req->saidx.src.sa.sa_family && newsp->req->saidx.dst.sa.sa_family) { - if (newsp->req->saidx.src.sa.sa_family != newsp->req->saidx.dst.sa.sa_family) { - _key_delsp(newsp); + if (newsp->req && newsp->req->saidx.src.sa.sa_family && + newsp->req->saidx.dst.sa.sa_family) { + if (newsp->req->saidx.src.sa.sa_family != + newsp->req->saidx.dst.sa.sa_family) { + KEY_FREESP(&newsp); return key_senderror(so, m, EINVAL); } } @@ -1932,9 +1898,9 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0; newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0; - newsp->refcnt = 1; /* do not reclaim until I say I do */ - newsp->state = IPSEC_SPSTATE_ALIVE; - LIST_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, secpolicy, chain); + SPTREE_WLOCK(); + TAILQ_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, chain); + SPTREE_WUNLOCK(); /* delete the entry in spacqtree */ if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { @@ -2109,9 +2075,7 @@ key_spddelete(struct socket *so, struct mbuf *m, /* save policy id to buffer to be returned. */ xpl0->sadb_x_policy_id = sp->id; - SPTREE_LOCK(); - sp->state = IPSEC_SPSTATE_DEAD; - SPTREE_UNLOCK(); + key_unlink(sp); KEY_FREESP(&sp); { @@ -2176,9 +2140,7 @@ key_spddelete2(struct socket *so, struct mbuf *m, return key_senderror(so, m, EINVAL); } - SPTREE_LOCK(); - sp->state = IPSEC_SPSTATE_DEAD; - SPTREE_UNLOCK(); + key_unlink(sp); KEY_FREESP(&sp); { @@ -2356,8 +2318,9 @@ key_spdacquire(struct secpolicy *sp) static int key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) { + TAILQ_HEAD(, secpolicy) drainq; struct sadb_msg *newmsg; - struct secpolicy *sp; + struct secpolicy *sp, *nextsp; u_int dir; IPSEC_ASSERT(so != NULL, ("null socket")); @@ -2368,11 +2331,17 @@ key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg))) return key_senderror(so, m, EINVAL); + TAILQ_INIT(&drainq); + SPTREE_WLOCK(); for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - SPTREE_LOCK(); - LIST_FOREACH(sp, &V_sptree[dir], chain) - sp->state = IPSEC_SPSTATE_DEAD; - SPTREE_UNLOCK(); + TAILQ_CONCAT(&drainq, &V_sptree[dir], chain); + } + SPTREE_WUNLOCK(); + sp = TAILQ_FIRST(&drainq); + while (sp != NULL) { + nextsp = TAILQ_NEXT(sp, chain); + KEY_FREESP(&sp); + sp = nextsp; } if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) { @@ -2405,6 +2374,7 @@ key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) static int key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) { + SPTREE_RLOCK_TRACKER; struct secpolicy *sp; int cnt; u_int dir; @@ -2417,20 +2387,20 @@ key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) /* search SPD entry and get buffer size. */ cnt = 0; - SPTREE_LOCK(); + SPTREE_RLOCK(); for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - LIST_FOREACH(sp, &V_sptree[dir], chain) { + TAILQ_FOREACH(sp, &V_sptree[dir], chain) { cnt++; } } if (cnt == 0) { - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); return key_senderror(so, m, ENOENT); } for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { - LIST_FOREACH(sp, &V_sptree[dir], chain) { + TAILQ_FOREACH(sp, &V_sptree[dir], chain) { --cnt; n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt, mhp->msg->sadb_msg_pid); @@ -2440,7 +2410,7 @@ key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp) } } - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); m_freem(m); return 0; } @@ -2452,6 +2422,8 @@ key_setdumpsp(struct secpolicy *sp, u_int8_t type, u_int32_t seq, struct mbuf *result = NULL, *m; struct seclifetime lt; + SPTREE_RLOCK_ASSERT(); + m = key_setsadbmsg(type, 0, SADB_SATYPE_UNSPEC, seq, pid, sp->refcnt); if (!m) goto fail; @@ -4226,47 +4198,29 @@ key_bbcmp(const void *a1, const void *a2, u_int bits) static void key_flush_spd(time_t now) { - static u_int16_t sptree_scangen = 0; - u_int16_t gen = sptree_scangen++; + SPTREE_RLOCK_TRACKER; struct secpolicy *sp; u_int dir; /* SPD */ for (dir = 0; dir < IPSEC_DIR_MAX; dir++) { restart: - SPTREE_LOCK(); - LIST_FOREACH(sp, &V_sptree[dir], chain) { - if (sp->scangen == gen) /* previously handled */ - continue; - sp->scangen = gen; - if (sp->state == IPSEC_SPSTATE_DEAD && - sp->refcnt == 1) { - /* - * Ensure that we only decrease refcnt once, - * when we're the last consumer. - * Directly call SP_DELREF/key_delsp instead - * of KEY_FREESP to avoid unlocking/relocking - * SPTREE_LOCK before key_delsp: may refcnt - * be increased again during that time ? - * NB: also clean entries created by - * key_spdflush - */ - SP_DELREF(sp); - key_delsp(sp); - SPTREE_UNLOCK(); - goto restart; - } + SPTREE_RLOCK(); + TAILQ_FOREACH(sp, &V_sptree[dir], chain) { if (sp->lifetime == 0 && sp->validtime == 0) continue; - if ((sp->lifetime && now - sp->created > sp->lifetime) - || (sp->validtime && now - sp->lastused > sp->validtime)) { - sp->state = IPSEC_SPSTATE_DEAD; - SPTREE_UNLOCK(); + if ((sp->lifetime && + now - sp->created > sp->lifetime) || + (sp->validtime && + now - sp->lastused > sp->validtime)) { + SPTREE_RUNLOCK(); + key_unlink(sp); key_spdexpire(sp); + KEY_FREESP(&sp); goto restart; } } - SPTREE_UNLOCK(); + SPTREE_RUNLOCK(); } } @@ -7609,7 +7563,7 @@ key_init(void) int i; for (i = 0; i < IPSEC_DIR_MAX; i++) - LIST_INIT(&V_sptree[i]); + TAILQ_INIT(&V_sptree[i]); LIST_INIT(&V_sahtree); @@ -7619,10 +7573,6 @@ key_init(void) LIST_INIT(&V_acqtree); LIST_INIT(&V_spacqtree); - /* system default */ - V_ip4_def_policy.policy = IPSEC_POLICY_NONE; - V_ip4_def_policy.refcnt++; /*never reclaim this*/ - if (!IS_DEFAULT_VNET(curvnet)) return; @@ -7647,6 +7597,7 @@ key_init(void) void key_destroy(void) { + TAILQ_HEAD(, secpolicy) drainq; struct secpolicy *sp, *nextsp; struct secacq *acq, *nextacq; struct secspacq *spacq, *nextspacq; @@ -7654,18 +7605,18 @@ key_destroy(void) struct secreg *reg; int i; - SPTREE_LOCK(); + TAILQ_INIT(&drainq); + SPTREE_WLOCK(); for (i = 0; i < IPSEC_DIR_MAX; i++) { - for (sp = LIST_FIRST(&V_sptree[i]); - sp != NULL; sp = nextsp) { - nextsp = LIST_NEXT(sp, chain); - if (__LIST_CHAINED(sp)) { - LIST_REMOVE(sp, chain); - free(sp, M_IPSEC_SP); - } - } + TAILQ_CONCAT(&drainq, &V_sptree[dir], chain); + } + SPTREE_WUNLOCK(); + sp = TAILQ_FIRST(&drainq); + while (sp != NULL) { + nextsp = TAILQ_NEXT(sp, chain); + KEY_FREESP(&sp); + sp = nextsp; } - SPTREE_UNLOCK(); SAHTREE_LOCK(); for (sah = LIST_FIRST(&V_sahtree); sah != NULL; sah = nextsah) { diff --git a/sys/netipsec/key_debug.c b/sys/netipsec/key_debug.c index 5cbc1db6c2b..97ac0616a11 100644 --- a/sys/netipsec/key_debug.c +++ b/sys/netipsec/key_debug.c @@ -463,8 +463,8 @@ kdebug_secpolicy(struct secpolicy *sp) if (sp == NULL) panic("%s: NULL pointer was passed.\n", __func__); - printf("secpolicy{ refcnt=%u state=%u policy=%u\n", - sp->refcnt, sp->state, sp->policy); + printf("secpolicy{ refcnt=%u policy=%u\n", + sp->refcnt, sp->policy); kdebug_secpolicyindex(&sp->spidx); From 04fef9c44612588e4b0d83cf7282d0f9c2bf0302 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 24 Dec 2014 18:51:25 +0000 Subject: [PATCH 141/207] Build gperf before gcc The ARM image builds build the in-tree gcc in order to build u-boot and gperf is needed to build gcc, but is no longer installed on archs that use clang. Invoking the make targets as separate steps is done to work around a build failure which is not yet fully understood. Reviewed by: gjb, imp Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D1317 --- release/arm/release.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/release/arm/release.sh b/release/arm/release.sh index 020583fdc25..dbbdbf53202 100755 --- a/release/arm/release.sh +++ b/release/arm/release.sh @@ -127,6 +127,14 @@ main() { BATCH=1 FORCE_PKG_REGISTER=1 install clean distclean done + # Certain u-boot versions hardcode the use of a host gcc, and gcc's + # build relies on having gperf installed. + eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/gperf \ + WITH_GCC=1 ${WORLD_FLAGS} obj + eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/gperf \ + WITH_GCC=1 ${WORLD_FLAGS} -j1 depend all + eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/gperf \ + WITH_GCC=1 ${WORLD_FLAGS} -j1 install eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/cc \ WITH_GCC=1 ${WORLD_FLAGS} -j1 obj depend all install From c4c27bc97fe4b9157a754f0aa00d43b4bcef2b23 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 18:54:31 +0000 Subject: [PATCH 142/207] Cleanup up ARM *frame structures... - Eliminate unused irqframe - Eliminate unused saframe - Instead of splitting r4-sp storage between the stack and switchframe, just put all the registers in switchframe and eliminate the un_32 struct. Submitted by: Svatopluk Kraus , Michal Meloun --- gnu/usr.bin/gdb/kgdb/trgt_arm.c | 18 ++--- sys/arm/arm/db_trace.c | 10 +-- sys/arm/arm/gdb_machdep.c | 24 +++--- sys/arm/arm/genassym.c | 19 +++-- sys/arm/arm/machdep.c | 22 +++--- sys/arm/arm/stack_machdep.c | 2 +- sys/arm/arm/swtch.S | 128 +++++++++----------------------- sys/arm/arm/trap.c | 2 +- sys/arm/arm/vm_machdep.c | 88 +++++++++++----------- sys/arm/include/db_machdep.h | 2 +- sys/arm/include/frame.h | 72 +++++------------- sys/arm/include/pcb.h | 39 +++------- 12 files changed, 160 insertions(+), 266 deletions(-) diff --git a/gnu/usr.bin/gdb/kgdb/trgt_arm.c b/gnu/usr.bin/gdb/kgdb/trgt_arm.c index 489c046cd79..cb23aa675ec 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_arm.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_arm.c @@ -72,20 +72,12 @@ kgdb_trgt_fetch_registers(int regno __unused) warnx("kvm_read: %s", kvm_geterr(kvm)); memset(&pcb, 0, sizeof(pcb)); } - for (i = ARM_A1_REGNUM + 8; i <= ARM_SP_REGNUM; i++) { - supply_register(i, (char *)&pcb.un_32.pcb32_r8 + - (i - (ARM_A1_REGNUM + 8 )) * 4); + for (i = ARM_A1_REGNUM + 4; i <= ARM_SP_REGNUM; i++) { + supply_register(i, (char *)&pcb.pcb_regs.sf_r4 + + (i - (ARM_A1_REGNUM + 4 )) * 4); } - if (pcb.un_32.pcb32_sp != 0) { - for (i = 0; i < 4; i++) { - if (kvm_read(kvm, pcb.un_32.pcb32_sp + (i) * 4, - ®, 4) != 4) { - warnx("kvm_read: %s", kvm_geterr(kvm)); - break; - } - supply_register(ARM_A1_REGNUM + 4 + i, (char *)®); - } - if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, ®, 4) != 4) + if (pcb.pcb_regs.sf_sp != 0) { + if (kvm_read(kvm, pcb.pcb_regs.sf_sp + 4 * 4, ®, 4) != 4) warnx("kvm_read :%s", kvm_geterr(kvm)); else supply_register(ARM_PC_REGNUM, (char *)®); diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c index 0f06486c9d1..04ab565e674 100644 --- a/sys/arm/arm/db_trace.c +++ b/sys/arm/arm/db_trace.c @@ -609,14 +609,14 @@ db_trace_thread(struct thread *thr, int count) ctx = kdb_thr_ctx(thr); #ifdef __ARM_EABI__ - state.registers[FP] = ctx->un_32.pcb32_r11; - state.registers[SP] = ctx->un_32.pcb32_sp; - state.registers[LR] = ctx->un_32.pcb32_lr; - state.registers[PC] = ctx->un_32.pcb32_pc; + state.registers[FP] = ctx->pcb_regs.sf_r11; + state.registers[SP] = ctx->pcb_regs.sf_sp; + state.registers[LR] = ctx->pcb_regs.sf_lr; + state.registers[PC] = ctx->pcb_regs.sf_pc; db_stack_trace_cmd(&state); #else - db_stack_trace_cmd(ctx->un_32.pcb32_r11, -1, TRUE); + db_stack_trace_cmd(ctx->pcb_regs.sf_r11, -1, TRUE); #endif } else db_trace_self(); diff --git a/sys/arm/arm/gdb_machdep.c b/sys/arm/arm/gdb_machdep.c index 11b9c0d2d91..8cc7a198bf8 100644 --- a/sys/arm/arm/gdb_machdep.c +++ b/sys/arm/arm/gdb_machdep.c @@ -67,22 +67,26 @@ gdb_cpu_getreg(int regnum, size_t *regsz) } switch (regnum) { - case 8: return (&kdb_thrctx->un_32.pcb32_r8); - case 9: return (&kdb_thrctx->un_32.pcb32_r9); - case 10: return (&kdb_thrctx->un_32.pcb32_r10); - case 11: return (&kdb_thrctx->un_32.pcb32_r11); - case 12: return (&kdb_thrctx->un_32.pcb32_r12); - case 13: stacktest = kdb_thrctx->un_32.pcb32_sp + 5 * 4; + case 4: return (&kdb_thrctx->pcb_regs.sf_r4); + case 5: return (&kdb_thrctx->pcb_regs.sf_r5); + case 6: return (&kdb_thrctx->pcb_regs.sf_r6); + case 7: return (&kdb_thrctx->pcb_regs.sf_r7); + case 8: return (&kdb_thrctx->pcb_regs.sf_r8); + case 9: return (&kdb_thrctx->pcb_regs.sf_r9); + case 10: return (&kdb_thrctx->pcb_regs.sf_r10); + case 11: return (&kdb_thrctx->pcb_regs.sf_r11); + case 12: return (&kdb_thrctx->pcb_regs.sf_r12); + case 13: stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4; return (&stacktest); case 15: /* * On context switch, the PC is not put in the PCB, but * we can retrieve it from the stack. */ - if (kdb_thrctx->un_32.pcb32_sp > KERNBASE) { - kdb_thrctx->un_32.pcb32_pc = *(register_t *) - (kdb_thrctx->un_32.pcb32_sp + 4 * 4); - return (&kdb_thrctx->un_32.pcb32_pc); + if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) { + kdb_thrctx->pcb_regs.sf_pc = *(register_t *) + (kdb_thrctx->pcb_regs.sf_sp + 4 * 4); + return (&kdb_thrctx->pcb_regs.sf_pc); } } diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c index ab0be4ca138..ce7b88d748f 100644 --- a/sys/arm/arm/genassym.c +++ b/sys/arm/arm/genassym.c @@ -63,13 +63,18 @@ ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags)); ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir)); ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec)); ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec)); -ASSYM(PCB_R8, offsetof(struct pcb, un_32.pcb32_r8)); -ASSYM(PCB_R9, offsetof(struct pcb, un_32.pcb32_r9)); -ASSYM(PCB_R10, offsetof(struct pcb, un_32.pcb32_r10)); -ASSYM(PCB_R11, offsetof(struct pcb, un_32.pcb32_r11)); -ASSYM(PCB_R12, offsetof(struct pcb, un_32.pcb32_r12)); -ASSYM(PCB_PC, offsetof(struct pcb, un_32.pcb32_pc)); -ASSYM(PCB_SP, offsetof(struct pcb, un_32.pcb32_sp)); +ASSYM(PCB_R4, offsetof(struct pcb, pcb_regs.sf_r4)); +ASSYM(PCB_R5, offsetof(struct pcb, pcb_regs.sf_r5)); +ASSYM(PCB_R6, offsetof(struct pcb, pcb_regs.sf_r6)); +ASSYM(PCB_R7, offsetof(struct pcb, pcb_regs.sf_r7)); +ASSYM(PCB_R8, offsetof(struct pcb, pcb_regs.sf_r8)); +ASSYM(PCB_R9, offsetof(struct pcb, pcb_regs.sf_r9)); +ASSYM(PCB_R10, offsetof(struct pcb, pcb_regs.sf_r10)); +ASSYM(PCB_R11, offsetof(struct pcb, pcb_regs.sf_r11)); +ASSYM(PCB_R12, offsetof(struct pcb, pcb_regs.sf_r12)); +ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp)); +ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr)); +ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc)); ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb)); ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread)); diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 341ea4a7cf4..f3e75d5e2c5 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -378,7 +378,7 @@ cpu_startup(void *dummy) bufinit(); vm_pager_bufferinit(); - pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack + + pcb->pcb_regs.sf_sp = (u_int)thread0.td_kstack + USPACE_SVC_STACK_TOP; vector_page_setprot(VM_PROT_READ); pmap_set_pcb_pagedir(pmap_kernel(), pcb); @@ -770,14 +770,18 @@ sys_sigreturn(td, uap) void makectx(struct trapframe *tf, struct pcb *pcb) { - pcb->un_32.pcb32_r8 = tf->tf_r8; - pcb->un_32.pcb32_r9 = tf->tf_r9; - pcb->un_32.pcb32_r10 = tf->tf_r10; - pcb->un_32.pcb32_r11 = tf->tf_r11; - pcb->un_32.pcb32_r12 = tf->tf_r12; - pcb->un_32.pcb32_pc = tf->tf_pc; - pcb->un_32.pcb32_lr = tf->tf_usr_lr; - pcb->un_32.pcb32_sp = tf->tf_usr_sp; + pcb->pcb_regs.sf_r4 = tf->tf_r4; + pcb->pcb_regs.sf_r5 = tf->tf_r5; + pcb->pcb_regs.sf_r6 = tf->tf_r6; + pcb->pcb_regs.sf_r7 = tf->tf_r7; + pcb->pcb_regs.sf_r8 = tf->tf_r8; + pcb->pcb_regs.sf_r9 = tf->tf_r9; + pcb->pcb_regs.sf_r10 = tf->tf_r10; + pcb->pcb_regs.sf_r11 = tf->tf_r11; + pcb->pcb_regs.sf_r12 = tf->tf_r12; + pcb->pcb_regs.sf_pc = tf->tf_pc; + pcb->pcb_regs.sf_lr = tf->tf_usr_lr; + pcb->pcb_regs.sf_sp = tf->tf_usr_sp; } /* diff --git a/sys/arm/arm/stack_machdep.c b/sys/arm/arm/stack_machdep.c index f1708f5bf58..9c984a9b4ac 100644 --- a/sys/arm/arm/stack_machdep.c +++ b/sys/arm/arm/stack_machdep.c @@ -76,7 +76,7 @@ stack_save_td(struct stack *st, struct thread *td) * as it doesn't have a frame pointer, however it's value is not used * when building for EABI. */ - frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11; + frame = (u_int32_t *)td->td_pcb->pcb_regs.sf_r11; stack_zero(st); stack_capture(st, frame); } diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S index 610d57537c8..e9d6f6159d2 100644 --- a/sys/arm/arm/swtch.S +++ b/sys/arm/arm/swtch.S @@ -116,6 +116,14 @@ __FBSDID("$FreeBSD$"); .Lblocked_lock: .word _C_LABEL(blocked_lock) +/* + * cpu_throw(oldtd, newtd) + * + * Remove current thread state, then select the next thread to run + * and load its state. + * r0 = oldtd + * r1 = newtd + */ ENTRY(cpu_throw) mov r5, r1 @@ -144,7 +152,6 @@ ENTRY(cpu_throw) * r0 = Pointer to L1 slot for vector_page (or NULL) * r1 = lwp0's DACR * r5 = lwp0 - * r6 = exit func * r7 = lwp0's PCB * r9 = cpufuncs */ @@ -181,25 +188,11 @@ ENTRY(cpu_throw) mov lr, pc ldr pc, [r9, #CF_CONTEXT_SWITCH] - /* Restore all the save registers */ -#ifndef _ARM_ARCH_5E - add r1, r7, #PCB_R8 - ldmia r1, {r8-r13} -#else - ldr r8, [r7, #(PCB_R8)] - ldr r9, [r7, #(PCB_R9)] - ldr r10, [r7, #(PCB_R10)] - ldr r11, [r7, #(PCB_R11)] - ldr r12, [r7, #(PCB_R12)] - ldr r13, [r7, #(PCB_SP)] -#endif - GET_PCPU(r6, r4) /* Hook in a new pcb */ str r7, [r6, #PC_CURPCB] /* We have a new curthread now so make a note it */ - add r6, r6, #PC_CURTHREAD - str r5, [r6] + str r5, [r6, #PC_CURTHREAD] #ifndef ARM_TP_ADDRESS mcr p15, 0, r5, c13, c0, 4 #endif @@ -215,22 +208,31 @@ ENTRY(cpu_throw) #else mcr p15, 0, r6, c13, c0, 3 #endif - - add sp, sp, #4; - ldmfd sp!, {r4-r7, pc} + /* Restore all the saved registers and exit */ + add r3, r7, #PCB_R4 + ldmia r3, {r4-r12, sp, pc} END(cpu_throw) +/* + * cpu_switch(oldtd, newtd, lock) + * + * Save the current thread state, then select the next thread to run + * and load its state. + * r0 = oldtd + * r1 = newtd + * r2 = lock (new lock for old thread) + */ ENTRY(cpu_switch) - stmfd sp!, {r4-r7, lr} - sub sp, sp, #4; -#ifdef __ARM_EABI__ - .save {r4-r7, lr} - .pad #4 -#endif + /* Interrupts are disabled. */ + /* Save all the registers in the old thread's pcb. */ + ldr r3, [r0, #(TD_PCB)] + + /* Restore all the saved registers and exit */ + add r3, #(PCB_R4) + stmia r3, {r4-r12, sp, lr, pc} mov r6, r2 /* Save the mutex */ -.Lswitch_resume: /* rem: r0 = old lwp */ /* rem: interrupts are disabled */ @@ -246,30 +248,12 @@ ENTRY(cpu_switch) ldr r2, [r1, #TD_PCB] str r2, [r7, #PC_CURPCB] - /* rem: r1 = new process */ - /* rem: interrupts are enabled */ - /* Stage two : Save old context */ /* Get the user structure for the old thread. */ ldr r2, [r0, #(TD_PCB)] mov r4, r0 /* Save the old thread. */ - /* Save all the registers in the old thread's pcb */ -#ifndef _ARM_ARCH_5E - add r7, r2, #(PCB_R8) - stmia r7, {r8-r13} -#else - strd r8, [r2, #(PCB_R8)] - strd r10, [r2, #(PCB_R10)] - strd r12, [r2, #(PCB_R12)] -#endif - str pc, [r2, #(PCB_PC)] - - /* - * NOTE: We can now use r8-r13 until it is time to restore - * them for the new process. - */ #ifdef ARM_TP_ADDRESS /* Store the old tp */ ldr r3, =ARM_TP_ADDRESS @@ -318,7 +302,6 @@ ENTRY(cpu_switch) /* rem: r2 = old PCB */ /* rem: r9 = new PCB */ - /* rem: interrupts are enabled */ ldr r5, [r9, #(PCB_DACR)] /* r5 = new DACR */ mov r2, #DOMAIN_CLIENT @@ -336,7 +319,6 @@ ENTRY(cpu_switch) mrc p15, 0, r10, c2, c0, 0 /* r10 = old L1 */ ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */ - teq r10, r11 /* Same L1? */ cmpeq r0, r5 /* Same DACR? */ beq .Lcs_context_switched /* yes! */ @@ -426,54 +408,18 @@ ENTRY(cpu_switch) /* rem: r9 = new PCB */ - /* Restore all the save registers */ -#ifndef _ARM_ARCH_5E - add r7, r9, #PCB_R8 - ldmia r7, {r8-r13} - sub r7, r7, #PCB_R8 /* restore PCB pointer */ -#else - mov r7, r9 - ldr r8, [r7, #(PCB_R8)] - ldr r9, [r7, #(PCB_R9)] - ldr r10, [r7, #(PCB_R10)] - ldr r11, [r7, #(PCB_R11)] - ldr r12, [r7, #(PCB_R12)] - ldr r13, [r7, #(PCB_SP)] -#endif - - /* rem: r5 = new lwp's proc */ - /* rem: r6 = lock */ - /* rem: r7 = new PCB */ - -.Lswitch_return: - - /* - * Pull the registers that got pushed when either savectx() or - * cpu_switch() was called and return. - */ - add sp, sp, #4; - ldmfd sp!, {r4-r7, pc} -#ifdef DIAGNOSTIC -.Lswitch_bogons: - adr r0, .Lswitch_panic_str - bl _C_LABEL(panic) -1: nop - b 1b - -.Lswitch_panic_str: - .asciz "cpu_switch: sched_qs empty with non-zero sched_whichqs!\n" -#endif + /* Restore all the saved registers and exit */ + add r3, r9, #PCB_R4 + ldmia r3, {r4-r12, sp, pc} END(cpu_switch) ENTRY(savectx) - stmfd sp!, {r4-r7, lr} + stmfd sp!, {lr} sub sp, sp, #4 - /* - * r0 = pcb - */ - /* Store all the registers in the process's pcb */ - add r2, r0, #(PCB_R8) - stmia r2, {r8-r13} + + /* Store all the registers in the thread's pcb */ + add r3, r0, #(PCB_R4) + stmia r3, {r4-r12, sp, lr, pc} #ifdef VFP fmrx r2, fpexc /* If the VFP is enabled */ tst r2, #(VFPEXC_EN) /* the current thread has */ @@ -482,7 +428,7 @@ ENTRY(savectx) blne _C_LABEL(vfp_store) /* and disable the VFP. */ #endif add sp, sp, #4; - ldmfd sp!, {r4-r7, pc} + ldmfd sp!, {pc} END(savectx) ENTRY(fork_trampoline) diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c index ec14feb1647..eaabf4f6e38 100644 --- a/sys/arm/arm/trap.c +++ b/sys/arm/arm/trap.c @@ -545,7 +545,7 @@ dab_buserr(struct trapframe *tf, u_int fsr, u_int far, struct thread *td, * If the current trapframe is at the top of the kernel stack, * the fault _must_ have come from user mode. */ - if (tf != ((struct trapframe *)pcb->un_32.pcb32_sp) - 1) { + if (tf != ((struct trapframe *)pcb->pcb_regs.sf_sp) - 1) { /* * Kernel mode. We're either about to die a * spectacular death, or pcb_onfault will come diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 7758a22f5ee..42587f5a063 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$"); * struct switchframe and trapframe must both be a multiple of 8 * for correct stack alignment. */ -CTASSERT(sizeof(struct switchframe) == 24); +CTASSERT(sizeof(struct switchframe) == 48); CTASSERT(sizeof(struct trapframe) == 80); /* @@ -93,43 +93,55 @@ cpu_fork(register struct thread *td1, register struct proc *p2, { struct pcb *pcb2; struct trapframe *tf; - struct switchframe *sf; struct mdproc *mdp2; if ((flags & RFPROC) == 0) return; - pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1; + + /* Point the pcb to the top of the stack */ + pcb2 = (struct pcb *) + (td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1; #ifdef __XSCALE__ #ifndef CPU_XSCALE_CORE3 pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE); #endif #endif td2->td_pcb = pcb2; + + /* Clone td1's pcb */ bcopy(td1->td_pcb, pcb2, sizeof(*pcb2)); + + /* Point to mdproc and then copy over td1's contents */ mdp2 = &p2->p_md; bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2)); - pcb2->un_32.pcb32_sp = td2->td_kstack + - USPACE_SVC_STACK_TOP - sizeof(*pcb2); + + /* Point the frame to the stack in front of pcb and copy td1's frame */ + td2->td_frame = (struct trapframe *)pcb2 - 1; + *td2->td_frame = *td1->td_frame; + + /* + * Create a new fresh stack for the new process. + * Copy the trap frame for the return to user mode as if from a + * syscall. This copies most of the user mode register values. + */ + pmap_set_pcb_pagedir(vmspace_pmap(p2->p_vmspace), pcb2); + pcb2->pcb_regs.sf_r4 = (register_t)fork_return; + pcb2->pcb_regs.sf_r5 = (register_t)td2; + pcb2->pcb_regs.sf_lr = (register_t)fork_trampoline; + pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame); + pcb2->pcb_vfpcpu = -1; pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ; - pmap_activate(td2); - td2->td_frame = tf = (struct trapframe *)STACKALIGN( - pcb2->un_32.pcb32_sp - sizeof(struct trapframe)); - *tf = *td1->td_frame; - sf = (struct switchframe *)tf - 1; - sf->sf_r4 = (u_int)fork_return; - sf->sf_r5 = (u_int)td2; - sf->sf_pc = (u_int)fork_trampoline; + + tf = td2->td_frame; tf->tf_spsr &= ~PSR_C; tf->tf_r0 = 0; tf->tf_r1 = 0; - pcb2->un_32.pcb32_sp = (u_int)sf; - KASSERT((pcb2->un_32.pcb32_sp & 7) == 0, - ("cpu_fork: Incorrect stack alignment")); + /* Setup to release spin count in fork_exit(). */ td2->td_md.md_spinlock_count = 1; - td2->td_md.md_saved_cspr = 0; + td2->td_md.md_saved_cspr = PSR_SVC32_MODE;; #ifdef ARM_TP_ADDRESS td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS; #else @@ -218,25 +230,21 @@ cpu_set_syscall_retval(struct thread *td, int error) void cpu_set_upcall(struct thread *td, struct thread *td0) { - struct trapframe *tf; - struct switchframe *sf; bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe)); bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb)); - tf = td->td_frame; - sf = (struct switchframe *)tf - 1; - sf->sf_r4 = (u_int)fork_return; - sf->sf_r5 = (u_int)td; - sf->sf_pc = (u_int)fork_trampoline; - tf->tf_spsr &= ~PSR_C; - tf->tf_r0 = 0; - td->td_pcb->un_32.pcb32_sp = (u_int)sf; - KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0, - ("cpu_set_upcall: Incorrect stack alignment")); + + td->td_pcb->pcb_regs.sf_r4 = (register_t)fork_return; + td->td_pcb->pcb_regs.sf_r5 = (register_t)td; + td->td_pcb->pcb_regs.sf_lr = (register_t)fork_trampoline; + td->td_pcb->pcb_regs.sf_sp = STACKALIGN(td->td_frame); + + td->td_frame->tf_spsr &= ~PSR_C; + td->td_frame->tf_r0 = 0; /* Setup to release spin count in fork_exit(). */ td->td_md.md_spinlock_count = 1; - td->td_md.md_saved_cspr = 0; + td->td_md.md_saved_cspr = PSR_SVC32_MODE; } /* @@ -250,8 +258,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, { struct trapframe *tf = td->td_frame; - tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size - - sizeof(struct trapframe)); + tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size); tf->tf_pc = (int)entry; tf->tf_r0 = (int)arg; tf->tf_spsr = PSR_USR32_MODE; @@ -289,9 +296,8 @@ cpu_thread_alloc(struct thread *td) * placed into the stack pointer which must be 8 byte aligned in * the ARM EABI. */ - td->td_frame = (struct trapframe *)STACKALIGN((u_int)td->td_kstack + - USPACE_SVC_STACK_TOP - sizeof(struct pcb) - - sizeof(struct trapframe)); + td->td_frame = (struct trapframe *)((caddr_t)td->td_pcb) - 1; + #ifdef __XSCALE__ #ifndef CPU_XSCALE_CORE3 pmap_use_minicache(td->td_kstack, td->td_kstack_pages * PAGE_SIZE); @@ -318,16 +324,8 @@ cpu_thread_clean(struct thread *td) void cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg) { - struct switchframe *sf; - struct trapframe *tf; - - tf = td->td_frame; - sf = (struct switchframe *)tf - 1; - sf->sf_r4 = (u_int)func; - sf->sf_r5 = (u_int)arg; - td->td_pcb->un_32.pcb32_sp = (u_int)sf; - KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0, - ("cpu_set_fork_handler: Incorrect stack alignment")); + td->td_pcb->pcb_regs.sf_r4 = (register_t)func; /* function */ + td->td_pcb->pcb_regs.sf_r5 = (register_t)arg; /* first arg */ } /* diff --git a/sys/arm/include/db_machdep.h b/sys/arm/include/db_machdep.h index da3b30e4f6f..741cae99922 100644 --- a/sys/arm/include/db_machdep.h +++ b/sys/arm/include/db_machdep.h @@ -38,7 +38,7 @@ typedef vm_offset_t db_addr_t; typedef int db_expr_t; -#define PC_REGS() ((db_addr_t)kdb_thrctx->un_32.pcb32_pc) +#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_regs.sf_pc) #define BKPT_INST (KERNEL_BREAKPOINT) #define BKPT_SIZE (INSN_SIZE) diff --git a/sys/arm/include/frame.h b/sys/arm/include/frame.h index 1e6f43a5b54..7655d89cadc 100644 --- a/sys/arm/include/frame.h +++ b/sys/arm/include/frame.h @@ -86,57 +86,16 @@ struct trapframe { #define tf_r13 tf_usr_sp #define tf_r14 tf_usr_lr #define tf_r15 tf_pc -/* - * * Scheduler activations upcall frame. Pushed onto user stack before - * * calling an SA upcall. - * */ - -struct saframe { -#if 0 /* in registers on entry to upcall */ - int sa_type; - struct sa_t ** sa_sas; - int sa_events; - int sa_interrupted; -#endif - void * sa_arg; -}; /* - * * Signal frame. Pushed onto user stack before calling sigcode. - * */ - -/* the pointers are use in the trampoline code to locate the ucontext */ + * Signal frame. Pushed onto user stack before calling sigcode. + * The pointers are used in the trampoline code to locate the ucontext. + */ struct sigframe { - siginfo_t sf_si; /* actual saved siginfo */ + siginfo_t sf_si; /* actual saved siginfo */ ucontext_t sf_uc; /* actual saved ucontext */ }; -/* - * System stack frames. - */ - - -typedef struct irqframe { - unsigned int if_spsr; - unsigned int if_r0; - unsigned int if_r1; - unsigned int if_r2; - unsigned int if_r3; - unsigned int if_r4; - unsigned int if_r5; - unsigned int if_r6; - unsigned int if_r7; - unsigned int if_r8; - unsigned int if_r9; - unsigned int if_r10; - unsigned int if_r11; - unsigned int if_r12; - unsigned int if_usr_sp; - unsigned int if_usr_lr; - unsigned int if_svc_sp; - unsigned int if_svc_lr; - unsigned int if_pc; -} irqframe_t; /* * Switch frame. @@ -144,16 +103,23 @@ typedef struct irqframe { * It is important this is a multiple of 8 bytes so the stack is correctly * aligned when we create new threads. */ - -struct switchframe { - u_int pad; /* Used to pad the struct to a multiple of 8-bytes */ - u_int sf_r4; - u_int sf_r5; - u_int sf_r6; - u_int sf_r7; - u_int sf_pc; +struct switchframe +{ + register_t sf_r4; + register_t sf_r5; + register_t sf_r6; + register_t sf_r7; + register_t sf_r8; + register_t sf_r9; + register_t sf_r10; + register_t sf_r11; + register_t sf_r12; + register_t sf_sp; + register_t sf_lr; + register_t sf_pc; }; + /* * Stack frame. Used during stack traces (db_trace.c) */ diff --git a/sys/arm/include/pcb.h b/sys/arm/include/pcb.h index 252d94e4522..b5ed607fc21 100644 --- a/sys/arm/include/pcb.h +++ b/sys/arm/include/pcb.h @@ -39,50 +39,29 @@ #define _MACHINE_PCB_H_ #include +#include -struct trapframe; - -struct pcb_arm32 { - vm_offset_t pcb32_pagedir; /* PT hooks */ - uint32_t *pcb32_pl1vec; /* PTR to vector_base L1 entry*/ - uint32_t pcb32_l1vec; /* Value to stuff on ctx sw */ - u_int pcb32_dacr; /* Domain Access Control Reg */ - /* - * WARNING! - * cpuswitch.S relies on pcb32_r8 being quad-aligned in struct pcb - * (due to the use of "strd" when compiled for XSCALE) - */ - u_int pcb32_r8; /* used */ - u_int pcb32_r9; /* used */ - u_int pcb32_r10; /* used */ - u_int pcb32_r11; /* used */ - u_int pcb32_r12; /* used */ - u_int pcb32_sp; /* used */ - u_int pcb32_lr; - u_int pcb32_pc; -}; -#define pcb_pagedir un_32.pcb32_pagedir -#define pcb_pl1vec un_32.pcb32_pl1vec -#define pcb_l1vec un_32.pcb32_l1vec -#define pcb_dacr un_32.pcb32_dacr -#define pcb_cstate un_32.pcb32_cstate - /* * WARNING! - * See warning for struct pcb_arm32, above, before changing struct pcb! + * Keep pcb_regs first for faster access in switch.S */ struct pcb { + struct switchframe pcb_regs; /* CPU state */ u_int pcb_flags; #define PCB_OWNFPU 0x00000001 #define PCB_NOALIGNFLT 0x00000002 caddr_t pcb_onfault; /* On fault handler */ - struct pcb_arm32 un_32; + vm_offset_t pcb_pagedir; /* PT hooks */ + uint32_t *pcb_pl1vec; /* PTR to vector_base L1 entry*/ + uint32_t pcb_l1vec; /* Value to stuff on ctx sw */ + u_int pcb_dacr; /* Domain Access Control Reg */ + struct vfp_state pcb_vfpstate; /* VP/NEON state */ u_int pcb_vfpcpu; /* VP/NEON last cpu */ } __aligned(8); /* * We need the PCB to be aligned on 8 bytes, as we may - * access it using ldrd/strd, and some CPUs require it + * access it using ldrd/strd, and ARM ABI require it * to by aligned on 8 bytes. */ From 1af5f5366cc126fe70ac6d2cb7450629714a8f2b Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Wed, 24 Dec 2014 19:47:50 +0000 Subject: [PATCH 143/207] Display the correct value for cache Level of Coherency. Like the other levels being displayed here, its value needs a +1 adjustment. --- sys/arm/arm/identcpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c index 955b9f53086..1b808aee8ab 100644 --- a/sys/arm/arm/identcpu.c +++ b/sys/arm/arm/identcpu.c @@ -457,7 +457,7 @@ identify_arm_cpu(void) if (arm_cache_level) { printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1, - arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1); + arm_cache_loc + 1, CPU_CLIDR_LOUIS(arm_cache_level) + 1); i = 0; while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) { printf("Cache level %d: \n", i + 1); From 65cb225c5ed08fce9287046029491d8b1e94409f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 24 Dec 2014 22:58:08 +0000 Subject: [PATCH 144/207] Modify vop_stdadvlock{async}() so that it only locks/unlocks the vnode and does a VOP_GETATTR() for the SEEK_END case. This is safe to do, since lf_advlock{async}() only uses the size argument for the SEEK_END case. The NFSv4 server needs this when vfs.nfsd.enable_locallocks!=0 since locking the vnode results in a LOR that can cause a deadlock for the nfsd threads. Reviewed by: kib MFC after: 1 week --- sys/kern/vfs_default.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index a34be50b227..8d850a135f6 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -401,17 +401,23 @@ int vop_stdadvlock(struct vop_advlock_args *ap) { struct vnode *vp; - struct ucred *cred; struct vattr vattr; int error; vp = ap->a_vp; - cred = curthread->td_ucred; - vn_lock(vp, LK_SHARED | LK_RETRY); - error = VOP_GETATTR(vp, &vattr, cred); - VOP_UNLOCK(vp, 0); - if (error) - return (error); + if (ap->a_fl->l_whence == SEEK_END) { + /* + * The NFSv4 server will LOR/deadlock if a vn_lock() call + * is done on vp. Fortunately, vattr.va_size is only + * needed for SEEK_END and the NFSv4 server only uses SEEK_SET. + */ + vn_lock(vp, LK_SHARED | LK_RETRY); + error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); + VOP_UNLOCK(vp, 0); + if (error) + return (error); + } else + vattr.va_size = 0; return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size)); } @@ -420,17 +426,19 @@ int vop_stdadvlockasync(struct vop_advlockasync_args *ap) { struct vnode *vp; - struct ucred *cred; struct vattr vattr; int error; vp = ap->a_vp; - cred = curthread->td_ucred; - vn_lock(vp, LK_SHARED | LK_RETRY); - error = VOP_GETATTR(vp, &vattr, cred); - VOP_UNLOCK(vp, 0); - if (error) - return (error); + if (ap->a_fl->l_whence == SEEK_END) { + /* The size argument is only needed for SEEK_END. */ + vn_lock(vp, LK_SHARED | LK_RETRY); + error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); + VOP_UNLOCK(vp, 0); + if (error) + return (error); + } else + vattr.va_size = 0; return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size)); } From 52f1bb38c25a12494477966dd34ccbe263e44158 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 25 Dec 2014 01:55:17 +0000 Subject: [PATCH 145/207] A deadlock in the NFSv4 server with vfs.nfsd.enable_locallocks=1 was reported via email. This was caused by a LOR between the sleep lock used to serialize the local locking (nfsrv_locklf()) and locking the vnode. I believe this patch fixes the problem by delaying relocking of the vnode until the sleep lock is unlocked (nfsrv_unlocklf()). To avoid nfsvno_advlock() having the side effect of unlocking the vnode, unlocking the vnode was moved to before the functions that call nfsvno_advlock(). It shouldn't affect the execution of the default case where vfs.nfsd.enable_locallocks=0. Reported by: loic.blot@unix-experience.fr Discussed with: kib MFC after: 1 week --- sys/fs/nfsserver/nfs_nfsdport.c | 9 +-- sys/fs/nfsserver/nfs_nfsdstate.c | 125 ++++++++++++++++++++++++------- 2 files changed, 101 insertions(+), 33 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 5bd4538f073..17ca5a693ca 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2970,12 +2970,7 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first, if (nfsrv_dolocallocks == 0) goto out; - - /* Check for VI_DOOMED here, so that VOP_ADVLOCK() isn't performed. */ - if ((vp->v_iflag & VI_DOOMED) != 0) { - error = EPERM; - goto out; - } + ASSERT_VOP_UNLOCKED(vp, "nfsvno_advlock: vp locked"); fl.l_whence = SEEK_SET; fl.l_type = ftype; @@ -2999,14 +2994,12 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first, fl.l_pid = (pid_t)0; fl.l_sysid = (int)nfsv4_sysid; - NFSVOPUNLOCK(vp, 0); if (ftype == F_UNLCK) error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_UNLCK, &fl, (F_POSIX | F_REMOTE)); else error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_SETLK, &fl, (F_POSIX | F_REMOTE)); - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); out: NFSEXITCODE(error); diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 97f8fffd622..5e9beebf087 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -1344,6 +1344,8 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep, vnode_t tvp = NULL; uint64_t first, end; + if (vp != NULL) + ASSERT_VOP_UNLOCKED(vp, "nfsrv_freeallnfslocks: vnode locked"); lop = LIST_FIRST(&stp->ls_lock); while (lop != LIST_END(&stp->ls_lock)) { nlop = LIST_NEXT(lop, lo_lckowner); @@ -1363,9 +1365,10 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep, if (gottvp == 0) { if (nfsrv_dolocallocks == 0) tvp = NULL; - else if (vp == NULL && cansleep != 0) + else if (vp == NULL && cansleep != 0) { tvp = nfsvno_getvp(&lfp->lf_fh); - else + NFSVOPUNLOCK(tvp, 0); + } else tvp = vp; gottvp = 1; } @@ -1386,7 +1389,7 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep, lop = nlop; } if (vp == NULL && tvp != NULL) - vput(tvp); + vrele(tvp); } /* @@ -1497,7 +1500,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp, struct nfsclient *clp = NULL; u_int32_t bits; int error = 0, haslock = 0, ret, reterr; - int getlckret, delegation = 0, filestruct_locked; + int getlckret, delegation = 0, filestruct_locked, vnode_unlocked = 0; fhandle_t nfh; uint64_t first, end; uint32_t lock_flags; @@ -1587,6 +1590,11 @@ tryagain: * locking rolled back. */ NFSUNLOCKSTATE(); + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl1"); + vnode_unlocked = 1; + NFSVOPUNLOCK(vp, 0); + } reterr = nfsrv_locallock(vp, lfp, (new_lop->lo_flags & (NFSLCK_READ | NFSLCK_WRITE)), new_lop->lo_first, new_lop->lo_end, cfp, p); @@ -1756,6 +1764,11 @@ tryagain: if (filestruct_locked != 0) { /* Roll back local locks. */ NFSUNLOCKSTATE(); + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl2"); + vnode_unlocked = 1; + NFSVOPUNLOCK(vp, 0); + } nfsrv_locallock_rollback(vp, lfp, p); NFSLOCKSTATE(); nfsrv_unlocklf(lfp); @@ -1833,6 +1846,12 @@ tryagain: if (filestruct_locked != 0) { /* Roll back local locks. */ NFSUNLOCKSTATE(); + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, + "nfsrv_lockctrl3"); + vnode_unlocked = 1; + NFSVOPUNLOCK(vp, 0); + } nfsrv_locallock_rollback(vp, lfp, p); NFSLOCKSTATE(); nfsrv_unlocklf(lfp); @@ -1852,6 +1871,8 @@ tryagain: bits = tstp->ls_flags; bits >>= NFSLCK_SHIFT; if (new_stp->ls_flags & bits & NFSLCK_ACCESSBITS) { + KASSERT(vnode_unlocked == 0, + ("nfsrv_lockctrl: vnode unlocked1")); ret = nfsrv_clientconflict(tstp->ls_clp, &haslock, vp, p); if (ret == 1) { @@ -1883,6 +1904,8 @@ tryagain: * For setattr, just get rid of all the Delegations for other clients. */ if (new_stp->ls_flags & NFSLCK_SETATTR) { + KASSERT(vnode_unlocked == 0, + ("nfsrv_lockctrl: vnode unlocked2")); ret = nfsrv_cleandeleg(vp, lfp, clp, &haslock, p); if (ret) { /* @@ -1933,14 +1956,26 @@ tryagain: (new_lop->lo_flags & NFSLCK_WRITE) && (clp != tstp->ls_clp || (tstp->ls_flags & NFSLCK_DELEGREAD)))) { + ret = 0; if (filestruct_locked != 0) { /* Roll back local locks. */ NFSUNLOCKSTATE(); + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl4"); + NFSVOPUNLOCK(vp, 0); + } nfsrv_locallock_rollback(vp, lfp, p); NFSLOCKSTATE(); nfsrv_unlocklf(lfp); + NFSUNLOCKSTATE(); + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); + vnode_unlocked = 0; + if ((vp->v_iflag & VI_DOOMED) != 0) + ret = NFSERR_SERVERFAULT; + NFSLOCKSTATE(); } - ret = nfsrv_delegconflict(tstp, &haslock, p, vp); + if (ret == 0) + ret = nfsrv_delegconflict(tstp, &haslock, p, vp); if (ret) { /* * nfsrv_delegconflict unlocks state when it @@ -1979,6 +2014,11 @@ tryagain: stateidp->other[2] = stp->ls_stateid.other[2]; if (filestruct_locked != 0) { NFSUNLOCKSTATE(); + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl5"); + vnode_unlocked = 1; + NFSVOPUNLOCK(vp, 0); + } /* Update the local locks. */ nfsrv_localunlock(vp, lfp, first, end, p); NFSLOCKSTATE(); @@ -2009,14 +2049,29 @@ tryagain: FREE((caddr_t)other_lop, M_NFSDLOCK); other_lop = NULL; } - ret = nfsrv_clientconflict(lop->lo_stp->ls_clp,&haslock,vp,p); + if (vnode_unlocked != 0) + ret = nfsrv_clientconflict(lop->lo_stp->ls_clp, &haslock, + NULL, p); + else + ret = nfsrv_clientconflict(lop->lo_stp->ls_clp, &haslock, + vp, p); if (ret == 1) { if (filestruct_locked != 0) { + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl6"); + NFSVOPUNLOCK(vp, 0); + } /* Roll back local locks. */ nfsrv_locallock_rollback(vp, lfp, p); NFSLOCKSTATE(); nfsrv_unlocklf(lfp); NFSUNLOCKSTATE(); + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); + vnode_unlocked = 0; + if ((vp->v_iflag & VI_DOOMED) != 0) { + error = NFSERR_SERVERFAULT; + goto out; + } } /* * nfsrv_clientconflict() unlocks state when it @@ -2050,6 +2105,11 @@ tryagain: if (filestruct_locked != 0 && ret == 0) { /* Roll back local locks. */ NFSUNLOCKSTATE(); + if (vnode_unlocked == 0) { + ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl7"); + vnode_unlocked = 1; + NFSVOPUNLOCK(vp, 0); + } nfsrv_locallock_rollback(vp, lfp, p); NFSLOCKSTATE(); nfsrv_unlocklf(lfp); @@ -2128,6 +2188,11 @@ out: nfsv4_unlock(&nfsv4rootfs_lock, 1); NFSUNLOCKV4ROOTMUTEX(); } + if (vnode_unlocked != 0) { + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); + if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0) + error = NFSERR_SERVERFAULT; + } if (other_lop) FREE((caddr_t)other_lop, M_NFSDLOCK); NFSEXITCODE2(error, nd); @@ -3235,11 +3300,14 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid, /* Get the lf lock */ nfsrv_locklf(lfp); NFSUNLOCKSTATE(); + ASSERT_VOP_ELOCKED(vp, "nfsrv_openupdate"); + NFSVOPUNLOCK(vp, 0); if (nfsrv_freeopen(stp, vp, 1, p) == 0) { NFSLOCKSTATE(); nfsrv_unlocklf(lfp); NFSUNLOCKSTATE(); } + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); } else { (void) nfsrv_freeopen(stp, NULL, 0, p); NFSUNLOCKSTATE(); @@ -4627,7 +4695,7 @@ static int nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp, NFSPROC_T *p) { - int gotlock, lktype; + int gotlock, lktype = 0; /* * If lease hasn't expired, we can't fix it. @@ -4637,8 +4705,10 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp, return (0); if (*haslockp == 0) { NFSUNLOCKSTATE(); - lktype = NFSVOPISLOCKED(vp); - NFSVOPUNLOCK(vp, 0); + if (vp != NULL) { + lktype = NFSVOPISLOCKED(vp); + NFSVOPUNLOCK(vp, 0); + } NFSLOCKV4ROOTMUTEX(); nfsv4_relref(&nfsv4rootfs_lock); do { @@ -4647,11 +4717,12 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp, } while (!gotlock); NFSUNLOCKV4ROOTMUTEX(); *haslockp = 1; - NFSVOPLOCK(vp, lktype | LK_RETRY); - if ((vp->v_iflag & VI_DOOMED) != 0) - return (2); - else - return (1); + if (vp != NULL) { + NFSVOPLOCK(vp, lktype | LK_RETRY); + if ((vp->v_iflag & VI_DOOMED) != 0) + return (2); + } + return (1); } NFSUNLOCKSTATE(); @@ -4692,7 +4763,7 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p, vnode_t vp) { struct nfsclient *clp = stp->ls_clp; - int gotlock, error, lktype, retrycnt, zapped_clp; + int gotlock, error, lktype = 0, retrycnt, zapped_clp; nfsv4stateid_t tstateid; fhandle_t tfh; @@ -4809,8 +4880,10 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p, */ if (*haslockp == 0) { NFSUNLOCKSTATE(); - lktype = NFSVOPISLOCKED(vp); - NFSVOPUNLOCK(vp, 0); + if (vp != NULL) { + lktype = NFSVOPISLOCKED(vp); + NFSVOPUNLOCK(vp, 0); + } NFSLOCKV4ROOTMUTEX(); nfsv4_relref(&nfsv4rootfs_lock); do { @@ -4819,14 +4892,16 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p, } while (!gotlock); NFSUNLOCKV4ROOTMUTEX(); *haslockp = 1; - NFSVOPLOCK(vp, lktype | LK_RETRY); - if ((vp->v_iflag & VI_DOOMED) != 0) { - *haslockp = 0; - NFSLOCKV4ROOTMUTEX(); - nfsv4_unlock(&nfsv4rootfs_lock, 1); - NFSUNLOCKV4ROOTMUTEX(); - error = NFSERR_PERM; - goto out; + if (vp != NULL) { + NFSVOPLOCK(vp, lktype | LK_RETRY); + if ((vp->v_iflag & VI_DOOMED) != 0) { + *haslockp = 0; + NFSLOCKV4ROOTMUTEX(); + nfsv4_unlock(&nfsv4rootfs_lock, 1); + NFSUNLOCKV4ROOTMUTEX(); + error = NFSERR_PERM; + goto out; + } } error = -1; goto out; From fce5da5f71de9439a219eb5085f1dfed3ec46055 Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Thu, 25 Dec 2014 02:17:17 +0000 Subject: [PATCH 146/207] Prevent zpool upgrade failing due to unavailable pools Prior to this fix "zpool upgrade" and "zpool upgrade -a" would fail due to an assert when operating on unavailable pools. We now print a warning to stderr but allow the processing of other pools to procesed. MFC after: 1 month --- cddl/contrib/opensolaris/cmd/zpool/zpool_main.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c index 31340b053a7..825198962aa 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c @@ -4629,6 +4629,13 @@ upgrade_cb(zpool_handle_t *zhp, void *arg) boolean_t printnl = B_FALSE; int ret; + if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { + (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is " + "currently unavailable\n\n"), zpool_get_name(zhp)); + /* Allow iteration to continue. */ + return (0); + } + config = zpool_get_config(zhp, NULL); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) == 0); @@ -4729,6 +4736,14 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) nvlist_t *config; uint64_t version; + if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { + (void) fprintf(stderr, gettext("cannot check supported " + "features on '%s': pool is currently unavailable\n\n"), + zpool_get_name(zhp)); + /* Allow iteration to continue. */ + return (0); + } + config = zpool_get_config(zhp, NULL); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) == 0); From 948ed04a87f19699d830119e39d0e6998666fedf Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Thu, 25 Dec 2014 03:15:56 +0000 Subject: [PATCH 147/207] Move libxo to /lib Update ObsoleteFiles to reflect libxo move. Reviewed by: ngie Differential Revision: https://reviews.freebsd.org/D1370 --- ObsoleteFiles.inc | 3 +++ lib/libxo/Makefile | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 70b76b8dd62..4078a30ab63 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20141224: libxo moved to /lib +OLD_FILES+=usr/lib/libxo.a +OLD_FILES+=usr/lib/libxo_p.a # 20141223: remove in6_gif.h, in_gif.h and if_stf.h OLD_FILES+=usr/include/net/if_stf.h OLD_FILES+=usr/include/netinet/in_gif.h diff --git a/lib/libxo/Makefile b/lib/libxo/Makefile index fbe7857647f..770db20c125 100644 --- a/lib/libxo/Makefile +++ b/lib/libxo/Makefile @@ -7,6 +7,8 @@ LIBXO= ${.CURDIR:H:H}/contrib/libxo LIB= xo SHLIB_MAJOR=0 +SHLIBDIR?= /lib + SRCS= libxo.c CFLAGS+=-I${LIBXO}/libxo From 7624957bc6175cc7b00e722bcc8f7e7c4c664da4 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 03:41:56 +0000 Subject: [PATCH 148/207] Change the style of the DO_AST macro to match the others in this file -- semicolons between the code and comments instead of after the comments, and line continuations in the arbitrary but now consistant column 76. No functional changes. --- sys/arm/arm/exception.S | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S index 5cef9657600..a6645f25dea 100644 --- a/sys/arm/arm/exception.S +++ b/sys/arm/arm/exception.S @@ -241,26 +241,26 @@ __FBSDID("$FreeBSD$"); #define UNWINDSVCFRAME #endif -#define DO_AST \ - ldr r0, [sp] /* Get the SPSR from stack */ ;\ - mrs r4, cpsr /* save CPSR */ ;\ - orr r1, r4, #(PSR_I|PSR_F) ;\ - msr cpsr_c, r1 /* Disable interrupts */ ;\ - and r0, r0, #(PSR_MODE) /* Returning to USR mode? */ ;\ - teq r0, #(PSR_USR32_MODE) ;\ - bne 2f /* Nope, get out now */ ;\ - bic r4, r4, #(PSR_I|PSR_F) ;\ -1: GET_CURTHREAD_PTR(r5) ;\ - ldr r1, [r5, #(TD_FLAGS)] ;\ - and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED) ;\ - teq r1, #0x00000000 ;\ - beq 2f /* Nope. Just bail */ ;\ - msr cpsr_c, r4 /* Restore interrupts */ ;\ - mov r0, sp ;\ - bl _C_LABEL(ast) /* ast(frame) */ ;\ - orr r0, r4, #(PSR_I|PSR_F) ;\ - msr cpsr_c, r0 ;\ - b 1b ;\ +#define DO_AST \ + ldr r0, [sp]; /* Get the SPSR from stack */ \ + mrs r4, cpsr; /* save CPSR */ \ + orr r1, r4, #(PSR_I|PSR_F); \ + msr cpsr_c, r1; /* Disable interrupts */ \ + and r0, r0, #(PSR_MODE); /* Returning to USR mode? */ \ + teq r0, #(PSR_USR32_MODE); \ + bne 2f; /* Nope, get out now */ \ + bic r4, r4, #(PSR_I|PSR_F); \ +1: GET_CURTHREAD_PTR(r5); \ + ldr r1, [r5, #(TD_FLAGS)]; \ + and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED); \ + teq r1, #0; \ + beq 2f; /* Nope. Just bail */ \ + msr cpsr_c, r4; /* Restore interrupts */ \ + mov r0, sp; \ + bl _C_LABEL(ast); /* ast(frame) */ \ + orr r0, r4, #(PSR_I|PSR_F); \ + msr cpsr_c, r0; \ + b 1b \ 2: From d1962184e0c176ccff2e9fcecdd530563694043e Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 04:18:31 +0000 Subject: [PATCH 149/207] Oops, I fumbled a semicolon on the style changes; recover it. --- sys/arm/arm/exception.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S index a6645f25dea..8210d32805a 100644 --- a/sys/arm/arm/exception.S +++ b/sys/arm/arm/exception.S @@ -260,7 +260,7 @@ __FBSDID("$FreeBSD$"); bl _C_LABEL(ast); /* ast(frame) */ \ orr r0, r4, #(PSR_I|PSR_F); \ msr cpsr_c, r0; \ - b 1b \ + b 1b; \ 2: From be483be81def01bffc1d2b46c386f538271011d8 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 04:41:43 +0000 Subject: [PATCH 150/207] Remove _PROF_PROLOGUE from the EENTRY() macros. These macros define 'extra' entry points which are nested within or provide a synonym name for another function. It's most likely not safe to be messing with the IP and LR registers at anything other than the primary entry point to a function. Anywhere beyond initial function entry, those registers may be in use as scratch or variable registers. --- sys/arm/include/asm.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 73b7355130c..4894b26f660 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -90,17 +90,17 @@ #endif #define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE -#define EENTRY(y) _EENTRY(_C_LABEL(y)); _PROF_PROLOGUE +#define EENTRY(y) _EENTRY(_C_LABEL(y)); #define ENTRY_NP(y) _ENTRY(_C_LABEL(y)) #define EENTRY_NP(y) _EENTRY(_C_LABEL(y)) #define END(y) _END(_C_LABEL(y)) -#define EEND(y) +#define EEND(y) _EEND(_C_LABEL(y)) #define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE -#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE +#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); #define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y)) #define ASEENTRY_NP(y) _EENTRY(_ASM_LABEL(y)) #define ASEND(y) _END(_ASM_LABEL(y)) -#define ASEEND(y) +#define ASEEND(y) _EEND(_ASM_LABEL(y)) #define ASMSTR .asciz From fe07a9d08f578f63f8501f47aa6a11b785987ebe Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Thu, 25 Dec 2014 13:38:51 +0000 Subject: [PATCH 151/207] Fix VIMAGE build. --- sys/netipsec/key.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 5fdf83b2c09..b9bcd5930ca 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -7608,7 +7608,7 @@ key_destroy(void) TAILQ_INIT(&drainq); SPTREE_WLOCK(); for (i = 0; i < IPSEC_DIR_MAX; i++) { - TAILQ_CONCAT(&drainq, &V_sptree[dir], chain); + TAILQ_CONCAT(&drainq, &V_sptree[i], chain); } SPTREE_WUNLOCK(); sp = TAILQ_FIRST(&drainq); From 46b34e5adcaf53dc322924d943cfe70dd53246dc Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 25 Dec 2014 14:44:04 +0000 Subject: [PATCH 152/207] Fix the comment introduced in r276192 so that it clearly states that the change is needed to avoid a deadlock. Suggested by: kib MFC after: 1 week --- sys/kern/vfs_default.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 8d850a135f6..d6b3765689a 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -407,9 +407,10 @@ vop_stdadvlock(struct vop_advlock_args *ap) vp = ap->a_vp; if (ap->a_fl->l_whence == SEEK_END) { /* - * The NFSv4 server will LOR/deadlock if a vn_lock() call - * is done on vp. Fortunately, vattr.va_size is only - * needed for SEEK_END and the NFSv4 server only uses SEEK_SET. + * The NFSv4 server must avoid doing a vn_lock() here, since it + * can deadlock the nfsd threads, due to a LOR. Fortunately + * the NFSv4 server always uses SEEK_SET and this code is + * only required for the SEEK_END case. */ vn_lock(vp, LK_SHARED | LK_RETRY); error = VOP_GETATTR(vp, &vattr, curthread->td_ucred); From 2433b5f10fb6159f39fe20f56c40a788c419c94e Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Thu, 25 Dec 2014 15:17:57 +0000 Subject: [PATCH 153/207] Replace CC_VAR with CCV, since the CC_VAR macro doesn't exist. While here, add MLINK for CCV.9 and DECLARE_CC_MODULE.9. --- share/man/man9/Makefile | 2 ++ share/man/man9/mod_cc.9 | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 195613f66ef..cf64df7c811 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1080,6 +1080,8 @@ MLINKS+=microuptime.9 binuptime.9 \ microuptime.9 sbinuptime.9 MLINKS+=mi_switch.9 cpu_switch.9 \ mi_switch.9 cpu_throw.9 +MLINKS+=mod_cc.9 CCV.9 \ + mod_cc.9 DECLARE_CC_MODULE.9 MLINKS+=mtx_pool.9 mtx_pool_alloc.9 \ mtx_pool.9 mtx_pool_create.9 \ mtx_pool.9 mtx_pool_destroy.9 \ diff --git a/share/man/man9/mod_cc.9 b/share/man/man9/mod_cc.9 index 12bc9be38f6..4875949da50 100644 --- a/share/man/man9/mod_cc.9 +++ b/share/man/man9/mod_cc.9 @@ -31,19 +31,19 @@ .\" .\" $FreeBSD$ .\" -.Dd September 15, 2011 +.Dd December 25, 2014 .Dt MOD_CC 9 .Os .Sh NAME .Nm mod_cc , .Nm DECLARE_CC_MODULE , -.Nm CC_VAR +.Nm CCV .Nd Modular Congestion Control .Sh SYNOPSIS .In netinet/cc.h .In netinet/cc/cc_module.h .Fn DECLARE_CC_MODULE "ccname" "ccalgo" -.Fn CC_VAR "ccv" "what" +.Fn CCV "ccv" "what" .Sh DESCRIPTION The .Nm @@ -223,7 +223,7 @@ To aid the eventual transition towards this goal, direct use of variables from the transport protocol's data structures is strongly discouraged. However, it is inevitable at the current time to require access to some of these variables, and so the -.Fn CC_VAR +.Fn CCV macro exists as a convenience accessor. The .Fa ccv From de064ce45960beda94405029ca742e58e45856d1 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 16:36:02 +0000 Subject: [PATCH 154/207] Stylish changes... put tabs where they need to be in macros, move lines around so that related things are more grouped together, rewrite comments. No functional changes, this is all so that the functional changes in the next commit will stand out. --- sys/arm/include/asm.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 4894b26f660..5d2fb64b59b 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -57,6 +57,22 @@ #define _FNEND #endif +/* + * gas/arm uses @ as a single comment character and thus cannot be used here. + * It recognises the # instead of an @ symbol in .type directives. + */ +#define _ASM_TYPE_FUNCTION #function +#define _ASM_TYPE_OBJECT #object + +/* XXX Is this still the right prologue for profiling? */ +#ifdef GPROF +#define _PROF_PROLOGUE \ + mov ip, lr; \ + bl __mcount +#else +#define _PROF_PROLOGUE +#endif + /* * EENTRY()/EEND() mark "extra" entry/exit points from a function. * The unwind info cannot handle the concept of a nested function, or a function @@ -69,25 +85,9 @@ #define _EENTRY(x) .globl x; .type x,_ASM_TYPE_FUNCTION; x: #define _EEND(x) /* nothing */ -/* - * gas/arm uses @ as a single comment character and thus cannot be used here - * Instead it recognised the # instead of an @ symbols in .type directives - * We define a couple of macros so that assembly code will not be dependent - * on one or the other. - */ -#define _ASM_TYPE_FUNCTION #function -#define _ASM_TYPE_OBJECT #object -#define GLOBAL(X) .globl x -#define _ENTRY(x) \ - .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART -#define _END(x) .size x, . - x; _FNEND - -#ifdef GPROF -# define _PROF_PROLOGUE \ - mov ip, lr; bl __mcount -#else -# define _PROF_PROLOGUE -#endif +#define GLOBAL(X) .globl x +#define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART +#define _END(x) .size x, . - x; _FNEND #define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE #define EENTRY(y) _EENTRY(_C_LABEL(y)); From 714429358f09dfd959792243eeea582526dfb04e Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 16:43:15 +0000 Subject: [PATCH 155/207] Fix the GLOBAL macro so it works (upper vs lowercase X), use it in _EENTRY. --- sys/arm/include/asm.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 5d2fb64b59b..6560ff50977 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -82,10 +82,11 @@ * basically just a label that you can jump to. The EEND() macro does nothing * at all, except document the exit point associated with the same-named entry. */ -#define _EENTRY(x) .globl x; .type x,_ASM_TYPE_FUNCTION; x: +#define GLOBAL(x) .global x + +#define _EENTRY(x) GLOBAL(x); .type x,_ASM_TYPE_FUNCTION; x: #define _EEND(x) /* nothing */ -#define GLOBAL(X) .globl x #define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART #define _END(x) .size x, . - x; _FNEND From b05d247e35781e85b91a10a1182fb0fed02c0f45 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 16:49:33 +0000 Subject: [PATCH 156/207] Create 'L' variants of all the ENTRY macros for file-static/local symbols. If it seems like this is getting out of hand, I quite agree. I wonder if it's safe, here in the 21st century, to lose the distinction between C and ASM symbols? --- sys/arm/include/asm.h | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 6560ff50977..506e99a9a21 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -75,6 +75,7 @@ /* * EENTRY()/EEND() mark "extra" entry/exit points from a function. + * LEENTRY()/LEEND() are the the same for local symbols. * The unwind info cannot handle the concept of a nested function, or a function * with multiple .fnstart directives, but some of our assembler code is written * with multiple labels to allow entry at several points. The EENTRY() macro @@ -84,11 +85,15 @@ */ #define GLOBAL(x) .global x -#define _EENTRY(x) GLOBAL(x); .type x,_ASM_TYPE_FUNCTION; x: -#define _EEND(x) /* nothing */ +#define _LEENTRY(x) .type x,_ASM_TYPE_FUNCTION; x: +#define _LEEND(x) /* nothing */ +#define _EENTRY(x) GLOBAL(x); _LEENTRY(x) +#define _EEND(x) _LEEND(x) -#define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART -#define _END(x) .size x, . - x; _FNEND +#define _LENTRY(x) .text; _ALIGN_TEXT; _LEENTRY(x); _FNSTART +#define _LEND(x) .size x, . - x; _FNEND +#define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x); _FNSTART +#define _END(x) _LEND(x) #define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE #define EENTRY(y) _EENTRY(_C_LABEL(y)); @@ -97,11 +102,17 @@ #define END(y) _END(_C_LABEL(y)) #define EEND(y) _EEND(_C_LABEL(y)) #define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE +#define ASLENTRY(y) _LENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE #define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); +#define ASLEENTRY(y) _LEENTRY(_ASM_LABEL(y)); #define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y)) +#define ASLENTRY_NP(y) _LENTRY(_ASM_LABEL(y)) #define ASEENTRY_NP(y) _EENTRY(_ASM_LABEL(y)) +#define ASLEENTRY_NP(y) _LEENTRY(_ASM_LABEL(y)) #define ASEND(y) _END(_ASM_LABEL(y)) +#define ASLEND(y) _LEND(_ASM_LABEL(y)) #define ASEEND(y) _EEND(_ASM_LABEL(y)) +#define ASLEEND(y) _LEEND(_ASM_LABEL(y)) #define ASMSTR .asciz From 26659812e2a8e447dc6366cad8c8033bcc001bd2 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 17:06:58 +0000 Subject: [PATCH 157/207] For data and instruction prefetch aborts, call the same handler in the C code, passing a 0/1 flag that indicates which type of abort it was. This sets the stage for unifying the handling of page faults in a single routine. Submitted by: Svatopluk Kraus , Michal Meloun Date: Thu, 25 Dec 2014 17:28:26 +0000 Subject: [PATCH 158/207] Add interrupt support for GPIO pins on OMAP4 and AM335x. This enables the use of GPIO pins as interrupt sources for kernel devices directly attached to gpiobus (userland notification will be added soon). The use of gpio interrupts for other kernel devices will be possible when intrng is complete. All GPIO pins can be set to trigger on: - active-low; - active-high; - rising edge; - falling edge. Tested on: Beaglebone-black --- sys/arm/ti/ti_gpio.c | 331 ++++++++++++++++++++++++++++--- sys/arm/ti/ti_gpio.h | 8 + sys/boot/fdt/dts/arm/am335x.dtsi | 2 + 3 files changed, 309 insertions(+), 32 deletions(-) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index 45ce9594409..45e849b657d 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -1,6 +1,6 @@ /*- - * Copyright (c) 2011 - * Ben Gray . + * Copyright (c) 2011 Ben Gray . + * Copyright (c) 2014 Luiz Otavio O Souza . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,17 +26,8 @@ */ /** - * Very simple GPIO (general purpose IO) driver module for TI OMAP SoC's. - * - * Currently this driver only does the basics, get a value on a pin & set a - * value on a pin. Hopefully over time I'll expand this to be a bit more generic - * and support interrupts and other various bits on the SoC can do ... in the - * meantime this is all you get. - * - * Beware the OMA datasheet(s) lists GPIO banks 1-6, whereas I've used 0-5 here - * in the code. - * - * + * Beware that the OMAP4 datasheet(s) lists GPIO banks 1-6, whereas the code + * here uses 0-5. */ #include @@ -52,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -120,6 +112,8 @@ __FBSDID("$FreeBSD$"); #define TI_GPIO_BANK(p) ((p) / PINS_PER_BANK) #define TI_GPIO_MASK(p) (1U << ((p) % PINS_PER_BANK)) +static struct ti_gpio_softc *ti_gpio_sc = NULL; + static u_int ti_max_gpio_banks(void) { @@ -228,14 +222,14 @@ static struct resource_spec ti_gpio_irq_spec[] = { /** * Macros for driver mutex locking */ -#define TI_GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) -#define TI_GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) +#define TI_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx) +#define TI_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx) #define TI_GPIO_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \ - "ti_gpio", MTX_DEF) -#define TI_GPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx) -#define TI_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED) -#define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED) + mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ + "ti_gpio", MTX_SPIN) +#define TI_GPIO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) +#define TI_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) +#define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED) /** * ti_gpio_read_4 - reads a 32-bit value from one of the GPIO registers @@ -279,6 +273,41 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask) ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_1, mask); } +static inline void +ti_gpio_intr_set(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask) +{ + + /* + * On OMAP4 we unmask only the MPU interrupt and on AM335x we + * also activate only the first interrupt. + */ + ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_SET_0, mask); +} + +static inline void +ti_gpio_intr_ack(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask) +{ + + /* + * Acknowledge the interrupt on both registers even if we use only + * the first one. + */ + ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_0, mask); + ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_1, mask); +} + +static inline uint32_t +ti_gpio_intr_status(struct ti_gpio_softc *sc, unsigned int bank) +{ + uint32_t reg; + + /* Get the status from both registers. */ + reg = ti_gpio_read_4(sc, bank, TI_GPIO_IRQSTATUS_0); + reg |= ti_gpio_read_4(sc, bank, TI_GPIO_IRQSTATUS_1); + + return (reg); +} + /** * ti_gpio_pin_max - Returns the maximum number of GPIO pins * @dev: gpio device handle @@ -575,20 +604,39 @@ ti_gpio_pin_toggle(device_t dev, uint32_t pin) * ti_gpio_intr - ISR for all GPIO modules * @arg: the soft context pointer * - * Unsused - * * LOCKING: * Internally locks the context * */ -static void +static int ti_gpio_intr(void *arg) { - struct ti_gpio_softc *sc = arg; + int bank_last, irq; + struct intr_event *event; + struct ti_gpio_softc *sc; + uint32_t reg; - TI_GPIO_LOCK(sc); - /* TODO: something useful */ - TI_GPIO_UNLOCK(sc); + sc = (struct ti_gpio_softc *)arg; + bank_last = -1; + for (irq = 0; irq < sc->sc_maxpin; irq++) { + + /* Read interrupt status only once for each bank. */ + if (TI_GPIO_BANK(irq) != bank_last) { + reg = ti_gpio_intr_status(sc, TI_GPIO_BANK(irq)); + bank_last = TI_GPIO_BANK(irq); + } + if ((reg & TI_GPIO_MASK(irq)) == 0) + continue; + event = sc->sc_events[irq]; + if (event != NULL && !TAILQ_EMPTY(&event->ie_handlers)) + intr_event_handle(event, NULL); + else + device_printf(sc->sc_dev, "Stray IRQ %d\n", irq); + /* Ack the IRQ Status bit. */ + ti_gpio_intr_ack(sc, TI_GPIO_BANK(irq), TI_GPIO_MASK(irq)); + } + + return (FILTER_HANDLED); } static int @@ -603,13 +651,13 @@ ti_gpio_attach_intr(device_t dev) break; /* - * Register our interrupt handler for each of the IRQ resources. + * Register our interrupt filter for each of the IRQ resources. */ if (bus_setup_intr(dev, sc->sc_irq_res[i], - INTR_TYPE_MISC | INTR_MPSAFE, NULL, ti_gpio_intr, sc, + INTR_TYPE_MISC | INTR_MPSAFE, ti_gpio_intr, NULL, sc, &sc->sc_irq_hdl[i]) != 0) { device_printf(dev, - "WARNING: unable to register interrupt handler\n"); + "WARNING: unable to register interrupt filter\n"); return (-1); } } @@ -623,7 +671,7 @@ ti_gpio_detach_intr(device_t dev) int i; struct ti_gpio_softc *sc; - /* Teardown our interrupt handlers. */ + /* Teardown our interrupt filters. */ sc = device_get_softc(dev); for (i = 0; i < ti_max_gpio_intrs(); i++) { if (sc->sc_irq_res[i] == NULL) @@ -699,7 +747,10 @@ ti_gpio_attach(device_t dev) unsigned int i; int err; - sc = device_get_softc(dev); + if (ti_gpio_sc != NULL) + return (ENXIO); + + ti_gpio_sc = sc = device_get_softc(dev); sc->sc_dev = dev; TI_GPIO_LOCK_INIT(sc); ti_gpio_pin_max(dev, &sc->sc_maxpin); @@ -728,6 +779,24 @@ ti_gpio_attach(device_t dev) return (ENXIO); } + /* + * Initialize the interrupt settings. The default is active-low + * interrupts. + */ + sc->sc_irq_trigger = malloc( + sizeof(*sc->sc_irq_trigger) * sc->sc_maxpin, + M_DEVBUF, M_WAITOK | M_ZERO); + sc->sc_irq_polarity = malloc( + sizeof(*sc->sc_irq_polarity) * sc->sc_maxpin, + M_DEVBUF, M_WAITOK | M_ZERO); + for (i = 0; i < sc->sc_maxpin; i++) { + sc->sc_irq_trigger[i] = INTR_TRIGGER_LEVEL; + sc->sc_irq_polarity[i] = INTR_POLARITY_LOW; + } + + sc->sc_events = malloc(sizeof(struct intr_event *) * sc->sc_maxpin, + M_DEVBUF, M_WAITOK | M_ZERO); + /* We need to go through each block and ensure the clocks are running and * the module is enabled. It might be better to do this only when the * pins are configured which would result in less power used if the GPIO @@ -784,6 +853,10 @@ ti_gpio_detach(device_t dev) bus_generic_detach(dev); + free(sc->sc_events, M_DEVBUF); + free(sc->sc_irq_polarity, M_DEVBUF); + free(sc->sc_irq_trigger, M_DEVBUF); + /* Release the memory and IRQ resources. */ ti_gpio_detach_intr(dev); bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res); @@ -794,6 +867,193 @@ ti_gpio_detach(device_t dev) return (0); } +static uint32_t +ti_gpio_intr_reg(struct ti_gpio_softc *sc, int irq) +{ + + if (ti_gpio_valid_pin(sc, irq) != 0) + return (0); + + if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_LEVEL) { + if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW) + return (TI_GPIO_LEVELDETECT0); + else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH) + return (TI_GPIO_LEVELDETECT1); + } else if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_EDGE) { + if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW) + return (TI_GPIO_FALLINGDETECT); + else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH) + return (TI_GPIO_RISINGDETECT); + } + + return (0); +} + +static void +ti_gpio_mask_irq(void *source) +{ + int irq; + uint32_t reg, val; + + irq = (int)source; + if (ti_gpio_valid_pin(ti_gpio_sc, irq) != 0) + return; + + TI_GPIO_LOCK(ti_gpio_sc); + ti_gpio_intr_clr(ti_gpio_sc, TI_GPIO_BANK(irq), TI_GPIO_MASK(irq)); + reg = ti_gpio_intr_reg(ti_gpio_sc, irq); + if (reg != 0) { + val = ti_gpio_read_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg); + val &= ~TI_GPIO_MASK(irq); + ti_gpio_write_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg, val); + } + TI_GPIO_UNLOCK(ti_gpio_sc); +} + +static void +ti_gpio_unmask_irq(void *source) +{ + int irq; + uint32_t reg, val; + + irq = (int)source; + if (ti_gpio_valid_pin(ti_gpio_sc, irq) != 0) + return; + + TI_GPIO_LOCK(ti_gpio_sc); + reg = ti_gpio_intr_reg(ti_gpio_sc, irq); + if (reg != 0) { + val = ti_gpio_read_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg); + val |= TI_GPIO_MASK(irq); + ti_gpio_write_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg, val); + ti_gpio_intr_set(ti_gpio_sc, TI_GPIO_BANK(irq), + TI_GPIO_MASK(irq)); + } + TI_GPIO_UNLOCK(ti_gpio_sc); +} + +static int +ti_gpio_activate_resource(device_t dev, device_t child, int type, int rid, + struct resource *res) +{ + int pin; + + if (type != SYS_RES_IRQ) + return (ENXIO); + + /* Unmask the interrupt. */ + pin = rman_get_start(res); + ti_gpio_unmask_irq((void *)(uintptr_t)pin); + + return (0); +} + +static int +ti_gpio_deactivate_resource(device_t dev, device_t child, int type, int rid, + struct resource *res) +{ + int pin; + + if (type != SYS_RES_IRQ) + return (ENXIO); + + /* Mask the interrupt. */ + pin = rman_get_start(res); + ti_gpio_mask_irq((void *)(uintptr_t)pin); + + return (0); +} + +static int +ti_gpio_config_intr(device_t dev, int irq, enum intr_trigger trig, + enum intr_polarity pol) +{ + struct ti_gpio_softc *sc; + uint32_t oldreg, reg, val; + + sc = device_get_softc(dev); + if (ti_gpio_valid_pin(sc, irq) != 0) + return (EINVAL); + + /* There is no standard trigger or polarity. */ + if (trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM) + return (EINVAL); + + TI_GPIO_LOCK(sc); + /* + * TRM recommends add the new event before remove the old one to + * avoid losing interrupts. + */ + oldreg = ti_gpio_intr_reg(sc, irq); + sc->sc_irq_trigger[irq] = trig; + sc->sc_irq_polarity[irq] = pol; + reg = ti_gpio_intr_reg(sc, irq); + if (reg != 0) { + /* Apply the new settings. */ + val = ti_gpio_read_4(sc, TI_GPIO_BANK(irq), reg); + val |= TI_GPIO_MASK(irq); + ti_gpio_write_4(sc, TI_GPIO_BANK(irq), reg, val); + } + if (oldreg != 0) { + /* Remove the old settings. */ + val = ti_gpio_read_4(sc, TI_GPIO_BANK(irq), oldreg); + val &= ~TI_GPIO_MASK(irq); + ti_gpio_write_4(sc, TI_GPIO_BANK(irq), oldreg, val); + } + TI_GPIO_UNLOCK(sc); + + return (0); +} + +static int +ti_gpio_setup_intr(device_t dev, device_t child, struct resource *ires, + int flags, driver_filter_t *filt, driver_intr_t *handler, + void *arg, void **cookiep) +{ + struct ti_gpio_softc *sc; + struct intr_event *event; + int pin, error; + + sc = device_get_softc(dev); + pin = rman_get_start(ires); + if (ti_gpio_valid_pin(sc, pin) != 0) + panic("%s: bad pin %d", __func__, pin); + + event = sc->sc_events[pin]; + if (event == NULL) { + error = intr_event_create(&event, (void *)(uintptr_t)pin, 0, + pin, ti_gpio_mask_irq, ti_gpio_unmask_irq, NULL, NULL, + "gpio%d pin%d:", device_get_unit(dev), pin); + if (error != 0) + return (error); + sc->sc_events[pin] = event; + } + intr_event_add_handler(event, device_get_nameunit(child), filt, + handler, arg, intr_priority(flags), flags, cookiep); + + return (0); +} + +static int +ti_gpio_teardown_intr(device_t dev, device_t child, struct resource *ires, + void *cookie) +{ + struct ti_gpio_softc *sc; + int pin, err; + + sc = device_get_softc(dev); + pin = rman_get_start(ires); + if (ti_gpio_valid_pin(sc, pin) != 0) + panic("%s: bad pin %d", __func__, pin); + if (sc->sc_events[pin] == NULL) + panic("Trying to teardown unoccupied IRQ"); + err = intr_event_remove_handler(cookie); + if (!err) + sc->sc_events[pin] = NULL; + + return (err); +} + static phandle_t ti_gpio_get_node(device_t bus, device_t dev) { @@ -816,6 +1076,13 @@ static device_method_t ti_gpio_methods[] = { DEVMETHOD(gpio_pin_set, ti_gpio_pin_set), DEVMETHOD(gpio_pin_toggle, ti_gpio_pin_toggle), + /* Bus interface */ + DEVMETHOD(bus_activate_resource, ti_gpio_activate_resource), + DEVMETHOD(bus_deactivate_resource, ti_gpio_deactivate_resource), + DEVMETHOD(bus_config_intr, ti_gpio_config_intr), + DEVMETHOD(bus_setup_intr, ti_gpio_setup_intr), + DEVMETHOD(bus_teardown_intr, ti_gpio_teardown_intr), + /* ofw_bus interface */ DEVMETHOD(ofw_bus_get_node, ti_gpio_get_node), diff --git a/sys/arm/ti/ti_gpio.h b/sys/arm/ti/ti_gpio.h index 6b6d79443c3..763fc8ae792 100644 --- a/sys/arm/ti/ti_gpio.h +++ b/sys/arm/ti/ti_gpio.h @@ -46,6 +46,11 @@ */ struct ti_gpio_softc { device_t sc_dev; + + /* Interrupt trigger type and level. */ + enum intr_trigger *sc_irq_trigger; + enum intr_polarity *sc_irq_polarity; + int sc_maxpin; struct mtx sc_mtx; @@ -57,6 +62,9 @@ struct ti_gpio_softc { struct resource *sc_mem_res[MAX_GPIO_BANKS]; struct resource *sc_irq_res[MAX_GPIO_INTRS]; + /* Interrupt events. */ + struct intr_event **sc_events; + /* The handle for the register IRQ handlers. */ void *sc_irq_hdl[MAX_GPIO_INTRS]; }; diff --git a/sys/boot/fdt/dts/arm/am335x.dtsi b/sys/boot/fdt/dts/arm/am335x.dtsi index 9378f34f25c..feb32f247ef 100644 --- a/sys/boot/fdt/dts/arm/am335x.dtsi +++ b/sys/boot/fdt/dts/arm/am335x.dtsi @@ -99,6 +99,8 @@ 0x481AE000 0x1000 >; interrupts = < 96 97 98 99 32 33 62 63 >; interrupt-parent = <&AINTC>; + interrupt-controller; + #interrupt-cells = <1>; }; uart0: serial@44E09000 { From 91b050b27bc2365f30d336908aca2eb15bdbfc9a Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Thu, 25 Dec 2014 17:50:04 +0000 Subject: [PATCH 159/207] Use compiled in default keymaps which are available both in syscons and vt. --- sys/amd64/conf/NOTES | 2 +- sys/conf/NOTES | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index d1220b6c132..9b697f087e0 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -215,7 +215,7 @@ hint.atkbd.0.irq="1" # Options for atkbd: options ATKBD_DFLT_KEYMAP # specify the built-in keymap -makeoptions ATKBD_DFLT_KEYMAP=jp.106 +makeoptions ATKBD_DFLT_KEYMAP=fr.dvorak # `flags' for atkbd: # 0x01 Force detection of keyboard, else we always assume a keyboard diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 70cffbead75..3e644dd8133 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2785,7 +2785,7 @@ options U3G_DEBUG # options for ukbd: options UKBD_DFLT_KEYMAP # specify the built-in keymap -makeoptions UKBD_DFLT_KEYMAP=it.iso +makeoptions UKBD_DFLT_KEYMAP=jp.pc98 # options for uplcom: options UPLCOM_INTR_INTERVAL=100 # interrupt pipe interval From 7a27628a3fe2cfc20282560d874ba54656548c93 Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Thu, 25 Dec 2014 17:53:43 +0000 Subject: [PATCH 160/207] Fix OLD_LIBS for libxo moved to /lib Pointed out by: kib --- ObsoleteFiles.inc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 4078a30ab63..f104281136a 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -39,8 +39,7 @@ # done # 20141224: libxo moved to /lib -OLD_FILES+=usr/lib/libxo.a -OLD_FILES+=usr/lib/libxo_p.a +OLD_LIBS+=usr/lib/libxo.so.0 # 20141223: remove in6_gif.h, in_gif.h and if_stf.h OLD_FILES+=usr/include/net/if_stf.h OLD_FILES+=usr/include/netinet/in_gif.h From e47bc3881114cb8a39308199026db77fd8d1349c Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Thu, 25 Dec 2014 17:54:22 +0000 Subject: [PATCH 161/207] Create the PKG_DIR if it is missing --- tools/tools/sysbuild/sysbuild.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh index bb22a697453..d95b8dfdc80 100644 --- a/tools/tools/sysbuild/sysbuild.sh +++ b/tools/tools/sysbuild/sysbuild.sh @@ -219,6 +219,10 @@ ports_build() ( ports_recurse . $PORTS_WE_WANT + if [ "x${PKG_DIR}" != "x" ] ; then + mkdir -p ${PKG_DIR} + fi + # Now build & install them for p in `cat /tmp/_.plist` do @@ -231,9 +235,7 @@ ports_build() ( ( cd $p - make clean ${PORTS_OPTS} - make all ${PORTS_OPTS} - make install ${PORTS_OPTS} + make clean all install ${PORTS_OPTS} ) > _.$b 2>&1 < /dev/null continue fi From eb4585bcc6eb2b1d2c8d5ba3de28336e7f3cb558 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 19:08:39 +0000 Subject: [PATCH 162/207] Add macros for asm barrier instructions with arch-specific implementations. --- sys/arm/include/asm.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index 506e99a9a21..deaccec19ee 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -39,6 +39,7 @@ #ifndef _MACHINE_ASM_H_ #define _MACHINE_ASM_H_ #include +#include #define _C_LABEL(x) x #define _ASM_LABEL(x) x @@ -221,4 +222,18 @@ # define RETc(c) mov##c pc, lr #endif +#if __ARM_ARCH >= 7 +#define ISB isb +#define DSB dsb +#define DMB dmb +#elif __ARM_ARCH == 6 +#define ISB mcr CP15_CP15ISB +#define DSB mcr CP15_CP15DSB +#define DMB mcr CP15_CP15DMB +#else +#define ISB mcr CP15_CP15ISB +#define DSB mcr CP15_CP15DSB /* DSB and DMB are the */ +#define DMB mcr CP15_CP15DSB /* same prior to v6.*/ +#endif + #endif /* !_MACHINE_ASM_H_ */ From c93be3714d0210509f9d3fb8e05cc293dec886cc Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Thu, 25 Dec 2014 19:22:02 +0000 Subject: [PATCH 163/207] Define only the CP15 register operations that are valid for the architecture. Submitted by: Svatopluk Kraus , Michal Meloun = 6 /* From ARMv6: */ #define CP15_IFSR(rr) p15, 0, rr, c5, c0, 1 /* Instruction Fault Status Register */ +#endif +#if __ARM_ARCH >= 7 /* From ARMv7: */ #define CP15_ADFSR(rr) p15, 0, rr, c5, c1, 0 /* Auxiliary Data Fault Status Register */ #define CP15_AIFSR(rr) p15, 0, rr, c5, c1, 1 /* Auxiliary Instruction Fault Status Register */ #endif - /* * CP15 C6 registers */ @@ -118,7 +119,7 @@ /* * CP15 C7 registers */ -#if __ARM_ARCH >= 6 +#if __ARM_ARCH >= 7 && defined(SMP) /* From ARMv7: */ #define CP15_ICIALLUIS p15, 0, r0, c7, c1, 0 /* Instruction cache invalidate all PoU, IS */ #define CP15_BPIALLIS p15, 0, r0, c7, c1, 6 /* Branch predictor invalidate all IS */ @@ -128,14 +129,14 @@ #define CP15_ICIALLU p15, 0, r0, c7, c5, 0 /* Instruction cache invalidate all PoU */ #define CP15_ICIMVAU(rr) p15, 0, rr, c7, c5, 1 /* Instruction cache invalidate */ -#if __ARM_ARCH >= 6 +#if __ARM_ARCH == 6 /* Deprecated in ARMv7 */ #define CP15_CP15ISB p15, 0, r0, c7, c5, 4 /* ISB */ #endif #define CP15_BPIALL p15, 0, r0, c7, c5, 6 /* Branch predictor invalidate all */ #define CP15_BPIMVA p15, 0, rr, c7, c5, 7 /* Branch predictor invalidate by MVA */ -#if __ARM_ARCH >= 6 +#if __ARM_ARCH == 6 /* Only ARMv6: */ #define CP15_DCIALL p15, 0, r0, c7, c6, 0 /* Data cache invalidate all */ #endif @@ -147,7 +148,7 @@ #define CP15_ATS1CUR(rr) p15, 0, rr, c7, c8, 2 /* Stage 1 Current state unprivileged read */ #define CP15_ATS1CUW(rr) p15, 0, rr, c7, c8, 3 /* Stage 1 Current state unprivileged write */ -#if __ARM_ARCH >= 6 +#if __ARM_ARCH >= 7 /* From ARMv7: */ #define CP15_ATS12NSOPR(rr) p15, 0, rr, c7, c8, 4 /* Stages 1 and 2 Non-secure only PL1 read */ #define CP15_ATS12NSOPW(rr) p15, 0, rr, c7, c8, 5 /* Stages 1 and 2 Non-secure only PL1 write */ @@ -155,24 +156,24 @@ #define CP15_ATS12NSOUW(rr) p15, 0, rr, c7, c8, 7 /* Stages 1 and 2 Non-secure only unprivileged write */ #endif -#if __ARM_ARCH >= 6 +#if __ARM_ARCH == 6 /* Only ARMv6: */ #define CP15_DCCALL p15, 0, r0, c7, c10, 0 /* Data cache clean all */ #endif #define CP15_DCCMVAC(rr) p15, 0, rr, c7, c10, 1 /* Data cache clean by MVA PoC */ #define CP15_DCCSW(rr) p15, 0, rr, c7, c10, 2 /* Data cache clean by set/way */ -#if __ARM_ARCH >= 6 +#if __ARM_ARCH == 6 /* Only ARMv6: */ #define CP15_CP15DSB p15, 0, r0, c7, c10, 4 /* DSB */ #define CP15_CP15DMB p15, 0, r0, c7, c10, 5 /* DMB */ #endif -#if __ARM_ARCH >= 6 +#if __ARM_ARCH >= 7 /* From ARMv7: */ #define CP15_DCCMVAU(rr) p15, 0, rr, c7, c11, 1 /* Data cache clean by MVA PoU */ #endif -#if __ARM_ARCH >= 6 +#if __ARM_ARCH == 6 /* Only ARMv6: */ #define CP15_DCCIALL p15, 0, r0, c7, c14, 0 /* Data cache clean and invalidate all */ #endif @@ -182,7 +183,7 @@ /* * CP15 C8 registers */ -#if __ARM_ARCH >= 6 +#if __ARM_ARCH >= 7 && defined(SMP) /* From ARMv7: */ #define CP15_TLBIALLIS p15, 0, r0, c8, c3, 0 /* Invalidate entire unified TLB IS */ #define CP15_TLBIMVAIS(rr) p15, 0, rr, c8, c3, 1 /* Invalidate unified TLB by MVA IS */ @@ -229,4 +230,9 @@ #define CP15_TPIDRURO(rr) p15, 0, rr, c13, c0, 3 /* User Read-Only Thread ID Register */ #define CP15_TPIDRPRW(rr) p15, 0, rr, c13, c0, 4 /* PL1 only Thread ID Register */ +/* + * CP15 C15 registers + */ +#define CP15_CBAR(rr) p15, 4, rr, c15, c0, 0 /* Configuration Base Address Register */ + #endif /* !MACHINE_SYSREG_H */ From c05bafc566aad6e7c22154b09b0a6aa860d91bb3 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Thu, 25 Dec 2014 20:15:13 +0000 Subject: [PATCH 164/207] Deorbit the IEEE-488/GPIB support. --- ObsoleteFiles.inc | 23 + include/Makefile | 6 +- lib/Makefile | 5 - share/man/man4/Makefile | 3 - share/man/man4/gpib.4 | 100 -- share/man/man4/pcii.4 | 97 -- share/man/man4/tnt4882.4 | 55 -- share/mk/src.opts.mk | 1 - sys/conf/NOTES | 13 - sys/conf/files | 4 - sys/dev/ieee488/ibfoo.c | 1127 ---------------------- sys/dev/ieee488/ibfoo_int.h | 147 --- sys/dev/ieee488/pcii.c | 255 ----- sys/dev/ieee488/tnt4882.c | 320 ------ sys/dev/ieee488/tnt4882.h | 77 -- sys/dev/ieee488/ugpib.h | 155 --- sys/dev/ieee488/upd7210.c | 369 ------- sys/dev/ieee488/upd7210.h | 237 ----- tools/build/mk/OptionalObsoleteFiles.inc | 21 - tools/build/options/WITHOUT_GPIB | 2 - 20 files changed, 24 insertions(+), 2993 deletions(-) delete mode 100644 share/man/man4/gpib.4 delete mode 100644 share/man/man4/pcii.4 delete mode 100644 share/man/man4/tnt4882.4 delete mode 100644 sys/dev/ieee488/ibfoo.c delete mode 100644 sys/dev/ieee488/ibfoo_int.h delete mode 100644 sys/dev/ieee488/pcii.c delete mode 100644 sys/dev/ieee488/tnt4882.c delete mode 100644 sys/dev/ieee488/tnt4882.h delete mode 100644 sys/dev/ieee488/ugpib.h delete mode 100644 sys/dev/ieee488/upd7210.c delete mode 100644 sys/dev/ieee488/upd7210.h delete mode 100644 tools/build/options/WITHOUT_GPIB diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index f104281136a..7fbd610ae5b 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,29 @@ # xargs -n1 | sort | uniq -d; # done +# 20141226: Remove gpib/ieee488 +OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h +OLD_FILES+=usr/include/dev/ieee488/tnt4882.h +OLD_FILES+=usr/include/dev/ieee488/ugpib.h +OLD_FILES+=usr/include/dev/ieee488/upd7210.h +OLD_DIRS+=usr/include/dev/ieee488 +OLD_FILES+=usr/include/gpib/gpib.h +OLD_DIRS+=usr/include/gpib +OLD_FILES+=usr/lib/libgpib.a +OLD_FILES+=usr/lib/libgpib_p.a +OLD_FILES+=usr/lib/libgpib.so +OLD_LIBS+=usr/lib/libgpib.so.3 +OLD_FILES+=usr/lib/libgpib_p.a +OLD_FILES+=share/man/man4/pcii.4.gz +OLD_FILES+=share/man/man4/gpib.4.gz +OLD_FILES+=share/man/man4/tnt4882.4.gz +.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64" +OLD_FILES+=usr/lib32/libgpib.a +OLD_FILES+=usr/lib32/libgpib_p.a +OLD_FILES+=usr/lib32/libgpib.so +OLD_LIBS+=usr/lib32/libgpib.so.3 +.endif + # 20141224: libxo moved to /lib OLD_LIBS+=usr/lib/libxo.so.0 # 20141223: remove in6_gif.h, in_gif.h and if_stf.h diff --git a/include/Makefile b/include/Makefile index fe62e5e26d4..fa815272c2b 100644 --- a/include/Makefile +++ b/include/Makefile @@ -42,7 +42,7 @@ LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \ LSUBDIRS= cam/ata cam/scsi \ dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \ dev/hwpmc \ - dev/ic dev/iicbus ${_dev_ieee488} dev/io dev/lmc dev/mfi dev/nvme \ + dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/nvme \ dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/smbus \ dev/speaker dev/usb dev/utopia dev/vkbd dev/wi \ fs/cuse \ @@ -63,10 +63,6 @@ LSUBSUBDIRS= dev/mpt/mpilib _dev_powermac_nvram= dev/powermac_nvram .endif -.if ${MK_GPIB} != "no" -_dev_ieee488= dev/ieee488 -.endif - .if ${MK_GSSAPI} != "no" SUBDIR+= gssapi INCS+= gssapi.h diff --git a/lib/Makefile b/lib/Makefile index 8bd565385ef..4d30c538760 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -52,7 +52,6 @@ SUBDIR= ${SUBDIR_ORDERED} \ libfetch \ libfigpar \ libgeom \ - ${_libgpib} \ libgpio \ ${_libgssapi} \ ${_librpcsec_gss} \ @@ -195,10 +194,6 @@ _cuse= libcuse _libelftc= libelftc .endif -.if ${MK_GPIB} != "no" -_libgpib= libgpib -.endif - .if ${MK_GSSAPI} != "no" _libgssapi= libgssapi _librpcsec_gss= librpcsec_gss diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 76b3d55c2c6..b20cda5dcff 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -156,7 +156,6 @@ MAN= aac.4 \ geom_uncompress.4 \ geom_uzip.4 \ gif.4 \ - gpib.4 \ gpio.4 \ gpioiic.4 \ gpioled.4 \ @@ -372,7 +371,6 @@ MAN= aac.4 \ pci.4 \ pcib.4 \ pcic.4 \ - pcii.4 \ pcm.4 \ pcn.4 \ ${_pf.4} \ @@ -495,7 +493,6 @@ MAN= aac.4 \ ti.4 \ timecounters.4 \ tl.4 \ - tnt4882.4 \ ${_tpm.4} \ trm.4 \ tty.4 \ diff --git a/share/man/man4/gpib.4 b/share/man/man4/gpib.4 deleted file mode 100644 index b5f29cd6017..00000000000 --- a/share/man/man4/gpib.4 +++ /dev/null @@ -1,100 +0,0 @@ -.\" Copyright (c) 2010, Joerg Wunsch -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 24, 2010 -.Dt GPIB 4 -.Os -.Sh NAME -.Nm gpib -.Nd General-Purpose Instrument Bus (GPIB) driver -.Sh SYNOPSIS -Either of the -.Xr pcii 4 -or -.Xr tnt4882 4 -drivers use this driver as the backend. -.Sh DESCRIPTION -The -.Nm -driver provides support for driving an IEEE-488 bus, also called -IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument -Bus), or GPIB (General Purpose Instrument Bus). -The device can become either a listener, talker, controller, and -in particular a master controller on the bus. -.Ss Example -The following example code queries the device provided as -.Va argv[1] -for its identification response. -.Bd -literal -/* compile with: cc -O -o ibtest ibtest.c -lgpib */ - -#include -#include -#include -#include - -#include - -int -main(int argc, char **argv) -{ - int dmm; - unsigned char buf[100]; - char vbuf[sizeof(buf) * 4]; - - /* DVM */ - dmm = ibdev(0, (argc > 1? atoi(argv[1]): 7), 0, - T10s, 1, 0); - if (dmm < 0) - errx(1, "ibdev = %d\\n", dmm); - ibwrt(dmm, "*IDN?\\r\\n", 7); - ibrd(dmm, buf, sizeof(buf) - 1); - strvisx(vbuf, buf, ibcnt, VIS_WHITE | VIS_CSTYLE); - printf("%s\\n", vbuf); - return (0); -} -.Ed -.Sh FILES -.Bl -tag -width /dev/gpibNNib -.It Pa /dev/gpib Ns Em N Ns "ib" -Main device node to access the driver. -.It Pa /dev/gpib Ns Em N Ns "l" -Listen-only entry to the driver. -When opening, an instrument can send data to this device on the -bus in an unaddressed mode, for example hard-copy printer data. -.El -.Sh SEE ALSO -.Xr gpib 3 , -.Xr pcii 4 , -.Xr tnt4882 4 -.Sh HISTORY -The -.Nm -driver was written by Poul-Henning Kamp, and first appeared in -.Fx 5.4 . -.Sh AUTHORS -This manual page was written by -.An J\(:org Wunsch . diff --git a/share/man/man4/pcii.4 b/share/man/man4/pcii.4 deleted file mode 100644 index 3369d3ffc72..00000000000 --- a/share/man/man4/pcii.4 +++ /dev/null @@ -1,97 +0,0 @@ -.\" Copyright (c) 2010, Joerg Wunsch -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 24, 2010 -.Dt PCII 4 -.Os -.Sh NAME -.Nm pcii -.Nd National Instruments PCIIA GPIB controller driver -.Sh SYNOPSIS -.Cd "device pcii" -.Pp -In -.Pa /boot/device.hints : -.Cd hint.pcii.0.at="isa" -.Cd hint.pcii.0.port="0x2e1" -.Cd hint.pcii.0.irq="7" -.Cd hint.pcii.0.drq="1" -.Sh DESCRIPTION -The -.Nm -driver provides support for driving an IEEE-488 bus, also called -IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument -Bus), or GPIB (General Purpose Instrument Bus). -The driver supports National Instruments PCIIA cards (sometimes -also referred to as PC2A) and compatibles. -These cards use a NEC \(mcPD7210 controller IC as the main -interface between the host computer and the instrument bus. -.Ss IO memory space layout -The PCIIA cards use a very specific IO memory space allocation layout. -The address bits A0 through A9 (which have traditionally been the only -address bits evaluated on IBM PC XT extension cards) are hardwired to -address 0x2e1. -Bits A10 through A12 are used by the \(mcPD7210 register select lines. -This makes the individual 7210 registers being 0x400 bytes apart in the -ISA bus address space. -Address bits A13 and A14 are compared to a DIP switch setting on the -card, allowing for up to 4 different cards being installed (at base -addresses 0x2e1, 0x22e1, 0x42e1, and 0x62e1, respectively). -A15 has been used to select an optional on-board time-of-day clock -chip (MM58167A) on the original PCIIA rather than the \(mcPD7210 -(which is not implemented on later boards and clones). -Finally, the IO addresses 0x2f0 ... 0x2f7 are used for a -.Em special interrupt handling feature -(re-enable interrupts so the IRQ can be shared), where actually only -address 0x2f0 plus the actual IRQ level is required for each card. -Some clones do not appear to require this special IRQ handling, and -are thus likely to not support the shared IRQ feature. -.Pp -Only the base address of the card needs to be specified in the ISA -device hints; the driver takes care to derive all other IO addresses -needed during the probe phase. -.Ss Supported cards -The following cards are known to be supported: -.Bl -bullet -offset indent -.It -B&C Microsystems PC488A-0 -.It -National Instruments GPIB-PCII/PCIIA (in PCIIa mode) -.It -Axiom AX5488 -.El -.Sh SEE ALSO -.Xr gpib 3 , -.Xr gpib 4 , -.Xr device.hints 5 -.Sh HISTORY -The -.Nm -driver was written by Poul-Henning Kamp, and first appeared in -.Fx 5.4 . -.Sh AUTHORS -This manual page was written by -.An J\(:org Wunsch . diff --git a/share/man/man4/tnt4882.4 b/share/man/man4/tnt4882.4 deleted file mode 100644 index e3eacbb3d49..00000000000 --- a/share/man/man4/tnt4882.4 +++ /dev/null @@ -1,55 +0,0 @@ -.\" Copyright (c) 2010, Joerg Wunsch -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 24, 2010 -.Dt TNT4882 4 -.Os -.Sh NAME -.Nm tnt4882 -.Nd National Instruments TNT4882A GPIB controller driver -.Sh SYNOPSIS -.Cd "device tnt4882" -.Sh DESCRIPTION -The -.Nm -driver provides support for driving an IEEE-488 bus, also called -IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument -Bus), or GPIB (General Purpose Instrument Bus). -The driver supports National Instruments PCI GPIB cards using -the TNT4882 bus interface chip. -This chip emulates a NEC \(mcPD7210 controller IC as the main -interface between the host computer and the instrument bus. -.Sh SEE ALSO -.Xr gpib 3 , -.Xr gpib 4 -.Sh HISTORY -The -.Nm -driver was written by Poul-Henning Kamp, and first appeared in -.Fx 5.4 . -.Sh AUTHORS -This manual page was written by -.An J\(:org Wunsch . diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 80313da12d2..f505f9822f6 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -85,7 +85,6 @@ __DEFAULT_YES_OPTIONS = \ GDB \ GNU \ GNU_GREP_COMPAT \ - GPIB \ GPIO \ GPL_DTC \ GROFF \ diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 3e644dd8133..66c1dbc1f22 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2353,19 +2353,6 @@ options SND_FEEDER_RATE_HP options SND_PCM_64 options SND_OLDSTEREO -# -# IEEE-488 hardware: -# pcii: PCIIA cards (uPD7210 based isa cards) -# tnt4882: National Instruments PCI-GPIB card. - -device pcii -hint.pcii.0.at="isa" -hint.pcii.0.port="0x2e1" -hint.pcii.0.irq="5" -hint.pcii.0.drq="1" - -device tnt4882 - # # Miscellaneous hardware: # diff --git a/sys/conf/files b/sys/conf/files index d419d4a64ae..237390fd802 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1448,10 +1448,6 @@ dev/ida/ida_eisa.c optional ida eisa dev/ida/ida_pci.c optional ida pci dev/ie/if_ie.c optional ie isa nowerror dev/ie/if_ie_isa.c optional ie isa -dev/ieee488/ibfoo.c optional pcii | tnt4882 -dev/ieee488/pcii.c optional pcii -dev/ieee488/tnt4882.c optional tnt4882 -dev/ieee488/upd7210.c optional pcii | tnt4882 dev/iicbus/ad7418.c optional ad7418 dev/iicbus/ds133x.c optional ds133x dev/iicbus/ds1374.c optional ds1374 diff --git a/sys/dev/ieee488/ibfoo.c b/sys/dev/ieee488/ibfoo.c deleted file mode 100644 index 2fe72dcd5f0..00000000000 --- a/sys/dev/ieee488/ibfoo.c +++ /dev/null @@ -1,1127 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * Copyright (c) 2010 Joerg Wunsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * High-level driver for µPD7210 based GPIB cards. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -# define IBDEBUG -# undef IBDEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define UPD7210_SW_DRIVER -#include -#include - -static MALLOC_DEFINE(M_IBFOO, "IBFOO", "IBFOO"); - - -/* ibfoo API */ - -#include - -/* XXX: This is really a bitmap */ -enum h_kind { - H_DEV = 1, - H_BOARD = 2, - H_EITHER = 3 -}; - -struct handle { - LIST_ENTRY(handle) list; - int handle; - enum h_kind kind; - int pad; - int sad; - struct timeval timeout; - int eot; - int eos; - int dma; -}; - -struct ibfoo { - struct upd7210 *u; - LIST_HEAD(,handle) handles; - struct unrhdr *unrhdr; - struct callout callout; - struct handle *h; - struct ibarg *ap; - - enum { - IDLE, - BUSY, - PIO_IDATA, - PIO_ODATA, - PIO_CMD, - DMA_IDATA, - FIFO_IDATA, - FIFO_ODATA, - FIFO_CMD - } mode; - - struct timeval deadline; - - struct handle *rdh; /* addressed for read */ - struct handle *wrh; /* addressed for write */ - - int doeoi; - - u_char *buf; - u_int buflen; -}; - -typedef int ibhandler_t(struct ibfoo *ib); - -static struct timeval timeouts[] = { - [TNONE] = { 0, 0}, - [T10us] = { 0, 10}, - [T30us] = { 0, 30}, - [T100us] = { 0, 100}, - [T300us] = { 0, 300}, - [T1ms] = { 0, 1000}, - [T3ms] = { 0, 3000}, - [T10ms] = { 0, 10000}, - [T30ms] = { 0, 30000}, - [T100ms] = { 0, 100000}, - [T300ms] = { 0, 300000}, - [T1s] = { 1, 0}, - [T3s] = { 3, 0}, - [T10s] = { 10, 0}, - [T30s] = { 30, 0}, - [T100s] = { 100, 0}, - [T300s] = { 300, 0}, - [T1000s] = { 1000, 0} -}; - -static const u_int max_timeouts = sizeof timeouts / sizeof timeouts[0]; - -static int ibdebug; - -static int -ib_set_error(struct ibarg *ap, int error) -{ - - if (ap->__iberr == 0) - ap->__iberr = error; - ap->__ibsta |= ERR; - ap->__retval = ap->__ibsta; - return (0); -} - -static int -ib_had_timeout(struct ibarg *ap) -{ - - ib_set_error(ap, EABO); - ap->__ibsta |= TIMO; - ap->__retval = ap->__ibsta; - return (0); -} - -static int -ib_set_errno(struct ibarg *ap, int errno) -{ - - if (ap->__iberr == 0) { - ap->__iberr = EDVR; - ap->__ibcnt = errno; - } - ap->__ibsta |= ERR; - ap->__retval = ap->__ibsta; - return (0); -} - -static int -gpib_ib_irq(struct upd7210 *u, int isr_3) -{ - struct ibfoo *ib; - - ib = u->ibfoo; - - mtx_assert(&u->mutex, MA_OWNED); - switch (ib->mode) { - case PIO_CMD: - if (!(u->rreg[ISR2] & IXR2_CO)) - return (0); - if (ib->buflen == 0) - break; - upd7210_wr(u, CDOR, *ib->buf); - ib->buf++; - ib->buflen--; - return (1); - case PIO_IDATA: - if (!(u->rreg[ISR1] & IXR1_DI)) - return (0); - *ib->buf = upd7210_rd(u, DIR); - ib->buf++; - ib->buflen--; - if (ib->buflen == 0 || (u->rreg[ISR1] & IXR1_ENDRX)) - break; - return (1); - case PIO_ODATA: - if (!(u->rreg[ISR1] & IXR1_DO)) - return (0); - if (ib->buflen == 0) - break; - if (ib->buflen == 1 && ib->doeoi) - upd7210_wr(u, AUXMR, AUXMR_SEOI); - upd7210_wr(u, CDOR, *ib->buf); - ib->buf++; - ib->buflen--; - return (1); - case DMA_IDATA: - if (!(u->rreg[ISR1] & IXR1_ENDRX)) - return (0); - break; - case FIFO_IDATA: - if (!(isr_3 & 0x15)) - return (0); - while (ib->buflen != 0 && (isr_3 & 0x04 /* NEF */) != 0) { - *ib->buf = bus_read_1(u->reg_res[0], fifob); - ib->buf++; - ib->buflen--; - isr_3 = bus_read_1(u->reg_res[0], isr3); - } - if ((isr_3 & 0x01) != 0 /* xfr done */ || - (u->rreg[ISR1] & IXR1_ENDRX) != 0 || - ib->buflen == 0) - break; - if (isr_3 & 0x10) - /* xfr stopped */ - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - upd7210_wr(u, AUXMR, AUXMR_RFD); - return (1); - case FIFO_CMD: - case FIFO_ODATA: - if (!(isr_3 & 0x19)) - return (0); - if (ib->buflen == 0) - /* xfr DONE */ - break; - while (ib->buflen != 0 && (isr_3 & 0x08 /* NFF */) != 0) { - bus_write_1(u->reg_res[0], fifob, *ib->buf); - ib->buf++; - ib->buflen--; - isr_3 = bus_read_1(u->reg_res[0], isr3); - } - if (isr_3 & 0x10) - /* xfr stopped */ - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - if (ib->buflen == 0) - /* no more NFF interrupts wanted */ - bus_write_1(u->reg_res[0], imr3, 0x11); /* STOP IE, DONE IE */ - return (1); - default: - return (0); - } - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); - if (u->use_fifo) { - bus_write_1(u->reg_res[0], imr3, 0x00); - bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ - } - ib->mode = BUSY; - wakeup(&ib->buflen); - return (1); -} - -static void -gpib_ib_timeout(void *arg) -{ - struct upd7210 *u; - struct ibfoo *ib; - struct timeval tv; - u_int isr_3; - - u = arg; - ib = u->ibfoo; - mtx_lock(&u->mutex); - if (ib->mode == DMA_IDATA && isa_dmatc(u->dmachan)) { - KASSERT(u->dmachan >= 0, ("Bogus dmachan = %d", u->dmachan)); - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); - ib->mode = BUSY; - wakeup(&ib->buflen); - } - if (ib->mode > BUSY) { - upd7210_rd(u, ISR1); - upd7210_rd(u, ISR2); - if (u->use_fifo) - isr_3 = bus_read_1(u->reg_res[0], isr3); - else - isr_3 = 0; - gpib_ib_irq(u, isr_3); - } - if (ib->mode != IDLE && timevalisset(&ib->deadline)) { - getmicrouptime(&tv); - if (timevalcmp(&ib->deadline, &tv, <)) { - ib_had_timeout(ib->ap); - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); - if (u->use_fifo) { - bus_write_1(u->reg_res[0], imr3, 0x00); - bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ - } - ib->mode = BUSY; - wakeup(&ib->buflen); - } - } - if (ib->mode != IDLE) - callout_reset(&ib->callout, hz / 5, gpib_ib_timeout, arg); - mtx_unlock(&u->mutex); -} - -static void -gpib_ib_wait_xfer(struct upd7210 *u, struct ibfoo *ib) -{ - int i; - - mtx_assert(&u->mutex, MA_OWNED); - while (ib->mode > BUSY) { - i = msleep(&ib->buflen, &u->mutex, - PZERO | PCATCH, "ibwxfr", 0); - if (i == EINTR) { - ib_set_errno(ib->ap, i); - break; - } - if (u->rreg[ISR1] & IXR1_ERR) { - ib_set_error(ib->ap, EABO); /* XXX ? */ - break; - } - } - if ((u->rreg[ISR1] & IXR1_ENDRX) != 0) { - ib->ap->__retval |= END; - ib->ap->__ibsta |= END; - } - if ((u->rreg[ISR2] & IXR2_SRQI) != 0) { - ib->ap->__retval |= SRQI; - ib->ap->__ibsta |= SRQI; - } - ib->mode = BUSY; - ib->buf = NULL; - upd7210_wr(u, IMR1, 0); - upd7210_wr(u, IMR2, 0); - if (u->use_fifo) - bus_write_1(u->reg_res[0], imr3, 0x00); -} - -static void -config_eos(struct upd7210 *u, struct handle *h) -{ - int i; - - i = 0; - if (h->eos & REOS) { - upd7210_wr(u, EOSR, h->eos & 0xff); - i |= AUXA_REOS; - } - if (h->eos & XEOS) { - upd7210_wr(u, EOSR, h->eos & 0xff); - i |= AUXA_XEOS; - } - if (h->eos & BIN) - i |= AUXA_BIN; - upd7210_wr(u, AUXRA, C_AUXA | i); -} - -/* - * Look up the handle, and set the deadline if the handle has a timeout. - */ -static int -gethandle(struct upd7210 *u, struct ibarg *ap, struct handle **hp) -{ - struct ibfoo *ib; - struct handle *h; - - KASSERT(ap->__field & __F_HANDLE, ("gethandle without __F_HANDLE")); - ib = u->ibfoo; - LIST_FOREACH(h, &ib->handles, list) { - if (h->handle == ap->handle) { - *hp = h; - return (0); - } - } - ib_set_error(ap, EARG); - return (1); -} - -static int -pio_cmd(struct upd7210 *u, u_char *cmd, int len) -{ - struct ibfoo *ib; - - ib = u->ibfoo; - - if (ib->rdh != NULL || ib->wrh != NULL) { - upd7210_take_ctrl_async(u); - ib->rdh = NULL; - ib->wrh = NULL; - } - mtx_lock(&u->mutex); - ib->buf = cmd; - ib->buflen = len; - if (u->use_fifo) { - /* TNT5004 or TNT4882 in FIFO mode */ - ib->mode = FIFO_CMD; - upd7210_wr(u, AUXMR, 0x51); /* holdoff immediately */ - bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ - bus_write_1(u->reg_res[0], cfg, 0x80); /* CMD, xfer OUT, 8-bit FIFO */ - bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */ - bus_write_1(u->reg_res[0], cnt0, -len); - bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); - bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); - bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - } else { - ib->mode = PIO_CMD; - upd7210_wr(u, IMR2, IXR2_CO); - gpib_ib_irq(u, 0); - } - - gpib_ib_wait_xfer(u, ib); - - if (u->use_fifo) - bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ - - mtx_unlock(&u->mutex); - return (len - ib->buflen); -} - -static int -pio_odata(struct upd7210 *u, u_char *data, int len) -{ - struct ibfoo *ib; - - ib = u->ibfoo; - - if (len == 0) - return (0); - mtx_lock(&u->mutex); - ib->buf = data; - ib->buflen = len; - if (u->use_fifo) { - /* TNT5004 or TNT4882 in FIFO mode */ - ib->mode = FIFO_ODATA; - bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ - if (ib->doeoi) - bus_write_1(u->reg_res[0], cfg, 0x08); /* CCEN */ - else - bus_write_1(u->reg_res[0], cfg, 0x00); /* xfer OUT, 8-bit FIFO */ - bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */ - bus_write_1(u->reg_res[0], cnt0, -len); - bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); - bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); - bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - } else { - ib->mode = PIO_ODATA; - upd7210_wr(u, IMR1, IXR1_DO); - } - - gpib_ib_wait_xfer(u, ib); - - if (u->use_fifo) - bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ - - mtx_unlock(&u->mutex); - return (len - ib->buflen); -} - -static int -pio_idata(struct upd7210 *u, u_char *data, int len) -{ - struct ibfoo *ib; - - ib = u->ibfoo; - - mtx_lock(&u->mutex); - ib->buf = data; - ib->buflen = len; - if (u->use_fifo) { - /* TNT5004 or TNT4882 in FIFO mode */ - ib->mode = FIFO_IDATA; - bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ - bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */ - bus_write_1(u->reg_res[0], cnt0, -len); - bus_write_1(u->reg_res[0], cnt1, (-len) >> 8); - bus_write_1(u->reg_res[0], cnt2, (-len) >> 16); - bus_write_1(u->reg_res[0], cnt3, (-len) >> 24); - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - upd7210_wr(u, AUXMR, AUXMR_RFD); - bus_write_1(u->reg_res[0], imr3, 0x15); /* STOP IE, NEF IE, DONE IE */ - } else { - ib->mode = PIO_IDATA; - upd7210_wr(u, IMR1, IXR1_DI); - } - - gpib_ib_wait_xfer(u, ib); - - if (u->use_fifo) - bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */ - - mtx_unlock(&u->mutex); - return (len - ib->buflen); -} - -static int -dma_idata(struct upd7210 *u, u_char *data, int len) -{ - int j; - struct ibfoo *ib; - - KASSERT(u->dmachan >= 0, ("Bogus dmachan %d", u->dmachan)); - ib = u->ibfoo; - ib->mode = DMA_IDATA; - isa_dmastart(ISADMA_READ, data, len, u->dmachan); - mtx_lock(&u->mutex); - upd7210_wr(u, IMR1, IXR1_ENDRX); - upd7210_wr(u, IMR2, IMR2_DMAI); - gpib_ib_wait_xfer(u, ib); - mtx_unlock(&u->mutex); - j = isa_dmastatus(u->dmachan); - isa_dmadone(ISADMA_READ, data, len, u->dmachan); - return (len - j); -} - -static int -ib_send_msg(struct ibfoo *ib, int msg) -{ - u_char buf[10]; - int i, j; - - i = 0; - buf[i++] = UNT; - buf[i++] = UNL; - buf[i++] = LAD | ib->h->pad; - if (ib->h->sad) - buf[i++] = LAD | TAD | ib->h->sad; - buf[i++] = TAD | 0; - buf[i++] = msg; - j = pio_cmd(ib->u, buf, i); - if (i != j) - ib_set_error(ib->ap, EABO); /* XXX ? */ - return (0); -} - -static int -ibask(struct ibfoo *ib) -{ /* XXX */ - - ibdebug = ib->ap->option; - return (0); -} - -#define ibbna NULL -#define ibcac NULL - -static int -ibclr(struct ibfoo *ib) -{ - - return (ib_send_msg(ib, SDC)); -} - -#define ibcmd NULL -#define ibcmda NULL -#define ibconfig NULL - -static int -ibdev(struct ibfoo *ib) -{ /* TBD */ - struct handle *h; - - h = malloc(sizeof *h, M_IBFOO, M_ZERO | M_WAITOK); - h->handle = alloc_unr(ib->unrhdr); - h->kind = H_DEV; - h->pad = ib->ap->pad; - h->sad = ib->ap->sad; - h->timeout = timeouts[ib->ap->tmo]; - h->eot = ib->ap->eot; - h->eos = ib->ap->eos; - mtx_lock(&ib->u->mutex); - LIST_INSERT_HEAD(&ib->handles, h, list); - mtx_unlock(&ib->u->mutex); - ib->ap->__retval = h->handle; - return (0); -} - -#define ibdiag NULL - -static int -ibdma(struct ibfoo *ib) -{ - - if (ib->u->dmachan < 0 && ib->ap->v) - return (ib_set_error(ib->ap, EARG)); - ib->h->dma = ib->ap->v; - return (0); -} - -static int -ibeos(struct ibfoo *ib) -{ - - ib->ap->__iberr = ib->h->eos; - ib->h->eos = ib->ap->eos; - if (ib->rdh == ib->h) - config_eos(ib->u, ib->h); - return (0); -} - -static int -ibeot(struct ibfoo *ib) -{ - - ib->h->eot = ib->ap->eot; - return (0); -} - -#define ibevent NULL -#define ibfind NULL -#define ibgts NULL -#define ibist NULL -#define iblines NULL -#define ibllo NULL -#define ibln NULL - -static int -ibloc(struct ibfoo *ib) -{ /* XXX */ - - if (ib->h->kind == H_BOARD) - return (EOPNOTSUPP); /* XXX */ - return (ib_send_msg(ib, GTL)); -} - -static int -ibonl(struct ibfoo *ib) -{ /* XXX */ - - if (ib->ap->v) - return (EOPNOTSUPP); /* XXX */ - mtx_lock(&ib->u->mutex); - LIST_REMOVE(ib->h, list); - mtx_unlock(&ib->u->mutex); - free(ib->h, M_IBFOO); - ib->h = NULL; - return (0); -} - -static int -ibpad(struct ibfoo *ib) -{ - - ib->h->pad = ib->ap->pad; - return (0); -} - -#define ibpct NULL -#define ibpoke NULL -#define ibppc NULL - -static int -ibrd(struct ibfoo *ib) -{ /* TBD */ - u_char buf[10], *bp; - int i, j, error, bl, bc; - u_char *dp; - - if (ib->h->kind == H_BOARD) - return (EOPNOTSUPP); /* XXX */ - bl = ib->ap->cnt; - if (bl > PAGE_SIZE) - bl = PAGE_SIZE; - bp = malloc(bl, M_IBFOO, M_WAITOK); - - if (ib->rdh != ib->h) { - i = 0; - buf[i++] = UNT; - buf[i++] = UNL; - buf[i++] = LAD | 0; - buf[i++] = TAD | ib->h->pad; - if (ib->h->sad) - buf[i++] = ib->h->sad; - i = pio_cmd(ib->u, buf, i); - config_eos(ib->u, ib->h); - ib->rdh = ib->h; - ib->wrh = NULL; - } - upd7210_goto_standby(ib->u); - dp = ib->ap->buffer; - bc = ib->ap->cnt; - error = 0; - while (bc > 0 && ib->ap->__iberr == 0) { - j = imin(bc, PAGE_SIZE); - if (ib->h->dma) - i = dma_idata(ib->u, bp, j); - else - i = pio_idata(ib->u, bp, j); - error = copyout(bp, dp , i); - if (error) - break; - ib->ap->__ibcnt += i; - if (i != j) - break; - bc -= i; - dp += i; - } - upd7210_take_ctrl_async(ib->u); - free(bp, M_IBFOO); - return (error); -} - -#define ibrda NULL -#define ibrdf NULL -#define ibrdkey NULL -#define ibrpp NULL -#define ibrsc NULL -#define ibrsp NULL -#define ibrsv NULL - -static int -ibsad(struct ibfoo *ib) -{ - - ib->h->sad = ib->ap->sad; - return (0); -} - -#define ibsgnl NULL - -static int -ibsic(struct ibfoo *ib) -{ /* TBD */ - - upd7210_wr(ib->u, AUXMR, AUXMR_SIFC); - DELAY(100); - upd7210_wr(ib->u, AUXMR, AUXMR_CIFC); - return (0); -} - -#define ibsre NULL -#define ibsrq NULL -#define ibstop NULL - -static int -ibtmo(struct ibfoo *ib) -{ - - ib->h->timeout = timeouts[ib->ap->tmo]; - return (0); -} - -#define ibtrap NULL - -static int -ibtrg(struct ibfoo *ib) -{ - - return (ib_send_msg(ib, GET)); -} - -#define ibwait NULL - -static int -ibwrt(struct ibfoo *ib) -{ /* XXX */ - u_char buf[10], *bp; - int i; - - if (ib->h->kind == H_BOARD) - return (EOPNOTSUPP); - bp = malloc(ib->ap->cnt, M_IBFOO, M_WAITOK); - /* XXX: bigger than PAGE_SIZE handling */ - i = copyin(ib->ap->buffer, bp, ib->ap->cnt); - if (i) { - free(bp, M_IBFOO); - return (i); - } - if (ib->wrh != ib->h) { - i = 0; - buf[i++] = UNT; - buf[i++] = UNL; - buf[i++] = LAD | ib->h->pad; - if (ib->h->sad) - buf[i++] = LAD | TAD | ib->h->sad; - buf[i++] = TAD | 0; - i = pio_cmd(ib->u, buf, i); - ib->rdh = NULL; - ib->wrh = ib->h; - config_eos(ib->u, ib->h); - } - upd7210_goto_standby(ib->u); - ib->doeoi = ib->h->eot; - i = pio_odata(ib->u, bp, ib->ap->cnt); - upd7210_take_ctrl_async(ib->u); - ib->ap->__ibcnt = i; - free(bp, M_IBFOO); - return (0); -} - -#define ibwrta NULL -#define ibwrtf NULL -#define ibwrtkey NULL -#define ibxtrc NULL - -static struct ibhandler { - const char *name; - enum h_kind kind; - ibhandler_t *func; - u_int args; -} ibhandlers[] = { - [__ID_IBASK] = { "ibask", H_EITHER, ibask, __F_HANDLE | __F_OPTION | __F_RETVAL }, - [__ID_IBBNA] = { "ibbna", H_DEV, ibbna, __F_HANDLE | __F_BDNAME }, - [__ID_IBCAC] = { "ibcac", H_BOARD, ibcac, __F_HANDLE | __F_V }, - [__ID_IBCLR] = { "ibclr", H_DEV, ibclr, __F_HANDLE }, - [__ID_IBCMD] = { "ibcmd", H_BOARD, ibcmd, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBCMDA] = { "ibcmda", H_BOARD, ibcmda, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBCONFIG] = { "ibconfig", H_EITHER, ibconfig, __F_HANDLE | __F_OPTION | __F_VALUE }, - [__ID_IBDEV] = { "ibdev", 0, ibdev, __F_BOARDID | __F_PAD | __F_SAD | __F_TMO | __F_EOT | __F_EOS }, - [__ID_IBDIAG] = { "ibdiag", H_EITHER, ibdiag, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBDMA] = { "ibdma", H_EITHER, ibdma, __F_HANDLE | __F_V }, - [__ID_IBEOS] = { "ibeos", H_EITHER, ibeos, __F_HANDLE | __F_EOS }, - [__ID_IBEOT] = { "ibeot", H_EITHER, ibeot, __F_HANDLE | __F_EOT }, - [__ID_IBEVENT] = { "ibevent", H_BOARD, ibevent, __F_HANDLE | __F_EVENT }, - [__ID_IBFIND] = { "ibfind", 0, ibfind, __F_BDNAME }, - [__ID_IBGTS] = { "ibgts", H_BOARD, ibgts, __F_HANDLE | __F_V }, - [__ID_IBIST] = { "ibist", H_BOARD, ibist, __F_HANDLE | __F_V }, - [__ID_IBLINES] = { "iblines", H_BOARD, iblines, __F_HANDLE | __F_LINES }, - [__ID_IBLLO] = { "ibllo", H_EITHER, ibllo, __F_HANDLE }, - [__ID_IBLN] = { "ibln", H_BOARD, ibln, __F_HANDLE | __F_PADVAL | __F_SADVAL | __F_LISTENFLAG }, - [__ID_IBLOC] = { "ibloc", H_EITHER, ibloc, __F_HANDLE }, - [__ID_IBONL] = { "ibonl", H_EITHER, ibonl, __F_HANDLE | __F_V }, - [__ID_IBPAD] = { "ibpad", H_EITHER, ibpad, __F_HANDLE | __F_PAD }, - [__ID_IBPCT] = { "ibpct", H_DEV, ibpct, __F_HANDLE }, - [__ID_IBPOKE] = { "ibpoke", H_EITHER, ibpoke, __F_HANDLE | __F_OPTION | __F_VALUE }, - [__ID_IBPPC] = { "ibppc", H_EITHER, ibppc, __F_HANDLE | __F_V }, - [__ID_IBRD] = { "ibrd", H_EITHER, ibrd, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBRDA] = { "ibrda", H_EITHER, ibrda, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBRDF] = { "ibrdf", H_EITHER, ibrdf, __F_HANDLE | __F_FLNAME }, - [__ID_IBRDKEY] = { "ibrdkey", H_EITHER, ibrdkey, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBRPP] = { "ibrpp", H_EITHER, ibrpp, __F_HANDLE | __F_PPR }, - [__ID_IBRSC] = { "ibrsc", H_BOARD, ibrsc, __F_HANDLE | __F_V }, - [__ID_IBRSP] = { "ibrsp", H_DEV, ibrsp, __F_HANDLE | __F_SPR }, - [__ID_IBRSV] = { "ibrsv", H_EITHER, ibrsv, __F_HANDLE | __F_V }, - [__ID_IBSAD] = { "ibsad", H_EITHER, ibsad, __F_HANDLE | __F_SAD }, - [__ID_IBSGNL] = { "ibsgnl", H_EITHER, ibsgnl, __F_HANDLE | __F_V }, - [__ID_IBSIC] = { "ibsic", H_BOARD, ibsic, __F_HANDLE }, - [__ID_IBSRE] = { "ibsre", H_BOARD, ibsre, __F_HANDLE | __F_V }, - [__ID_IBSRQ] = { "ibsrq", H_EITHER, ibsrq, __F_FUNC }, - [__ID_IBSTOP] = { "ibstop", H_EITHER, ibstop, __F_HANDLE }, - [__ID_IBTMO] = { "ibtmo", H_EITHER, ibtmo, __F_HANDLE | __F_TMO }, - [__ID_IBTRAP] = { "ibtrap", H_EITHER, ibtrap, __F_MASK | __F_MODE }, - [__ID_IBTRG] = { "ibtrg", H_DEV, ibtrg, __F_HANDLE }, - [__ID_IBWAIT] = { "ibwait", H_EITHER, ibwait, __F_HANDLE | __F_MASK }, - [__ID_IBWRT] = { "ibwrt", H_EITHER, ibwrt, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBWRTA] = { "ibwrta", H_EITHER, ibwrta, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBWRTF] = { "ibwrtf", H_EITHER, ibwrtf, __F_HANDLE | __F_FLNAME }, - [__ID_IBWRTKEY] = { "ibwrtkey", H_EITHER, ibwrtkey, __F_HANDLE | __F_BUFFER | __F_CNT }, - [__ID_IBXTRC] = { "ibxtrc", H_EITHER, ibxtrc, __F_HANDLE | __F_BUFFER | __F_CNT }, -}; - -static const u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0]; - -static void -ib_dump_args(struct ibhandler *ih, struct ibarg *ap) -{ - - if (ih->name != NULL) - printf("%s(", ih->name); - else - printf("ibinvalid("); - printf("[0x%x]", ap->__field); - if (ap->__field & __F_HANDLE) printf(" handle=%d", ap->handle); - if (ap->__field & __F_EOS) printf(" eos=0x%x", ap->eos); - if (ap->__field & __F_EOT) printf(" eot=%d", ap->eot); - if (ap->__field & __F_TMO) printf(" tmo=%d", ap->tmo); - if (ap->__field & __F_PAD) printf(" pad=0x%x", ap->pad); - if (ap->__field & __F_SAD) printf(" sad=0x%x", ap->sad); - if (ap->__field & __F_BUFFER) printf(" buffer=%p", ap->buffer); - if (ap->__field & __F_CNT) printf(" cnt=%ld", ap->cnt); - if (ap->__field & __F_V) printf(" v=%d/0x%x", ap->v, ap->v); - /* XXX more ... */ - printf(")\n"); -} - -static int -gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct upd7210 *u; - struct ibfoo *ib; - int error = 0; - - u = dev->si_drv1; - - mtx_lock(&u->mutex); - if (u->busy) { - mtx_unlock(&u->mutex); - return (EBUSY); - } - u->busy = 1; - mtx_unlock(&u->mutex); - - if (u->dmachan >= 0) { - error = isa_dma_acquire(u->dmachan); - if (!error) { - error = isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK); - if (error) - isa_dma_release(u->dmachan); - } - } - - if (error) { - mtx_lock(&u->mutex); - u->busy = 0; - mtx_unlock(&u->mutex); - return (error); - } - - ib = malloc(sizeof *ib, M_IBFOO, M_WAITOK | M_ZERO); - LIST_INIT(&ib->handles); - callout_init(&ib->callout, CALLOUT_MPSAFE); - ib->unrhdr = new_unrhdr(0, INT_MAX, NULL); - dev->si_drv2 = ib; - ib->u = u; - u->ibfoo = ib; - u->irq = gpib_ib_irq; - - upd7210_wr(u, AUXMR, AUXMR_CRST); - DELAY(10000); - DELAY(1000); - upd7210_wr(u, IMR1, 0x00); - upd7210_wr(u, IMR2, 0x00); - upd7210_wr(u, SPMR, 0x00); - upd7210_wr(u, ADR, 0x00); - upd7210_wr(u, ADR, ADR_ARS | ADR_DL | ADR_DT); - upd7210_wr(u, ADMR, ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1); - upd7210_wr(u, EOSR, 0x00); - upd7210_wr(u, AUXMR, C_ICR | 8); - upd7210_wr(u, AUXMR, C_PPR | PPR_U); - upd7210_wr(u, AUXMR, C_AUXA); - upd7210_wr(u, AUXMR, C_AUXB + 3); - upd7210_wr(u, AUXMR, C_AUXE + 0); - upd7210_wr(u, AUXMR, AUXMR_PON); - if (u->use_fifo) { - bus_write_1(u->reg_res[0], imr3, 0x00); - bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft reset */ - bus_write_1(u->reg_res[0], cmdr, 0x03); /* set system - * controller bit */ - } - upd7210_wr(u, AUXMR, AUXMR_CIFC); - DELAY(100); - upd7210_wr(u, AUXMR, AUXMR_SIFC); - upd7210_wr(u, AUXMR, AUXMR_SREN); - return (0); -} - -static int -gpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct upd7210 *u; - struct ibfoo *ib; - - u = dev->si_drv1; - ib = dev->si_drv2; - /* XXX: assert pointer consistency */ - - u->ibfoo = NULL; - /* XXX: free handles */ - dev->si_drv2 = NULL; - free(ib, M_IBFOO); - - if (u->dmachan >= 0) { - isa_dma_release(u->dmachan); - } - mtx_lock(&u->mutex); - u->busy = 0; - ibdebug = 0; - upd7210_wr(u, IMR1, 0x00); - upd7210_wr(u, IMR2, 0x00); - if (u->use_fifo) { - bus_write_1(u->reg_res[0], imr3, 0x00); - bus_write_1(u->reg_res[0], cmdr, 0x02); /* clear system - * controller bit */ - } - upd7210_wr(u, AUXMR, AUXMR_CRST); - DELAY(10000); - mtx_unlock(&u->mutex); - return (0); -} - -static int -gpib_ib_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) -{ - struct ibarg *ap; - struct ibhandler *ih; - struct handle *h; - struct upd7210 *u; - struct ibfoo *ib; - int error; - struct timeval deadline, tv; - - u = dev->si_drv1; - ib = u->ibfoo; - - /* We only support a single ioctl, everything else is a mistake */ - if (cmd != GPIB_IBFOO) - return (ENOIOCTL); - - /* Check the identifier and field-bitmap in the arguments. */ - ap = (void *)data; - if (ap->__ident < 0 || ap->__ident >= max_ibhandler) - return (EINVAL); - ih = &ibhandlers[ap->__ident]; - if (ap->__field != ih->args) - return (EINVAL); - - if (ibdebug) - ib_dump_args(ih, ap); - - if (ih->func == NULL) - return (EOPNOTSUPP); - - ap->__iberr = 0; - ap->__ibsta = 0; - ap->__ibcnt = 0; - ap->__retval = 0; - - if (ap->__field & __F_TMO) { - if (ap->tmo < 0 || ap->tmo >= max_timeouts) - return (ib_set_error(ap, EARG)); - } - - if (ap->__field & __F_EOS) { - if ((ap->eos & ~(REOS | XEOS | BIN | 0xff)) || - ((ap->eos & (BIN | 0x80)) == 0x80)) - return (ib_set_error(ap, EARG)); - } - if (ap->__field & __F_PAD) { - if (ap->pad < 0 || ap->pad > 30) - return (ib_set_error(ap, EARG)); - } - if (ap->__field & __F_SAD) { - if (ap->sad != 0 && (ap->sad < 0x60 || ap->sad > 126)) - return (ib_set_error(ap, EARG)); - } - - - mtx_lock(&u->mutex); - - - /* Find the handle, if any */ - h = NULL; - if ((ap->__field & __F_HANDLE) && gethandle(u, ap, &h)) { - mtx_unlock(&u->mutex); - return (0); - } - - /* Check that the handle is the right kind */ - if (h != NULL && !(h->kind & ih->kind)) { - mtx_unlock(&u->mutex); - return (ib_set_error(ap, EARG)); - } - - /* Set up handle and deadline */ - if (h != NULL && timevalisset(&h->timeout)) { - getmicrouptime(&deadline); - timevaladd(&deadline, &h->timeout); - } else { - timevalclear(&deadline); - } - - /* Wait for the card to be(come) available, respect deadline */ - while(u->busy != 1) { - error = msleep(ib, &u->mutex, - PZERO | PCATCH, "gpib_ibioctl", hz / 10); - if (error == 0) - continue; - mtx_unlock(&u->mutex); - if (error == EINTR) - return(ib_set_error(ap, EABO)); - if (error == EWOULDBLOCK && timevalisset(&deadline)) { - getmicrouptime(&tv); - if (timevalcmp(&deadline, &tv, <)) - return(ib_had_timeout(ap)); - } - mtx_lock(&u->mutex); - } - u->busy = 2; - mtx_unlock(&u->mutex); - - /* Hand over deadline handling to the callout routine */ - ib->ap = ap; - ib->h = h; - ib->mode = BUSY; - ib->deadline = deadline; - callout_reset(&ib->callout, hz / 5, gpib_ib_timeout, u); - - error = ih->func(ib); - - /* Release card */ - ib->mode = IDLE; - ib->ap = NULL; - ib->h = NULL; - timevalclear(&deadline); - callout_stop(&ib->callout); - - mtx_lock(&u->mutex); - u->busy = 1; - wakeup(ib); - mtx_unlock(&u->mutex); - - if (error) - return(ib_set_errno(ap, error)); - return (0); -} - -struct cdevsw gpib_ib_cdevsw = { - .d_version = D_VERSION, - .d_name = "gpib_ib", - .d_open = gpib_ib_open, - .d_ioctl = gpib_ib_ioctl, - .d_close = gpib_ib_close, -}; diff --git a/sys/dev/ieee488/ibfoo_int.h b/sys/dev/ieee488/ibfoo_int.h deleted file mode 100644 index 28f72897a9d..00000000000 --- a/sys/dev/ieee488/ibfoo_int.h +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file defines the ABI between the userland gpib library and the - * kernel. This file should not be used anywhere else. - * - * $FreeBSD$ - */ - -#include - -typedef void ibsrq_t(void); -enum ibfoo_id { - __ID_INVALID = 0, - __ID_IBASK, - __ID_IBBNA, - __ID_IBCAC, - __ID_IBCLR, - __ID_IBCMD, - __ID_IBCMDA, - __ID_IBCONFIG, - __ID_IBDEV, - __ID_IBDIAG, - __ID_IBDMA, - __ID_IBEOS, - __ID_IBEOT, - __ID_IBEVENT, - __ID_IBFIND, - __ID_IBGTS, - __ID_IBIST, - __ID_IBLINES, - __ID_IBLLO, - __ID_IBLN, - __ID_IBLOC, - __ID_IBONL, - __ID_IBPAD, - __ID_IBPCT, - __ID_IBPOKE, - __ID_IBPPC, - __ID_IBRD, - __ID_IBRDA, - __ID_IBRDF, - __ID_IBRDKEY, - __ID_IBRPP, - __ID_IBRSC, - __ID_IBRSP, - __ID_IBRSV, - __ID_IBSAD, - __ID_IBSGNL, - __ID_IBSIC, - __ID_IBSRE, - __ID_IBSRQ, - __ID_IBSTOP, - __ID_IBTMO, - __ID_IBTRAP, - __ID_IBTRG, - __ID_IBWAIT, - __ID_IBWRT, - __ID_IBWRTA, - __ID_IBWRTF, - __ID_IBWRTKEY, - __ID_IBXTRC -}; - -#define __F_HANDLE (1 << 0) -#define __F_SPR (1 << 1) -#define __F_BUFFER (1 << 2) -#define __F_RETVAL (1 << 3) -#define __F_BDNAME (1 << 4) -#define __F_MASK (1 << 5) -#define __F_PADVAL (1 << 6) -#define __F_SADVAL (1 << 7) -#define __F_CNT (1 << 8) -#define __F_TMO (1 << 9) -#define __F_EOS (1 << 10) -#define __F_PPR (1 << 11) -#define __F_EOT (1 << 12) -#define __F_V (1 << 13) -#define __F_VALUE (1 << 14) -#define __F_SAD (1 << 15) -#define __F_BOARDID (1 << 16) -#define __F_OPTION (1 << 17) -#define __F_FLNAME (1 << 18) -#define __F_FUNC (1 << 19) -#define __F_LINES (1 << 20) -#define __F_PAD (1 << 21) -#define __F_MODE (1 << 22) -#define __F_LISTENFLAG (1 << 23) -#define __F_EVENT (1 << 24) - -struct ibarg { - enum ibfoo_id __ident; - unsigned int __field; - int __retval; - int __ibsta; - int __iberr; - int __ibcnt; - int handle; - char * spr; - void * buffer; - int * retval; - char * bdname; - int mask; - int padval; - int sadval; - long cnt; - int tmo; - int eos; - char * ppr; - int eot; - int v; - int value; - int sad; - int boardID; - int option; - char * flname; - ibsrq_t * func; - short * lines; - int pad; - int mode; - short * listenflag; - short * event; -}; - -#define GPIB_IBFOO _IOWR(4, 0, struct ibarg) diff --git a/sys/dev/ieee488/pcii.c b/sys/dev/ieee488/pcii.c deleted file mode 100644 index 833ec9194f6..00000000000 --- a/sys/dev/ieee488/pcii.c +++ /dev/null @@ -1,255 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * Copyright (c) 2010 Joerg Wunsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Driver for GPIB cards based on NEC µPD7210 and compatibles. - * - * This driver just hooks up to the hardware and leaves all the interesting - * stuff to upd7210.c. - * - * Supported hardware: - * PCIIA compatible cards. - * - * Tested and known working: - * "B&C Microsystems PC488A-0" - * "National Instruments GPIB-PCII/PCIIA" (in PCIIa mode) - * "Axiom AX5488" - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define UPD7210_HW_DRIVER -#include - -struct pcii_softc { - int foo; - struct resource *res[11]; - void *intr_handler; - struct upd7210 upd7210; -}; - -static devclass_t pcii_devclass; - -static int pcii_probe(device_t dev); -static int pcii_attach(device_t dev); - -static device_method_t pcii_methods[] = { - DEVMETHOD(device_probe, pcii_probe), - DEVMETHOD(device_attach, pcii_attach), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - { 0, 0 } -}; - -static struct resource_spec pcii_res_spec[] = { - { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE}, - { SYS_RES_DRQ, 0, RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL}, - { SYS_RES_IOPORT, 0, RF_ACTIVE}, - { SYS_RES_IOPORT, 1, RF_ACTIVE}, - { SYS_RES_IOPORT, 2, RF_ACTIVE}, - { SYS_RES_IOPORT, 3, RF_ACTIVE}, - { SYS_RES_IOPORT, 4, RF_ACTIVE}, - { SYS_RES_IOPORT, 5, RF_ACTIVE}, - { SYS_RES_IOPORT, 6, RF_ACTIVE}, - { SYS_RES_IOPORT, 7, RF_ACTIVE}, - { SYS_RES_IOPORT, 8, RF_ACTIVE | RF_SHAREABLE}, - { -1, 0, 0 } -}; - -static driver_t pcii_driver = { - "pcii", - pcii_methods, - sizeof(struct pcii_softc), -}; - -static int -pcii_probe(device_t dev) -{ - int rid, i, j; - u_long start, count, addr; - int error = 0; - struct pcii_softc *sc; - - device_set_desc(dev, "PCII IEEE-4888 controller"); - sc = device_get_softc(dev); - - rid = 0; - if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0) - return ENXIO; - /* - * The PCIIA decodes a fixed pattern of 0x2e1 for the lower 10 - * address bits A0 ... A9. Bits A10 through A12 are used by - * the µPD7210 register select lines. This makes the - * individual 7210 register being 0x400 bytes apart in the ISA - * bus address space. Address bits A13 and A14 are compared - * to a DIP switch setting on the card, allowing for up to 4 - * different cards being installed (at base addresses 0x2e1, - * 0x22e1, 0x42e1, and 0x62e1, respectively). A15 has been - * used to select an optional on-board time-of-day clock chip - * (MM58167A) on the original PCIIA rather than the µPD7210 - * (which is not implemented on later boards). The - * documentation states the respective addresses for that chip - * should be handled as reserved addresses, which we don't do - * (right now). Finally, the IO addresses 0x2f0 ... 0x2f7 for - * a "special interrupt handling feature" (re-enable - * interrupts so the IRQ can be shared). - * - * Usually, the user will only set the base address in the - * device hints, so we handle the rest here. - * - * (Source: GPIB-PCIIA Technical Reference Manual, September - * 1989 Edition, National Instruments.) - */ - if ((start & 0x3ff) != 0x2e1) { - if (bootverbose) - printf("pcii_probe: PCIIA base address 0x%lx not " - "0x2e1/0x22e1/0x42e1/0x62e1\n", - start); - return (ENXIO); - } - - for (rid = 0, addr = start; rid < 8; rid++, addr += 0x400) { - if (bus_set_resource(dev, SYS_RES_IOPORT, rid, addr, 1) != 0) { - printf("pcii_probe: could not set IO port 0x%lx\n", - addr); - return (ENXIO); - } - } - if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) { - printf("pcii_probe: cannot obtain IRQ level\n"); - return ENXIO; - } - if (start > 7) { - printf("pcii_probe: IRQ level %lu too high\n", start); - return ENXIO; - } - - if (bus_set_resource(dev, SYS_RES_IOPORT, 8, 0x2f0 + start, 1) != 0) { - printf("pcii_probe: could not set IO port 0x%3lx\n", - 0x2f0 + start); - return (ENXIO); - } - - error = bus_alloc_resources(dev, pcii_res_spec, sc->res); - if (error) { - printf("pcii_probe: Could not allocate resources\n"); - return (error); - } - error = ENXIO; - /* - * Perform some basic tests on the µPD7210 registers. At - * least *some* register must read different from 0x00 or - * 0xff. - */ - for (i = 0; i < 8; i++) { - j = bus_read_1(sc->res[2 + i], 0); - if (j != 0x00 && j != 0xff) - error = 0; - } - /* SPSR/SPMR read/write test */ - if (!error) { - bus_write_1(sc->res[2 + 3], 0, 0x55); - if (bus_read_1(sc->res[2 + 3], 0) != 0x55) - error = ENXIO; - } - if (!error) { - bus_write_1(sc->res[2 + 3], 0, 0xaa); - if (bus_read_1(sc->res[2 + 3], 0) != 0xaa) - error = ENXIO; - } - if (error) - printf("pcii_probe: probe failure\n"); - - bus_release_resources(dev, pcii_res_spec, sc->res); - return (error); -} - -static int -pcii_attach(device_t dev) -{ - struct pcii_softc *sc; - u_long start, count; - int unit; - int rid; - int error = 0; - - unit = device_get_unit(dev); - sc = device_get_softc(dev); - memset(sc, 0, sizeof *sc); - - device_set_desc(dev, "PCII IEEE-4888 controller"); - - if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) { - printf("pcii_attach: cannot obtain IRQ number\n"); - return ENXIO; - } - - error = bus_alloc_resources(dev, pcii_res_spec, sc->res); - if (error) - return (error); - - error = bus_setup_intr(dev, sc->res[0], - INTR_TYPE_MISC | INTR_MPSAFE, NULL, - upd7210intr, &sc->upd7210, &sc->intr_handler); - if (error) { - bus_release_resources(dev, pcii_res_spec, sc->res); - return (error); - } - - for (rid = 0; rid < 8; rid++) { - sc->upd7210.reg_res[rid] = sc->res[2 + rid]; - sc->upd7210.reg_offset[rid] = 0; - } - sc->upd7210.irq_clear_res = sc->res[10]; - sc->upd7210.use_fifo = 0; - - if (sc->res[1] == NULL) - sc->upd7210.dmachan = -1; - else - sc->upd7210.dmachan = rman_get_start(sc->res[1]); - - upd7210attach(&sc->upd7210); - device_printf(dev, "attached gpib%d\n", sc->upd7210.unit); - - return (0); -} - -DRIVER_MODULE(pcii, isa, pcii_driver, pcii_devclass, 0, 0); -DRIVER_MODULE(pcii, acpi, pcii_driver, pcii_devclass, 0, 0); diff --git a/sys/dev/ieee488/tnt4882.c b/sys/dev/ieee488/tnt4882.c deleted file mode 100644 index 4b69d0dbd00..00000000000 --- a/sys/dev/ieee488/tnt4882.c +++ /dev/null @@ -1,320 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * Copyright (c) 2010 Joerg Wunsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* vtophys */ -#include -#include -#include - -#define UPD7210_HW_DRIVER 1 -#include -#include - -struct tnt_softc { - int foo; - struct upd7210 upd7210; - - struct resource *res[3]; - void *intr_handler; -}; - -static struct resource_spec tnt_res_spec[] = { - { SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE}, - { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE}, - { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE}, - { -1, 0 } -}; - -struct tst { - enum {RD, WT, xDELAY, END} - action; - enum tnt4882reg reg; - uint8_t val; -}; - -/* - * From NI Application note 095: - * Writing Functional Self-Tests for the TNT4882 GPIB Interface Chip - * XXX: fill in the rest ? - */ -static struct tst tst_reset[] = { - {WT, tauxcr, 0x80}, /* chip reset if in 9914 mode */ - {WT, auxmr, 0x80}, /* swrst if swapped */ - {WT, tauxcr, 0x99}, /* switch to 7210 mode */ - {WT, auxmr, 0x99}, /* switch to 7210 mode if swapped */ - {WT, auxmr, 0x02}, /* execute chip reset */ - {WT, keyreg, 0x00}, /* important! clear the swap bit */ - {WT, eosr, 0x00}, /* clear EOS register */ - {WT, cdor, 0x00}, /* clear data lines */ - {WT, imr1, 0x00}, /* disable all interrupts */ - {WT, imr2, 0x00}, - {WT, imr0, 0x80}, - {WT, adr, 0x80}, - {WT, adr, 0x00}, - {WT, admr, 0x00}, /* clear addressing modes */ - {WT, auxmr, 0x00}, /* release from idle state with pon */ - {WT, auxmr, 0x60}, /* reset ppr */ - {WT, bcr, 0x00}, /* reset bcr */ - {WT, misc, 0x04}, /* set wrap plug bit */ - {WT, cmdr, 0xB2}, /* issue soft reset */ - {WT, hssel, 0x00}, /* select two-chip mode */ - {END, 0, 0} -}; - -static struct tst tst_read_reg[] = { - {RD, isr1, 0x00}, /* Verify mask registers are clear */ - {RD, isr2, 0x00}, - {RD, adsr, 0x40}, /* Verify ATN is not asserted */ - {RD, adr0, 0x00}, /* Verify Primary address not set */ - {RD, adr1, 0x00}, /* Verify Secondary address not set */ - {RD, sts1, 0x8B}, /* Verify DONE, STOP, HALT, and GSYNC set */ - {RD, isr3, 0x19}, /* Verify STOP, Not Full FIFO, & DONE set */ - {RD, sts2, 0x9A}, /* Verify FIFO A/B is empty */ - {RD, sasr, 0x00}, /* Verify clear */ - {RD, isr0, 0x01}, /* Verify SYNC bit is set */ - {END, 0, 0} -}; - -static struct tst tst_bsr_dcr[] = { - {WT, bcr, 0x55}, /* Set DAV, NRFD, SRQ, and REN */ - {WT, dcr, 0xAA}, /* Write pattern to GPIB data lines */ - {RD, bsr, 0x55}, /* Verify DAV, NRFD, SRQ, and REN are set */ - {RD, dsr, 0xAA}, /* Verify data pattern written previously */ - {WT, bcr, 0xAA}, /* Set ATN, NDAC, EOI, & IFC */ - {WT, dcr, 0x55}, /* Write pattern to GPIB data lines */ - {RD, bsr, 0xAA}, /* Verify ATN, NDAC, EOI, & IFC are set */ - {RD, dsr, 0x55}, /* Verify data pattern written previously */ - {WT, bcr, 0x00}, /* Clear control lines */ - {WT, dcr, 0x00}, /* Clear data lines */ - {RD, bsr, 0x00}, /* Verify control lines are clear */ - {RD, dsr, 0x00}, /* Verify data lines are clear */ - {END, 0, 0} -}; - -static struct tst tst_adr0_1[] = { - {WT, adr, 0x55}, /* Set Primary talk address */ - {WT, adr, 0xAA}, /* Set Secondary listen address */ - {RD, adr0, 0x55}, /* Read Primary address */ - {RD, adr1, 0x2A}, /* Read Secondary address */ - {WT, adr, 0x2A}, /* Set Primay listen address */ - {WT, adr, 0xD5}, /* Set Secondary talk address */ - {RD, adr0, 0x2A}, /* Read Primary address */ - {RD, adr1, 0x55}, /* Read Secondary address */ - {END, 0, 0} -}; - -static struct tst tst_cdor_dir[] = { - {WT, admr, 0xF0}, /* program AT-GPIB as talker only and - * listener only */ - {RD, isr1, 0x02}, /* check DO bit set */ - {RD, adsr, 0x46}, /* check AT-GPIB is both talker active - * and listener active */ - {WT, cdor, 0xAA}, /* write out data byte */ - {xDELAY, 0, 1}, /* One ISA I/O Cycle (500-ns) */ - {RD, isr1, 0x03}, /* check DO and DI bits set */ - {RD, dir, 0xAA}, /* verify data received */ - {WT, cdor, 0x55}, /* write out data byte */ - {xDELAY, 0, 1}, /* One ISA I/O Cycle (500-ns) */ - {RD, dir, 0x55}, /* verify data received */ - {END, 0, 0} -}; - -static struct tst tst_spmr_spsr[] = { - {WT, spsr, 0x00}, /* Write pattern to SPSR register */ - {RD, spmr, 0x00}, /* Read back previously written pattern */ - {WT, spsr, 0xBF}, /* Write pattern to SPSR register */ - {RD, spmr, 0xBF}, /* Read back previously written pattern */ - {END, 0, 0} -}; - -static struct tst tst_count0_1[] = { - {WT, cnt0, 0x55}, /* Verify every other bit can be set */ - {WT, cnt1, 0xAA}, - {RD, cnt0, 0x55}, /* Read back previously written pattern */ - {RD, cnt1, 0xAA}, - {WT, cnt0, 0xAA}, /* Verify every other bit can be set */ - {WT, cnt1, 0x55}, - {RD, cnt0, 0xAA}, /* Read back previously written pattern */ - {RD, cnt1, 0x55}, - {END, 0, 0} -}; - -static int -tst_exec(struct tnt_softc *sc, struct tst *tp, const char *name) -{ - uint8_t u; - int step; - - for (step = 0; tp->action != END; tp++, step++) { - switch (tp->action) { - case WT: - bus_write_1(sc->res[1], tp->reg, tp->val); - break; - case RD: - u = bus_read_1(sc->res[1], tp->reg); - if (u != tp->val) { - printf( - "Test %s, step %d: reg(%02x) = %02x", - name, step, tp->reg, u); - printf( "should have been %02x\n", tp->val); - return (1); - } - break; - case xDELAY: - DELAY(tp->val); - break; - default: - printf("Unknown action in test %s, step %d: %d\n", - name, step, tp->action); - return (1); - } - } - if (bootverbose) - printf("Test %s passed\n", name); - return (0); -} - -static int -tnt_probe(device_t dev) -{ - - if (pci_get_vendor(dev) == 0x1093 && pci_get_device(dev) == 0xc801) { - device_set_desc(dev, "NI PCI-GPIB"); - return (BUS_PROBE_DEFAULT); - } - return (ENXIO); -} - -static int -tnt_attach(device_t dev) -{ - struct tnt_softc *sc; - int error, i; - uint8_t version; - - sc = device_get_softc(dev); - - error = bus_alloc_resources(dev, tnt_res_spec, sc->res); - if (error) - return (error); - - error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_MISC | INTR_MPSAFE, - NULL, upd7210intr, &sc->upd7210, &sc->intr_handler); - - /* IO Device Window Base Size Register (IODWBSR) */ - bus_write_4(sc->res[0], 0xc0, rman_get_start(sc->res[1]) | 0x80); - - tst_exec(sc, tst_reset, "Reset"); - tst_exec(sc, tst_read_reg, "Read registers"); - tst_exec(sc, tst_bsr_dcr, "BSR & DCR"); - tst_exec(sc, tst_adr0_1, "ADR0,1"); - tst_exec(sc, tst_cdor_dir, "CDOR/DIR"); - tst_exec(sc, tst_spmr_spsr, "CPMR/SPSR"); - tst_exec(sc, tst_count0_1, "COUNT0:1"); - tst_exec(sc, tst_reset, "Reset"); - - version = bus_read_1(sc->res[1], csr); - version = (version >> 4) & 0x0f; - device_printf(dev, "Chip version 0x%02x (TNT%s)\n", - version, - version >= 4? "5004 or above": "4882"); - if (version >= 4) { - device_printf(dev, "Forcing FIFO mode\n"); - sc->upd7210.use_fifo = 1; - } else { - sc->upd7210.use_fifo = 0; - } - - /* pass 7210 interrupts through */ - bus_write_1(sc->res[1], imr3, 0x02); - - for (i = 0; i < 8; i++) { - sc->upd7210.reg_res[i] = sc->res[1]; - sc->upd7210.reg_offset[i] = i * 2; - } - - /* No DMA help */ - sc->upd7210.dmachan = -1; - - /* No "special interrupt handling" needed here. */ - sc->upd7210.irq_clear_res = NULL; - - upd7210attach(&sc->upd7210); - device_printf(dev, "attached gpib%d\n", sc->upd7210.unit); - - if (sc->upd7210.use_fifo) - bus_write_1(sc->res[0], hssel, 0x01); /* one-chip mode */ - - - return (0); -} - -static int -tnt_detach(device_t dev) -{ - struct tnt_softc *sc; - - sc = device_get_softc(dev); - bus_teardown_intr(dev, sc->res[2], sc->intr_handler); - upd7210detach(&sc->upd7210); - - bus_release_resources(dev, tnt_res_spec, sc->res); - - return (0); -} - -static device_method_t tnt4882_methods[] = { - DEVMETHOD(device_probe, tnt_probe), - DEVMETHOD(device_attach, tnt_attach), - DEVMETHOD(device_detach, tnt_detach), - { 0, 0 } -}; - -static driver_t pci_gpib_driver = { - "tnt4882", - tnt4882_methods, - sizeof(struct tnt_softc) -}; - -static devclass_t pci_gpib_devclass; - -DRIVER_MODULE(pci_gpib, pci, pci_gpib_driver, pci_gpib_devclass, 0, 0); diff --git a/sys/dev/ieee488/tnt4882.h b/sys/dev/ieee488/tnt4882.h deleted file mode 100644 index 221cfd943cc..00000000000 --- a/sys/dev/ieee488/tnt4882.h +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * Copyright (c) 2010 Joerg Wunsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -enum tnt4882reg { - dir = 0x00, - cdor = 0x00, - isr1 = 0x02, - imr1 = 0x02, - isr2 = 0x04, - imr2 = 0x04, - accwr = 0x05, - spsr = 0x06, - spmr = 0x06, - intr = 0x07, - adsr = 0x08, - admr = 0x08, - cnt2 = 0x09, - cptr = 0x0a, - auxmr = 0x0a, - tauxcr = 0x0a, /* 9914 mode register */ - cnt3 = 0x0b, - adr0 = 0x0c, - adr = 0x0c, - hssel = 0x0d, - adr1 = 0x0e, - eosr = 0x0e, - sts1 = 0x10, - cfg = 0x10, - dsr = 0x11, - sh_cnt = 0x11, - imr3 = 0x12, - hier = 0x13, - cnt0 = 0x14, - misc = 0x15, - cnt1 = 0x16, - csr = 0x17, - keyreg = 0x17, - fifob = 0x18, - fifoa = 0x19, - isr3 = 0x1a, - ccr = 0x1a, - sasr = 0x1b, - dcr = 0x1b, - sts2 = 0x1c, - cmdr = 0x1c, - isr0 = 0x1d, - imr0 = 0x1d, - timer = 0x1e, - bsr = 0x1f, - bcr = 0x1f -}; - diff --git a/sys/dev/ieee488/ugpib.h b/sys/dev/ieee488/ugpib.h deleted file mode 100644 index 726a70219dd..00000000000 --- a/sys/dev/ieee488/ugpib.h +++ /dev/null @@ -1,155 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -#ifndef _DEV_IEEE488_UGPIB_H_ -#define _DEV_IEEE488_UGPIB_H_ - -/* ibfoo() return values */ -#define EDVR 0 /* System error */ -#define ECIC 1 /* Not Active Controller */ -#define ENOL 2 /* Nobody listening */ -#define EADR 3 /* Controller not addressed */ -#define EARG 4 /* Invalid argument */ -#define ESAC 5 /* Not System Controller */ -#define EABO 6 /* I/O Aborted/Time out */ -#define ENEB 7 /* No such controller */ -#define EOIP 10 /* Async I/O in progress */ -#define ECAP 11 /* No such capability */ -#define EFSO 12 /* File system error */ -#define EBUS 14 /* Command byte xfer error */ -#define ESTB 15 /* Serial poll status byte lost */ -#define ESRQ 16 /* SRQ line stuck */ -#define ETAB 20 /* Table problem */ - -/* ibsta bits */ -#define ERR (1<<15) /* Error */ -#define TIMO (1<<14) /* Timeout */ -#define END (1<<13) /* EOI/EOS */ -#define SRQI (1<<12) /* SRQ */ -#define RQS (1<<11) /* Device requests service */ -#define SPOLL (1<<10) /* Serial Poll */ -#define EVENT (1<<9) /* Event occured */ -#define CMPL (1<<8) /* I/O complete */ -#define LOK (1<<7) /* Lockout */ -#define REM (1<<6) /* Remote */ -#define CIC (1<<5) /* CIC */ -#define ATN (1<<4) /* ATN */ -#define TACS (1<<3) /* Talker */ -#define LACS (1<<2) /* Listener */ -#define DTAS (1<<1) /* Device trigger status */ -#define DCAS (1<<0) /* Device clear state */ - -/* Timeouts */ -#define TNONE 0 -#define T10us 1 -#define T30us 2 -#define T100us 3 -#define T300us 4 -#define T1ms 5 -#define T3ms 6 -#define T10ms 7 -#define T30ms 8 -#define T100ms 9 -#define T300ms 10 -#define T1s 11 -#define T3s 12 -#define T10s 13 -#define T30s 14 -#define T100s 15 -#define T300s 16 -#define T1000s 17 - -/* EOS bits */ -#define REOS (1 << 10) -#define XEOS (1 << 11) -#define BIN (1 << 12) - -/* Bus commands */ -#define GTL 0x01 /* Go To Local */ -#define SDC 0x04 /* Selected Device Clear */ -#define GET 0x08 /* Group Execute Trigger */ -#define LAD 0x20 /* Listen address */ -#define UNL 0x3F /* Unlisten */ -#define TAD 0x40 /* Talk address */ -#define UNT 0x5F /* Untalk */ - -#ifndef _KERNEL - -extern int ibcnt, iberr, ibsta; - -int ibask(int handle, int option, int *retval); -int ibbna(int handle, char *bdname); -int ibcac(int handle, int v); -int ibclr(int handle); -int ibcmd(int handle, void *buffer, long cnt); -int ibcmda(int handle, void *buffer, long cnt); -int ibconfig(int handle, int option, int value); -int ibdev(int boardID, int pad, int sad, int tmo, int eot, int eos); -int ibdiag(int handle, void *buffer, long cnt); -int ibdma(int handle, int v); -int ibeos(int handle, int eos); -int ibeot(int handle, int eot); -int ibevent(int handle, short *event); -int ibfind(char *bdname); -int ibgts(int handle, int v); -int ibist(int handle, int v); -int iblines(int handle, short *lines); -int ibllo(int handle); -int ibln(int handle, int padval, int sadval, short *listenflag); -int ibloc(int handle); -int ibonl(int handle, int v); -int ibpad(int handle, int pad); -int ibpct(int handle); -int ibpoke(int handle, int option, int value); -int ibppc(int handle, int v); -int ibrd(int handle, void *buffer, long cnt); -int ibrda(int handle, void *buffer, long cnt); -int ibrdf(int handle, char *flname); -int ibrdkey(int handle, void *buffer, int cnt); -int ibrpp(int handle, char *ppr); -int ibrsc(int handle, int v); -int ibrsp(int handle, char *spr); -int ibrsv(int handle, int v); -int ibsad(int handle, int sad); -int ibsgnl(int handle, int v); -int ibsic(int handle); -int ibsre(int handle, int v); -int ibsrq(void (*func)(void)); -int ibstop(int handle); -int ibtmo(int handle, int tmo); -int ibtrap(int mask, int mode); -int ibtrg(int handle); -int ibwait(int handle, int mask); -int ibwrt(int handle, const void *buffer, long cnt); -int ibwrta(int handle, const void *buffer, long cnt); -int ibwrtf(int handle, const char *flname); -int ibwrtkey(int handle, const void *buffer, int cnt); -int ibxtrc(int handle, void *buffer, long cnt); -#endif /* _KERNEL */ -#endif /* _DEV_IEEE488_UGPIB_H_ */ diff --git a/sys/dev/ieee488/upd7210.c b/sys/dev/ieee488/upd7210.c deleted file mode 100644 index 0e76c83b122..00000000000 --- a/sys/dev/ieee488/upd7210.c +++ /dev/null @@ -1,369 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * Copyright (c) 2010 Joerg Wunsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * High-level driver for µPD7210 based GPIB cards. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -# define GPIB_DEBUG -# undef GPIB_DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define UPD7210_HW_DRIVER -#define UPD7210_SW_DRIVER -#include -#include - -static MALLOC_DEFINE(M_GPIB, "GPIB", "GPIB"); - -/* upd7210 generic stuff */ - -void -upd7210_print_isr(u_int isr1, u_int isr2) -{ - printf("isr1=0x%b isr2=0x%b", - isr1, "\20\10CPT\7APT\6DET\5ENDRX\4DEC\3ERR\2DO\1DI", - isr2, "\20\10INT\7SRQI\6LOK\5REM\4CO\3LOKC\2REMC\1ADSC"); -} - -u_int -upd7210_rd(struct upd7210 *u, enum upd7210_rreg reg) -{ - u_int r; - - r = bus_read_1(u->reg_res[reg], u->reg_offset[reg]); - u->rreg[reg] = r; - return (r); -} - -void -upd7210_wr(struct upd7210 *u, enum upd7210_wreg reg, u_int val) -{ - - bus_write_1(u->reg_res[reg], u->reg_offset[reg], val); - u->wreg[reg] = val; - if (reg == AUXMR) - u->wreg[8 + (val >> 5)] = val & 0x1f; -} - -void -upd7210intr(void *arg) -{ - u_int isr_1, isr_2, isr_3; - struct upd7210 *u; - - u = arg; - mtx_lock(&u->mutex); - isr_1 = upd7210_rd(u, ISR1); - isr_2 = upd7210_rd(u, ISR2); - if (u->use_fifo) { - isr_3 = bus_read_1(u->reg_res[0], isr3); - } else { - isr_3 = 0; - } - if (isr_1 != 0 || isr_2 != 0 || isr_3 != 0) { - if (u->busy == 0 || u->irq == NULL || !u->irq(u, isr_3)) { -#if 0 - printf("upd7210intr [%02x %02x %02x", - upd7210_rd(u, DIR), isr1, isr2); - printf(" %02x %02x %02x %02x %02x] ", - upd7210_rd(u, SPSR), - upd7210_rd(u, ADSR), - upd7210_rd(u, CPTR), - upd7210_rd(u, ADR0), - upd7210_rd(u, ADR1)); - upd7210_print_isr(isr1, isr2); - printf("\n"); -#endif - } - /* - * "special interrupt handling" - * - * In order to implement shared IRQs, the original - * PCIIa uses IO locations 0x2f0 + (IRQ#) as an output - * location. If an ISR for a particular card has - * detected this card triggered the IRQ, it must reset - * the card's IRQ by writing (anything) to that IO - * location. - * - * Some clones apparently don't implement this - * feature, but National Instrument cards do. - */ - if (u->irq_clear_res != NULL) - bus_write_1(u->irq_clear_res, 0, 42); - } - mtx_unlock(&u->mutex); -} - -int -upd7210_take_ctrl_async(struct upd7210 *u) -{ - int i; - - upd7210_wr(u, AUXMR, AUXMR_TCA); - - if (!(upd7210_rd(u, ADSR) & ADSR_ATN)) - return (0); - for (i = 0; i < 20; i++) { - DELAY(1); - if (!(upd7210_rd(u, ADSR) & ADSR_ATN)) - return (0); - } - return (1); -} - -int -upd7210_goto_standby(struct upd7210 *u) -{ - int i; - - upd7210_wr(u, AUXMR, AUXMR_GTS); - - if (upd7210_rd(u, ADSR) & ADSR_ATN) - return (0); - for (i = 0; i < 20; i++) { - DELAY(1); - if (upd7210_rd(u, ADSR) & ADSR_ATN) - return (0); - } - return (1); -} - -/* Unaddressed Listen Only mode */ - -static int -gpib_l_irq(struct upd7210 *u, int isr_3) -{ - int i; - int have_data = 0; - - if (u->use_fifo) { - /* TNT5004 or TNT4882 in FIFO mode */ - if (isr_3 & 0x04) { - /* FIFO not empty */ - i = bus_read_1(u->reg_res[0], fifob); - have_data = 1; - bus_write_1(u->reg_res[0], cnt0, -1); - bus_write_1(u->reg_res[0], cnt1, (-1) >> 8); - bus_write_1(u->reg_res[0], cnt2, (-1) >> 16); - bus_write_1(u->reg_res[0], cnt3, (-1) >> 24); - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - } - } else if (u->rreg[ISR1] & 1) { - i = upd7210_rd(u, DIR); - have_data = 1; - } - - if (have_data) { - u->buf[u->buf_wp++] = i; - u->buf_wp &= (u->bufsize - 1); - i = (u->buf_rp + u->bufsize - u->buf_wp) & (u->bufsize - 1); - if (i < 8) { - if (u->use_fifo) - bus_write_1(u->reg_res[0], imr3, 0x00); - else - upd7210_wr(u, IMR1, 0); - } - wakeup(u->buf); - return (1); - } - return (0); -} - -static int -gpib_l_open(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct upd7210 *u; - - u = dev->si_drv1; - - mtx_lock(&u->mutex); - if (u->busy) { - mtx_unlock(&u->mutex); - return (EBUSY); - } - u->busy = 1; - u->irq = gpib_l_irq; - mtx_unlock(&u->mutex); - - u->buf = malloc(PAGE_SIZE, M_GPIB, M_WAITOK); - u->bufsize = PAGE_SIZE; - u->buf_wp = 0; - u->buf_rp = 0; - - upd7210_wr(u, AUXMR, AUXMR_CRST); /* chip reset */ - DELAY(10000); - upd7210_wr(u, AUXMR, C_ICR | 8); /* 8 MHz clock */ - DELAY(1000); - upd7210_wr(u, ADR, 0x60); /* ADR0: disable listener and talker 0 */ - upd7210_wr(u, ADR, 0xe0); /* ADR1: disable listener and talker 1 */ - upd7210_wr(u, ADMR, 0x70); /* listen-only (lon) */ - upd7210_wr(u, AUXMR, AUXMR_PON); /* immediate execute power-on (pon) */ - if (u->use_fifo) { - /* TNT5004 or TNT4882 in FIFO mode */ - bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */ - bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */ - bus_write_1(u->reg_res[0], cnt0, -1); - bus_write_1(u->reg_res[0], cnt1, (-1) >> 8); - bus_write_1(u->reg_res[0], cnt2, (-1) >> 16); - bus_write_1(u->reg_res[0], cnt3, (-1) >> 24); - bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */ - bus_write_1(u->reg_res[0], imr3, 0x04); /* NEF IE */ - } else { - /* µPD7210/NAT7210, or TNT4882 in non-FIFO mode */ - upd7210_wr(u, IMR1, 0x01); /* data in interrupt enable */ - } - return (0); -} - -static int -gpib_l_close(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct upd7210 *u; - - u = dev->si_drv1; - - mtx_lock(&u->mutex); - u->busy = 0; - if (u->use_fifo) { - /* TNT5004 or TNT4882 in FIFO mode */ - bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */ - bus_write_1(u->reg_res[0], imr3, 0x00); - } - upd7210_wr(u, AUXMR, AUXMR_CRST); - DELAY(10000); - upd7210_wr(u, IMR1, 0x00); - upd7210_wr(u, IMR2, 0x00); - free(u->buf, M_GPIB); - u->buf = NULL; - mtx_unlock(&u->mutex); - return (0); -} - -static int -gpib_l_read(struct cdev *dev, struct uio *uio, int ioflag) -{ - struct upd7210 *u; - int error; - size_t z; - - u = dev->si_drv1; - error = 0; - - mtx_lock(&u->mutex); - while (u->buf_wp == u->buf_rp) { - error = msleep(u->buf, &u->mutex, PZERO | PCATCH, - "gpibrd", hz); - if (error && error != EWOULDBLOCK) { - mtx_unlock(&u->mutex); - return (error); - } - } - while (uio->uio_resid > 0 && u->buf_wp != u->buf_rp) { - if (u->buf_wp < u->buf_rp) - z = u->bufsize - u->buf_rp; - else - z = u->buf_wp - u->buf_rp; - if (z > uio->uio_resid) - z = uio->uio_resid; - mtx_unlock(&u->mutex); - error = uiomove(u->buf + u->buf_rp, z, uio); - mtx_lock(&u->mutex); - if (error) - break; - u->buf_rp += z; - u->buf_rp &= (u->bufsize - 1); - } - if (u->use_fifo) { - bus_write_1(u->reg_res[0], imr3, 0x04); /* NFF IE */ - } else { - if (u->wreg[IMR1] == 0) - upd7210_wr(u, IMR1, 0x01); - } - mtx_unlock(&u->mutex); - return (error); -} - -static struct cdevsw gpib_l_cdevsw = { - .d_version = D_VERSION, - .d_name = "gpib_l", - .d_open = gpib_l_open, - .d_close = gpib_l_close, - .d_read = gpib_l_read, -}; - -/* Housekeeping */ - -static struct unrhdr *units; - -void -upd7210attach(struct upd7210 *u) -{ - struct cdev *dev; - - if (units == NULL) - units = new_unrhdr(0, INT_MAX, NULL); - u->unit = alloc_unr(units); - mtx_init(&u->mutex, "gpib", NULL, MTX_DEF); - u->cdev = make_dev(&gpib_l_cdevsw, u->unit, - UID_ROOT, GID_WHEEL, 0444, - "gpib%ul", u->unit); - u->cdev->si_drv1 = u; - - dev = make_dev(&gpib_ib_cdevsw, u->unit, - UID_ROOT, GID_WHEEL, 0444, - "gpib%uib", u->unit); - dev->si_drv1 = u; - dev_depends(u->cdev, dev); -} - -void -upd7210detach(struct upd7210 *u) -{ - - destroy_dev(u->cdev); - mtx_destroy(&u->mutex); - free_unr(units, u->unit); -} diff --git a/sys/dev/ieee488/upd7210.h b/sys/dev/ieee488/upd7210.h deleted file mode 100644 index 27e3a7a65f7..00000000000 --- a/sys/dev/ieee488/upd7210.h +++ /dev/null @@ -1,237 +0,0 @@ -/*- - * Copyright (c) 2005 Poul-Henning Kamp - * Copyright (c) 2010 Joerg Wunsch - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - * Locating an actual µPD7210 data book has proven quite impossible for me. - * There are a fair number of newer chips which are supersets of the µPD7210 - * but they are particular eager to comprehensively mark what the extensions - * are and what is in the base set. Some even give the registers and their - * bits new names. - * - * The following information is based on a description of the µPD7210 found - * in an old manual for a VME board which used the chip. - */ - -#ifndef _DEV_IEEE488_UPD7210_H_ -#define _DEV_IEEE488_UPD7210_H_ -#ifdef _KERNEL - -struct upd7210; -struct ibfoo; - -/* upd7210 interface definitions for HW drivers */ - -typedef int upd7210_irq_t(struct upd7210 *, int); - -struct upd7210 { - struct resource *reg_res[8]; - struct resource *irq_clear_res; - u_int reg_offset[8]; - int dmachan; - int unit; - int use_fifo; - - /* private stuff */ - struct mtx mutex; - uint8_t rreg[8]; - uint8_t wreg[8 + 8]; - - upd7210_irq_t *irq; - - int busy; - u_char *buf; - size_t bufsize; - u_int buf_wp; - u_int buf_rp; - struct cdev *cdev; - - struct ibfoo *ibfoo; -}; - -#ifdef UPD7210_HW_DRIVER -void upd7210intr(void *); -void upd7210attach(struct upd7210 *); -void upd7210detach(struct upd7210 *); -#endif - -#ifdef UPD7210_SW_DRIVER - -/* upd7210 hardware definitions. */ - -/* Write registers */ -enum upd7210_wreg { - CDOR = 0, /* Command/Data Out Register */ - IMR1 = 1, /* Interrupt Mask Register 1 */ - IMR2 = 2, /* Interrupt Mask Register 2 */ - SPMR = 3, /* Serial Poll Mode Register */ - ADMR = 4, /* ADdress Mode Register */ - AUXMR = 5, /* AUXilliary Mode Register */ - ICR = 5, /* Internal Counter Register */ - PPR = 5, /* Parallel Poll Register */ - AUXRA = 5, /* AUXilliary Register A */ - AUXRB = 5, /* AUXilliary Register B */ - AUXRE = 5, /* AUXilliary Register E */ - ADR = 6, /* ADdress Register */ - EOSR = 7, /* End-Of-String Register */ -}; - -/* Read registers */ -enum upd7210_rreg { - DIR = 0, /* Data In Register */ - ISR1 = 1, /* Interrupt Status Register 1 */ - ISR2 = 2, /* Interrupt Status Register 2 */ - SPSR = 3, /* Serial Poll Status Register */ - ADSR = 4, /* ADdress Status Register */ - CPTR = 5, /* Command Pass Though Register */ - ADR0 = 6, /* ADdress Register 0 */ - ADR1 = 7, /* ADdress Register 1 */ -}; - -/* Bits for ISR1 and IMR1 */ -#define IXR1_DI (1 << 0) /* Data In */ -#define IXR1_DO (1 << 1) /* Data Out */ -#define IXR1_ERR (1 << 2) /* Error */ -#define IXR1_DEC (1 << 3) /* Device Clear */ -#define IXR1_ENDRX (1 << 4) /* End Received */ -#define IXR1_DET (1 << 5) /* Device Execute Trigger */ -#define IXR1_APT (1 << 6) /* Address Pass-Through */ -#define IXR1_CPT (1 << 7) /* Command Pass-Through */ - -/* Bits for ISR2 and IMR2 */ -#define IXR2_ADSC (1 << 0) /* Addressed Status Change */ -#define IXR2_REMC (1 << 1) /* Remote Change */ -#define IXR2_LOKC (1 << 2) /* Lockout Change */ -#define IXR2_CO (1 << 3) /* Command Out */ -#define ISR2_REM (1 << 4) /* Remove */ -#define IMR2_DMAI (1 << 4) /* DMA In Enable */ -#define ISR2_LOK (1 << 5) /* Lockout */ -#define IMR2_DMAO (1 << 5) /* DMA Out Enable */ -#define IXR2_SRQI (1 << 6) /* Service Request Input */ -#define ISR2_INT (1 << 7) /* Interrupt */ - -#define SPSR_PEND (1 << 6) /* Pending */ -#define SPMR_RSV (1 << 6) /* Request SerVice */ - -#define ADSR_MJMN (1 << 0) /* MaJor MiNor */ -#define ADSR_TA (1 << 1) /* Talker Active */ -#define ADSR_LA (1 << 2) /* Listener Active */ -#define ADSR_TPAS (1 << 3) /* Talker Primary Addr. State */ -#define ADSR_LPAS (1 << 4) /* Listener Primary Addr. State */ -#define ADSR_SPMS (1 << 5) /* Serial Poll Mode State */ -#define ADSR_ATN (1 << 6) /* Attention */ -#define ADSR_CIC (1 << 7) /* Controller In Charge */ - -#define ADMR_ADM0 (1 << 0) /* Address Mode 0 */ -#define ADMR_ADM1 (1 << 1) /* Address Mode 1 */ -#define ADMR_TRM0 (1 << 4) /* Transmit/Receive Mode 0 */ -#define ADMR_TRM1 (1 << 5) /* Transmit/Receive Mode 1 */ -#define ADMR_LON (1 << 6) /* Listen Only */ -#define ADMR_TON (1 << 7) /* Talk Only */ - -/* Constant part of overloaded write registers */ -#define C_ICR 0x20 -#define C_PPR 0x60 -#define C_AUXA 0x80 -#define C_AUXB 0xa0 -#define C_AUXE 0xc0 - -#define AUXMR_PON 0x00 /* Immediate Execute pon */ -#define AUXMR_CPP 0x01 /* Clear Parallel Poll */ -#define AUXMR_CRST 0x02 /* Chip Reset */ -#define AUXMR_RFD 0x03 /* Finish Handshake */ -#define AUXMR_TRIG 0x04 /* Trigger */ -#define AUXMR_RTL 0x05 /* Return to local */ -#define AUXMR_SEOI 0x06 /* Send EOI */ -#define AUXMR_NVSA 0x07 /* Non-Valid Secondary cmd/addr */ - /* 0x08 undefined/unknown */ -#define AUXMR_SPP 0x09 /* Set Parallel Poll */ - /* 0x0a undefined/unknown */ - /* 0x0b undefined/unknown */ - /* 0x0c undefined/unknown */ - /* 0x0d undefined/unknown */ - /* 0x0e undefined/unknown */ -#define AUXMR_VSA 0x0f /* Valid Secondary cmd/addr */ -#define AUXMR_GTS 0x10 /* Go to Standby */ -#define AUXMR_TCA 0x11 /* Take Control Async (pulsed) */ -#define AUXMR_TCS 0x12 /* Take Control Synchronously */ -#define AUXMR_LISTEN 0x13 /* Listen */ -#define AUXMR_DSC 0x14 /* Disable System Control */ - /* 0x15 undefined/unknown */ -#define AUXMR_SIFC 0x16 /* Set IFC */ -#define AUXMR_CREN 0x17 /* Clear REN */ - /* 0x18 undefined/unknown */ - /* 0x19 undefined/unknown */ -#define AUXMR_TCSE 0x1a /* Take Control Sync on End */ -#define AUXMR_LCM 0x1b /* Listen Continuously Mode */ -#define AUXMR_LUNL 0x1c /* Local Unlisten */ -#define AUXMR_EPP 0x1d /* Execute Parallel Poll */ -#define AUXMR_CIFC 0x1e /* Clear IFC */ -#define AUXMR_SREN 0x1f /* Set REN */ - -#define PPR_U (1 << 4) /* Unconfigure */ -#define PPR_S (1 << 3) /* Status Polarity */ - -#define AUXA_HLDA (1 << 0) /* Holdoff on All */ -#define AUXA_HLDE (1 << 1) /* Holdoff on END */ -#define AUXA_REOS (1 << 2) /* End on EOS received */ -#define AUXA_XEOS (1 << 3) /* Transmit END with EOS */ -#define AUXA_BIN (1 << 4) /* Binary */ - -#define AUXB_CPTE (1 << 0) /* Cmd Pass Through Enable */ -#define AUXB_SPEOI (1 << 1) /* Send Serial Poll EOI */ -#define AUXB_TRI (1 << 2) /* Three-State Timing */ -#define AUXB_INV (1 << 3) /* Invert */ -#define AUXB_ISS (1 << 4) /* Individual Status Select */ - -#define AUXE_DHDT (1 << 0) /* DAC Holdoff on DTAS */ -#define AUXE_DHDC (1 << 1) /* DAC Holdoff on DCAS */ - -#define ADR0_DL0 (1 << 5) /* Disable Listener 0 */ -#define ADR0_DT0 (1 << 6) /* Disable Talker 0 */ - -#define ADR_DL (1 << 5) /* Disable Listener */ -#define ADR_DT (1 << 6) /* Disable Talker */ -#define ADR_ARS (1 << 7) /* Address Register Select */ - -#define ADR1_DL1 (1 << 5) /* Disable Listener 1 */ -#define ADR1_DT1 (1 << 6) /* Disable Talker 1 */ -#define ADR1_EOI (1 << 7) /* End or Identify */ - -/* Stuff from software drivers */ -extern struct cdevsw gpib_ib_cdevsw; - -/* Stuff from upd7210.c */ -void upd7210_print_isr(u_int isr1, u_int isr2); -u_int upd7210_rd(struct upd7210 *u, enum upd7210_rreg reg); -void upd7210_wr(struct upd7210 *u, enum upd7210_wreg reg, u_int val); -int upd7210_take_ctrl_async(struct upd7210 *u); -int upd7210_goto_standby(struct upd7210 *u); - -#endif /* UPD7210_SW_DRIVER */ - -#endif /* _KERNEL */ -#endif /* _DEV_IEEE488_UPD7210_H_ */ diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index c3c7a282110..cba7fcff489 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1331,26 +1331,6 @@ OLD_FILES+=usr/share/man/man1/gdbserver.1.gz OLD_FILES+=usr/share/man/man1/kgdb.1.gz .endif -.if ${MK_GPIB} == no -OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h -OLD_FILES+=usr/include/dev/ieee488/tnt4882.h -OLD_FILES+=usr/include/dev/ieee488/ugpib.h -OLD_FILES+=usr/include/dev/ieee488/upd7210.h -OLD_DIRS+=usr/include/dev/ieee488 -OLD_FILES+=usr/include/gpib/gpib.h -OLD_DIRS+=usr/include/gpib -OLD_FILES+=usr/lib/libgpib.a -OLD_FILES+=usr/lib/libgpib.so -OLD_LIBS+=usr/lib/libgpib.so.3 -OLD_FILES+=usr/lib/libgpib_p.a -.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64" -OLD_FILES+=usr/lib32/libgpib.a -OLD_FILES+=usr/lib32/libgpib.so -OLD_LIBS+=usr/lib32/libgpib.so.3 -OLD_FILES+=usr/lib32/libgpib_p.a -.endif -.endif - .if ${MK_GPIO} == no OLD_FILES+=usr/sbin/gpioctl OLD_FILES+=usr/share/man/man8/gpioctl.8.gz @@ -3703,7 +3683,6 @@ OLD_FILES+=usr/lib/libformw_p.a OLD_FILES+=usr/lib/libgcc_p.a OLD_FILES+=usr/lib/libgeom_p.a OLD_FILES+=usr/lib/libgnuregex_p.a -OLD_FILES+=usr/lib/libgpib_p.a OLD_FILES+=usr/lib/libgssapi_krb5_p.a OLD_FILES+=usr/lib/libgssapi_p.a OLD_FILES+=usr/lib/libhdb_p.a diff --git a/tools/build/options/WITHOUT_GPIB b/tools/build/options/WITHOUT_GPIB deleted file mode 100644 index 82cec15d57c..00000000000 --- a/tools/build/options/WITHOUT_GPIB +++ /dev/null @@ -1,2 +0,0 @@ -.\" $FreeBSD$ -Set to not build GPIB bus support. From f188f14d43bbbfc175eebaf9a54d137b6fecf16b Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Thu, 25 Dec 2014 21:32:37 +0000 Subject: [PATCH 165/207] Extern declarations in C files loses compile-time checking that the functions' calls match their definitions. Move them to header files. Reviewed by: jilles (previous version) --- sys/net/if_gif.c | 10 ---------- sys/net/if_gif.h | 10 ++++++++++ sys/net/if_gre.c | 10 ---------- sys/net/if_gre.h | 9 +++++++++ sys/netinet/in_gif.c | 4 ---- sys/netinet/ip_gre.c | 5 ----- sys/netinet6/in6_gif.c | 4 ---- sys/netinet6/ip6_gre.c | 5 ----- 8 files changed, 19 insertions(+), 38 deletions(-) diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 421d1b34b8d..0a4139ffa78 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -118,16 +118,6 @@ void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af); void (*ng_gif_attach_p)(struct ifnet *ifp); void (*ng_gif_detach_p)(struct ifnet *ifp); -#ifdef INET -extern int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); -extern int in_gif_encapcheck(const struct mbuf *, int, int, void *); -extern int in_gif_attach(struct gif_softc *); -#endif -#ifdef INET6 -extern int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); -extern int in6_gif_encapcheck(const struct mbuf *, int, int, void *); -extern int in6_gif_attach(struct gif_softc *); -#endif static int gif_set_tunnel(struct ifnet *, struct sockaddr *, struct sockaddr *); static void gif_delete_tunnel(struct ifnet *); diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h index b5ebf15d3c4..b263850ef47 100644 --- a/sys/net/if_gif.h +++ b/sys/net/if_gif.h @@ -114,6 +114,16 @@ void gif_input(struct mbuf *, struct ifnet *, int, uint8_t); int gif_output(struct ifnet *, struct mbuf *, const struct sockaddr *, struct route *); int gif_encapcheck(const struct mbuf *, int, int, void *); +#ifdef INET +int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +int in_gif_encapcheck(const struct mbuf *, int, int, void *); +int in_gif_attach(struct gif_softc *); +#endif +#ifdef INET6 +int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); +int in6_gif_encapcheck(const struct mbuf *, int, int, void *); +int in6_gif_attach(struct gif_softc *); +#endif #endif /* _KERNEL */ #define GIFGOPTS _IOWR('i', 150, struct ifreq) diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 4d00ca2911a..23e55e21c5c 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -119,16 +119,6 @@ static int gre_set_tunnel(struct ifnet *, struct sockaddr *, struct sockaddr *); static void gre_delete_tunnel(struct ifnet *); -int gre_input(struct mbuf **, int *, int); -#ifdef INET -extern int in_gre_attach(struct gre_softc *); -extern int in_gre_output(struct mbuf *, int, int); -#endif -#ifdef INET6 -extern int in6_gre_attach(struct gre_softc *); -extern int in6_gre_output(struct mbuf *, int, int); -#endif - SYSCTL_DECL(_net_link); static SYSCTL_NODE(_net_link, IFT_TUNNEL, gre, CTLFLAG_RW, 0, "Generic Routing Encapsulation"); diff --git a/sys/net/if_gre.h b/sys/net/if_gre.h index 3a48efe85e1..806b0cb8296 100644 --- a/sys/net/if_gre.h +++ b/sys/net/if_gre.h @@ -100,6 +100,15 @@ struct gre_softc { #define gre_oip gre_gihdr->gi_ip #define gre_oip6 gre_gi6hdr->gi6_ip6 +int gre_input(struct mbuf **, int *, int); +#ifdef INET +int in_gre_attach(struct gre_softc *); +int in_gre_output(struct mbuf *, int, int); +#endif +#ifdef INET6 +int in6_gre_attach(struct gre_softc *); +int in6_gre_output(struct mbuf *, int, int); +#endif /* * CISCO uses special type for GRE tunnel created as part of WCCP * connection, while in fact those packets are just IPv4 encapsulated diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index 261c88acf99..cd412adc0c9 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -67,10 +67,6 @@ __FBSDID("$FreeBSD$"); #include -int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); -int in_gif_encapcheck(const struct mbuf *, int, int, void *); -int in_gif_attach(struct gif_softc *); - static int gif_validate4(const struct ip *, struct gif_softc *, struct ifnet *); static int in_gif_input(struct mbuf **, int *, int); diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c index 9f281913116..59423644c73 100644 --- a/sys/netinet/ip_gre.c +++ b/sys/netinet/ip_gre.c @@ -68,11 +68,6 @@ __FBSDID("$FreeBSD$"); #include extern struct domain inetdomain; -extern int gre_input(struct mbuf **, int *, int); - -int in_gre_attach(struct gre_softc *); -int in_gre_output(struct mbuf *, int, int); - static const struct protosw in_gre_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inetdomain, diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 855315ed150..3db4b4f1d58 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -81,10 +81,6 @@ SYSCTL_DECL(_net_inet6_ip6); SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_gif_hlim), 0, ""); -int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t); -int in6_gif_encapcheck(const struct mbuf *, int, int, void *); -int in6_gif_attach(struct gif_softc *); - static int gif_validate6(const struct ip6_hdr *, struct gif_softc *, struct ifnet *); static int in6_gif_input(struct mbuf **, int *, int); diff --git a/sys/netinet6/ip6_gre.c b/sys/netinet6/ip6_gre.c index 29a07253a0c..095a1deeb63 100644 --- a/sys/netinet6/ip6_gre.c +++ b/sys/netinet6/ip6_gre.c @@ -62,11 +62,6 @@ __FBSDID("$FreeBSD$"); #include extern struct domain inet6domain; -extern int gre_input(struct mbuf **, int *, int); - -int in6_gre_attach(struct gre_softc *); -int in6_gre_output(struct mbuf *, int, int); - struct protosw in6_gre_protosw = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, From 2612bc21b4df390b151333c85302d3829cb86e93 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 25 Dec 2014 21:33:25 +0000 Subject: [PATCH 166/207] Import mandoc 1.13.2 --- INSTALL | 71 ++++-- LICENSE | 6 +- Makefile | 113 ++++----- Makefile.depend | 16 +- NEWS | 71 +++++- TODO | 55 ++--- compat_fts.c | 47 +--- compat_reallocarray.c | 10 +- compat_strcasestr.c | 3 +- compat_strsep.c | 3 +- configure | 33 ++- configure.local.example | 32 ++- example.style.css | 11 +- html.c | 6 +- html.h | 14 +- libman.h | 6 +- libmandoc.h | 11 +- libmdoc.h | 6 +- libroff.h | 10 +- main.c | 70 ++++-- main.h | 16 +- man.h | 6 +- man_hash.c | 3 +- man_html.c | 20 +- man_term.c | 46 ++-- mandoc.1 | 31 ++- mandoc.h | 14 +- mandoc_aux.h | 6 +- mandoc_headers.3 | 511 ++++++++++++++++++++++++++++++++++++++++ mandocdb.c | 425 +++++++++++++++++++-------------- manpath.h | 6 +- mansearch.3 | 6 +- mansearch.c | 6 +- mansearch.h | 8 +- mansearch_const.c | 3 +- mdoc.7 | 18 +- mdoc.h | 6 +- mdoc_html.c | 11 +- mdoc_macro.c | 50 ++-- mdoc_man.c | 5 +- mdoc_term.c | 8 +- mdoc_validate.c | 4 +- msec.c | 3 +- out.c | 4 +- out.h | 12 +- read.c | 9 +- roff.7 | 10 +- st.in | 5 +- term.c | 6 +- term.h | 18 +- term_ps.c | 5 +- 51 files changed, 1309 insertions(+), 566 deletions(-) create mode 100644 mandoc_headers.3 diff --git a/INSTALL b/INSTALL index 31ffaf00c00..cc30f4c8ebb 100644 --- a/INSTALL +++ b/INSTALL @@ -1,13 +1,12 @@ -$Id: INSTALL,v 1.5 2014/08/18 13:27:47 kristaps Exp $ +$Id: INSTALL,v 1.9 2014/12/11 07:44:46 schwarze Exp $ About mdocml, the portable mandoc distribution ---------------------------------------------- The mandoc manpage compiler toolset is a suite of tools compiling mdoc(7), the roff(7) macro language of choice for BSD manual pages, and man(7), the predominant historical language for UNIX manuals. -The toolset does not yet implement man(1); that is only scheduled -for the next release, 1.13.2. It can, however, already serve to -translate source manpages to the output displayed by man(1). +Since the present version 1.13.2, it includes a man(1) manual viewer +in addition to the apropos(1) manual page search tool. For general information, see . In this document, we describe the installation and deployment of @@ -22,7 +21,7 @@ tech@ mailing list, too. Enjoy using the mandoc toolset! -Ingo Schwarze, Karlsruhe, August 2014 +Ingo Schwarze, Karlsruhe, December 2014 Installation @@ -59,8 +58,8 @@ should work. If the build fails, look at "configure.local.example" and go back to step 2. 4. Run "make -n install" and check whether everything will be -installed to the intended places. Otherwise, put some *DIR variables -into "configure.local" and go back to step 2. +installed to the intended places. Otherwise, put some *DIR or *NM* +variables into "configure.local" and go back to step 2. 5. Run "sudo make install". If you intend to build a binary package using some kind of fake root mechanism, you may need a @@ -70,14 +69,14 @@ in the "Makefile" to understand how DESTDIR is used. 6. To set up a man.cgi(8) server, read its manual page. 7. To use mandoc(1) as your man(1) formatter, read the "Deployment" -section below. +sections below. Understanding mandoc dependencies --------------------------------- -The mandoc(1), preconv(1), and demandoc(1) utilities have no external -dependencies. However, makewhatis(8) and apropos(1) depend on the -following software: +The mandoc(1) and demandoc(1) utilities have no external dependencies. +However, makewhatis(8), apropos(1), and man(1) depend on the following +software: 1. The SQLite database system, see . The recommended version of SQLite is 3.8.4.3 or newer. The mandoc @@ -89,14 +88,14 @@ fails due to the missing sqlite3_errstr() API. Both are very minor problems, apropos(1) is fully usable with SQLite 3.7.5. Versions older than 3.7.5 may or may not work, they have not been tested. -1.2. The fts(3) directory traversion functions. +2. The fts(3) directory traversion functions. If your system does not have them, the bundled compatibility version will be used, so you need not worry in that case. But be careful: the glibc version of fts(3) is known to be broken on 32bit platforms, see . If you run into that problem, set "HAVE_FTS=0" in configure.local. -1.3. Marc Espie's ohash(3) library. +3. Marc Espie's ohash(3) library. If your system does not have it, the bundled compatibility version will be used, so you probably need not worry about it. @@ -145,11 +144,39 @@ in unusual headers. You can also look at the file "config.h" and check that no "#define HAVE_*" differ from your expectations. -Deployment ----------- -If you want to integrate the mandoc(1) tools with your existing -man(1) system as a formatter, then contact us first: on systems without -mandoc(1) as the default, you may have your work cut out for you! +Deployment using the integrated man(1) viewer +--------------------------------------------- +This mode of deployment requires database support. In case of +doubt, look at the section "user settings related to database +support" in the file configure.local.example. + +Deployment requires the following steps: + +1. Build and install mandoc as described above in steps 2 to 5 +below "Installation". + +2. If your system uses manpath(1), make sure it is configured +correctly, in particular, it returns all directory trees where +manual pages are installed. If your system uses man.conf(5), make +sure it contains a "_whatdb" line for each directory tree, and the +order of these lines meets your wishes. + +3. Run the command "sudo makewhatis" to build mandoc.db(5) databases +in all the directory trees configured in step 2. + +At this point, your new man(1), apropos(1), and whatis(1) should work. +Otherwise, please look at , both +for help and to have these instructions improved. + +Whenever installing new manual pages, re-run makewhatis(8) to update +the databases, or man(1) will not find the new pages. + + +Deployment using your system's native man(1) viewer +--------------------------------------------------- +This mode of deployment does not require database support, +so it works even if you don't have SQLite3. + Usually, you can have your default installation and mandoc(1) work right alongside each other by using user-specific versions of the files mentioned below. @@ -174,15 +201,17 @@ mandoc(1)" to disregard them. of cached pages being pulled up. You can usually do this by commenting out NOCACHE or similar. + mandoc(1) still has a long way to go in understanding non-trivial low-level roff(7) markup embedded in some man(7) pages. On the BSD systems using mandoc(1), third-party software is generally vetted on whether it may be formatted with mandoc(1). If not, groff(1) is pulled in as a dependency and used to install a pre-formatted -"catpage" intead of directly as manual page source. +"catpage" instead of directly as manual page source. For more background on switching operating systems to use mandoc(1) -instead of groff(1) to format manuals, see the two BSDCan presentations -by Ingo Schwarze: +instead of groff(1) to format manuals, see the BSDCan and EuroBSDCon +presentations by Ingo Schwarze: + diff --git a/LICENSE b/LICENSE index db26171c9de..12bf65ade9c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,17 +1,17 @@ -$Id: LICENSE,v 1.4 2014/08/21 00:42:38 schwarze Exp $ +$Id: LICENSE,v 1.5 2014/12/11 07:56:24 schwarze Exp $ With the exceptions noted below, all code and documentation contained in the mdocml toolkit is protected by the Copyright of the following developers: -Copyright (c) 2008, 2009, 2010, 2011, 2012 Kristaps Dzonsons +Copyright (c) 2008-2012, 2014 Kristaps Dzonsons Copyright (c) 2010, 2011, 2012, 2013, 2014 Ingo Schwarze Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger Copyright (c) 2013 Franco Fichtner Copyright (c) 1999, 2004 Marc Espie Copyright (c) 1998, 2010 Todd C. Miller Copyright (c) 2008 Otto Moerbeek -Copyright (c) 2003 Jason McIntyre +Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre See the individual source files for information about who contributed to which file during which years. diff --git a/Makefile b/Makefile index a8255fecc82..e3f48f71179 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.448 2014/11/28 18:57:31 schwarze Exp $ +# $Id: Makefile,v 1.453 2014/12/09 09:14:33 schwarze Exp $ # # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons # Copyright (c) 2011, 2013, 2014 Ingo Schwarze @@ -15,9 +15,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -BASEBIN = mandoc demandoc -DBBIN = makewhatis -CGIBIN = man.cgi +# === LIST OF FILES ==================================================== TESTSRCS = test-dirent-namlen.c \ test-fgetln.c \ @@ -131,6 +129,7 @@ DISTFILES = INSTALL \ mandoc_aux.h \ mandoc_char.7 \ mandoc_escape.3 \ + mandoc_headers.3 \ mandoc_html.3 \ mandoc_malloc.3 \ manpath.h \ @@ -208,18 +207,19 @@ MANDOC_TERM_OBJS = eqn_term.o \ term_ps.o \ tbl_term.o -MANDOC_OBJS = $(MANDOC_HTML_OBJS) \ +BASE_OBJS = $(MANDOC_HTML_OBJS) \ $(MANDOC_MAN_OBJS) \ $(MANDOC_TERM_OBJS) \ main.o \ out.o \ tree.o -MAN_OBJS = $(MANDOC_OBJS) +MAIN_OBJS = $(BASE_OBJS) -MAKEWHATIS_OBJS = mandocdb.o mansearch_const.o manpath.o - -APROPOS_OBJS = mansearch.o mansearch_const.o manpath.o +DB_OBJS = mandocdb.o \ + mansearch.o \ + mansearch_const.o \ + manpath.o CGI_OBJS = $(MANDOC_HTML_OBJS) \ cgi.o \ @@ -237,6 +237,7 @@ WWW_MANS = apropos.1.html \ mandoc.1.html \ mandoc.3.html \ mandoc_escape.3.html \ + mandoc_headers.3.html \ mandoc_html.3.html \ mandoc_malloc.3.html \ mansearch.3.html \ @@ -261,19 +262,17 @@ WWW_MANS = apropos.1.html \ WWW_OBJS = mdocml.tar.gz \ mdocml.sha256 -include Makefile.local +# === USER CONFIGURATION =============================================== -INSTALL_TARGETS = $(BUILD_TARGETS:-build=-install) +include Makefile.local # === DEPENDENCY HANDLING ============================================== all: base-build $(BUILD_TARGETS) Makefile.local -base-build: $(BASEBIN) +base-build: mandoc demandoc -db-build: $(DBBIN) - -cgi-build: $(CGIBIN) +cgi-build: man.cgi install: base-install $(INSTALL_TARGETS) @@ -281,6 +280,9 @@ www: $(WWW_OBJS) $(WWW_MANS) $(WWW_MANS): mandoc +.PHONY: base-install cgi-install db-install install www-install +.PHONY: clean distclean depend + include Makefile.depend # === TARGETS CONTAINING SHELL COMMANDS ================================ @@ -290,8 +292,7 @@ distclean: clean clean: rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS) - rm -f mandoc $(MANDOC_OBJS) $(APROPOS_OBJS) - rm -f makewhatis $(MAKEWHATIS_OBJS) + rm -f mandoc $(BASE_OBJS) $(DB_OBJS) rm -f man.cgi $(CGI_OBJS) rm -f manpage $(MANPAGE_OBJS) rm -f demandoc $(DEMANDOC_OBJS) @@ -306,34 +307,41 @@ base-install: base-build mkdir -p $(DESTDIR)$(MANDIR)/man1 mkdir -p $(DESTDIR)$(MANDIR)/man3 mkdir -p $(DESTDIR)$(MANDIR)/man7 - $(INSTALL_PROGRAM) $(BASEBIN) $(DESTDIR)$(BINDIR) + $(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR) $(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR) $(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \ $(DESTDIR)$(INCLUDEDIR) - $(INSTALL_MAN) man.1 mandoc.1 demandoc.1 \ - $(DESTDIR)$(MANDIR)/man1 + $(INSTALL_MAN) mandoc.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1 $(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \ mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3 - $(INSTALL_MAN) man.7 mdoc.7 roff.7 eqn.7 tbl.7 mandoc_char.7 \ - $(DESTDIR)$(MANDIR)/man7 + $(INSTALL_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MAN}.7 + $(INSTALL_MAN) mdoc.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MDOC}.7 + $(INSTALL_MAN) roff.7 $(DESTDIR)$(MANDIR)/man7/${MANM_ROFF}.7 + $(INSTALL_MAN) eqn.7 $(DESTDIR)$(MANDIR)/man7/${MANM_EQN}.7 + $(INSTALL_MAN) tbl.7 $(DESTDIR)$(MANDIR)/man7/${MANM_TBL}.7 + $(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7 $(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR) -db-install: db-build +db-install: base-build mkdir -p $(DESTDIR)$(BINDIR) mkdir -p $(DESTDIR)$(SBINDIR) mkdir -p $(DESTDIR)$(MANDIR)/man1 mkdir -p $(DESTDIR)$(MANDIR)/man3 mkdir -p $(DESTDIR)$(MANDIR)/man5 mkdir -p $(DESTDIR)$(MANDIR)/man8 - ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/apropos - ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/whatis - $(INSTALL_PROGRAM) makewhatis $(DESTDIR)$(SBINDIR) - $(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1 - ln -f $(DESTDIR)$(MANDIR)/man1/apropos.1 \ - $(DESTDIR)$(MANDIR)/man1/whatis.1 + ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS) + ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN) + ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS) + ln -f $(DESTDIR)$(BINDIR)/mandoc \ + $(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS) + $(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 + $(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1 + ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \ + $(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1 $(INSTALL_MAN) mansearch.3 $(DESTDIR)$(MANDIR)/man3 $(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5 - $(INSTALL_MAN) makewhatis.8 $(DESTDIR)$(MANDIR)/man8 + $(INSTALL_MAN) makewhatis.8 \ + $(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8 cgi-install: cgi-build mkdir -p $(DESTDIR)$(CGIBINDIR) @@ -346,34 +354,15 @@ cgi-install: cgi-build $(INSTALL_MAN) apropos.1 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1/ $(INSTALL_MAN) man.cgi.8 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8/ -www-install: www - mkdir -p $(DESTDIR)$(HTDOCDIR)/snapshots - $(INSTALL_DATA) $(WWW_MANS) style.css $(DESTDIR)$(HTDOCDIR) - $(INSTALL_DATA) $(WWW_OBJS) $(DESTDIR)$(HTDOCDIR)/snapshots - $(INSTALL_DATA) mdocml.tar.gz \ - $(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz - $(INSTALL_DATA) mdocml.sha256 \ - $(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256 - Makefile.local config.h: configure ${TESTSRCS} @echo "$@ is out of date; please run ./configure" @exit 1 -depend: config.h - mkdep -f Makefile.depend $(CFLAGS) $(SRCS) - perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \ - s|\\\n||g; s| +| |g; s| $$||mg; print;' \ - Makefile.depend > Makefile.tmp - mv Makefile.tmp Makefile.depend - libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS) $(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS) -mandoc: $(MAN_OBJS) libmandoc.a - $(CC) $(LDFLAGS) -o $@ $(MAN_OBJS) libmandoc.a $(DBLIB) - -makewhatis: $(MAKEWHATIS_OBJS) libmandoc.a - $(CC) $(LDFLAGS) -o $@ $(MAKEWHATIS_OBJS) libmandoc.a $(DBLIB) +mandoc: $(MAIN_OBJS) libmandoc.a + $(CC) $(LDFLAGS) -o $@ $(MAIN_OBJS) libmandoc.a $(DBLIB) manpage: $(MANPAGE_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(MANPAGE_OBJS) libmandoc.a $(DBLIB) @@ -384,6 +373,24 @@ man.cgi: $(CGI_OBJS) libmandoc.a demandoc: $(DEMANDOC_OBJS) libmandoc.a $(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a +# --- maintainer targets --- + +www-install: www + mkdir -p $(HTDOCDIR)/snapshots + $(INSTALL_DATA) $(WWW_MANS) style.css $(HTDOCDIR)/man + $(INSTALL_DATA) $(WWW_OBJS) $(HTDOCDIR)/snapshots + $(INSTALL_DATA) mdocml.tar.gz \ + $(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz + $(INSTALL_DATA) mdocml.sha256 \ + $(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256 + +depend: config.h + mkdep -f Makefile.depend $(CFLAGS) $(SRCS) + perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \ + s|\\\n||g; s| +| |g; s| $$||mg; print;' \ + Makefile.depend > Makefile.tmp + mv Makefile.tmp Makefile.depend + mdocml.sha256: mdocml.tar.gz sha256 mdocml.tar.gz > $@ @@ -394,8 +401,8 @@ mdocml.tar.gz: $(DISTFILES) ( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) ) rm -rf .dist/ -.PHONY: base-install cgi-install db-install install www-install -.PHONY: clean distclean depend +# === SUFFIX RULES ===================================================== + .SUFFIXES: .1 .3 .5 .7 .8 .h .SUFFIXES: .1.html .3.html .5.html .7.html .8.html .h.html diff --git a/Makefile.depend b/Makefile.depend index d3c13e09cf5..a61de19fcdd 100644 --- a/Makefile.depend +++ b/Makefile.depend @@ -15,12 +15,12 @@ demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h -html.o: html.c config.h mandoc.h mandoc_aux.h libmandoc.h out.h html.h main.h +html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h main.h lib.o: lib.c config.h mdoc.h libmdoc.h lib.in main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h manpath.h mansearch.h man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h -man_hash.o: man_hash.c config.h man.h mandoc.h libman.h -man_html.o: man_html.c config.h mandoc.h mandoc_aux.h out.h html.h man.h main.h +man_hash.o: man_hash.c config.h man.h libman.h +man_html.o: man_html.c config.h mandoc_aux.h man.h out.h html.h main.h man_macro.o: man_macro.c config.h man.h mandoc.h libmandoc.h libman.h man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h @@ -30,19 +30,19 @@ mandocdb.o: mandocdb.c config.h compat_fts.h compat_ohash.h mdoc.h man.h mandoc. manpage.o: manpage.c config.h manpath.h mansearch.h manpath.o: manpath.c config.h mandoc_aux.h manpath.h mansearch.o: mansearch.c config.h compat_ohash.h mandoc.h mandoc_aux.h manpath.h mansearch.h -mansearch_const.o: mansearch_const.c config.h manpath.h mansearch.h +mansearch_const.o: mansearch_const.c config.h mansearch.h mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h mdoc_hash.o: mdoc_hash.c config.h mdoc.h libmdoc.h -mdoc_html.o: mdoc_html.c config.h mandoc.h mandoc_aux.h out.h html.h mdoc.h main.h +mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mdoc.h out.h html.h main.h mdoc_macro.o: mdoc_macro.c config.h mdoc.h mandoc.h libmdoc.h libmandoc.h mdoc_man.o: mdoc_man.c config.h mandoc.h mandoc_aux.h out.h man.h mdoc.h main.h mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main.h mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h -msec.o: msec.c config.h mandoc.h libmandoc.h msec.in +msec.o: msec.c config.h libmandoc.h msec.in out.o: out.c config.h mandoc_aux.h mandoc.h out.h preconv.o: preconv.c config.h mandoc.h libmandoc.h -read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h main.h +read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h roff.o: roff.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h predefs.in st.o: st.c config.h mdoc.h libmdoc.h st.in tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h @@ -53,7 +53,7 @@ tbl_opts.o: tbl_opts.c config.h mandoc.h libmandoc.h libroff.h tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h -term_ps.o: term_ps.c config.h mandoc.h mandoc_aux.h out.h main.h term.h +term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h main.h tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h test-dirent-namlen.o: test-dirent-namlen.c test-fgetln.o: test-fgetln.c diff --git a/NEWS b/NEWS index f47a807dadc..fbcdfc2ad3c 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,76 @@ -$Id: NEWS,v 1.6 2014/08/11 01:39:00 schwarze Exp $ +$Id: NEWS,v 1.8 2014/12/13 13:43:47 schwarze Exp $ This file lists the most important changes in the mdocml.bsd.lv distribution. +Changes in version 1.13.2, released on December 13, 2014 + + --- MAJOR NEW FEATURES --- + * Include an implementation of man(1), the manual page viewer. + * Unified set of command line option, each one supported by all + command names, including new options -a (format all), -c (no + pager), -h (synopsis only), and -w (list filenames). + * Support the MANPAGER and PAGER environment variables. + * Support gzip'ed manuals by the whole toolset, even as .so targets. + * Support UTF-8 and Latin-1 input by the whole toolset, delete preconv(1). + * Switch the default output mode from -Tascii to -Tlocale. + * Improve -Tascii output for Unicode escape sequences. + * Let the -Thtml output mode produce polyglot HTML5. + * Many improvements for eqn(7), in particular in-line equations, + MathML output in -Thtml mode, and much improved terminal formatting. + --- PORTABILITY IMPROVEMENTS --- + * Change the build sequence to the usual ./configure; make; make install. + * Support ./configure.local for build customizations. + * Autodetect wchar, sqlite3, and manpath support. + * Provide a fallback version of fts(3) for systems lacking it. + * Support choosing alternative binary and manual names. + --- MINOR NEW FEATURES --- + * Rudimentary implementation of the e, x, and z tbl(7) layout + modifiers to equalize, maximize, and ignore the width of columns. + * Implement font modifiers in tbl(7) layouts. + * Allow comma-separated options in the tbl(7) options line. + * Parse and ignore the .pl (page length) roff(7) request. + * Implement .An -[no]split for the mdoc(7) -Thtml output mode. + * Support bold italic font in PostScript and PDF output. + * Warn about commas in function arguments and parentheses in function names. + * Warn about botched .Xr ordering and punctuation below SEE ALSO. + * Warn about AUTHORS sections without .An macros. + * Warn about attempts to call non-callable macros. + * New developer documentation manual page mandoc_headers(3). + --- BUGFIXES --- + * Fix read buffer overrun sometimes triggered by trailing whitespace. + * Fix read buffer overrun triggered by certain invalid \H sequences. + * Fix NULL pointer access triggered by .Bl without any arguments. + * Fix NULL pointer access triggered by .It Nm Fo without .Fc. + * Fix NULL pointer access triggered by .Sh Xo .Sh without .Xc. + * Fix NULL pointer access triggered by missing .Nm. + * Fix an assertion triggered by .It right after .El. + * Fix an assertion triggered by .Ec without preceding .Eo. + * Fix an assertion triggered by .Sm or .Db with multiple arguments. + * Fix assertion failures triggered by very large width arguments. + * Fix a division by zero in the roff(7) parser. + * Prevent negative arguments to .ll from causing integer underflow. + * Correctly autodetect source format even when .Dd is preceded by .ll. + * Multiple fixes with respect to .Bd and .Bl -offset and -width. + * Many bugfixes with respect to scaling units. + * Multiple fixes with respect to delimiter handling by in-line macros. + * Multiple fixes with respect to .Pf. + * Make \c work properly in no-fill mode. + * Stricter syntax checking of Unicode character names. + --- THANKS TO --- + * Kristaps Dzonsons for rewriting the eqn(7) parser, implementing + HTML5 and MathML output, and various other code contributions. + * Jonathan Gray (OpenBSD) for extensive testing with afl (the + American Fuzzy Lop security fuzzer) resulting in many bug reports. + * Anthony Bentley (OpenBSD), Baptiste Daroussin (FreeBSD), Daniel + Dickman, Doug Hogan, Jason McIntyre, Theo de Raadt (OpenBSD), + and Martin Natano for source code patches. + * Carsten Kunze (Heirloom troff), Daniel Levai (Slackware), + Garrett D'Amore (illumos), Giovanni Becchis, Matthew Dempsky, + Stuart Henderson, Ted Unangst, Todd Miller (OpenBSD), Thomas + Klausner (NetBSD), Ulrich Spoerlein (FreeBSD), Justin Haynes, + Marcus Merighi, Sebastien Marie, Steffen Nurpmeso and Theo Buehler + for bug reports. + Changes in version 1.13.1, released on August 10, 2014 --- MAJOR NEW FEATURES --- diff --git a/TODO b/TODO index 98cb687eaa2..b213e8b92c2 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,6 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.189 2014/11/26 21:40:17 schwarze Exp $ +* $Id: TODO,v 1.195 2014/12/13 13:14:39 schwarze Exp $ ************************************************************************ Many issues are annotated for difficulty as follows: @@ -72,7 +72,8 @@ are mere guesses, and some may be wrong. - .ta (tab settings) occurs in ircbug(1) and probably gnats(1) reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500 also Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100 - loc ** exist *** algo ** size ** imp ** + also posix2time(3) Carsten Kunze Mon, 1 Dec 2014 13:03:10 +0100 + loc ** exist *** algo ** size ** imp *** - .ti (temporary indent) found by naddy@ in xloadimage(1) @@ -83,14 +84,10 @@ are mere guesses, and some may be wrong. found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200 loc * exist ** algo ** size ** imp ** -- \c (interrupted text) should prevent the line break - even inside .Bd literal; that occurs in chat(8) - also found in cclive(1) - DocBook output - loc ** exist *** algo ** size * imp * - - \h horizontal move - found in cclive(1) DocBook output - Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600 + found in cclive(1) and nasm(1) asciidoc/DocBook output + bentley@ on discuss@ Sat, 21 Sep 2013 22:29:34 -0600 + naddy@ Thu, 4 Dec 2014 16:26:41 +0100 loc ** exist ** algo ** size * imp ** (parser reorg helps a lot) - \n+ and \n- numerical register increment and decrement @@ -125,13 +122,6 @@ are mere guesses, and some may be wrong. from jmc@ Wed, 14 Jul 2010 18:10:32 +0100 loc * exist *** algo *** size ** imp ** -- \\ is now implemented correctly - * when defining strings and macros using .ds and .de - * when parsing roff(7) and man(7) macro arguments - It does not yet work in mdoc(7) macro arguments - because libmdoc does not yet use mandoc_getarg(). - Also check what happens in plain text, it must be identical to \e. - - .Bd -centered implies -filled, not -unfilled, which is not easy to implement; it requires code similar to .ce, which we don't have either. @@ -172,12 +162,6 @@ are mere guesses, and some may be wrong. is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab." but should give "ab ." -- set a meaningful default if no `Bl' list type is assigned - loc * exist * algo * size * imp ** (already done?) - -- have a blank `It' head for `Bl -tag' not puke - loc * exist * algo * size * imp ** (already done?) - - check whether it is correct that `D1' uses INDENT+1; does it need its own constant? loc * exist ** algo ** size * imp ** @@ -315,9 +299,18 @@ are mere guesses, and some may be wrong. * formatting issues: ugly output ************************************************************************ -- a column list with blank `Ta' cells triggers a spurrious +- revisit empty in-line macros + look at the difference between "Em x Em ." and "Sq x Em ." + Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100 + loc *** exist *** algo *** size * imp ** + +- a column list with blank `Ta' cells triggers a spurious start-with-whitespace printing of a newline +- In .Bl -column, .It a"bc" + shows the quotes in groff, but not in mandoc + loc * exist *** algo ** size * imp ** + - In .Bl -column, .It Em AuthenticationKey Length ought to render "Key Length" with emphasis, too, @@ -403,16 +396,6 @@ are mere guesses, and some may be wrong. Steffen Nurpmeso Sat, 08 Nov 2014 13:34:59 +0100 loc * exist ** algo ** size * imp ** -- .Rv (and probably .Ex) print different text if an `Nm' has been named - or not (run a manual without `Nm blah' to see this). I'm not sure - that this exists in the wild, but it's still an error. - loc * exist * algo * size * imp * (already done?) - -- In .Bl -bullet, the groff bullet is "+\b+\bo\bo", the mandoc bullet - is just "o\bo". The problem is to not break ps/pdf when fixing. - see for example OpenBSD ksh(1) - loc ** exist ** algo ** size * imp ** - - In .Bl -enum -width 0n, groff continues one the same line after the number, mandoc breaks the line. mail to kristaps@ Mon, 20 Jul 2009 02:21:39 +0200 @@ -601,3 +584,9 @@ Several areas can be cleaned up to make mandoc even faster. These are - Have Mac OSX systems automatically disable -static compilation of the CGI: -static isn't supported. +************************************************************************ +* to improve in the groff_mdoc(7) macros +************************************************************************ + +- use uname(1) to set doc-default-operating-system at install time + tobimensch Mon, 1 Dec 2014 00:25:07 +0100 diff --git a/compat_fts.c b/compat_fts.c index 4caf74c1380..d6e99e611aa 100644 --- a/compat_fts.c +++ b/compat_fts.c @@ -6,8 +6,8 @@ int dummy; #else -/* $Id: compat_fts.c,v 1.4 2014/08/17 20:45:59 schwarze Exp $ */ -/* $OpenBSD: fts.c,v 1.46 2014/05/25 17:47:04 tedu Exp $ */ +/* $Id: compat_fts.c,v 1.6 2014/12/11 18:20:07 schwarze Exp $ */ +/* $OpenBSD: fts.c,v 1.49 2014/11/23 00:14:22 guenther Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -62,6 +62,10 @@ static unsigned short fts_stat(FTS *, FTSENT *); static int fts_safe_changedir(FTS *, FTSENT *, int, const char *); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#ifndef O_DIRECTORY +#define O_DIRECTORY 0 +#endif #define CLR(opt) (sp->fts_options &= ~(opt)) #define ISSET(opt) (sp->fts_options & (opt)) @@ -146,7 +150,8 @@ fts_open(char * const *argv, int options, void *dummy) * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ - if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0) + if (!ISSET(FTS_NOCHDIR) && + (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0) SET(FTS_NOCHDIR); if (nitems == 0) @@ -406,7 +411,7 @@ fts_build(FTS *sp) DIR *dirp; void *oldaddr; size_t dlen, len, maxlen; - int nitems, cderrno, descend, level, nlinks, nostat, doadjust; + int nitems, cderrno, descend, level, doadjust; int saved_errno; char *cp; @@ -423,14 +428,6 @@ fts_build(FTS *sp) return (NULL); } - /* - * Nlinks is the number of possible entries of type directory in the - * directory if we're cheating on stat calls, 0 if we're not doing - * any stat calls at all, -1 if we're doing stats on everything. - */ - nlinks = -1; - nostat = 0; - /* * If we're going to need to stat anything or we want to descend * and stay in the directory, chdir. If this fails we keep going, @@ -448,8 +445,7 @@ fts_build(FTS *sp) */ cderrno = 0; if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) { - if (nlinks) - cur->fts_errno = errno; + cur->fts_errno = errno; cur->fts_flags |= FTS_DONTCHDIR; descend = 0; cderrno = errno; @@ -544,21 +540,9 @@ mem1: saved_errno = errno; } if (cderrno) { - if (nlinks) { - p->fts_info = FTS_NS; - p->fts_errno = cderrno; - } else - p->fts_info = FTS_NSOK; + p->fts_info = FTS_NS; + p->fts_errno = cderrno; p->fts_accpath = cur->fts_accpath; - } else if (nlinks == 0 -#ifdef DT_DIR - || (nostat && - dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN) -#endif - ) { - p->fts_accpath = - ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name; - p->fts_info = FTS_NSOK; } else { /* Build a file name for fts_stat to stat. */ if (ISSET(FTS_NOCHDIR)) { @@ -568,11 +552,6 @@ mem1: saved_errno = errno; p->fts_accpath = p->fts_name; /* Stat it. */ p->fts_info = fts_stat(sp, p); - - /* Decrement link count if applicable. */ - if (nlinks > 0 && (p->fts_info == FTS_D || - p->fts_info == FTS_DC || p->fts_info == FTS_DOT)) - --nlinks; } /* We walk in directory order so "ls -f" doesn't get upset. */ @@ -803,7 +782,7 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path) newfd = fd; if (ISSET(FTS_NOCHDIR)) return (0); - if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0) + if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0) return (-1); if (fstat(newfd, &sb)) { ret = -1; diff --git a/compat_reallocarray.c b/compat_reallocarray.c index 6e96a6ab7d7..66151904257 100644 --- a/compat_reallocarray.c +++ b/compat_reallocarray.c @@ -6,7 +6,8 @@ int dummy; #else -/* $OpenBSD: malloc.c,v 1.158 2014/04/23 15:07:27 tedu Exp $ */ +/* $Id: compat_reallocarray.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */ +/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */ /* * Copyright (c) 2008 Otto Moerbeek * @@ -22,12 +23,17 @@ int dummy; * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + #include #include #include #include -#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) +/* + * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX + * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW + */ +#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) void * reallocarray(void *optr, size_t nmemb, size_t size) diff --git a/compat_strcasestr.c b/compat_strcasestr.c index 0706ee00e50..62c0ff740c8 100644 --- a/compat_strcasestr.c +++ b/compat_strcasestr.c @@ -6,7 +6,8 @@ int dummy; #else -/* ($)NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */ +/* $Id: compat_strcasestr.c,v 1.4 2014/12/11 09:19:32 schwarze Exp $ */ +/* $NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $ */ /*- * Copyright (c) 1990, 1993 diff --git a/compat_strsep.c b/compat_strsep.c index 348f7ebf67f..1df57582802 100644 --- a/compat_strsep.c +++ b/compat_strsep.c @@ -6,7 +6,8 @@ int dummy; #else -/* ($)OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ +/* $Id: compat_strsep.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */ +/* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $ */ /*- * Copyright (c) 1990, 1993 diff --git a/configure b/configure index 0fb841cfcf2..57ac898f248 100755 --- a/configure +++ b/configure @@ -31,7 +31,7 @@ echo "config.log: writing..." # Initialize all variables here, # such that nothing can leak in from the environment. -VERSION="1.13.1" +VERSION="1.13.2" echo "VERSION=\"${VERSION}\"" 1>&2 echo "VERSION=\"${VERSION}\"" 1>&3 @@ -75,6 +75,16 @@ WWWPREFIX="/var/www" HTDOCDIR= CGIBINDIR= +BINM_APROPOS="apropos" +BINM_MAN="man" +BINM_WHATIS="whatis" +BINM_MAKEWHATIS="makewhatis" +MANM_MAN="man" +MANM_MDOC="mdoc" +MANM_ROFF="roff" +MANM_EQN="eqn" +MANM_TBL="tbl" + INSTALL="install" INSTALL_PROGRAM= INSTALL_LIB= @@ -285,6 +295,11 @@ cat << __HEREDOC__ #define HAVE_OHASH ${HAVE_OHASH} #define HAVE_MANPATH ${HAVE_MANPATH} +#define BINM_APROPOS "${BINM_APROPOS}" +#define BINM_MAN "${BINM_MAN}" +#define BINM_WHATIS "${BINM_WHATIS}" +#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}" + #if !defined(__BEGIN_DECLS) # ifdef __cplusplus # define __BEGIN_DECLS extern "C" { @@ -358,12 +373,15 @@ if [ ${BUILD_DB} -eq 0 -a ${BUILD_CGI} -gt 0 ]; then fi BUILD_TARGETS="base-build" -[ ${BUILD_DB} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} db-build" [ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} cgi-build" +INSTALL_TARGETS="base-install" +[ ${BUILD_DB} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} db-install" +[ ${BUILD_CGI} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} cgi-install" cat << __HEREDOC__ VERSION = ${VERSION} BUILD_TARGETS = ${BUILD_TARGETS} +INSTALL_TARGETS = ${INSTALL_TARGETS} CFLAGS = ${CFLAGS} DBLIB = ${DBLIB} STATIC = ${STATIC} @@ -377,6 +395,15 @@ EXAMPLEDIR = ${EXAMPLEDIR} WWWPREFIX = ${WWWPREFIX} HTDOCDIR = ${HTDOCDIR} CGIBINDIR = ${CGIBINDIR} +BINM_APROPOS = ${BINM_APROPOS} +BINM_MAN = ${BINM_MAN} +BINM_WHATIS = ${BINM_WHATIS} +BINM_MAKEWHATIS = ${BINM_MAKEWHATIS} +MANM_MAN = ${MANM_MAN} +MANM_MDOC = ${MANM_MDOC} +MANM_ROFF = ${MANM_ROFF} +MANM_EQN = ${MANM_EQN} +MANM_TBL = ${MANM_TBL} INSTALL = ${INSTALL} INSTALL_PROGRAM = ${INSTALL_PROGRAM} INSTALL_LIB = ${INSTALL_LIB} @@ -385,7 +412,7 @@ INSTALL_DATA = ${INSTALL_DATA} __HEREDOC__ [ ${BUILD_DB} -gt 0 ] && \ - echo "MAN_OBJS = \$(MANDOC_OBJS) \$(APROPOS_OBJS)" + echo "MAIN_OBJS = \$(BASE_OBJS) \$(DB_OBJS)" echo "Makefile.local: written" 1>&2 echo "Makefile.local: written" 1>&3 diff --git a/configure.local.example b/configure.local.example index 76dcc629762..037d48a48f9 100644 --- a/configure.local.example +++ b/configure.local.example @@ -1,4 +1,4 @@ -# $Id: configure.local.example,v 1.1 2014/08/16 19:00:01 schwarze Exp $ +# $Id: configure.local.example,v 1.2 2014/12/09 09:14:33 schwarze Exp $ # # Copyright (c) 2014 Ingo Schwarze # @@ -58,7 +58,7 @@ HAVE_WCHAR=0 # If you do not want uname(3) to be called but instead want a fixed # string to be used, use the following line: -OSNAME="OpenBSD 5.5" +OSNAME="OpenBSD 5.6" # The following installation directories are used. # It is possible to set only one or a few of these variables, @@ -74,6 +74,19 @@ LIBDIR="${PREFIX}/lib/mandoc" MANDIR="${PREFIX}/man" EXAMPLEDIR="${PREFIX}/share/examples/mandoc" +# Some distributions may want to avoid naming conflicts among manuals. +# If you want to change the names of installed section 7 manual pages, +# the following alternative names are suggested. +# The suffix ".7" will automatically be appended. +# It is possible to set only one or a few of these variables, +# there is no need to copy the whole block. + +MANM_MAN="mandoc_man" # default is "man" +MANM_MDOC="mandoc_mdoc" # default is "mdoc" +MANM_ROFF="mandoc_roff" # default is "roff" +MANM_EQN="mandoc_eqn" # default is "eqn" +MANM_TBL="mandoc_tbl" # default is "tbl" + # It is possible to change the utility program used for installation # and the modes files are installed with. The defaults are: @@ -125,6 +138,21 @@ HAVE_MANPATH=1 HAVE_MANPATH=0 +# Some distributions may want to avoid naming conflicts +# with groff, man-db, or other tools. +# If you want to change the names of binary programs, +# the following alternative names are suggested. +# Using other names is possible as well. +# This changes the names of the installed section 1 and section 8 +# manual pages as well. +# It is possible to set only one or a few of these variables, +# there is no need to copy the whole block. + +BINM_APROPOS=mapropos # default is "apropos" +BINM_MAN=mman # default is "man" +BINM_WHATIS=mwhatis # default is "whatis" +BINM_MAKEWHATIS=mandocdb # default is "makewhatis" + # --- user settings related man.cgi ------------------------------------ # By default, building man.cgi(8) is disabled. To enable it, copy diff --git a/example.style.css b/example.style.css index d7d7e857138..905412b52d3 100644 --- a/example.style.css +++ b/example.style.css @@ -1,4 +1,4 @@ -/* $Id: example.style.css,v 1.53 2014/09/27 11:16:24 kristaps Exp $ */ +/* $Id: example.style.css,v 1.54 2014/12/10 22:19:45 schwarze Exp $ */ /* * This is an example style-sheet provided for mandoc(1) and the -Thtml * or -Txhtml output mode. @@ -20,11 +20,14 @@ div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */ div.mandoc table.synopsis { } /* SYNOPSIS section table. */ div.mandoc table.foot { } /* Document footer. */ div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */ -div.mandoc td.foot-os { width: 50%; } /* Document footer: OS/source. */ +div.mandoc td.foot-os { width: 50%; + text-align: right; } /* Document footer: OS/source. */ div.mandoc table.head { } /* Document header. */ div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */ -div.mandoc td.head-vol { width: 80%; } /* Document header: volume. */ -div.mandoc td.head-rtitle { width: 10%; } /* Document header: right-title. */ +div.mandoc td.head-vol { width: 80%; + text-align: center; } /* Document header: volume. */ +div.mandoc td.head-rtitle { width: 10%; + text-align: right; } /* Document header: right-title. */ div.mandoc .display { } /* All Bd, D1, Dl. */ div.mandoc .list { } /* All Bl. */ div.mandoc i { } /* Italic: BI, IB, I, (implicit). */ diff --git a/html.c b/html.c index 050fefe698a..fe16224e8e3 100644 --- a/html.c +++ b/html.c @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.181 2014/10/29 00:17:43 schwarze Exp $ */ +/* $Id: html.c,v 1.183 2014/12/02 10:08:06 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze @@ -30,7 +30,6 @@ #include "mandoc.h" #include "mandoc_aux.h" -#include "libmandoc.h" #include "out.h" #include "html.h" #include "main.h" @@ -563,8 +562,9 @@ print_text(struct html *h, const char *word) if ( ! print_encode(h, word, 0)) { if ( ! (h->flags & HTML_NONOSPACE)) h->flags &= ~HTML_NOSPACE; + h->flags &= ~HTML_NONEWLINE; } else - h->flags |= HTML_NOSPACE; + h->flags |= HTML_NOSPACE | HTML_NONEWLINE; if (h->metaf) { print_tagq(h, h->metaf); diff --git a/html.h b/html.h index 521635f96fd..bbf6183cc5c 100644 --- a/html.h +++ b/html.h @@ -1,4 +1,4 @@ -/* $Id: html.h,v 1.67 2014/10/28 17:36:19 schwarze Exp $ */ +/* $Id: html.h,v 1.70 2014/12/02 10:08:06 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * @@ -14,10 +14,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef HTML_H -#define HTML_H - -__BEGIN_DECLS enum htmltag { TAG_HTML, @@ -130,6 +126,7 @@ struct html { #define HTML_SKIPCHAR (1 << 6) /* skip the next character */ #define HTML_NOSPLIT (1 << 7) /* do not break line before .An */ #define HTML_SPLIT (1 << 8) /* break line before .An */ +#define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */ struct tagq tags; /* stack of open tags */ struct rofftbl tbl; /* current table */ struct tag *tblt; /* current open table scope */ @@ -146,6 +143,11 @@ struct html { #define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */ }; +__BEGIN_DECLS + +struct tbl_span; +struct eqn; + void print_gen_decls(struct html *); void print_gen_head(struct html *); struct tag *print_otag(struct html *, enum htmltag, @@ -176,5 +178,3 @@ void buffmt_includes(struct html *, const char *); int html_strlen(const char *); __END_DECLS - -#endif /*!HTML_H*/ diff --git a/libman.h b/libman.h index 8f66013ab24..b26c2b60efe 100644 --- a/libman.h +++ b/libman.h @@ -1,4 +1,4 @@ -/* $Id: libman.h,v 1.65 2014/11/28 05:51:32 schwarze Exp $ */ +/* $Id: libman.h,v 1.66 2014/12/01 04:05:31 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef LIBMAN_H -#define LIBMAN_H enum man_next { MAN_NEXT_SIBLING = 0, @@ -75,5 +73,3 @@ void man_valid_post(struct man *); void man_unscope(struct man *, const struct man_node *); __END_DECLS - -#endif /*!LIBMAN_H*/ diff --git a/libmandoc.h b/libmandoc.h index c5a8d5cd73e..6aa8b8dcf0f 100644 --- a/libmandoc.h +++ b/libmandoc.h @@ -1,4 +1,4 @@ -/* $Id: libmandoc.h,v 1.49 2014/11/28 06:27:05 schwarze Exp $ */ +/* $Id: libmandoc.h,v 1.51 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef LIBMANDOC_H -#define LIBMANDOC_H enum rofferr { ROFF_CONT, /* continue processing line */ @@ -37,6 +35,11 @@ struct buf { __BEGIN_DECLS +struct mparse; +struct mchars; +enum mandocerr; +struct tbl_span; +struct eqn; struct roff; struct mdoc; struct man; @@ -91,5 +94,3 @@ const struct tbl_span *roff_span(const struct roff *); const struct eqn *roff_eqn(const struct roff *); __END_DECLS - -#endif /*!LIBMANDOC_H*/ diff --git a/libmdoc.h b/libmdoc.h index 056e9c9b052..b245213a8f2 100644 --- a/libmdoc.h +++ b/libmdoc.h @@ -1,4 +1,4 @@ -/* $Id: libmdoc.h,v 1.95 2014/11/29 03:37:44 schwarze Exp $ */ +/* $Id: libmdoc.h,v 1.96 2014/12/01 04:05:32 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef LIBMDOC_H -#define LIBMDOC_H enum mdoc_next { MDOC_NEXT_SIBLING = 0, @@ -129,5 +127,3 @@ void mdoc_macroend(struct mdoc *); enum mdelim mdoc_isdelim(const char *); __END_DECLS - -#endif /*!LIBMDOC_H*/ diff --git a/libroff.h b/libroff.h index bd9bcd220e4..dd7ad75a947 100644 --- a/libroff.h +++ b/libroff.h @@ -1,4 +1,4 @@ -/* $Id: libroff.h,v 1.31 2014/10/25 14:35:37 schwarze Exp $ */ +/* $Id: libroff.h,v 1.33 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -15,10 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef LIBROFF_H -#define LIBROFF_H - -__BEGIN_DECLS enum tbl_part { TBL_PART_OPTS, /* in options (first line) */ @@ -66,6 +62,8 @@ struct eqn_def { size_t valsz; }; +__BEGIN_DECLS + struct tbl_node *tbl_alloc(int, int, struct mparse *); void tbl_restart(int, int, struct tbl_node *); void tbl_free(struct tbl_node *); @@ -84,5 +82,3 @@ enum rofferr eqn_read(struct eqn_node **, int, const char *, int, int *); __END_DECLS - -#endif /*LIBROFF_H*/ diff --git a/main.c b/main.c index 34784994ced..ec6e9800647 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.200 2014/11/26 21:40:17 schwarze Exp $ */ +/* $Id: main.c,v 1.205 2014/12/11 19:19:35 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze @@ -83,12 +83,17 @@ struct curparse { }; static int koptions(int *, char *); +#if HAVE_SQLITE3 +int mandocdb(int, char**); +#endif static int moptions(int *, char *); static void mmsg(enum mandocerr, enum mandoclevel, const char *, int, int, const char *); static void parse(struct curparse *, int, const char *, enum mandoclevel *); +#if HAVE_SQLITE3 static enum mandoclevel passthrough(const char *, int, int); +#endif static void spawn_pager(void); static int toptions(struct curparse *, char *); static void usage(enum argmode) __attribute__((noreturn)); @@ -96,6 +101,8 @@ static void version(void) __attribute__((noreturn)); static int woptions(struct curparse *, char *); static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9}; +static char help_arg[] = "help"; +static char *help_argv[] = {help_arg, NULL}; static const char *progname; @@ -105,12 +112,13 @@ main(int argc, char *argv[]) struct curparse curp; struct mansearch search; struct manpaths paths; - char *conf_file, *defpaths, *auxpaths; + char *auxpaths; char *defos; #if HAVE_SQLITE3 struct manpage *res, *resp; + char *conf_file, *defpaths; size_t isec, i, sz; - int prio, best_prio; + int prio, best_prio, synopsis_only; char sec; #endif enum mandoclevel rc; @@ -118,7 +126,6 @@ main(int argc, char *argv[]) int fd; int show_usage; int use_pager; - int synopsis_only; int options; int c; @@ -128,34 +135,46 @@ main(int argc, char *argv[]) else ++progname; +#if HAVE_SQLITE3 + if (strcmp(progname, BINM_MAKEWHATIS) == 0) + return(mandocdb(argc, argv)); +#endif + /* Search options. */ memset(&paths, 0, sizeof(struct manpaths)); - conf_file = defpaths = auxpaths = NULL; +#if HAVE_SQLITE3 + conf_file = defpaths = NULL; +#endif + auxpaths = NULL; memset(&search, 0, sizeof(struct mansearch)); search.outkey = "Nd"; - if (strcmp(progname, "man") == 0) + if (strcmp(progname, BINM_MAN) == 0) search.argmode = ARG_NAME; - else if (strncmp(progname, "apropos", 7) == 0) + else if (strcmp(progname, BINM_APROPOS) == 0) search.argmode = ARG_EXPR; - else if (strncmp(progname, "whatis", 6) == 0) + else if (strcmp(progname, BINM_WHATIS) == 0) search.argmode = ARG_WORD; + else if (strncmp(progname, "help", 4) == 0) + search.argmode = ARG_NAME; else search.argmode = ARG_FILE; /* Parser and formatter options. */ memset(&curp, 0, sizeof(struct curparse)); - curp.outtype = OUTT_ASCII; + curp.outtype = OUTT_LOCALE; curp.wlevel = MANDOCLEVEL_FATAL; options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1; defos = NULL; use_pager = 1; show_usage = 0; +#if HAVE_SQLITE3 synopsis_only = 0; +#endif outmode = OUTMODE_DEF; while (-1 != (c = getopt(argc, argv, @@ -165,7 +184,9 @@ main(int argc, char *argv[]) outmode = OUTMODE_ALL; break; case 'C': +#if HAVE_SQLITE3 conf_file = optarg; +#endif break; case 'c': use_pager = 0; @@ -175,7 +196,9 @@ main(int argc, char *argv[]) break; case 'h': (void)strlcat(curp.outopts, "synopsis,", BUFSIZ); +#if HAVE_SQLITE3 synopsis_only = 1; +#endif use_pager = 0; outmode = OUTMODE_ALL; break; @@ -209,7 +232,9 @@ main(int argc, char *argv[]) outmode = OUTMODE_ALL; break; case 'M': +#if HAVE_SQLITE3 defpaths = optarg; +#endif break; case 'm': auxpaths = optarg; @@ -273,15 +298,24 @@ main(int argc, char *argv[]) resp = NULL; #endif - /* Quirk for a man(1) section argument without -s. */ + /* + * Quirks for help(1) + * and for a man(1) section argument without -s. + */ - if (search.argmode == ARG_NAME && - argv[0] != NULL && - isdigit((unsigned char)argv[0][0]) && - (argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) { - search.sec = argv[0]; - argv++; - argc--; + if (search.argmode == ARG_NAME) { + if (*progname == 'h') { + if (argc == 0) { + argv = help_argv; + argc = 1; + } + } else if (argv[0] != NULL && + isdigit((unsigned char)argv[0][0]) && + (argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) { + search.sec = argv[0]; + argv++; + argc--; + } } rc = MANDOCLEVEL_OK; @@ -583,6 +617,7 @@ parse(struct curparse *curp, int fd, const char *file, *level = rc; } +#if HAVE_SQLITE3 static enum mandoclevel passthrough(const char *file, int fd, int synopsis_only) { @@ -646,6 +681,7 @@ fail: progname, file, syscall, strerror(errno)); return(MANDOCLEVEL_SYSERR); } +#endif static int koptions(int *options, char *arg) diff --git a/main.h b/main.h index c7768e3bb16..147c22f5946 100644 --- a/main.h +++ b/main.h @@ -1,4 +1,4 @@ -/* $Id: main.h,v 1.17 2014/10/28 17:36:19 schwarze Exp $ */ +/* $Id: main.h,v 1.19 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -14,16 +14,14 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MAIN_H -#define MAIN_H - -__BEGIN_DECLS - -struct mdoc; -struct man; #define UNCONST(a) ((void *)(uintptr_t)(const void *)(a)) +__BEGIN_DECLS + +struct mchars; +struct mdoc; +struct man; /* * Definitions for main.c-visible output device functions, e.g., -Thtml @@ -56,5 +54,3 @@ void terminal_mdoc(void *, const struct mdoc *); void terminal_man(void *, const struct man *); __END_DECLS - -#endif /*!MAIN_H*/ diff --git a/man.h b/man.h index 22827c53769..08bfcc8e4de 100644 --- a/man.h +++ b/man.h @@ -1,4 +1,4 @@ -/* $Id: man.h,v 1.66 2014/11/28 05:51:32 schwarze Exp $ */ +/* $Id: man.h,v 1.67 2014/12/01 04:05:32 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MAN_H -#define MAN_H enum mant { MAN_br = 0, @@ -116,5 +114,3 @@ const struct mparse *man_mparse(const struct man *); void man_deroff(char **, const struct man_node *); __END_DECLS - -#endif /*!MAN_H*/ diff --git a/man_hash.c b/man_hash.c index c52add28efa..1cbfb1b7f8e 100644 --- a/man_hash.c +++ b/man_hash.c @@ -1,4 +1,4 @@ -/* $Id: man_hash.c,v 1.28 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: man_hash.c,v 1.29 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons * @@ -24,7 +24,6 @@ #include #include "man.h" -#include "mandoc.h" #include "libman.h" #define HASH_DEPTH 6 diff --git a/man_html.c b/man_html.c index 6fe40a974b0..1455e1e4aec 100644 --- a/man_html.c +++ b/man_html.c @@ -1,4 +1,4 @@ -/* $Id: man_html.c,v 1.104 2014/09/27 11:17:19 kristaps Exp $ */ +/* $Id: man_html.c,v 1.107 2014/12/04 02:05:42 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -25,11 +25,10 @@ #include #include -#include "mandoc.h" #include "mandoc_aux.h" +#include "man.h" #include "out.h" #include "html.h" -#include "man.h" #include "main.h" /* TODO: preserve ident widths. */ @@ -213,21 +212,14 @@ print_man_node(MAN_ARGS) man_root_pre(man, n, mh, h); break; case MAN_TEXT: - /* - * If we have a blank line, output a vertical space. - * If we have a space as the first character, break - * before printing the line's data. - */ if ('\0' == *n->string) { print_paragraph(h); return; } - - if (' ' == *n->string && MAN_LINE & n->flags) + if (n->flags & MAN_LINE && (*n->string == ' ' || + (n->prev != NULL && mh->fl & MANH_LITERAL && + ! (h->flags & HTML_NONEWLINE)))) print_otag(h, TAG_BR, 0, NULL); - else if (MANH_LITERAL & mh->fl && n->prev) - print_otag(h, TAG_BR, 0, NULL); - print_text(h, n->string); return; case MAN_EQN: @@ -290,7 +282,7 @@ a2width(const struct man_node *n, struct roffsu *su) if (MAN_TEXT != n->type) return(0); - if (a2roffsu(n->string, su, SCALE_BU)) + if (a2roffsu(n->string, su, SCALE_EN)) return(1); return(0); diff --git a/man_term.c b/man_term.c index 2531f816f76..9a9abafdbc5 100644 --- a/man_term.c +++ b/man_term.c @@ -1,4 +1,4 @@ -/* $Id: man_term.c,v 1.156 2014/11/21 01:52:53 schwarze Exp $ */ +/* $Id: man_term.c,v 1.159 2014/12/04 02:05:42 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -123,7 +123,7 @@ static const struct termact termacts[MAN_MAX] = { { NULL, NULL, 0 }, /* RE */ { pre_RS, post_RS, 0 }, /* RS */ { pre_ign, NULL, 0 }, /* DT */ - { pre_ign, NULL, 0 }, /* UC */ + { pre_ign, NULL, MAN_NOTEXT }, /* UC */ { pre_PD, NULL, MAN_NOTEXT }, /* PD */ { pre_ign, NULL, 0 }, /* AT */ { pre_in, NULL, MAN_NOTEXT }, /* in */ @@ -201,7 +201,7 @@ a2width(const struct termp *p, const char *cp) { struct roffsu su; - if ( ! a2roffsu(cp, &su, SCALE_BU)) + if ( ! a2roffsu(cp, &su, SCALE_EN)) return(-1); return((int)term_hspan(p, &su)); @@ -778,12 +778,18 @@ pre_SS(DECL_ARGS) mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); - /* If following a prior empty `SS', no vspace. */ - if (n->prev && MAN_SS == n->prev->tok) - if (NULL == n->prev->body->child) - break; - if (NULL == n->prev) + + /* + * No vertical space before the first subsection + * and after an empty subsection. + */ + + do { + n = n->prev; + } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT); + if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL)) break; + for (i = 0; i < mt->pardist; i++) term_vspace(p); break; @@ -827,13 +833,18 @@ pre_SH(DECL_ARGS) mt->fl &= ~MANT_LITERAL; mt->lmargin[mt->lmargincur] = term_len(p, p->defindent); mt->offset = term_len(p, p->defindent); - /* If following a prior empty `SH', no vspace. */ - if (n->prev && MAN_SH == n->prev->tok) - if (NULL == n->prev->body->child) - break; - /* If the first macro, no vspae. */ - if (NULL == n->prev) + + /* + * No vertical space before the first section + * and after an empty section. + */ + + do { + n = n->prev; + } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT); + if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL)) break; + for (i = 0; i < mt->pardist; i++) term_vspace(p); break; @@ -1018,13 +1029,14 @@ out: * -man doesn't have nested macros, we don't need to be * more specific than this. */ - if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) && - (NULL == n->next || MAN_LINE & n->next->flags)) { + if (mt->fl & MANT_LITERAL && + ! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) && + (n->next == NULL || n->next->flags & MAN_LINE)) { rm = p->rmargin; rmax = p->maxrmargin; p->rmargin = p->maxrmargin = TERM_MAXMARGIN; p->flags |= TERMP_NOSPACE; - if (NULL != n->string && '\0' != *n->string) + if (n->string != NULL && *n->string != '\0') term_flushln(p); else term_newln(p); diff --git a/mandoc.1 b/mandoc.1 index 9f2d6ba71f3..45a6b0cf7e6 100644 --- a/mandoc.1 +++ b/mandoc.1 @@ -1,4 +1,4 @@ -.\" $Id: mandoc.1,v 1.125 2014/11/28 18:09:01 schwarze Exp $ +.\" $Id: mandoc.1,v 1.128 2014/12/02 11:31:51 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2012, 2014 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 28 2014 $ +.Dd $Mdocdate: December 2 2014 $ .Dt MANDOC 1 .Os .Sh NAME @@ -49,7 +49,7 @@ or text from stdin, implying .Fl m Ns Cm andoc , and produces -.Fl T Ns Cm ascii +.Fl T Ns Cm locale output. .Pp The options are as follows: @@ -146,7 +146,7 @@ See .Sx Output Formats for available formats. Defaults to -.Fl T Ns Cm ascii . +.Fl T Ns Cm locale . .It Fl V Print version and exit. .It Fl W Ns Ar level @@ -255,7 +255,6 @@ arguments, which correspond to output modes: .Bl -tag -width "-Tlocale" .It Fl T Ns Cm ascii Produce 7-bit ASCII output. -This is the default. See .Sx ASCII Output . .It Fl T Ns Cm html @@ -268,6 +267,7 @@ Implies .Fl W Ns Cm warning . .It Fl T Ns Cm locale Encode output using the current locale. +This is the default. See .Sx Locale Output . .It Fl T Ns Cm man @@ -299,8 +299,8 @@ If multiple input files are specified, these will be processed by the corresponding filter in-order. .Ss ASCII Output Output produced by -.Fl T Ns Cm ascii , -which is the default, is rendered in standard 7-bit ASCII documented in +.Fl T Ns Cm ascii +is rendered in standard 7-bit ASCII documented in .Xr ascii 7 . .Pp Font styles are applied by using back-spaced encoding such that an @@ -413,6 +413,8 @@ relative URI. .Ss Locale Output Locale-depending output encoding is triggered with .Fl T Ns Cm locale . +This is the default. +.Pp This option is not available on all systems: systems without locale support, or those whose internal representation is not natively UCS-4, will fall back to @@ -803,6 +805,13 @@ Probably, there are author names lacking markup. See the .Xr mdoc 7 manual for replacements. +.It Sy "macro neither callable nor escaped" +.Pq mdoc +The name of a macro that is not callable appears on a macro line. +It is printed verbatim. +If the intention is to call it, move it to its own line; +otherwise, escape it by prepending +.Sq \e& . .It Sy "skipping paragraph macro" In .Xr mdoc 7 @@ -1047,6 +1056,14 @@ argument is invalid. The default font .Cm \efR is used instead. +.It Sy "nothing follows prefix" +.Pq mdoc +A +.Ic \&Pf +macro has no argument, or only one argument and no macro follows +on the same input line. +This defeats its purpose; in particular, spacing is not suppressed +before the text or macros following on the next input line. .It Sy "missing -std argument, adding it" .Pq mdoc An diff --git a/mandoc.h b/mandoc.h index 98578ed4545..e4cdccbc43f 100644 --- a/mandoc.h +++ b/mandoc.h @@ -1,4 +1,4 @@ -/* $Id: mandoc.h,v 1.171 2014/11/28 18:09:01 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.176 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MANDOC_H -#define MANDOC_H #define ASCII_NBRSP 31 /* non-breaking space */ #define ASCII_HYPH 30 /* breakable hyphen */ @@ -77,6 +75,7 @@ enum mandocerr { /* related to macros and nesting */ MANDOCERR_MACRO_OBS, /* obsolete macro: macro */ + MANDOCERR_MACRO_CALL, /* macro neither callable nor escaped: macro */ MANDOCERR_PAR_SKIP, /* skipping paragraph macro: macro ... */ MANDOCERR_PAR_MOVE, /* moving paragraph macro out of list: macro */ MANDOCERR_NS_SKIP, /* skipping no-space macro */ @@ -102,6 +101,7 @@ enum mandocerr { MANDOCERR_IT_NOBODY, /* empty list item: Bl -type It */ MANDOCERR_BF_NOFONT, /* missing font type, using \fR: Bf */ MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */ + MANDOCERR_PF_SKIP, /* nothing follows prefix: Pf arg */ MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */ MANDOCERR_EQN_NOBOX, /* missing eqn box, using "": op */ @@ -414,13 +414,13 @@ enum mandoc_esc { typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel, const char *, int, int, const char *); +__BEGIN_DECLS + struct mparse; struct mchars; struct mdoc; struct man; -__BEGIN_DECLS - enum mandoc_esc mandoc_escape(const char **, const char **, int *); struct mchars *mchars_alloc(void); void mchars_free(struct mchars *); @@ -437,7 +437,7 @@ void mparse_free(struct mparse *); void mparse_keep(struct mparse *); enum mandoclevel mparse_open(struct mparse *, int *, const char *); enum mandoclevel mparse_readfd(struct mparse *, int, const char *); -enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t, +enum mandoclevel mparse_readmem(struct mparse *, void *, size_t, const char *); void mparse_reset(struct mparse *); void mparse_result(struct mparse *, @@ -448,5 +448,3 @@ const char *mparse_strlevel(enum mandoclevel); enum mandoclevel mparse_wait(struct mparse *); __END_DECLS - -#endif /*!MANDOC_H*/ diff --git a/mandoc_aux.h b/mandoc_aux.h index 04f4baff606..e72fe4e40ed 100644 --- a/mandoc_aux.h +++ b/mandoc_aux.h @@ -1,4 +1,4 @@ -/* $Id: mandoc_aux.h,v 1.2 2014/04/23 21:06:41 schwarze Exp $ */ +/* $Id: mandoc_aux.h,v 1.3 2014/12/01 04:05:32 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MANDOC_AUX_H -#define MANDOC_AUX_H __BEGIN_DECLS @@ -29,5 +27,3 @@ char *mandoc_strdup(const char *); char *mandoc_strndup(const char *, size_t); __END_DECLS - -#endif /*!MANDOC_AUX_H*/ diff --git a/mandoc_headers.3 b/mandoc_headers.3 new file mode 100644 index 00000000000..aa8754e46ec --- /dev/null +++ b/mandoc_headers.3 @@ -0,0 +1,511 @@ +.Dd December 1, 2014 +.Dt MANDOC_HEADERS 3 +.Os +.Sh NAME +.Nm mandoc_headers +.Nd ordering of mandoc include files +.Sh DESCRIPTION +To support a cleaner coding style, the mandoc header files do not +contain any include directives and do not guard against multiple +inclusion. +The application developer has to make sure that the headers are +included in a proper order, and that no header is included more +than once. +.Pp +The headers and functions form three major groups: +.Sx Parser interface , +.Sx Parser internals , +and +.Sx Formatter interface . +.Pp +Various rules are given below prohibiting the inclusion of certain +combinations of headers into the same file. +The intention is to keep the following functional components +separate from each other: +.Pp +.Bl -dash -offset indent -compact +.It +.Xr mdoc 7 +parser +.It +.Xr man 7 +parser +.It +.Xr roff 7 +parser +.It +.Xr tbl 7 +parser +.It +.Xr eqn 7 +parser +.It +terminal formatters +.It +HTML formatters +.It +search tools +.El +.Pp +Note that mere usage of an opaque type does +.Em not +require inclusion of the header where that type is defined. +.Ss Parser interface +Each of the following headers can be included without including +any other mandoc header. +These headers should be included before any other mandoc headers. +Afterwards, any other mandoc headers can be included as needed. +.Bl -tag -width Ds +.It Qq Pa mandoc_aux.h +Requires +.In sys/types.h +for +.Vt size_t . +Provides the utility functions documented in +.Xr mandoc_malloc 3 . +.It Qq Pa mandoc.h +Requires +.In sys/types.h +for +.Vt size_t . +.Pp +Provides +.Vt enum mandoc_esc , +.Vt enum mandocerr , +.Vt enum mandoclevel , +.Vt enum tbl_cellt , +.Vt enum tbl_datt , +.Vt enum tbl_spant , +.Vt enum eqn_boxt , +.Vt enum eqn_fontt , +.Vt enum eqn_pilet , +.Vt enum eqn_post , +.Vt struct tbl_opts , +.Vt struct tbl_head , +.Vt struct tbl_cell , +.Vt struct tbl_row , +.Vt struct tbl_dat , +.Vt struct tbl_span , +.Vt struct eqn_box , +.Vt struct eqn , +the function prototype typedef +.Fn mandocmsg , +the function +.Xr mandoc_escape 3 , +the functions described in +.Xr mchars_alloc 3 , +and the functions +.Fn mparse_* +described in +.Xr mandoc 3 . +.Pp +Uses the opaque types +.Vt struct mparse +from +.Pa read.c +and +.Vt struct mchars +from +.Pa chars.c +for function prototypes. +Uses the types +.Vt struct mdoc +from +.Pa libmdoc.h +and +.Vt struct man +from +.Pa libman.h +as opaque types for function prototypes. +.It Qq Pa mdoc.h +Requires +.In sys/types.h +for +.Vt size_t . +.Pp +Provides +.Vt enum mdoct , +.Vt enum mdocargt , +.Vt enum mdoc_type , +.Vt enum mdoc_sec , +.Vt enum mdoc_endbody , +.Vt enum mdoc_disp , +.Vt enum mdoc_list , +.Vt enum mdoc_auth , +.Vt enum mdoc_font , +.Vt struct mdoc_meta , +.Vt struct mdoc_argv , +.Vt struct mdoc_arg , +.Vt struct mdoc_bd , +.Vt struct mdoc_bl , +.Vt struct mdoc_an , +.Vt struct mdoc_bf , +.Vt struct mdoc_rs , +.Vt struct mdoc_node , +and the functions +.Fn mdoc_* +described in +.Xr mandoc 3 . +.Pp +Uses the type +.Vt struct mdoc +from +.Pa libmdoc.h +as an opaque type for function prototypes. +Uses pointers to the types +.Vt struct tbl_span +and +.Vt struct eqn +as opaque struct members. +.Pp +When this header is included, the same file should not include +.Pa libman.h +or +.Pa libroff.h . +.It Qq Pa man.h +Provides +.Vt enum mant , +.Vt enum man_type , +.Vt struct man_meta , +.Vt struct man_node , +and the functions +.Fn man_* +described in +.Xr mandoc 3 . +.Pp +Uses the opaque type +.Vt struct mparse +from +.Pa read.c +for function prototypes. +Uses the type +.Vt struct man +from +.Pa libman.h +as an opaque type for function prototypes. +Uses pointers to the types +.Vt struct tbl_span +and +.Vt struct eqn +as opaque struct members. +.Pp +When this header is included, the same file should not include +.Pa libmdoc.h +or +.Pa libroff.h . +.El +.Ss Parser internals +The following headers require inclusion of a parser interface header +before they can be included. All parser interface headers should +precede all parser internal headers. When any parser internal headers +are included, the same file should not include any formatter headers. +.Bl -tag -width Ds +.It Qq Pa libmandoc.h +Requires +.In sys/types.h +for +.Vt size_t . +.Pp +Provides +.Vt enum rofferr , +.Vt struct buf , +utility functions needed by multiple parsers, +and the top-level functions to call the parsers. +.Pp +Uses the opaque types +.Vt struct mparse +from +.Pa read.c +and +.Vt struct roff +from +.Pa roff.c +for function prototypes. +Uses the types +.Vt enum mandocerr , +.Vt struct tbl_span , +and +.Vt struct eqn +from +.Pa mandoc.h , +.Vt struct mdoc +from +.Pa libmdoc.h , +and +.Vt struct man +from +.Pa libman.h +as opaque types for function prototypes. +.It Qq Pa libmdoc.h +Requires +.Qq Pa mdoc.h +for +.Vt enum mdoct , +.Vt enum mdoc_* , +and +.Vt struct mdoc_* . +.Pp +Provides +.Vt enum mdoc_next , +.Vt enum margserr , +.Vt enum mdelim , +.Vt struct mdoc , +.Vt struct mdoc_macro , +and many functions internal to the +.Xr mdoc 7 +parser. +.Pp +Uses the opaque types +.Vt struct mparse +from +.Pa read.c +and +.Vt struct roff +from +.Pa roff.c . +.Pp +When this header is included, the same file should not include +.Pa man.h , +.Pa libman.h , +or +.Pa libroff.h . +.It Qq Pa libman.h +Requires +.Qq Pa man.h +for +.Vt enum mant +and +.Vt struct man_node. +.Pp +Provides +.Vt enum man_next , +.Vt struct man , +.Vt struct man_macro , +and many functions internal to the +.Xr man 7 +parser. +.Pp +Uses the opaque types +.Vt struct mparse +from +.Pa read.c +and +.Vt struct roff +from +.Pa roff.c . +.Pp +When this header is included, the same file should not include +.Pa mdoc.h , +.Pa libmdoc.h , +or +.Pa libroff.h . +.It Qq Pa libroff.h +Requires +.In sys/types.h +for +.Vt size_t , +.Qq Pa mandoc.h +for +.Vt struct tbl_* +and +.Vt struct eqn , +and +.Qq Pa libmandoc.h +for +.Vt enum rofferr . +.Pp +Provides +.Vt enum tbl_part , +.Vt struct tbl_node , +.Vt struct eqn_def , +.Vt struct eqn_node , +and many functions internal to the +.Xr tbl 7 +and +.Xr eqn 7 +parsers. +.Pp +Uses the opaque type +.Vt struct mparse +from +.Pa read.c . +.Pp +When this header is included, the same file should not include +.Pa man.h , +.Pa mdoc.h , +.Pa libman.h , +or +.Pa libmdoc.h . +.El +.Ss Formatter interface +These headers should be included after any parser interface headers. +No parser internal headers should be included by the same file. +.Bl -tag -width Ds +.It Qq Pa out.h +Requires +.In sys/types.h +for +.Vt size_t . +.Pp +Provides +.Vt enum roffscale , +.Vt struct roffcol , +.Vt struct roffsu , +.Vt struct rofftbl , +.Fn a2roffsu , +and +.Fn tblcalc . +.Pp +Uses +.Vt struct tbl_span +from +.Pa mandoc.h +as an opaque type for function prototypes. +.Pp +When this header is included, the same file should not include +.Pa manpath.h +or +.Pa mansearch.h . +.It Qq Pa term.h +Requires +.In sys/types.h +for +.Vt size_t +and +.Qq Pa out.h +for +.Vt struct roffsu +and +.Vt struct rofftbl . +.Pp +Provides +.Vt enum termenc , +.Vt enum termfont , +.Vt enum termtype , +.Vt struct termp_tbl , +.Vt struct termp , +and many terminal formatting functions. +.Pp +Uses the opaque types +.Vt struct mchars +from +.Pa chars.c +and +.Vt struct termp_ps +from +.Pa term_ps.c . +Uses +.Vt struct tbl_span +and +.Vt struct eqn +from +.Pa mandoc.h +as opaque types for function prototypes. +.Pp +When this header is included, the same file should not include +.Pa html.h , +.Pa manpath.h +or +.Pa mansearch.h . +.It Qq Pa html.h +Requires +.In sys/types.h +for +.Vt size_t , +.In stdio.h +for +.Dv BUFSIZ , +and +.Qq Pa out.h +for +.Vt struct roffsu +and +.Vt struct rofftbl . +.Pp +Provides +.Vt enum htmltag , +.Vt enum htmlattr , +.Vt enum htmlfont , +.Vt struct tag , +.Vt struct tagq , +.Vt struct htmlpair , +.Vt struct html , +and many HTML formatting functions. +.Pp +Uses the opaque type +.Vt struct mchars +from +.Pa chars.c . +.Pp +When this header is included, the same file should not include +.Pa term.h , +.Pa manpath.h +or +.Pa mansearch.h . +.It Qq Pa main.h +Provides the top level steering functions for all formatters. +.Pp +Uses the opaque type +.Vt struct mchars +from +.Pa chars.c . +Uses the types +.Vt struct mdoc +from +.Pa libmdoc.h +and +.Vt struct man +from +.Pa libman.h +as opaque types for function prototypes. +.It Qq Pa manpath.h +Requires +.In sys/types.h +for +.Vt size_t . +.Pp +Provides +.Vt struct manpaths +and the functions +.Fn manpath_manconf , +.Fn manpath_parse , +and +.Fn manpath_free . +.Pp +When this header is included, the same file should not include +.Pa out.h , +.Pa term.h , +or +.Pa html.h . +.It Qq Pa mansearch.h +Requires +.In sys/types.h +for +.Vt size_t +and +.In stdint.h +for +.Vt uint64_t . +.Pp +Provides +.Vt enum argmode , +.Vt struct manpage , +.Vt struct mansearch , +and the functions +.Fn mansearch_setup , +.Fn mansearch , +and +.Fn mansearch_free . +.Pp +Uses +.Vt struct manpaths +from +.Pa manpath.h +as an opaque type for function prototypes. +.Pp +When this header is included, the same file should not include +.Pa out.h , +.Pa term.h , +or +.Pa html.h . +.El diff --git a/mandocdb.c b/mandocdb.c index 4f6a062fe62..a2fac2027d5 100644 --- a/mandocdb.c +++ b/mandocdb.c @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.171 2014/11/27 01:58:21 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.179 2014/12/09 07:29:42 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze @@ -84,10 +84,9 @@ enum op { }; struct str { - char *rendered; /* key in UTF-8 or ASCII form */ const struct mpage *mpage; /* if set, the owning parse */ uint64_t mask; /* bitmask in sequence */ - char key[]; /* may contain escape sequences */ + char key[]; /* rendered text */ }; struct inodev { @@ -104,6 +103,7 @@ struct mpage { char *desc; /* description from file content */ struct mlink *mlinks; /* singly linked list */ int form; /* format from file content */ + int name_head_done; }; struct mlink { @@ -124,11 +124,13 @@ enum stmt { STMT_INSERT_PAGE, /* insert mpage */ STMT_INSERT_LINK, /* insert mlink */ STMT_INSERT_NAME, /* insert name */ + STMT_SELECT_NAME, /* retrieve existing name flags */ STMT_INSERT_KEY, /* insert parsed key */ STMT__MAX }; -typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_node *); +typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); struct mdoc_handler { mdoc_fp fp; /* optional handler */ @@ -136,7 +138,7 @@ struct mdoc_handler { }; static void dbclose(int); -static void dbadd(struct mpage *, struct mchars *); +static void dbadd(struct mpage *); static void dbadd_mlink(const struct mlink *mlink); static void dbadd_mlink_name(const struct mlink *mlink); static int dbopen(int); @@ -150,25 +152,37 @@ static void mlink_check(struct mpage *, struct mlink *); static void mlink_free(struct mlink *); static void mlinks_undupe(struct mpage *); static void mpages_free(void); -static void mpages_merge(struct mchars *, struct mparse *); +static void mpages_merge(struct mparse *); static void names_check(void); static void parse_cat(struct mpage *, int); -static void parse_man(struct mpage *, const struct man_node *); -static void parse_mdoc(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_body(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_head(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Fd(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Fn(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Nd(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Nm(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Sh(struct mpage *, const struct mdoc_node *); -static int parse_mdoc_Xr(struct mpage *, const struct mdoc_node *); +static void parse_man(struct mpage *, const struct man_meta *, + const struct man_node *); +static void parse_mdoc(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_body(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_head(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Fd(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static void parse_mdoc_fname(struct mpage *, const struct mdoc_node *); +static int parse_mdoc_Fn(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Fo(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Nd(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Nm(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Sh(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); +static int parse_mdoc_Xr(struct mpage *, const struct mdoc_meta *, + const struct mdoc_node *); static void putkey(const struct mpage *, char *, uint64_t); -static void putkeys(const struct mpage *, - const char *, size_t, uint64_t); +static void putkeys(const struct mpage *, char *, size_t, uint64_t); static void putmdockey(const struct mpage *, const struct mdoc_node *, uint64_t); -static void render_key(struct mchars *, struct str *); +static int render_string(char **, size_t *); static void say(const char *, const char *, ...); static int set_basedir(const char *, int); static int treescan(void); @@ -185,6 +199,7 @@ static int write_utf8; /* write UTF-8 output; else ASCII */ static int exitcode; /* to be returned by main */ static enum op op; /* operational mode */ static char basedir[PATH_MAX]; /* current base directory */ +static struct mchars *mchars; /* table of named characters */ static struct ohash mpages; /* table of distinct manual pages */ static struct ohash mlinks; /* table of directory entries */ static struct ohash names; /* table of all names */ @@ -290,7 +305,7 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = { { NULL, 0 }, /* Ux */ { NULL, 0 }, /* Xc */ { NULL, 0 }, /* Xo */ - { parse_mdoc_head, 0 }, /* Fo */ + { parse_mdoc_Fo, 0 }, /* Fo */ { NULL, 0 }, /* Fc */ { NULL, 0 }, /* Oo */ { NULL, 0 }, /* Oc */ @@ -321,12 +336,11 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = { int -main(int argc, char *argv[]) +mandocdb(int argc, char *argv[]) { int ch, i; size_t j, sz; const char *path_arg; - struct mchars *mc; struct manpaths dirs; struct mparse *mp; struct ohash_info mpages_info, mlinks_info; @@ -426,9 +440,9 @@ main(int argc, char *argv[]) } exitcode = (int)MANDOCLEVEL_OK; - mc = mchars_alloc(); + mchars = mchars_alloc(); mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL, - mc, NULL); + mchars, NULL); ohash_init(&mpages, 6, &mpages_info); ohash_init(&mlinks, 6, &mlinks_info); @@ -464,7 +478,7 @@ main(int argc, char *argv[]) goto out; } if (OP_DELETE != op) - mpages_merge(mc, mp); + mpages_merge(mp); dbclose(OP_DEFAULT == op ? 0 : 1); } else { /* @@ -511,7 +525,7 @@ main(int argc, char *argv[]) if (0 == dbopen(0)) continue; - mpages_merge(mc, mp); + mpages_merge(mp); if (warnings && !nodb && ! (MPARSE_QUICK & mparse_options)) names_check(); @@ -527,7 +541,7 @@ main(int argc, char *argv[]) out: manpath_free(&dirs); mparse_free(mp); - mchars_free(mc); + mchars_free(mchars); mpages_free(); ohash_delete(&mpages); ohash_delete(&mlinks); @@ -1074,7 +1088,7 @@ mlink_check(struct mpage *mpage, struct mlink *mlink) * and filename to determine whether the file is parsable or not. */ static void -mpages_merge(struct mchars *mc, struct mparse *mp) +mpages_merge(struct mparse *mp) { char any[] = "any"; struct ohash_info str_info; @@ -1213,16 +1227,14 @@ mpages_merge(struct mchars *mc, struct mparse *mp) putkey(mpage, mlink->name, NAME_FILE); } - assert(NULL == mpage->desc); - if (NULL != mdoc) { - if (NULL != (cp = mdoc_meta(mdoc)->name)) - putkey(mpage, cp, NAME_HEAD); - parse_mdoc(mpage, mdoc_node(mdoc)); - } else if (NULL != man) - parse_man(mpage, man_node(man)); + assert(mpage->desc == NULL); + if (mdoc != NULL) + parse_mdoc(mpage, mdoc_meta(mdoc), mdoc_node(mdoc)); + else if (man != NULL) + parse_man(mpage, man_meta(man), man_node(man)); else parse_cat(mpage, fd); - if (NULL == mpage->desc) + if (mpage->desc == NULL) mpage->desc = mandoc_strdup(mpage->mlinks->name); if (warnings && !use_all) @@ -1230,7 +1242,7 @@ mpages_merge(struct mchars *mc, struct mparse *mp) mlink = mlink->next) mlink_check(mpage, mlink); - dbadd(mpage, mc); + dbadd(mpage); nextpage: if (mparse_wait(mp) != MANDOCLEVEL_OK) { @@ -1427,7 +1439,8 @@ putmdockey(const struct mpage *mpage, } static void -parse_man(struct mpage *mpage, const struct man_node *n) +parse_man(struct mpage *mpage, const struct man_meta *meta, + const struct man_node *n) { const struct man_node *head, *body; char *start, *title; @@ -1493,6 +1506,11 @@ parse_man(struct mpage *mpage, const struct man_node *n) break; putkey(mpage, start, NAME_TITLE); + if ( ! (mpage->name_head_done || + strcasecmp(start, meta->title))) { + putkey(mpage, start, NAME_HEAD); + mpage->name_head_done = 1; + } if (' ' == byte) { start += sz + 1; @@ -1507,6 +1525,11 @@ parse_man(struct mpage *mpage, const struct man_node *n) if (start == title) { putkey(mpage, start, NAME_TITLE); + if ( ! (mpage->name_head_done || + strcasecmp(start, meta->title))) { + putkey(mpage, start, NAME_HEAD); + mpage->name_head_done = 1; + } free(title); return; } @@ -1537,12 +1560,13 @@ parse_man(struct mpage *mpage, const struct man_node *n) for (n = n->child; n; n = n->next) { if (NULL != mpage->desc) break; - parse_man(mpage, n); + parse_man(mpage, meta, n); } } static void -parse_mdoc(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { assert(NULL != n); @@ -1558,7 +1582,7 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node *n) /* FALLTHROUGH */ case MDOC_TAIL: if (NULL != mdocs[n->tok].fp) - if (0 == (*mdocs[n->tok].fp)(mpage, n)) + if (0 == (*mdocs[n->tok].fp)(mpage, meta, n)) break; if (mdocs[n->tok].mask) putmdockey(mpage, n->child, @@ -1569,14 +1593,15 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node *n) continue; } if (NULL != n->child) - parse_mdoc(mpage, n); + parse_mdoc(mpage, meta, n); } } static int -parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { - const char *start, *end; + char *start, *end; size_t sz; if (SEC_SYNOPSIS != n->sec || @@ -1616,41 +1641,61 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n) return(0); } -static int -parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_node *n) +static void +parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n) { char *cp; + size_t sz; - if (NULL == (n = n->child) || MDOC_TEXT != n->type) + if (n->type != MDOC_TEXT) + return; + + /* Skip function pointer punctuation. */ + + cp = n->string; + while (*cp == '(' || *cp == '*') + cp++; + sz = strcspn(cp, "()"); + + putkeys(mpage, cp, sz, TYPE_Fn); + if (n->sec == SEC_SYNOPSIS) + putkeys(mpage, cp, sz, NAME_SYN); +} + +static int +parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) +{ + + if (n->child == NULL) return(0); - /* - * Parse: .Fn "struct type *name" "char *arg". - * First strip away pointer symbol. - * Then store the function name, then type. - * Finally, store the arguments. - */ + parse_mdoc_fname(mpage, n->child); - if (NULL == (cp = strrchr(n->string, ' '))) - cp = n->string; - - while ('*' == *cp) - cp++; - - putkey(mpage, cp, TYPE_Fn); - - if (n->string < cp) - putkeys(mpage, n->string, cp - n->string, TYPE_Ft); - - for (n = n->next; NULL != n; n = n->next) - if (MDOC_TEXT == n->type) + for (n = n->child->next; n != NULL; n = n->next) + if (n->type == MDOC_TEXT) putkey(mpage, n->string, TYPE_Fa); return(0); } static int -parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Fo(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) +{ + + if (n->type != MDOC_HEAD) + return(1); + + if (n->child != NULL) + parse_mdoc_fname(mpage, n->child); + + return(0); +} + +static int +parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { char *cp; @@ -1669,7 +1714,8 @@ parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n) } static int -parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { if (MDOC_BODY == n->type) @@ -1678,32 +1724,46 @@ parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n) } static int -parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { if (SEC_NAME == n->sec) putmdockey(mpage, n->child, NAME_TITLE); - else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) - putmdockey(mpage, n->child, NAME_SYN); + else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) { + if (n->child == NULL) + putkey(mpage, meta->name, NAME_SYN); + else + putmdockey(mpage, n->child, NAME_SYN); + } + if ( ! (mpage->name_head_done || + n->child == NULL || n->child->string == NULL || + strcasecmp(n->child->string, meta->title))) { + putkey(mpage, n->child->string, NAME_HEAD); + mpage->name_head_done = 1; + } return(0); } static int -parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { return(SEC_CUSTOM == n->sec && MDOC_HEAD == n->type); } static int -parse_mdoc_head(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_head(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { return(MDOC_HEAD == n->type); } static int -parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n) +parse_mdoc_body(struct mpage *mpage, const struct mdoc_meta *meta, + const struct mdoc_node *n) { return(MDOC_BODY == n->type); @@ -1715,18 +1775,19 @@ parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n) * When we finish the manual, we'll dump the table. */ static void -putkeys(const struct mpage *mpage, - const char *cp, size_t sz, uint64_t v) +putkeys(const struct mpage *mpage, char *cp, size_t sz, uint64_t v) { struct ohash *htab; struct str *s; const char *end; unsigned int slot; - int i; + int i, mustfree; if (0 == sz) return; + mustfree = render_string(&cp, &sz); + if (TYPE_Nm & v) { htab = &names; v &= name_mask; @@ -1734,7 +1795,7 @@ putkeys(const struct mpage *mpage, name_mask &= ~NAME_FIRST; if (debug > 1) say(mpage->mlinks->file, - "Adding name %*s", sz, cp); + "Adding name %*s, bits=%d", sz, cp, v); } else { htab = &strings; if (debug > 1) @@ -1759,6 +1820,9 @@ putkeys(const struct mpage *mpage, } s->mpage = mpage; s->mask = v; + + if (mustfree) + free(cp); } /* @@ -1814,20 +1878,19 @@ utf8(unsigned int cp, char out[7]) } /* - * Store the rendered version of a key, or alias the pointer - * if the key contains no escape sequences. + * If the string contains escape sequences, + * replace it with an allocated rendering and return 1, + * such that the caller can free it after use. + * Otherwise, do nothing and return 0. */ -static void -render_key(struct mchars *mc, struct str *key) +static int +render_string(char **public, size_t *psz) { - size_t sz, bsz, pos; + const char *src, *scp, *addcp, *seq; + char *dst; + size_t ssz, dsz, addsz; char utfbuf[7], res[6]; - char *buf; - const char *seq, *cpp, *val; - int len, u; - enum mandoc_esc esc; - - assert(NULL == key->rendered); + int seqlen, unicode; res[0] = '\\'; res[1] = '\t'; @@ -1836,68 +1899,62 @@ render_key(struct mchars *mc, struct str *key) res[4] = ASCII_BREAK; res[5] = '\0'; - val = key->key; - bsz = strlen(val); + src = scp = *public; + ssz = *psz; + dst = NULL; + dsz = 0; - /* - * Pre-check: if we have no stop-characters, then set the - * pointer as ourselvse and get out of here. - */ - if (strcspn(val, res) == bsz) { - key->rendered = key->key; - return; - } + while (scp < src + *psz) { - /* Pre-allocate by the length of the input */ + /* Leave normal characters unchanged. */ - buf = mandoc_malloc(++bsz); - pos = 0; - - while ('\0' != *val) { - /* - * Halt on the first escape sequence. - * This also halts on the end of string, in which case - * we just copy, fallthrough, and exit the loop. - */ - if ((sz = strcspn(val, res)) > 0) { - memcpy(&buf[pos], val, sz); - pos += sz; - val += sz; + if (strchr(res, *scp) == NULL) { + if (dst != NULL) + dst[dsz++] = *scp; + scp++; + continue; } - switch (*val) { - case ASCII_HYPH: - buf[pos++] = '-'; - val++; - continue; + /* + * Found something that requires replacing, + * make sure we have a destination buffer. + */ + + if (dst == NULL) { + dst = mandoc_malloc(ssz + 1); + dsz = scp - src; + memcpy(dst, src, dsz); + } + + /* Handle single-char special characters. */ + + switch (*scp) { + case '\\': + break; case '\t': /* FALLTHROUGH */ case ASCII_NBRSP: - buf[pos++] = ' '; - val++; + dst[dsz++] = ' '; + scp++; + continue; + case ASCII_HYPH: + dst[dsz++] = '-'; /* FALLTHROUGH */ case ASCII_BREAK: + scp++; continue; default: - break; + abort(); } - if ('\\' != *val) - break; - - /* Read past the slash. */ - - val++; /* - * Parse the escape sequence and see if it's a - * predefined character or special character. + * Found an escape sequence. + * Read past the slash, then parse it. + * Ignore everything except characters. */ - esc = mandoc_escape((const char **)&val, - &seq, &len); - if (ESCAPE_ERROR == esc) - break; - if (ESCAPE_SPECIAL != esc) + scp++; + if (mandoc_escape(&scp, &seq, &seqlen) != ESCAPE_SPECIAL) continue; /* @@ -1906,32 +1963,44 @@ render_key(struct mchars *mc, struct str *key) */ if (write_utf8) { - if ((u = mchars_spec2cp(mc, seq, len)) <= 0) + unicode = mchars_spec2cp(mchars, seq, seqlen); + if (unicode <= 0) continue; - cpp = utfbuf; - if (0 == (sz = utf8(u, utfbuf))) + addsz = utf8(unicode, utfbuf); + if (addsz == 0) continue; - sz = strlen(cpp); + addcp = utfbuf; } else { - cpp = mchars_spec2str(mc, seq, len, &sz); - if (NULL == cpp) + addcp = mchars_spec2str(mchars, seq, seqlen, &addsz); + if (addcp == NULL) continue; - if (ASCII_NBRSP == *cpp) { - cpp = " "; - sz = 1; + if (*addcp == ASCII_NBRSP) { + addcp = " "; + addsz = 1; } } /* Copy the rendered glyph into the stream. */ - bsz += sz; - buf = mandoc_realloc(buf, bsz); - memcpy(&buf[pos], cpp, sz); - pos += sz; + ssz += addsz; + dst = mandoc_realloc(dst, ssz + 1); + memcpy(dst + dsz, addcp, addsz); + dsz += addsz; + } + if (dst != NULL) { + *public = dst; + *psz = dsz; } - buf[pos] = '\0'; - key->rendered = buf; + /* Trim trailing whitespace and NUL-terminate. */ + + while (*psz > 0 && (*public)[*psz - 1] == ' ') + --*psz; + if (dst != NULL) { + (*public)[*psz] = '\0'; + return(1); + } else + return(0); } static void @@ -1951,12 +2020,21 @@ dbadd_mlink(const struct mlink *mlink) static void dbadd_mlink_name(const struct mlink *mlink) { + uint64_t bits; size_t i; dbadd_mlink(mlink); i = 1; - SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, NAME_FILE & NAME_MASK); + SQL_BIND_INT64(stmts[STMT_SELECT_NAME], i, mlink->mpage->pageid); + bits = NAME_FILE & NAME_MASK; + if (sqlite3_step(stmts[STMT_SELECT_NAME]) == SQLITE_ROW) { + bits |= sqlite3_column_int64(stmts[STMT_SELECT_NAME], 0); + sqlite3_reset(stmts[STMT_SELECT_NAME]); + } + + i = 1; + SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, bits); SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, mlink->name); SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mlink->mpage->pageid); SQL_STEP(stmts[STMT_INSERT_NAME]); @@ -1970,28 +2048,24 @@ dbadd_mlink_name(const struct mlink *mlink) * Also, handle escape sequences at the last possible moment. */ static void -dbadd(struct mpage *mpage, struct mchars *mc) +dbadd(struct mpage *mpage) { struct mlink *mlink; struct str *key; + char *cp; size_t i; unsigned int slot; + int mustfree; mlink = mpage->mlinks; if (nodb) { for (key = ohash_first(&names, &slot); NULL != key; - key = ohash_next(&names, &slot)) { - if (key->rendered != key->key) - free(key->rendered); + key = ohash_next(&names, &slot)) free(key); - } for (key = ohash_first(&strings, &slot); NULL != key; - key = ohash_next(&strings, &slot)) { - if (key->rendered != key->key) - free(key->rendered); + key = ohash_next(&strings, &slot)) free(key); - } if (0 == debug) return; while (NULL != mlink) { @@ -2020,21 +2094,17 @@ dbadd(struct mpage *mpage, struct mchars *mc) if (debug) say(mlink->file, "Adding to database"); - i = strlen(mpage->desc) + 1; - key = mandoc_calloc(1, sizeof(struct str) + i); - memcpy(key->key, mpage->desc, i); - render_key(mc, key); - + cp = mpage->desc; + i = strlen(cp); + mustfree = render_string(&cp, &i); i = 1; - SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, key->rendered); + SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, cp); SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, mpage->form); SQL_STEP(stmts[STMT_INSERT_PAGE]); mpage->pageid = sqlite3_last_insert_rowid(db); sqlite3_reset(stmts[STMT_INSERT_PAGE]); - - if (key->rendered != key->key) - free(key->rendered); - free(key); + if (mustfree) + free(cp); while (NULL != mlink) { dbadd_mlink(mlink); @@ -2045,31 +2115,23 @@ dbadd(struct mpage *mpage, struct mchars *mc) for (key = ohash_first(&names, &slot); NULL != key; key = ohash_next(&names, &slot)) { assert(key->mpage == mpage); - if (NULL == key->rendered) - render_key(mc, key); i = 1; SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask); - SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->rendered); + SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->key); SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->pageid); SQL_STEP(stmts[STMT_INSERT_NAME]); sqlite3_reset(stmts[STMT_INSERT_NAME]); - if (key->rendered != key->key) - free(key->rendered); free(key); } for (key = ohash_first(&strings, &slot); NULL != key; key = ohash_next(&strings, &slot)) { assert(key->mpage == mpage); - if (NULL == key->rendered) - render_key(mc, key); i = 1; SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask); - SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered); + SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->key); SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->pageid); SQL_STEP(stmts[STMT_INSERT_KEY]); sqlite3_reset(stmts[STMT_INSERT_KEY]); - if (key->rendered != key->key) - free(key->rendered); free(key); } } @@ -2269,7 +2331,8 @@ create_tables: " \"bits\" INTEGER NOT NULL,\n" " \"name\" TEXT NOT NULL,\n" " \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) " - "ON DELETE CASCADE\n" + "ON DELETE CASCADE,\n" + " UNIQUE (\"name\", \"pageid\") ON CONFLICT REPLACE\n" ");\n" "\n" "CREATE TABLE \"keys\" (\n" @@ -2307,6 +2370,8 @@ prepare_statements: sql = "INSERT INTO mlinks " "(sec,arch,name,pageid) VALUES (?,?,?,?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_LINK], NULL); + sql = "SELECT bits FROM names where pageid = ?"; + sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_SELECT_NAME], NULL); sql = "INSERT INTO names " "(bits,name,pageid) VALUES (?,?,?)"; sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_NAME], NULL); diff --git a/manpath.h b/manpath.h index 2fe1b36e15f..728373b2cc0 100644 --- a/manpath.h +++ b/manpath.h @@ -1,4 +1,4 @@ -/* $Id: manpath.h,v 1.6 2012/06/08 10:32:40 kristaps Exp $ */ +/* $Id: manpath.h,v 1.7 2014/12/01 04:05:32 schwarze Exp $ */ /* * Copyright (c) 2011 Ingo Schwarze * Copyright (c) 2011 Kristaps Dzonsons @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MANPATH_H -#define MANPATH_H /* * Unsorted list of unique, absolute paths to be searched for manual @@ -34,5 +32,3 @@ void manpath_parse(struct manpaths *, const char *, char *, char *); void manpath_free(struct manpaths *); __END_DECLS - -#endif /*!MANPATH_H*/ diff --git a/mansearch.3 b/mansearch.3 index 28590e52845..f41e3617f7e 100644 --- a/mansearch.3 +++ b/mansearch.3 @@ -1,4 +1,4 @@ -.\" $Id: mansearch.3,v 1.2 2014/08/05 15:29:30 schwarze Exp $ +.\" $Id: mansearch.3,v 1.3 2014/12/12 21:44:33 schwarze Exp $ .\" .\" Copyright (c) 2014 Ingo Schwarze .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 5 2014 $ +.Dd $Mdocdate: December 12 2014 $ .Dt MANSEARCH 3 .Os .Sh NAME @@ -172,7 +172,7 @@ using the following query: If the .Fa outkey differs from -.Qq Nd , +.Qq Ic \&Nd , the requested output data is assembled into the .Va output field of the result structure by the function diff --git a/mansearch.c b/mansearch.c index 77d4c074c06..dbfbe0255fd 100644 --- a/mansearch.c +++ b/mansearch.c @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.51 2014/11/27 01:58:21 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.52 2014/12/06 01:23:24 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -246,7 +247,8 @@ mansearch(const struct mansearch *search, SQLITE_OPEN_READONLY, NULL); if (SQLITE_OK != c) { - perror(MANDOC_DB); + fprintf(stderr, "%s/%s: %s\n", + paths->paths[i], MANDOC_DB, strerror(errno)); sqlite3_close(db); continue; } diff --git a/mansearch.h b/mansearch.h index 4f92ef26083..14ec8ceacd8 100644 --- a/mansearch.h +++ b/mansearch.h @@ -1,4 +1,4 @@ -/* $Id: mansearch.h,v 1.21 2014/11/27 01:58:21 schwarze Exp $ */ +/* $Id: mansearch.h,v 1.23 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons * Copyright (c) 2013, 2014 Ingo Schwarze @@ -15,8 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MANSEARCH_H -#define MANSEARCH_H #define MANDOC_DB "mandoc.db" @@ -99,6 +97,8 @@ struct mansearch { __BEGIN_DECLS +struct manpaths; + int mansearch_setup(int); int mansearch(const struct mansearch *cfg, /* options */ const struct manpaths *paths, /* manpaths */ @@ -109,5 +109,3 @@ int mansearch(const struct mansearch *cfg, /* options */ void mansearch_free(struct manpage *, size_t); __END_DECLS - -#endif /* MANSEARCH_H */ diff --git a/mansearch_const.c b/mansearch_const.c index 9ba8bc250ab..61351c3c2a4 100644 --- a/mansearch_const.c +++ b/mansearch_const.c @@ -1,4 +1,4 @@ -/* $Id: mansearch_const.c,v 1.6 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: mansearch_const.c,v 1.7 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2014 Ingo Schwarze * @@ -20,7 +20,6 @@ #include -#include "manpath.h" #include "mansearch.h" const int mansearch_keymax = 40; diff --git a/mdoc.7 b/mdoc.7 index a13d613bbf8..a9b0fe2f3ac 100644 --- a/mdoc.7 +++ b/mdoc.7 @@ -1,4 +1,4 @@ -.\" $Id: mdoc.7,v 1.244 2014/11/28 18:36:35 schwarze Exp $ +.\" $Id: mdoc.7,v 1.245 2014/11/30 21:56:18 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons .\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 28 2014 $ +.Dd $Mdocdate: November 30 2014 $ .Dt MDOC 7 .Os .Sh NAME @@ -2396,8 +2396,6 @@ The original C standard. .Pp .It \-isoC-99 .St -isoC-99 -.It \-ansiC-99 -.St -ansiC-99 .br The second major version of the C language standard. .Pp @@ -2497,9 +2495,6 @@ The following three refer to parts of it. .br Networking APIs, including sockets. .Pp -.It \-xpg4.3 -.St -xpg4.3 -.Pp .It \-svid4 .St -svid4 , .br @@ -2529,14 +2524,9 @@ The following refer to parts of it. .It \-xns5.2 .St -xns5.2 .El -.It Single UNIX Specification version 3 and related standards -.Pp -.Bl -tag -width "-p1003.1g-2000X" -compact -.It \-p1003.1d-99 -.St -p1003.1d-99 -.br -Additional real-time extensions. +.It Single UNIX Specification version 3 .Pp +.Bl -tag -width "-p1003.1-2001" -compact .It \-p1003.1-2001 .St -p1003.1-2001 .It \-susv3 diff --git a/mdoc.h b/mdoc.h index 58ad81318f5..f7c933d562e 100644 --- a/mdoc.h +++ b/mdoc.h @@ -1,4 +1,4 @@ -/* $Id: mdoc.h,v 1.131 2014/07/29 13:58:18 schwarze Exp $ */ +/* $Id: mdoc.h,v 1.132 2014/12/01 04:05:32 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * @@ -14,8 +14,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef MDOC_H -#define MDOC_H enum mdoct { MDOC_Ap = 0, @@ -395,5 +393,3 @@ const struct mdoc_meta *mdoc_meta(const struct mdoc *); void mdoc_deroff(char **, const struct mdoc_node *); __END_DECLS - -#endif /*!MDOC_H*/ diff --git a/mdoc_html.c b/mdoc_html.c index 0cd3cf01744..ca51049eec5 100644 --- a/mdoc_html.c +++ b/mdoc_html.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_html.c,v 1.213 2014/11/27 22:27:56 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.216 2014/12/02 10:08:06 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -26,11 +26,10 @@ #include #include -#include "mandoc.h" #include "mandoc_aux.h" +#include "mdoc.h" #include "out.h" #include "html.h" -#include "mdoc.h" #include "main.h" #define INDENT 5 @@ -1202,7 +1201,8 @@ mdoc_bd_pre(MDOC_ARGS) default: break; } - if (nn->next && nn->next->line == nn->line) + if (h->flags & HTML_NONEWLINE || + (nn->next && ! (nn->next->flags & MDOC_LINE))) continue; else if (nn->next) print_text(h, "\n"); @@ -1869,7 +1869,8 @@ static void mdoc_pf_post(MDOC_ARGS) { - h->flags |= HTML_NOSPACE; + if ( ! (n->next == NULL || n->next->flags & MDOC_LINE)) + h->flags |= HTML_NOSPACE; } static int diff --git a/mdoc_macro.c b/mdoc_macro.c index b501d4d6294..b354e540a1b 100644 --- a/mdoc_macro.c +++ b/mdoc_macro.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_macro.c,v 1.154 2014/11/29 04:31:35 schwarze Exp $ */ +/* $Id: mdoc_macro.c,v 1.157 2014/12/13 13:14:39 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze @@ -53,7 +53,8 @@ static void phrase_ta(MACRO_PROT_ARGS); static void dword(struct mdoc *, int, int, const char *, enum mdelim, int); static void append_delims(struct mdoc *, int, int *, char *); -static enum mdoct lookup(enum mdoct, const char *); +static enum mdoct lookup(struct mdoc *, enum mdoct, + int, int, const char *); static int macro_or_word(MACRO_PROT_ARGS, int); static int make_pending(struct mdoc_node *, enum mdoct, struct mdoc *, int, int); @@ -245,14 +246,19 @@ mdoc_macroend(struct mdoc *mdoc) * or as a line macro if from == MDOC_MAX. */ static enum mdoct -lookup(enum mdoct from, const char *p) +lookup(struct mdoc *mdoc, enum mdoct from, int line, int ppos, const char *p) { enum mdoct res; if (from == MDOC_MAX || mdoc_macros[from].flags & MDOC_PARSED) { res = mdoc_hash_find(p); - if (res != MDOC_MAX && mdoc_macros[res].flags & MDOC_CALLABLE) - return(res); + if (res != MDOC_MAX) { + if (mdoc_macros[res].flags & MDOC_CALLABLE) + return(res); + if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll) + mandoc_msg(MANDOCERR_MACRO_CALL, + mdoc->parse, line, ppos, p); + } } return(MDOC_MAX); } @@ -666,12 +672,10 @@ macro_or_word(MACRO_PROT_ARGS, int parsed) p = buf + ppos; ntok = MDOC_MAX; - if (mdoc->flags & MDOC_PHRASELIT) - /* nothing */; - else if (*p == '"') + if (*p == '"') p++; - else if (parsed) - ntok = lookup(tok, p); + else if (parsed && ! (mdoc->flags & MDOC_PHRASELIT)) + ntok = lookup(mdoc, tok, line, ppos, p); if (ntok == MDOC_MAX) { dword(mdoc, line, ppos, p, DELIM_MAX, tok == MDOC_MAX || @@ -832,7 +836,8 @@ blk_exp_close(MACRO_PROT_ARGS) if (ac == ARGS_PUNCT || ac == ARGS_EOLN) break; - ntok = ac == ARGS_QWORD ? MDOC_MAX : lookup(tok, p); + ntok = ac == ARGS_QWORD ? MDOC_MAX : + lookup(mdoc, tok, line, lastarg, p); if (ntok == MDOC_MAX) { dword(mdoc, line, lastarg, p, DELIM_MAX, @@ -933,7 +938,7 @@ in_line(MACRO_PROT_ARGS) } ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ? - MDOC_MAX : lookup(tok, p); + MDOC_MAX : lookup(mdoc, tok, line, la, p); /* * In this case, we've located a submacro and must @@ -1389,7 +1394,7 @@ in_line_argn(MACRO_PROT_ARGS) char *p; enum mdoct ntok; - nl = MDOC_NEWLINE & mdoc->flags; + nl = mdoc->flags & MDOC_NEWLINE; /* * A line macro that has a fixed number of arguments (maxargs). @@ -1421,11 +1426,18 @@ in_line_argn(MACRO_PROT_ARGS) mdoc_argv(mdoc, line, tok, &arg, pos, buf); - for (flushed = j = 0; ; ) { + p = NULL; + flushed = j = 0; + for (;;) { la = *pos; ac = mdoc_args(mdoc, line, pos, buf, tok, &p); - if (ac == ARGS_PUNCT || ac == ARGS_EOLN) + if (ac == ARGS_PUNCT || ac == ARGS_EOLN) { + if (j < 2 && tok == MDOC_Pf) + mandoc_vmsg(MANDOCERR_PF_SKIP, + mdoc->parse, line, ppos, "Pf %s", + p == NULL ? "at eol" : p); break; + } if ( ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) && ac != ARGS_QWORD && j == 0 && @@ -1440,7 +1452,8 @@ in_line_argn(MACRO_PROT_ARGS) flushed = 1; } - ntok = ac == ARGS_QWORD ? MDOC_MAX : lookup(tok, p); + ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && j == 0)) ? + MDOC_MAX : lookup(mdoc, tok, line, la, p); if (ntok != MDOC_MAX) { if ( ! flushed) @@ -1463,8 +1476,11 @@ in_line_argn(MACRO_PROT_ARGS) j++; } - if (j == 0) + if (j == 0) { mdoc_elem_alloc(mdoc, line, ppos, tok, arg); + if (ac == ARGS_PUNCT && tok == MDOC_Pf) + append_delims(mdoc, line, pos, buf); + } if ( ! flushed) rew_elem(mdoc, tok); if (nl) diff --git a/mdoc_man.c b/mdoc_man.c index 41cc65b5765..974cfbd46f5 100644 --- a/mdoc_man.c +++ b/mdoc_man.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_man.c,v 1.76 2014/11/27 22:27:56 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.77 2014/11/30 05:29:00 schwarze Exp $ */ /* * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze * @@ -1602,7 +1602,8 @@ static void post_pf(DECL_ARGS) { - outflags &= ~MMAN_spc; + if ( ! (n->next == NULL || n->next->flags & MDOC_LINE)) + outflags &= ~MMAN_spc; } static int diff --git a/mdoc_term.c b/mdoc_term.c index dcc2682f4e8..7f57aed3764 100644 --- a/mdoc_term.c +++ b/mdoc_term.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_term.c,v 1.297 2014/11/28 16:54:23 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.299 2014/12/02 10:08:06 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze @@ -1632,7 +1632,8 @@ termp_bd_pre(DECL_ARGS) default: break; } - if (nn->next && nn->next->line == nn->line) + if (p->flags & TERMP_NONEWLINE || + (nn->next && ! (nn->next->flags & MDOC_LINE))) continue; term_flushln(p); p->flags |= TERMP_NOSPACE; @@ -1734,7 +1735,8 @@ static void termp_pf_post(DECL_ARGS) { - p->flags |= TERMP_NOSPACE; + if ( ! (n->next == NULL || n->next->flags & MDOC_LINE)) + p->flags |= TERMP_NOSPACE; } static int diff --git a/mdoc_validate.c b/mdoc_validate.c index 5a07af3e2e6..7990ffe9385 100644 --- a/mdoc_validate.c +++ b/mdoc_validate.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_validate.c,v 1.262 2014/11/28 18:36:35 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.263 2014/11/30 05:29:00 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -210,7 +210,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = { { NULL, NULL }, /* Nx */ { NULL, NULL }, /* Ox */ { NULL, NULL }, /* Pc */ - { NULL, ewarn_eq1 }, /* Pf */ + { NULL, NULL }, /* Pf */ { NULL, NULL }, /* Po */ { NULL, NULL }, /* Pq */ { NULL, NULL }, /* Qc */ diff --git a/msec.c b/msec.c index 2d0d85bbe69..ffe5024ff1e 100644 --- a/msec.c +++ b/msec.c @@ -1,4 +1,4 @@ -/* $Id: msec.c,v 1.12 2014/08/10 23:54:41 schwarze Exp $ */ +/* $Id: msec.c,v 1.13 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons * @@ -20,7 +20,6 @@ #include -#include "mandoc.h" #include "libmandoc.h" #define LINE(x, y) \ diff --git a/out.c b/out.c index 5b08a09abd4..7a61b39969c 100644 --- a/out.c +++ b/out.c @@ -1,4 +1,4 @@ -/* $Id: out.c,v 1.53 2014/10/14 18:18:05 schwarze Exp $ */ +/* $Id: out.c,v 1.54 2014/12/04 02:05:42 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011, 2014 Ingo Schwarze @@ -110,7 +110,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def) case '\0': if (SCALE_MAX == def) return(0); - unit = SCALE_EN; + unit = def; break; case 'u': unit = SCALE_BU; diff --git a/out.h b/out.h index de38ec1754a..cc218f4fec3 100644 --- a/out.h +++ b/out.h @@ -1,4 +1,4 @@ -/* $Id: out.h,v 1.24 2014/10/14 02:16:06 schwarze Exp $ */ +/* $Id: out.h,v 1.26 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons * @@ -14,8 +14,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef OUT_H -#define OUT_H enum roffscale { SCALE_CM, /* centimeters (c) */ @@ -52,8 +50,6 @@ struct rofftbl { void *arg; /* passed to slen and len */ }; -__BEGIN_DECLS - #define SCALE_VS_INIT(p, v) \ do { (p)->unit = SCALE_VS; \ (p)->scale = (v); } \ @@ -64,10 +60,12 @@ __BEGIN_DECLS (p)->scale = (v); } \ while (/* CONSTCOND */ 0) +__BEGIN_DECLS + +struct tbl_span; + int a2roffsu(const char *, struct roffsu *, enum roffscale); void tblcalc(struct rofftbl *tbl, const struct tbl_span *, size_t); __END_DECLS - -#endif /*!OUT_H*/ diff --git a/read.c b/read.c index 96444f59ffa..8d6cb1038be 100644 --- a/read.c +++ b/read.c @@ -1,4 +1,4 @@ -/* $Id: read.c,v 1.101 2014/11/28 18:09:01 schwarze Exp $ */ +/* $Id: read.c,v 1.104 2014/12/01 04:14:14 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -41,7 +41,6 @@ #include "libmandoc.h" #include "mdoc.h" #include "man.h" -#include "main.h" #define REPARSE_LIMIT 1000 @@ -120,6 +119,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { /* related to macros and nesting */ "obsolete macro", + "macro neither callable nor escaped", "skipping paragraph macro", "moving paragraph macro out of list", "skipping no-space macro", @@ -145,6 +145,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "empty list item", "missing font type, using \\fR", "unknown font type, using \\fR", + "nothing follows prefix", "missing -std argument, adding it", "missing eqn box, using \"\"", @@ -754,12 +755,12 @@ mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file) } enum mandoclevel -mparse_readmem(struct mparse *curp, const void *buf, size_t len, +mparse_readmem(struct mparse *curp, void *buf, size_t len, const char *file) { struct buf blk; - blk.buf = UNCONST(buf); + blk.buf = buf; blk.sz = len; mparse_parse_buffer(curp, blk, file); diff --git a/roff.7 b/roff.7 index 6e2e8dd9ab3..6ee29321884 100644 --- a/roff.7 +++ b/roff.7 @@ -1,4 +1,4 @@ -.\" $Id: roff.7,v 1.59 2014/11/19 01:20:25 schwarze Exp $ +.\" $Id: roff.7,v 1.60 2014/12/02 10:08:06 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons .\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 19 2014 $ +.Dd $Mdocdate: December 2 2014 $ .Dt ROFF 7 .Os .Sh NAME @@ -1196,8 +1196,10 @@ Bracket building function; ignored by .Sx Special Characters with names of arbitrary length. .Ss \ec -Interrupt text processing to insert requests or macros; ignored by -.Xr mandoc 1 . +When encountered at the end of an input text line, +the next input text line is considered to continue that line, +even if there are request or macro lines in between. +No whitespace is inserted. .Ss \eD\(aq Ns Ar string Ns \(aq Draw graphics function; ignored by .Xr mandoc 1 . diff --git a/st.in b/st.in index ee79aedb811..5d2f129e3f4 100644 --- a/st.in +++ b/st.in @@ -1,4 +1,4 @@ -/* $Id: st.in,v 1.26 2014/11/16 20:46:21 schwarze Exp $ */ +/* $Id: st.in,v 1.27 2014/11/30 21:56:18 schwarze Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons * @@ -39,7 +39,6 @@ LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)") LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)") LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)") LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)") -LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)") LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)") LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)") LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)") @@ -57,7 +56,6 @@ LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)") LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)") LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)") LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)") -LINE("-ansiC-99", "ANSI/ISO/IEC 9899-1999 (\\(lqANSI\\~C99\\(rq)") LINE("-ieee754", "IEEE Std 754-1985") LINE("-iso8802-3", "ISO 8802-3: 1989") LINE("-iso8601", "ISO 8601") @@ -65,7 +63,6 @@ LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)") LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)") LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)") LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)") -LINE("-xpg4.3", "X/Open Portability Guide Issue\\~4, Version\\~3 (\\(lqXPG4.3\\(rq)") LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)") LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)") LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)") diff --git a/term.c b/term.c index 5b01aa68813..33f8f90027a 100644 --- a/term.c +++ b/term.c @@ -1,4 +1,4 @@ -/* $Id: term.c,v 1.236 2014/11/21 01:52:53 schwarze Exp $ */ +/* $Id: term.c,v 1.237 2014/12/02 10:08:06 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -417,7 +417,7 @@ term_word(struct termp *p, const char *word) else p->flags |= TERMP_NOSPACE; - p->flags &= ~TERMP_SENTENCE; + p->flags &= ~(TERMP_SENTENCE | TERMP_NONEWLINE); while ('\0' != *word) { if ('\\' != *word) { @@ -487,7 +487,7 @@ term_word(struct termp *p, const char *word) if (TERMP_SKIPCHAR & p->flags) p->flags &= ~TERMP_SKIPCHAR; else if ('\0' == *word) - p->flags |= TERMP_NOSPACE; + p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE); continue; case ESCAPE_SKIPCHAR: p->flags |= TERMP_SKIPCHAR; diff --git a/term.h b/term.h index e17c244596c..62c6ffe8af8 100644 --- a/term.h +++ b/term.h @@ -1,4 +1,4 @@ -/* $Id: term.h,v 1.105 2014/10/28 17:36:19 schwarze Exp $ */ +/* $Id: term.h,v 1.108 2014/12/02 10:08:06 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze @@ -15,12 +15,6 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef TERM_H -#define TERM_H - -__BEGIN_DECLS - -struct termp; enum termenc { TERMENC_ASCII, @@ -44,6 +38,8 @@ enum termfont { #define TERM_MAXMARGIN 100000 /* FIXME */ +struct termp; + typedef void (*term_margin)(struct termp *, const void *); struct termp_tbl { @@ -83,6 +79,7 @@ struct termp { #define TERMP_HANG (1 << 11) /* See term_flushln(). */ #define TERMP_NOSPLIT (1 << 12) /* Do not break line before .An. */ #define TERMP_SPLIT (1 << 13) /* Break line before .An. */ +#define TERMP_NONEWLINE (1 << 14) /* No line break in nofill mode. */ int *buf; /* Output buffer. */ enum termenc enc; /* Type of encoding. */ const struct mchars *symtab; /* Character table. */ @@ -104,6 +101,11 @@ struct termp { struct termp_ps *ps; }; +__BEGIN_DECLS + +struct tbl_span; +struct eqn; + const char *ascii_uc2str(int); void term_eqn(struct termp *, const struct eqn *); @@ -134,5 +136,3 @@ void term_fontrepl(struct termp *, enum termfont); void term_fontlast(struct termp *); __END_DECLS - -#endif /*!TERM_H*/ diff --git a/term_ps.c b/term_ps.c index 2f0b434a2e8..e3299d70640 100644 --- a/term_ps.c +++ b/term_ps.c @@ -1,4 +1,4 @@ -/* $Id: term_ps.c,v 1.69 2014/11/20 13:56:20 schwarze Exp $ */ +/* $Id: term_ps.c,v 1.70 2014/12/01 08:05:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons * Copyright (c) 2014 Ingo Schwarze @@ -27,11 +27,10 @@ #include #include -#include "mandoc.h" #include "mandoc_aux.h" #include "out.h" -#include "main.h" #include "term.h" +#include "main.h" /* These work the buffer used by the header and footer. */ #define PS_BUFSLOP 128 From 547e0acbec32a6bb2dc1e75804460ed9fd201d27 Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Thu, 25 Dec 2014 21:51:28 +0000 Subject: [PATCH 167/207] patch: Bring in xstrdup and use it when appropriate. The function savestr allows NULL return values during Plan A patching so in case of out of memory conditions, Plan B can step in. In many cases, NULL value is not properly handled, so use xstrdup here (it's outside Plan A/B patching, which means that even Plan B relies on successful operations). Clean up some whitespaces while here Obtained from: OpenBSD MFC after: 2 weeks --- usr.bin/patch/patch.c | 20 ++++++++++---------- usr.bin/patch/pch.c | 14 +++++++------- usr.bin/patch/util.c | 16 ++++++++++++++++ usr.bin/patch/util.h | 3 ++- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c index 14aca68daa6..987bddc6004 100644 --- a/usr.bin/patch/patch.c +++ b/usr.bin/patch/patch.c @@ -23,7 +23,7 @@ * -C option added in 1998, original code by Marc Espie, based on FreeBSD * behaviour * - * $OpenBSD: patch.c,v 1.52 2014/11/26 18:34:51 millert Exp $ + * $OpenBSD: patch.c,v 1.54 2014/12/13 10:31:07 tobias Exp $ * $FreeBSD$ * */ @@ -215,13 +215,13 @@ main(int argc, char *argv[]) for (open_patch_file(filearg[1]); there_is_another_patch(); reinitialize_almost_everything()) { /* for each patch in patch file */ - + patch_seen = true; warn_on_invalid_line = true; if (outname == NULL) - outname = savestr(filearg[0]); + outname = xstrdup(filearg[0]); /* for ed script just up and do it and exit */ if (diff_type == ED_DIFF) { @@ -416,7 +416,7 @@ main(int argc, char *argv[]) } set_signals(1); } - + if (!patch_seen) error = 2; @@ -514,10 +514,10 @@ get_some_switches(void) /* FALLTHROUGH */ case 'z': /* must directly follow 'b' case for backwards compat */ - simple_backup_suffix = savestr(optarg); + simple_backup_suffix = xstrdup(optarg); break; case 'B': - origprae = savestr(optarg); + origprae = xstrdup(optarg); break; case 'c': diff_type = CONTEXT_DIFF; @@ -555,7 +555,7 @@ get_some_switches(void) case 'i': if (++filec == MAXFILEC) fatal("too many file arguments\n"); - filearg[filec] = savestr(optarg); + filearg[filec] = xstrdup(optarg); break; case 'l': canonicalize = true; @@ -567,7 +567,7 @@ get_some_switches(void) noreverse = true; break; case 'o': - outname = savestr(optarg); + outname = xstrdup(optarg); break; case 'p': strippath = atoi(optarg); @@ -611,12 +611,12 @@ get_some_switches(void) Argv += optind; if (Argc > 0) { - filearg[0] = savestr(*Argv++); + filearg[0] = xstrdup(*Argv++); Argc--; while (Argc > 0) { if (++filec == MAXFILEC) fatal("too many file arguments\n"); - filearg[filec] = savestr(*Argv++); + filearg[filec] = xstrdup(*Argv++); Argc--; } } diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c index bb4a6882ca5..aacafc8ad6d 100644 --- a/usr.bin/patch/pch.c +++ b/usr.bin/patch/pch.c @@ -205,14 +205,14 @@ there_is_another_patch(void) while (filearg[0] == NULL) { if (force || batch) { say("No file to patch. Skipping...\n"); - filearg[0] = savestr(bestguess); + filearg[0] = xstrdup(bestguess); skip_rest_of_patch = true; return true; } ask("File to patch: "); if (*buf != '\n') { free(bestguess); - bestguess = savestr(buf); + bestguess = xstrdup(buf); filearg[0] = fetchname(buf, &exists, 0); } if (!exists) { @@ -319,7 +319,7 @@ intuit_diff_type(void) else if (strnEQ(s, "Prereq:", 7)) { for (t = s + 7; isspace((unsigned char)*t); t++) ; - revision = savestr(t); + revision = xstrdup(t); for (t = revision; *t && !isspace((unsigned char)*t); t++) ; @@ -403,7 +403,7 @@ scan_exit: free(bestguess); bestguess = NULL; if (filearg[0] != NULL) - bestguess = savestr(filearg[0]); + bestguess = xstrdup(filearg[0]); else if (!ok_to_create_file) { /* * We don't want to create a new file but we need a @@ -1505,7 +1505,7 @@ posix_name(const struct file_name *names, bool assume_exists) path = names[NEW_FILE].path; } - return path ? savestr(path) : NULL; + return path ? xstrdup(path) : NULL; } static char * @@ -1571,7 +1571,7 @@ best_name(const struct file_name *names, bool assume_exists) best = names[NEW_FILE].path; } - return best ? savestr(best) : NULL; + return best ? xstrdup(best) : NULL; } static size_t @@ -1613,7 +1613,7 @@ strtolinenum(char *nptr, char **endptr) if (errstr != NULL) fatal("invalid line number at line %ld: `%s' is %s\n", p_input_line, nptr, errstr); - + *p = c; *endptr = p; diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c index 69806763020..6d696b0f923 100644 --- a/usr.bin/patch/util.c +++ b/usr.bin/patch/util.c @@ -201,6 +201,22 @@ savestr(const char *s) return rv; } +/* + * Allocate a unique area for a string. Call fatal if out of memory. + */ +char * +xstrdup(const char *s) +{ + char *rv; + + if (!s) + s = "Oops"; + rv = strdup(s); + if (rv == NULL) + fatal("out of memory\n"); + return rv; +} + /* * Vanilla terminal output (buffered). */ diff --git a/usr.bin/patch/util.h b/usr.bin/patch/util.h index 5759d68f6e6..ff2feabebfa 100644 --- a/usr.bin/patch/util.h +++ b/usr.bin/patch/util.h @@ -23,7 +23,7 @@ * -C option added in 1998, original code by Marc Espie, based on FreeBSD * behaviour * - * $OpenBSD: util.h,v 1.15 2005/06/20 07:14:06 otto Exp $ + * $OpenBSD: util.h,v 1.16 2014/12/13 10:31:07 tobias Exp $ * $FreeBSD$ */ @@ -41,6 +41,7 @@ void pfatal(const char *, ...) void ask(const char *, ...) __attribute__((__format__(__printf__, 1, 2))); char *savestr(const char *); +char *xstrdup(const char *); void set_signals(int); void ignore_signals(void); void makedirs(const char *, bool); From fd83961f7227f20a2cecb2dfda3243ad4979420a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 25 Dec 2014 22:04:16 +0000 Subject: [PATCH 168/207] mandoc -Tlocale is now the default, no need to enforce it anymore --- usr.bin/man/man.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh index de03f400bf1..86d6b14b864 100755 --- a/usr.bin/man/man.sh +++ b/usr.bin/man/man.sh @@ -312,7 +312,7 @@ man_display_page() { fi testline="mandoc -Tlint -Werror 2>/dev/null" - pipeline="mandoc -Tlocale | $MANPAGER" + pipeline="mandoc | $MANPAGER" if ! eval "$cattool $manpage | $testline" ;then if which -s groff; then From 2f88b3d20a46a707970c8f592c3279babff1a74f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 25 Dec 2014 22:29:37 +0000 Subject: [PATCH 169/207] Delete some duplicate code that was harmless because exactly the same code is at the end of the nfscl_checksattr() function that is called just before it. As such, this code had already been executed and didn't do anything. MFC after: 1 week --- sys/fs/nfsclient/nfs_clvnops.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 818551fa3b6..513abf4d70c 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -1606,20 +1606,6 @@ again: } } else if (NFS_ISV34(dvp) && (fmode & O_EXCL)) { if (nfscl_checksattr(vap, &nfsva)) { - /* - * We are normally called with only a partially - * initialized VAP. Since the NFSv3 spec says that - * the server may use the file attributes to - * store the verifier, the spec requires us to do a - * SETATTR RPC. FreeBSD servers store the verifier in - * atime, but we can't really assume that all servers - * will so we ensure that our SETATTR sets both atime - * and mtime. - */ - if (vap->va_mtime.tv_sec == VNOVAL) - vfs_timestamp(&vap->va_mtime); - if (vap->va_atime.tv_sec == VNOVAL) - vap->va_atime = vap->va_mtime; error = nfsrpc_setattr(newvp, vap, NULL, cnp->cn_cred, cnp->cn_thread, &nfsva, &attrflag, NULL); if (error && (vap->va_uid != (uid_t)VNOVAL || From e43b65f9516d77b96ce1ab746f26ea3f3b1ad80f Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 26 Dec 2014 00:01:00 +0000 Subject: [PATCH 170/207] Let's see if we can fix the NOINET if_gif(4) module build after r276215 going by example. --- sys/modules/if_gif/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/modules/if_gif/Makefile b/sys/modules/if_gif/Makefile index 663c679f463..3b3a172db75 100644 --- a/sys/modules/if_gif/Makefile +++ b/sys/modules/if_gif/Makefile @@ -6,7 +6,11 @@ SYSDIR?=${.CURDIR}/../.. .PATH: ${SYSDIR}/net ${SYSDIR}/netinet ${SYSDIR}/netinet6 KMOD= if_gif -SRCS= if_gif.c in_gif.c opt_inet.h opt_inet6.h +SRCS= if_gif.c opt_inet.h opt_inet6.h + +.if ${MK_INET_SUPPORT} != "no" +SRCS+= in_gif.c +.endif .if ${MK_INET6_SUPPORT} != "no" SRCS+= in6_gif.c From ec1b033c60935e1fe22ef50adbf41397d007641f Mon Sep 17 00:00:00 2001 From: Steven Hartland Date: Fri, 26 Dec 2014 01:12:02 +0000 Subject: [PATCH 171/207] Enhancements to zpool upgrade processing Introduce a seperate phase to list all unavailable pools when listing pools to upgrade. This avoids confusing output when displaying older and disabled feature pools. These existing phases now silently skip unavailable pools. Introduce cb_unavail to upgrade_cbdata_t which enables the final output for zpool list to correctly detail if all pools or only all available pools where up-to-date on version / features. Correct the type of upgrade_cbdata_t.cb_first from int -> boolean_t. Change the pool iteration when upgrading named pools to include unavailable pools and update upgrade_one so it doesn't try to upgrade unavailable pools but warns about them. This allows the correct error to be displayed as well as upgrades with available and unavailable pools intermixed to partially complete. Also correct some missing trailing \n's from output in upgrade_one. MFC after: 1 month X-MFC-With: r276194 --- .../opensolaris/cmd/zpool/zpool_main.c | 93 ++++++++++++++----- 1 file changed, 72 insertions(+), 21 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c index 825198962aa..2985d0f2ae4 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c @@ -4509,11 +4509,12 @@ zpool_do_status(int argc, char **argv) } typedef struct upgrade_cbdata { - int cb_first; - char cb_poolname[ZPOOL_MAXNAMELEN]; - int cb_argc; - uint64_t cb_version; - char **cb_argv; + boolean_t cb_first; + boolean_t cb_unavail; + char cb_poolname[ZPOOL_MAXNAMELEN]; + int cb_argc; + uint64_t cb_version; + char **cb_argv; } upgrade_cbdata_t; #ifdef __FreeBSD__ @@ -4631,7 +4632,8 @@ upgrade_cb(zpool_handle_t *zhp, void *arg) if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is " - "currently unavailable\n\n"), zpool_get_name(zhp)); + "currently unavailable.\n\n"), zpool_get_name(zhp)); + cbp->cb_unavail = B_TRUE; /* Allow iteration to continue. */ return (0); } @@ -4696,6 +4698,26 @@ upgrade_cb(zpool_handle_t *zhp, void *arg) return (0); } +static int +upgrade_list_unavail(zpool_handle_t *zhp, void *arg) +{ + upgrade_cbdata_t *cbp = arg; + + if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { + if (cbp->cb_first) { + (void) fprintf(stderr, gettext("The following pools " + "are unavailable and cannot be upgraded as this " + "time.\n\n")); + (void) fprintf(stderr, gettext("POOL\n")); + (void) fprintf(stderr, gettext("------------\n")); + cbp->cb_first = B_FALSE; + } + (void) printf(gettext("%s\n"), zpool_get_name(zhp)); + cbp->cb_unavail = B_TRUE; + } + return (0); +} + static int upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) { @@ -4703,6 +4725,15 @@ upgrade_list_older_cb(zpool_handle_t *zhp, void *arg) nvlist_t *config; uint64_t version; + if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { + /* + * This will have been reported by upgrade_list_unavail so + * just allow iteration to continue. + */ + cbp->cb_unavail = B_TRUE; + return (0); + } + config = zpool_get_config(zhp, NULL); verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION, &version) == 0); @@ -4737,10 +4768,11 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg) uint64_t version; if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { - (void) fprintf(stderr, gettext("cannot check supported " - "features on '%s': pool is currently unavailable\n\n"), - zpool_get_name(zhp)); - /* Allow iteration to continue. */ + /* + * This will have been reported by upgrade_list_unavail so + * just allow iteration to continue. + */ + cbp->cb_unavail = B_TRUE; return (0); } @@ -4797,10 +4829,17 @@ upgrade_one(zpool_handle_t *zhp, void *data) uint64_t cur_version; int ret; + if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { + (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is " + "is currently unavailable.\n\n"), zpool_get_name(zhp)); + cbp->cb_unavail = B_TRUE; + return (1); + } + if (strcmp("log", zpool_get_name(zhp)) == 0) { (void) printf(gettext("'log' is now a reserved word\n" "Pool 'log' must be renamed using export and import" - " to upgrade.\n")); + " to upgrade.\n\n")); return (1); } @@ -4844,7 +4883,7 @@ upgrade_one(zpool_handle_t *zhp, void *data) #endif /* __FreeBSD __*/ } else if (cur_version == SPA_VERSION) { (void) printf(gettext("Pool '%s' already has all " - "supported features enabled.\n"), + "supported features enabled.\n\n"), zpool_get_name(zhp)); } } @@ -5001,11 +5040,13 @@ zpool_do_upgrade(int argc, char **argv) ret = zpool_iter(g_zfs, upgrade_cb, &cb); if (ret == 0 && cb.cb_first) { if (cb.cb_version == SPA_VERSION) { - (void) printf(gettext("All pools are already " - "formatted using feature flags.\n\n")); - (void) printf(gettext("Every feature flags " + (void) printf(gettext("All %spools are already " + "formatted using feature flags.\n\n"), + cb.cb_unavail ? gettext("available ") : ""); + (void) printf(gettext("Every %sfeature flags " "pool already has all supported features " - "enabled.\n")); + "enabled.\n"), + cb.cb_unavail ? gettext("available ") : ""); } else { (void) printf(gettext("All pools are already " "formatted with version %llu or higher.\n"), @@ -5013,13 +5054,22 @@ zpool_do_upgrade(int argc, char **argv) } } } else if (argc == 0) { + cb.cb_first = B_TRUE; + ret = zpool_iter(g_zfs, upgrade_list_unavail, &cb); + assert(ret == 0); + + if (!cb.cb_first) { + (void) fprintf(stderr, "\n"); + } + cb.cb_first = B_TRUE; ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb); assert(ret == 0); if (cb.cb_first) { - (void) printf(gettext("All pools are formatted " - "using feature flags.\n\n")); + (void) printf(gettext("All %spools are formatted using " + "feature flags.\n\n"), cb.cb_unavail ? + gettext("available ") : ""); } else { (void) printf(gettext("\nUse 'zpool upgrade -v' " "for a list of available legacy versions.\n")); @@ -5030,13 +5080,14 @@ zpool_do_upgrade(int argc, char **argv) assert(ret == 0); if (cb.cb_first) { - (void) printf(gettext("Every feature flags pool has " - "all supported features enabled.\n")); + (void) printf(gettext("Every %sfeature flags pool has " + "all supported features enabled.\n"), + cb.cb_unavail ? gettext("available ") : ""); } else { (void) printf(gettext("\n")); } } else { - ret = for_each_pool(argc, argv, B_FALSE, NULL, + ret = for_each_pool(argc, argv, B_TRUE, NULL, upgrade_one, &cb); } From 5547f9fb510989a9ae75bc5c6af86f5e7f48da9a Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Fri, 26 Dec 2014 01:48:44 +0000 Subject: [PATCH 172/207] Mention cc_cdg. --- share/man/man4/mod_cc.4 | 3 ++- share/man/man9/mod_cc.9 | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/share/man/man4/mod_cc.4 b/share/man/man4/mod_cc.4 index 4b08a6d9cff..b280d36b528 100644 --- a/share/man/man4/mod_cc.4 +++ b/share/man/man4/mod_cc.4 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 15, 2011 +.Dd December 26, 2014 .Dt MOD_CC 4 .Os .Sh NAME @@ -75,6 +75,7 @@ one of the names listed by the MIB variable. .El .Sh SEE ALSO +.Xr cc_cdg 4 , .Xr cc_chd 4 , .Xr cc_cubic 4 , .Xr cc_hd 4 , diff --git a/share/man/man9/mod_cc.9 b/share/man/man9/mod_cc.9 index 4875949da50..f1cd5be0807 100644 --- a/share/man/man9/mod_cc.9 +++ b/share/man/man9/mod_cc.9 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 25, 2014 +.Dd December 26, 2014 .Dt MOD_CC 9 .Os .Sh NAME @@ -290,6 +290,7 @@ by the value of the congestion window. Algorithms should use the absence of this flag being set to avoid accumulating a large difference between the congestion window and send window. .Sh SEE ALSO +.Xr cc_cdg 4 , .Xr cc_chd 4 , .Xr cc_cubic 4 , .Xr cc_hd 4 , From 32d0bb7e1b222ba8d8414fecd8f055c9e1e351bc Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Fri, 26 Dec 2014 03:03:41 +0000 Subject: [PATCH 173/207] gas: use memmove instead of bogus memcpy. partial_where points into the buffer that begins with buffer_start so we need to use memmove() to handle the overlap. Sourceware-PR 11456. Obtained from: OpenBSD (CVS rev. 1.2) MFC after: 3 days --- contrib/binutils/gas/input-scrub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/binutils/gas/input-scrub.c b/contrib/binutils/gas/input-scrub.c index 5698a6dc22a..6eb01898bd9 100644 --- a/contrib/binutils/gas/input-scrub.c +++ b/contrib/binutils/gas/input-scrub.c @@ -335,7 +335,7 @@ input_scrub_next_buffer (char **bufp) if (partial_size) { - memcpy (buffer_start + BEFORE_SIZE, partial_where, + memmove (buffer_start + BEFORE_SIZE, partial_where, (unsigned int) partial_size); memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE); } From e63365a08974e09eb10a922680b041e66d6cb10a Mon Sep 17 00:00:00 2001 From: "Pedro F. Giffuni" Date: Fri, 26 Dec 2014 04:33:53 +0000 Subject: [PATCH 174/207] Backport fix for binutils 11867: .quad directive not assembled correctly Alan Modra (and Alan's employer) graciously permitted use of his patch under GPLv2. Obtained from: OpenBSD MFC after: 5 days --- contrib/binutils/gas/expr.c | 21 ++++++++++++++------- contrib/binutils/gas/read.c | 23 ++++++++++++++++++++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/contrib/binutils/gas/expr.c b/contrib/binutils/gas/expr.c index 11f2942672c..3f364b51f2e 100644 --- a/contrib/binutils/gas/expr.c +++ b/contrib/binutils/gas/expr.c @@ -1040,6 +1040,15 @@ operand (expressionS *expressionP, enum expr_mode mode) { for (i = 0; i < expressionP->X_add_number; ++i) generic_bignum[i] = ~generic_bignum[i]; + + /* Extend the bignum to at least the size of .octa. */ + if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER) + { + expressionP->X_add_number = SIZE_OF_LARGE_NUMBER; + for (; i < expressionP->X_add_number; ++i) + generic_bignum[i] = ~(LITTLENUM_TYPE) 0; + } + if (c == '-') for (i = 0; i < expressionP->X_add_number; ++i) { @@ -1050,14 +1059,12 @@ operand (expressionS *expressionP, enum expr_mode mode) } else if (c == '!') { - int nonzero = 0; for (i = 0; i < expressionP->X_add_number; ++i) - { - if (generic_bignum[i]) - nonzero = 1; - generic_bignum[i] = 0; - } - generic_bignum[0] = nonzero; + if (generic_bignum[i] != 0) + break; + expressionP->X_add_number = i >= expressionP->X_add_number; + expressionP->X_op = O_constant; + expressionP->X_unsigned = 1; } } else if (expressionP->X_op != O_illegal diff --git a/contrib/binutils/gas/read.c b/contrib/binutils/gas/read.c index 0098d7691b3..5e0bdb0d54b 100644 --- a/contrib/binutils/gas/read.c +++ b/contrib/binutils/gas/read.c @@ -4117,15 +4117,32 @@ emit_expr (expressionS *exp, unsigned int nbytes) unsigned int size; LITTLENUM_TYPE *nums; - know (nbytes % CHARS_PER_LITTLENUM == 0); - size = exp->X_add_number * CHARS_PER_LITTLENUM; if (nbytes < size) { - as_warn (_("bignum truncated to %d bytes"), nbytes); + int i = nbytes / CHARS_PER_LITTLENUM; + if (i != 0) + { + LITTLENUM_TYPE sign = 0; + if ((generic_bignum[--i] + & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0) + sign = ~(LITTLENUM_TYPE) 0; + while (++i < exp->X_add_number) + if (generic_bignum[i] != sign) + break; + } + if (i < exp->X_add_number) + as_warn (_("bignum truncated to %d bytes"), nbytes); size = nbytes; } + if (nbytes == 1) + { + md_number_to_chars (p, (valueT) generic_bignum[0], 1); + return; + } + know (nbytes % CHARS_PER_LITTLENUM == 0); + if (target_big_endian) { while (nbytes > size) From e3fe6b94889d9c040e3c2c70b072e4554dc4bc6a Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 07:34:42 +0000 Subject: [PATCH 175/207] Fix .TH having too many arguments --- contrib/ee/ee.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ee/ee.1 b/contrib/ee/ee.1 index 7d482a85727..b66c8aae17a 100644 --- a/contrib/ee/ee.1 +++ b/contrib/ee/ee.1 @@ -7,7 +7,7 @@ .\" $Header: /home/hugh/sources/old_ae/RCS/ee.1,v 1.22 2001/12/16 04:49:27 hugh Exp $ .\" .\" -.TH ee 1 "" "" "" "" +.TH ee 1 "" "" "" .SH NAME ee \- easy editor .SH SYNOPSIS From 445ed7b40948c160f2f7d363d2d0ae1ffac4aabd Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 07:36:42 +0000 Subject: [PATCH 176/207] Remove unknown macro --- contrib/bzip2/bzip2.1 | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/bzip2/bzip2.1 b/contrib/bzip2/bzip2.1 index ce3a78e6b4f..7bd45f0eaf8 100644 --- a/contrib/bzip2/bzip2.1 +++ b/contrib/bzip2/bzip2.1 @@ -1,4 +1,3 @@ -.PU .TH bzip2 1 .SH NAME bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6 From 7161cdb37bab56bfc73e166bf6686a920f72166c Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Fri, 26 Dec 2014 09:18:33 +0000 Subject: [PATCH 177/207] Minor Xr fix. --- lib/msun/man/csqrt.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/msun/man/csqrt.3 b/lib/msun/man/csqrt.3 index 1a1dfa05563..d8066aea156 100644 --- a/lib/msun/man/csqrt.3 +++ b/lib/msun/man/csqrt.3 @@ -85,7 +85,7 @@ an \*(Na is generated, an invalid exception will be thrown. .Sh SEE ALSO .Xr cabs 3 , .Xr fenv 3 , -.Xr math 3 , +.Xr math 3 .Sh STANDARDS The .Fn csqrt , From bf15fc88e94001637cf844b6f6cb27d806d44758 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Fri, 26 Dec 2014 09:35:23 +0000 Subject: [PATCH 178/207] Minor mdoc fixes. --- share/man/man4/netmap.4 | 80 +++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/share/man/man4/netmap.4 b/share/man/man4/netmap.4 index f6ca70b01f6..bd5f4f28782 100644 --- a/share/man/man4/netmap.4 +++ b/share/man/man4/netmap.4 @@ -243,7 +243,6 @@ contains the index of the first of these free rings, which are connected in a list (the first uint32_t of each buffer being the index of the next buffer in the list). A 0 indicates the end of the list. -.Pp .It Dv struct netmap_ring (one per ring) .Bd -literal struct netmap_ring { @@ -266,7 +265,6 @@ Implements transmit and receive rings, with read/write pointers, metadata and and an array of .Pa slots describing the buffers. -.Pp .It Dv struct netmap_slot (one per buffer) .Bd -literal struct netmap_slot { @@ -367,7 +365,6 @@ are pushed to the port, and .Va tail may advance if further slots have become available. Below is an example of the evolution of a TX ring: -.Pp .Bd -literal after the syscall, slots between cur and tail are (a)vailable head=cur tail @@ -455,7 +452,6 @@ it MUST be used when the buf_idx in the slot is changed. This can be used to implement zero-copy forwarding, see .Sx ZERO-COPY FORWARDING . -.Pp .It NS_REPORT reports when this buffer has been transmitted. Normally, @@ -533,7 +529,6 @@ A file descriptor obtained through .Pa /dev/netmap also supports the ioctl supported by network devices, see .Xr netintro 4 . -.Pp .Bl -tag -width XXXX .It Dv NIOCGINFO returns EINVAL if the named port does not support netmap. @@ -541,7 +536,6 @@ Otherwise, it returns 0 and (advisory) information about the port. Note that all the information below can change before the interface is actually put in netmap mode. -.Pp .Bl -tag -width XX .It Pa nr_memsize indicates the size of the @@ -603,7 +597,6 @@ that application libraries (such as the .Nm nm_open indicated below) can use to indicate the specific set of rings. In the example below, "netmap:foo" is any valid netmap port name. -.Pp .Bl -tag -width XXXXX .It NR_REG_ALL_NIC "netmap:foo" (default) all hardware ring pairs @@ -784,7 +777,6 @@ are controlled through sysctl variables on FreeBSD .Em ( dev.netmap.* ) and module parameters on Linux .Em ( /sys/module/netmap_lin/parameters/* ) : -.Pp .Bl -tag -width indent .It Va dev.netmap.admode: 0 Controls the use of native or emulated adapter mode. @@ -852,42 +844,6 @@ OS primitives, see In particular, .Xr pthread_setaffinity_np 3 may be of use. -.Sh CAVEATS -No matter how fast the CPU and OS are, -achieving line rate on 10G and faster interfaces -requires hardware with sufficient performance. -Several NICs are unable to sustain line rate with -small packet sizes. Insufficient PCIe or memory bandwidth -can also cause reduced performance. -.Pp -Another frequent reason for low performance is the use -of flow control on the link: a slow receiver can limit -the transmit speed. -Be sure to disable flow control when running high -speed experiments. -.Pp -.Ss SPECIAL NIC FEATURES -.Nm -is orthogonal to some NIC features such as -multiqueue, schedulers, packet filters. -.Pp -Multiple transmit and receive rings are supported natively -and can be configured with ordinary OS tools, -such as -.Xr ethtool -or -device-specific sysctl variables. -The same goes for Receive Packet Steering (RPS) -and filtering of incoming traffic. -.Pp -.Nm -.Em does not use -features such as -.Em checksum offloading , TCP segmentation offloading , -.Em encryption , VLAN encapsulation/decapsulation , -etc. . -When using netmap to exchange packets with the host stack, -make sure to disable these features. .Sh EXAMPLES .Ss TEST PROGRAMS .Nm @@ -1065,3 +1021,39 @@ and .Nm VALE have been funded by the European Commission within FP7 Projects CHANGE (257422) and OPENLAB (287581). +.Sh CAVEATS +No matter how fast the CPU and OS are, +achieving line rate on 10G and faster interfaces +requires hardware with sufficient performance. +Several NICs are unable to sustain line rate with +small packet sizes. Insufficient PCIe or memory bandwidth +can also cause reduced performance. +.Pp +Another frequent reason for low performance is the use +of flow control on the link: a slow receiver can limit +the transmit speed. +Be sure to disable flow control when running high +speed experiments. +.Pp +.Ss SPECIAL NIC FEATURES +.Nm +is orthogonal to some NIC features such as +multiqueue, schedulers, packet filters. +.Pp +Multiple transmit and receive rings are supported natively +and can be configured with ordinary OS tools, +such as +.Xr ethtool +or +device-specific sysctl variables. +The same goes for Receive Packet Steering (RPS) +and filtering of incoming traffic. +.Pp +.Nm +.Em does not use +features such as +.Em checksum offloading , TCP segmentation offloading , +.Em encryption , VLAN encapsulation/decapsulation , +etc. . +When using netmap to exchange packets with the host stack, +make sure to disable these features. From d0bd1251350a0564fb20f0044f061f1c6b6079c2 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 26 Dec 2014 10:25:34 +0000 Subject: [PATCH 179/207] Add proper Makefiles to build some infiniband example utilities. MFC after: 1 week Sponsored by: Mellanox Technologies --- contrib/ofed/libibverbs/examples/Makefile | 28 ------------------- .../ofed/libibverbs/examples/build/Makefile | 4 +++ .../libibverbs/examples/build/Makefile.inc | 7 +++++ .../examples/build/asyncwatch/Makefile | 9 ++++++ .../examples/build/device_list/Makefile | 9 ++++++ .../examples/build/devinfo/Makefile | 9 ++++++ .../examples/build/rc_pingpong/Makefile | 9 ++++++ .../examples/build/srq_pingpong/Makefile | 9 ++++++ .../examples/build/uc_pingpong/Makefile | 9 ++++++ .../examples/build/ud_pingpong/Makefile | 9 ++++++ 10 files changed, 74 insertions(+), 28 deletions(-) delete mode 100644 contrib/ofed/libibverbs/examples/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/Makefile.inc create mode 100644 contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/device_list/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/devinfo/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile create mode 100644 contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile diff --git a/contrib/ofed/libibverbs/examples/Makefile b/contrib/ofed/libibverbs/examples/Makefile deleted file mode 100644 index 06da51161e1..00000000000 --- a/contrib/ofed/libibverbs/examples/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -CFLAGS= -I../../../../sys/ofed/include -libverbs -lmlx4 -lmthca -pthread - -all: asyncwatch devinfo device_list rc_pingpong srq_pingpong uc_pingpong ud_pingpong - -clean: - rm asyncwatch devinfo device_list rc_pingpong srq_pingpong uc_pingpong ud_pingpong - -asyncwatch: - gcc -o asyncwatch asyncwatch.c ${CFLAGS} - -devinfo: - gcc -o devinfo devinfo.c ${CFLAGS} - -device_list: - gcc -o device_list device_list.c ${CFLAGS} - -rc_pingpong: - gcc -o rc_pingpong rc_pingpong.c pingpong.c ${CFLAGS} - -srq_pingpong: - gcc -o srq_pingpong srq_pingpong.c pingpong.c ${CFLAGS} - -uc_pingpong: - gcc -o uc_pingpong uc_pingpong.c pingpong.c ${CFLAGS} - -ud_pingpong: - gcc -o ud_pingpong ud_pingpong.c pingpong.c ${CFLAGS} - diff --git a/contrib/ofed/libibverbs/examples/build/Makefile b/contrib/ofed/libibverbs/examples/build/Makefile new file mode 100644 index 00000000000..311899dfed8 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/Makefile @@ -0,0 +1,4 @@ +SUBDIR= asyncwatch devinfo device_list rc_pingpong \ + srq_pingpong uc_pingpong ud_pingpong + +.include diff --git a/contrib/ofed/libibverbs/examples/build/Makefile.inc b/contrib/ofed/libibverbs/examples/build/Makefile.inc new file mode 100644 index 00000000000..9683a312a25 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/Makefile.inc @@ -0,0 +1,7 @@ +CFLAGS+= \ + -I../../../../../../sys/ofed/include \ + -I../../../../libibverbs/include \ + -I../../../../include + +LDADD+= -libverbs -lmlx4 -lmthca -pthread + diff --git a/contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile b/contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile new file mode 100644 index 00000000000..7a0a5b2ac06 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= asyncwatch +MAN= +SRCS= asyncwatch.c + +.include diff --git a/contrib/ofed/libibverbs/examples/build/device_list/Makefile b/contrib/ofed/libibverbs/examples/build/device_list/Makefile new file mode 100644 index 00000000000..4cdeff5c1c3 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/device_list/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= device_list +MAN= +SRCS= device_list.c + +.include diff --git a/contrib/ofed/libibverbs/examples/build/devinfo/Makefile b/contrib/ofed/libibverbs/examples/build/devinfo/Makefile new file mode 100644 index 00000000000..ca6fb6cdd52 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/devinfo/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= devinfo +MAN= +SRCS= devinfo.c + +.include diff --git a/contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile new file mode 100644 index 00000000000..824b08e9db6 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= rc_pingpong +MAN= +SRCS= rc_pingpong.c pingpong.c + +.include diff --git a/contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile new file mode 100644 index 00000000000..c485d502e66 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= srq_pingpong +MAN= +SRCS= srq_pingpong.c pingpong.c + +.include diff --git a/contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile new file mode 100644 index 00000000000..7427eb9db77 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= uc_pingpong +MAN= +SRCS= uc_pingpong.c pingpong.c + +.include diff --git a/contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile new file mode 100644 index 00000000000..8a0f8e82571 --- /dev/null +++ b/contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile @@ -0,0 +1,9 @@ +# +# $FreeBSD$ +# +.PATH: ${.CURDIR}/../.. +PROG= ud_pingpong +MAN= +SRCS= ud_pingpong.c pingpong.c + +.include From 7e19194edf990418b7513f6923d68e4d31abd60f Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 26 Dec 2014 10:53:22 +0000 Subject: [PATCH 180/207] Add more quirks. PR: 180617 MFC after: 1 day --- sys/dev/usb/quirk/usb_quirk.c | 1 + sys/dev/usb/usbdevs | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c index 1799d47c0e8..6b2f6b8ba6f 100644 --- a/sys/dev/usb/quirk/usb_quirk.c +++ b/sys/dev/usb/quirk/usb_quirk.c @@ -449,6 +449,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(WESTERN, MYPASSPORT_08, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WESTERN, MYPASSPORT_09, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WESTERN, MYPASSPORT_10, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), + USB_QUIRK(WESTERN, MYPASSPORT_11, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WESTERN, MYPASSPORTES_00, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WESTERN, MYPASSPORTES_01, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), USB_QUIRK(WESTERN, MYPASSPORTES_02, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE), diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 2d86d1ba6a6..eca50bade13 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -4492,6 +4492,7 @@ product WESTERN EXTHDD 0x0400 External HDD product WESTERN HUB 0x0500 USB HUB product WESTERN MYBOOK 0x0901 MyBook External HDD product WESTERN MYPASSPORT_00 0x0704 MyPassport External HDD +product WESTERN MYPASSPORT_11 0x0741 MyPassport External HDD product WESTERN MYPASSPORT_01 0x0746 MyPassport External HDD product WESTERN MYPASSPORT_02 0x0748 MyPassport External HDD product WESTERN MYPASSPORT_03 0x074A MyPassport External HDD From f0442cf2e0f58a35bb952ad395dbfa29776e39af Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 26 Dec 2014 10:57:39 +0000 Subject: [PATCH 181/207] Add more USB devices. MFC after: 1 day Submitted by: Dmitry Luhtionov --- sys/dev/usb/usbdevs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index eca50bade13..b9ea927338c 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -2411,6 +2411,8 @@ product INTEL EASYPC_CAMERA 0x0110 Easy PC Camera product INTEL TESTBOARD 0x9890 82930 test board product INTEL2 IRMH 0x0020 Integrated Rate Matching Hub product INTEL2 IRMH2 0x0024 Integrated Rate Matching Hub +product INTEL2 IRMH3 0x8000 Integrated Rate Matching Hub +product INTEL2 IRMH4 0x8008 Integrated Rate Matching Hub /* Interbiometric products */ product INTERBIOMETRICS IOBOARD 0x1002 FTDI compatible adapter From 2ed434b4bf929508567efd16a6df2c24597ef822 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Fri, 26 Dec 2014 13:44:41 +0000 Subject: [PATCH 182/207] Squelch a (bogus) gcc use-before-init warning. --- sys/arm/ti/ti_gpio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index 45e849b657d..5fe8094bf55 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -618,6 +618,7 @@ ti_gpio_intr(void *arg) sc = (struct ti_gpio_softc *)arg; bank_last = -1; + reg = 0; /* squelch bogus gcc warning */ for (irq = 0; irq < sc->sc_maxpin; irq++) { /* Read interrupt status only once for each bank. */ From efa8bab71345f020fbcca80d8a7ece05dc406747 Mon Sep 17 00:00:00 2001 From: Ian Lepore Date: Fri, 26 Dec 2014 14:29:27 +0000 Subject: [PATCH 183/207] Include acle-compat.h directly (we use its symbols) rather than getting it via sysreg.h. --- sys/arm/include/asm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h index deaccec19ee..9122e6ea3a3 100644 --- a/sys/arm/include/asm.h +++ b/sys/arm/include/asm.h @@ -39,6 +39,7 @@ #ifndef _MACHINE_ASM_H_ #define _MACHINE_ASM_H_ #include +#include #include #define _C_LABEL(x) x From f2e44b6029eb1db87bccdb7db68242556c2bcffd Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 26 Dec 2014 17:45:49 +0000 Subject: [PATCH 184/207] Fix the musb initialization sequence on AM335x. According to http://e2e.ti.com/support/arm/sitara_arm/f/791/t/210729 the USB reset pulse has an undocumented duration of 200ns and during this period the module must not be acessed. We wait for 100us to take into account for some imprecision of the early DELAY() loop. This fixes the eventual 'External Non-Linefetch Abort (S)' that happens at boot while resetting the musb subsystem. While here, enable the USB subsystem clock before the first access. Discussed with: ian, adrian MFC after: 2 weeks --- sys/arm/ti/am335x/am335x_usbss.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/sys/arm/ti/am335x/am335x_usbss.c b/sys/arm/ti/am335x/am335x_usbss.c index f1204f35e96..0173922a1a5 100644 --- a/sys/arm/ti/am335x/am335x_usbss.c +++ b/sys/arm/ti/am335x/am335x_usbss.c @@ -288,21 +288,30 @@ musbotg_attach(device_t dev) return (ENXIO); } + /* Enable device clocks. */ + ti_prcm_clk_enable(MUSB0_CLK); + /* - * Reset USBSS, USB0 and USB1 + * Reset USBSS, USB0 and USB1. + * The registers of USB subsystem must not be accessed while the + * reset pulse is active (200ns). */ + USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET); + DELAY(100); + i = 10; + while (USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET) { + DELAY(100); + if (i-- == 0) { + device_printf(dev, "reset timeout.\n"); + return (ENXIO); + } + } + + /* Read the module revision. */ rev = USBSS_READ4(sc, USBSS_REVREG); device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n", (rev >> 8) & 7, (rev >> 6) & 3, rev & 63); - ti_prcm_clk_enable(MUSB0_CLK); - - USBSS_WRITE4(sc, USBSS_SYSCONFIG, - USBSS_SYSCONFIG_SRESET); - while (USBSS_READ4(sc, USBSS_SYSCONFIG) & - USBSS_SYSCONFIG_SRESET) - ; - err = bus_setup_intr(dev, sc->sc_irq_res[0], INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)musbotg_usbss_interrupt, sc, From 003e64df933815479ea78ede810180d6b04ffafe Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 26 Dec 2014 18:53:29 +0000 Subject: [PATCH 185/207] DOF tables are aligned according to the DOF section's alignment constraint, so take this into account when iterating over DOF tables. PR: 195555 Submitted by: Fedor Indutny (original version) MFC after: 1 week --- cddl/contrib/opensolaris/lib/libdtrace/common/drti.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c index d7b34907e4b..6f3c9c7d3de 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c @@ -127,6 +127,7 @@ dtrace_dof_init(void) int efd; char *s; size_t shstridx; + uint64_t aligned_filesz; #endif if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL) @@ -183,7 +184,9 @@ dtrace_dof_init(void) } while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) { - dof_next = (void *) ((char *) dof + dof->dofh_filesz); + aligned_filesz = (shdr.sh_addralign == 0 ? dof->dofh_filesz : + roundup2(dof->dofh_filesz, shdr.sh_addralign)); + dof_next = (void *) ((char *) dof + aligned_filesz); #endif if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 || From df7f007fe8aa1f15631555ba3719fb6b040f3027 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 20:49:23 +0000 Subject: [PATCH 186/207] mdoc fixes --- contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 | 1 + contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 | 1 + contrib/elftoolchain/libdwarf/dwarf_hasattr.3 | 1 + contrib/elftoolchain/libdwarf/dwarf_whatattr.3 | 1 + 4 files changed, 4 insertions(+) diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 index 5b5d5a1167a..e88e3cf362b 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 @@ -247,6 +247,7 @@ constants. .It Fn dwarf_get_VIS_name .Dv DW_VIS_* constants. +.El .Sh RETURN VALUES These functions return .Dv DW_DLV_OK on success. diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 index e8dac7810a0..2e67871bf36 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 @@ -102,6 +102,7 @@ One of the arguments or .Ar cu_die_offset was NULL. +.El .Sh EXAMPLE To loop through all the address lookup table entries, use: .Bd -literal -offset indent diff --git a/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 index 5b4699bd777..d3bcb271e2d 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 @@ -85,6 +85,7 @@ Either of argument or .Va ret_bool was NULL. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , diff --git a/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 index 7c9a6d04bfc..96d9ad288ed 100644 --- a/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 +++ b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 @@ -72,6 +72,7 @@ Either of argument or .Va retcode was NULL. +.El .Sh SEE ALSO .Xr dwarf 3 , .Xr dwarf_attr 3 , From e66fe60d56bc6099243df96c03e390eef1b41aa2 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 20:50:40 +0000 Subject: [PATCH 187/207] mdoc fixes --- contrib/elftoolchain/libelf/elf.3 | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/elftoolchain/libelf/elf.3 b/contrib/elftoolchain/libelf/elf.3 index 462e7285417..eb5c3eb2741 100644 --- a/contrib/elftoolchain/libelf/elf.3 +++ b/contrib/elftoolchain/libelf/elf.3 @@ -389,7 +389,6 @@ See .It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. .It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. .El -.TE .Ss Functional Grouping This section contains a brief overview of the available functionality in the ELF library. From 6047eb6e49a24a3fc1aebad90736c421a5b1c1d1 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 20:57:10 +0000 Subject: [PATCH 188/207] mdoc fixes --- contrib/libxo/libxo/xo_create.3 | 2 +- contrib/libxo/libxo/xo_emit.3 | 2 +- contrib/libxo/libxo/xo_open_container.3 | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contrib/libxo/libxo/xo_create.3 b/contrib/libxo/libxo/xo_create.3 index 1e0a69babc9..ec241ee1e0e 100644 --- a/contrib/libxo/libxo/xo_create.3 +++ b/contrib/libxo/libxo/xo_create.3 @@ -76,7 +76,7 @@ https://github.com/Juniper/libxo/releases .Sh SEE ALSO .Xr xo_emit 3 and -.Xf xo_set_options 3 . +.Xr xo_set_options 3 . .Sh HISTORY The .Fa libxo diff --git a/contrib/libxo/libxo/xo_emit.3 b/contrib/libxo/libxo/xo_emit.3 index 1128dc72ee9..9f76e13c632 100644 --- a/contrib/libxo/libxo/xo_emit.3 +++ b/contrib/libxo/libxo/xo_emit.3 @@ -35,7 +35,7 @@ but using a more complex format description string, as described in .Pp .Fn xo_emit uses the default output handle, as described in -.Xf libxo 3 , +.Xr libxo 3 , where .Fn xo_emit_h uses an explicit handle. diff --git a/contrib/libxo/libxo/xo_open_container.3 b/contrib/libxo/libxo/xo_open_container.3 index af54d05576a..a872be207da 100644 --- a/contrib/libxo/libxo/xo_open_container.3 +++ b/contrib/libxo/libxo/xo_open_container.3 @@ -105,7 +105,7 @@ container, a warning will be generated.
my-host.example.org
.Ed -.SH EMITTING HIERARCHY +.Sh EMITTING HIERARCHY To create a container, use the .Fn xo_open_container and @@ -131,7 +131,7 @@ traditional C strings can be used directly. The close functions with the .Dq _d suffix are used in -.Dq Do The Right Thing +.Dq The Right Thing mode, where the name of the open containers, lists, and instances are maintained internally by .Em libxo @@ -161,7 +161,7 @@ Some user may find tracking the names of open containers, lists, and instances inconvenient. .Em libxo offers -.Dq Do The Right Thing +.Dq The Right Thing mode, where .Em libxo will track the names of open containers, lists, and instances so From fe1e4a6cfaa4780f5cb92f5c922cdb408face976 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 21:03:56 +0000 Subject: [PATCH 189/207] mdoc fixes (escape the dot to prevent ... to be considered as a macro) --- share/man/man4/netmap.4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/netmap.4 b/share/man/man4/netmap.4 index bd5f4f28782..d0516207731 100644 --- a/share/man/man4/netmap.4 +++ b/share/man/man4/netmap.4 @@ -885,7 +885,7 @@ The following code implements a traffic generator .Pp .Bd -literal -compact #include -... +\&... void sender(void) { struct netmap_if *nifp; @@ -920,7 +920,7 @@ A simple receiver can be implemented using the helper functions .Bd -literal -compact #define NETMAP_WITH_LIBS #include -... +\&... void receiver(void) { struct nm_desc *d; From 6342c823b5355f2ae56301794d879e9cb914f617 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 21:11:33 +0000 Subject: [PATCH 190/207] Escape Ed to prevent mandoc to avoid confusion with the mdoc's Ed macros --- share/man/man3/ATOMIC_VAR_INIT.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man3/ATOMIC_VAR_INIT.3 b/share/man/man3/ATOMIC_VAR_INIT.3 index f6c0a5da21a..e2786027a42 100644 --- a/share/man/man3/ATOMIC_VAR_INIT.3 +++ b/share/man/man3/ATOMIC_VAR_INIT.3 @@ -297,5 +297,5 @@ These macros attempt to conform to These macros appeared in .Fx 10.0 . .Sh AUTHORS -.An Ed Schouten Aq Mt ed@FreeBSD.org +.An \&Ed Schouten Aq Mt ed@FreeBSD.org .An David Chisnall Aq Mt theraven@FreeBSD.org From 5b4d85125ba775848db9ddf872138618b6de9d0f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 21:45:01 +0000 Subject: [PATCH 191/207] mdoc fix --- share/man/man4/ohci.4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/ohci.4 b/share/man/man4/ohci.4 index b89eeb774f3..f68afc1cc19 100644 --- a/share/man/man4/ohci.4 +++ b/share/man/man4/ohci.4 @@ -60,9 +60,9 @@ NVIDIA nForce3 Sun PCIO-2 (RIO USB) .El .Sh SEE ALSO -.Xr xhci 4 , .Xr ehci 4 , -.Xr uhci 4 +.Xr uhci 4 , +.Xr xhci 4 .Sh HISTORY The .Nm From 914f6e629041cb3c5d1be5812198bb0e5c2d7d69 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Fri, 26 Dec 2014 21:56:23 +0000 Subject: [PATCH 192/207] mdoc: sort SEE ALSO. --- usr.bin/dpv/dpv.1 | 4 ++-- usr.bin/iscsictl/iscsi.conf.5 | 4 ++-- usr.bin/last/last.1 | 4 ++-- usr.bin/man/man.1 | 18 +++++++++--------- usr.bin/mkcsmapper/mkcsmapper.1 | 4 ++-- usr.bin/mkesdb/mkesdb.1 | 4 ++-- usr.bin/rup/rup.1 | 4 ++-- usr.bin/rusers/rusers.1 | 4 ++-- usr.bin/rwall/rwall.1 | 4 ++-- usr.bin/script/script.1 | 2 +- usr.bin/setchannel/setchannel.1 | 2 +- usr.bin/showmount/showmount.8 | 4 ++-- usr.sbin/bluetooth/btpand/btpand.8 | 4 ++-- .../bsnmpd/modules/snmp_bridge/snmp_bridge.3 | 4 ++-- usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 | 4 ++-- usr.sbin/gpioctl/gpioctl.8 | 4 ++-- usr.sbin/gssd/gssd.8 | 4 ++-- usr.sbin/jail/jail.8 | 2 +- usr.sbin/nandsim/nandsim.8 | 2 +- usr.sbin/nfsuserd/nfsuserd.8 | 4 ++-- usr.sbin/rpc.umntall/rpc.umntall.8 | 2 +- usr.sbin/rtadvctl/rtadvctl.8 | 4 ++-- usr.sbin/rtadvd/rtadvd.conf.5 | 2 +- 23 files changed, 47 insertions(+), 47 deletions(-) diff --git a/usr.bin/dpv/dpv.1 b/usr.bin/dpv/dpv.1 index dacfdf96f5b..d277446e5c0 100644 --- a/usr.bin/dpv/dpv.1 +++ b/usr.bin/dpv/dpv.1 @@ -359,9 +359,9 @@ dpv -o /dev/md42 < /dev/zero .Ed .Sh SEE ALSO .Xr dialog 1 , -.Xr dialog 3 , .Xr sh 1 , -.Xr Xdialog 1 +.Xr Xdialog 1 , +.Xr dialog 3 .Sh HISTORY A .Nm diff --git a/usr.bin/iscsictl/iscsi.conf.5 b/usr.bin/iscsictl/iscsi.conf.5 index 2e7a68dc647..03433859cc1 100644 --- a/usr.bin/iscsictl/iscsi.conf.5 +++ b/usr.bin/iscsictl/iscsi.conf.5 @@ -175,8 +175,8 @@ chaptest { .Ed .Sh SEE ALSO .Xr iscsi_initiator 4 , -.Xr iscsictl 8 , -.Xr iscontrol 8 +.Xr iscontrol 8 , +.Xr iscsictl 8 .Sh STANDARDS ISCSI RFC 3720 .\"Sh HISTORY diff --git a/usr.bin/last/last.1 b/usr.bin/last/last.1 index 6cb2e6873a6..e552dd685f8 100644 --- a/usr.bin/last/last.1 +++ b/usr.bin/last/last.1 @@ -198,9 +198,9 @@ login data base .El .Sh SEE ALSO .Xr lastcomm 1 , -.Xr lastlogin 8 , .Xr getutxent 3 , -.Xr ac 8 +.Xr ac 8 , +.Xr lastlogin 8 .Sh HISTORY A .Nm diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1 index ca497f32a25..5647b6c7491 100644 --- a/usr.bin/man/man.1 +++ b/usr.bin/man/man.1 @@ -349,17 +349,17 @@ Local configuration files. .Sh SEE ALSO .Xr apropos 1 , .Xr intro 1 , -.Xr intro 2 , -.Xr intro 3 , -.Xr intro 4 , -.Xr intro 5 , -.Xr intro 6 , -.Xr intro 7 , -.Xr intro 8 , -.Xr intro 9 , .Xr locale 1 , .Xr manpath 1 , .Xr nroff 1 , .Xr troff 1 , .Xr whatis 1 , -.Xr man.conf 5 +.Xr intro 2 , +.Xr intro 3 , +.Xr intro 4 , +.Xr intro 5 , +.Xr man.conf 5 , +.Xr intro 6 , +.Xr intro 7 , +.Xr intro 8 , +.Xr intro 9 diff --git a/usr.bin/mkcsmapper/mkcsmapper.1 b/usr.bin/mkcsmapper/mkcsmapper.1 index cf1fde23368..8faf5e6ba6d 100644 --- a/usr.bin/mkcsmapper/mkcsmapper.1 +++ b/usr.bin/mkcsmapper/mkcsmapper.1 @@ -77,8 +77,8 @@ Generate pivot data from .Ex -std mkcsmapper .Sh SEE ALSO .Xr iconv 1 , -.Xr iconv 3 , -.Xr mkesdb 1 +.Xr mkesdb 1 , +.Xr iconv 3 .Sh HISTORY .Nm first appeared in diff --git a/usr.bin/mkesdb/mkesdb.1 b/usr.bin/mkesdb/mkesdb.1 index c5d2edfed72..a0743b6ea8e 100644 --- a/usr.bin/mkesdb/mkesdb.1 +++ b/usr.bin/mkesdb/mkesdb.1 @@ -72,8 +72,8 @@ Put generated binary data to .Ex -std mkesdb .Sh SEE ALSO .Xr iconv 1 , -.Xr iconv 3 , -.Xr mkcsmapper 1 +.Xr mkcsmapper 1 , +.Xr iconv 3 .Sh HISTORY .Nm first appeared in diff --git a/usr.bin/rup/rup.1 b/usr.bin/rup/rup.1 index 8b16670e9d1..499d6ab8157 100644 --- a/usr.bin/rup/rup.1 +++ b/usr.bin/rup/rup.1 @@ -83,8 +83,8 @@ and cannot accommodate any RPC-based services. The host may be down. .El .Sh SEE ALSO -.Xr rpcbind 8 , -.Xr rpc.rstatd 8 +.Xr rpc.rstatd 8 , +.Xr rpcbind 8 .Sh HISTORY The .Nm diff --git a/usr.bin/rusers/rusers.1 b/usr.bin/rusers/rusers.1 index b96933f8f61..8980d21dbe1 100644 --- a/usr.bin/rusers/rusers.1 +++ b/usr.bin/rusers/rusers.1 @@ -92,8 +92,8 @@ The host may be down. .Xr rwho 1 , .Xr users 1 , .Xr who 1 , -.Xr rpcbind 8 , -.Xr rpc.rusersd 8 +.Xr rpc.rusersd 8 , +.Xr rpcbind 8 .Sh HISTORY The .Nm diff --git a/usr.bin/rwall/rwall.1 b/usr.bin/rwall/rwall.1 index 7e54603c86b..bb545e81de8 100644 --- a/usr.bin/rwall/rwall.1 +++ b/usr.bin/rwall/rwall.1 @@ -67,8 +67,8 @@ The host may be down. .El .Sh SEE ALSO .Xr who 1 , -.Xr rpcbind 8 , -.Xr rpc.rwalld 8 +.Xr rpc.rwalld 8 , +.Xr rpcbind 8 .Sh HISTORY The .Nm diff --git a/usr.bin/script/script.1 b/usr.bin/script/script.1 index de8e7fff17b..239508ffb06 100644 --- a/usr.bin/script/script.1 +++ b/usr.bin/script/script.1 @@ -164,7 +164,7 @@ is assumed. .Pq Most shells set this variable automatically . .El .Sh SEE ALSO -.Xr csh 1 +.Xr csh 1 , .Xr filemon 4 .Po for the diff --git a/usr.bin/setchannel/setchannel.1 b/usr.bin/setchannel/setchannel.1 index 5b2d4ab8225..d0c865e0483 100644 --- a/usr.bin/setchannel/setchannel.1 +++ b/usr.bin/setchannel/setchannel.1 @@ -85,8 +85,8 @@ Channel number to set. Frequency in MHz (must include decimal point). .El .Sh SEE ALSO -.Xr cxm 4 , .Xr bktr 4 , +.Xr cxm 4 , .Xr meteor 4 .Sh HISTORY The diff --git a/usr.bin/showmount/showmount.8 b/usr.bin/showmount/showmount.8 index 106b1a18c2b..28315937cbf 100644 --- a/usr.bin/showmount/showmount.8 +++ b/usr.bin/showmount/showmount.8 @@ -84,8 +84,8 @@ Ignored for backwards compatibility. .El .Sh SEE ALSO .Xr mount 8 , -.Xr mountd 8 , -.Xr mount_nfs 8 +.Xr mount_nfs 8 , +.Xr mountd 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/bluetooth/btpand/btpand.8 b/usr.sbin/bluetooth/btpand/btpand.8 index b89bf95348e..4f6ede6ac2d 100644 --- a/usr.sbin/bluetooth/btpand/btpand.8 +++ b/usr.sbin/bluetooth/btpand/btpand.8 @@ -206,10 +206,10 @@ Will create a Group Network and register the GN service with the local SDP server. .Sh SEE ALSO .Xr bluetooth 3 , -.Xr tap 4 , .Xr bridge 4 , -.Xr hccontrol 8 , +.Xr tap 4 , .Xr dhclient 8 , +.Xr hccontrol 8 , .Xr ifconfig 8 , .Xr sdpd 8 .Pp diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 index 677a276c189..09484cfe87b 100644 --- a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 +++ b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 @@ -112,8 +112,8 @@ This is the private BEGEMOT-BRIDGE-MIB that is implemented by this module. .Sh SEE ALSO .Xr bsnmpd 1 , .Xr gensnmptree 1 , +.Xr snmpmod 3 , .Xr if_bridge 4 , -.Xr ifconfig 8 , -.Xr snmpmod 3 +.Xr ifconfig 8 .Sh AUTHORS .An Shteryana Shopova Aq Mt syrinx@FreeBSD.org diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 index 205f11fd26f..d695eee11b1 100644 --- a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 +++ b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 @@ -151,10 +151,10 @@ The private BEGEMOT-WIRELESS-MIB that is implemented by this module. .Sh SEE ALSO .Xr bsnmpd 1 , .Xr gensnmptree 1 , +.Xr snmpmod 3 , .Xr wlan 4 , .Xr wlan_acl 4 , .Xr wlan_wep 4 , -.Xr ifconfig 8 , -.Xr snmpmod 3 +.Xr ifconfig 8 .Sh AUTHORS .An Shteryana Shopova Aq Mt syrinx@FreeBSD.org diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8 index 8a433726391..a0bf6536f8f 100644 --- a/usr.sbin/gpioctl/gpioctl.8 +++ b/usr.sbin/gpioctl/gpioctl.8 @@ -108,8 +108,8 @@ Configure pin 12 to be input pin gpioctl -f /dev/gpioc0 -c 12 IN .El .Sh SEE ALSO -.Xr gpio 4 -.Xr gpioiic 4 +.Xr gpio 4 , +.Xr gpioiic 4 , .Xr gpioled 4 .Sh HISTORY The diff --git a/usr.sbin/gssd/gssd.8 b/usr.sbin/gssd/gssd.8 index 82611f847a1..7eaf11afeff 100644 --- a/usr.sbin/gssd/gssd.8 +++ b/usr.sbin/gssd/gssd.8 @@ -106,8 +106,8 @@ by kernel GSS-API services. .Ex -std .Sh SEE ALSO .Xr gssapi 3 , -.Xr mount_nfs 8 , -.Xr syslog 3 +.Xr syslog 3 , +.Xr mount_nfs 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8 index 927e2bb449e..9719854cdcf 100644 --- a/usr.sbin/jail/jail.8 +++ b/usr.sbin/jail/jail.8 @@ -1183,7 +1183,6 @@ environment of the first jail. .Xr pkill 1 , .Xr ps 1 , .Xr quota 1 , -.Xr ifconfig 8 , .Xr jail_set 2 , .Xr devfs 5 , .Xr fdescfs 5 , @@ -1194,6 +1193,7 @@ environment of the first jail. .Xr chroot 8 , .Xr devfs 8 , .Xr halt 8 , +.Xr ifconfig 8 , .Xr inetd 8 , .Xr jexec 8 , .Xr jls 8 , diff --git a/usr.sbin/nandsim/nandsim.8 b/usr.sbin/nandsim/nandsim.8 index c7bdb9a4f01..d89767bf177 100644 --- a/usr.sbin/nandsim/nandsim.8 +++ b/usr.sbin/nandsim/nandsim.8 @@ -217,7 +217,7 @@ All commands issues to any chip on this controller are ignored. .El .Sh SEE ALSO .Xr nand 4 , -.Xr nandsim 4 +.Xr nandsim 4 , .Xr nandsim.conf 5 .Sh HISTORY The diff --git a/usr.sbin/nfsuserd/nfsuserd.8 b/usr.sbin/nfsuserd/nfsuserd.8 index 04100ea75cb..6e170db7323 100644 --- a/usr.sbin/nfsuserd/nfsuserd.8 +++ b/usr.sbin/nfsuserd/nfsuserd.8 @@ -89,12 +89,12 @@ performance impact, whereas running too many will only tie up some resources, such as a process table entry and swap space. .El .Sh SEE ALSO -.Xr getpwent 3 , .Xr getgrent 3 , +.Xr getpwent 3 , .Xr nfsv4 4 , .Xr group 5 , .Xr passwd 5 , -.Xr nfsd 8 . +.Xr nfsd 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/rpc.umntall/rpc.umntall.8 b/usr.sbin/rpc.umntall/rpc.umntall.8 index 7f294a0457d..1f7607f9b7f 100644 --- a/usr.sbin/rpc.umntall/rpc.umntall.8 +++ b/usr.sbin/rpc.umntall/rpc.umntall.8 @@ -114,8 +114,8 @@ entry. mounted nfs-file systems .El .Sh SEE ALSO -.Xr mountd 8 , .Xr mount_nfs 8 , +.Xr mountd 8 , .Xr umount 8 .Sh HISTORY The diff --git a/usr.sbin/rtadvctl/rtadvctl.8 b/usr.sbin/rtadvctl/rtadvctl.8 index 5df6e5cc234..4b7c888b4b1 100644 --- a/usr.sbin/rtadvctl/rtadvctl.8 +++ b/usr.sbin/rtadvctl/rtadvctl.8 @@ -92,8 +92,8 @@ Displays information on Router Advertisement messages being sent on each interface. .El .Sh SEE ALSO -.Xr rtadvd 8 , -.Xr rtadvd.conf 5 +.Xr rtadvd.conf 5 , +.Xr rtadvd 8 .Sh HISTORY The .Nm diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5 index e8b3011a1fd..d4a0c025891 100644 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ b/usr.sbin/rtadvd/rtadvd.conf.5 @@ -488,8 +488,8 @@ ef0:\\ :addr="2001:db8:ffff:1000::":prefixlen#64:tc=default: .Ed .Sh SEE ALSO -.Xr termcap 5 , .Xr resolver 5 , +.Xr termcap 5 , .Xr rtadvd 8 , .Xr rtsol 8 .Rs From 923544aa8d3517a20da9d99befa0a5e929790df2 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 22:30:18 +0000 Subject: [PATCH 193/207] Sort SEE ALSO --- share/man/man4/ata.4 | 4 ++-- share/man/man4/audit.4 | 2 +- share/man/man4/bhyve.4 | 4 ++-- share/man/man4/carp.4 | 2 +- share/man/man4/ch.4 | 2 +- share/man/man4/ehci.4 | 4 ++-- share/man/man4/geom.4 | 2 +- share/man/man4/hv_ata_pci_disengage.4 | 6 +++--- share/man/man4/hv_kvp.4 | 6 +++--- share/man/man4/hv_netvsc.4 | 6 +++--- share/man/man4/hv_storvsc.4 | 6 +++--- share/man/man4/hv_utils.4 | 4 ++-- share/man/man4/hv_vmbus.4 | 4 ++-- share/man/man4/igmp.4 | 6 +++--- share/man/man4/ip6.4 | 2 +- share/man/man4/ips.4 | 2 +- share/man/man4/lagg.4 | 4 ++-- share/man/man4/man4.powerpc/smu.4 | 4 ++-- share/man/man4/mmc.4 | 2 +- share/man/man4/mmcsd.4 | 2 +- share/man/man4/mpt.4 | 4 ++-- share/man/man4/pflog.4 | 4 ++-- share/man/man4/pfsync.4 | 4 ++-- share/man/man4/ral.4 | 2 +- share/man/man4/rsu.4 | 2 +- share/man/man4/rum.4 | 2 +- share/man/man4/run.4 | 4 ++-- share/man/man4/uhci.4 | 4 ++-- share/man/man4/umass.4 | 2 +- 29 files changed, 51 insertions(+), 51 deletions(-) diff --git a/share/man/man4/ata.4 b/share/man/man4/ata.4 index 4b53bf795e6..cf0b5de22c7 100644 --- a/share/man/man4/ata.4 +++ b/share/man/man4/ata.4 @@ -253,10 +253,10 @@ work well on long cables, especially at high speeds. .Xr ada 4 , .Xr ahci 4 , .Xr cam 4 , -.Xr camcontrol 8 , .Xr cd 4 , .Xr mvs 4 , -.Xr siis 4 +.Xr siis 4 , +.Xr camcontrol 8 .Sh HISTORY The .Nm diff --git a/share/man/man4/audit.4 b/share/man/man4/audit.4 index 9f3f17f0ff6..512f5c3798a 100644 --- a/share/man/man4/audit.4 +++ b/share/man/man4/audit.4 @@ -88,10 +88,10 @@ to track users and events in a fine-grained manner. .Xr setauid 2 , .Xr libbsm 3 , .Xr auditpipe 4 , +.Xr audit.log 5 , .Xr audit_class 5 , .Xr audit_control 5 , .Xr audit_event 5 , -.Xr audit.log 5 , .Xr audit_user 5 , .Xr audit_warn 5 , .Xr rc.conf 5 , diff --git a/share/man/man4/bhyve.4 b/share/man/man4/bhyve.4 index 4947ecfc903..f4ff2e1273b 100644 --- a/share/man/man4/bhyve.4 +++ b/share/man/man4/bhyve.4 @@ -45,10 +45,10 @@ unmodified guest operating systems on top of FreeBSD. relies heavily on hardware assist provided by the CPU and chipset to virtualize processor and memory resources. .Sh SEE ALSO +.Xr vmm 4 , .Xr bhyve 8 , -.Xr bhyveload 8 , .Xr bhyvectl 8 , -.Xr vmm 4 +.Xr bhyveload 8 .Sh HISTORY .Nm first appeared in diff --git a/share/man/man4/carp.4 b/share/man/man4/carp.4 index 56335980f8e..d1844b88cc4 100644 --- a/share/man/man4/carp.4 +++ b/share/man/man4/carp.4 @@ -303,8 +303,8 @@ tcpdump -npi vlan0 -T carp .Sh SEE ALSO .Xr inet 4 , .Xr pfsync 4 , -.Xr rc.conf 5 , .Xr devd.conf 5 , +.Xr rc.conf 5 , .Xr ifconfig 8 , .Xr sysctl 8 , .Xr tcpdump 8 diff --git a/share/man/man4/ch.4 b/share/man/man4/ch.4 index 121199b4c66..312a0f1f59f 100644 --- a/share/man/man4/ch.4 +++ b/share/man/man4/ch.4 @@ -325,8 +325,8 @@ If the media changer does not support features requested by the driver, it will produce both console error messages and failure return codes to the ioctls described here. .Sh SEE ALSO -.Xr cam 4 , .Xr chio 1 , +.Xr cam 4 , .Xr cd 4 , .Xr da 4 , .Xr sa 4 diff --git a/share/man/man4/ehci.4 b/share/man/man4/ehci.4 index 1d06bf9b0dc..5e15411d056 100644 --- a/share/man/man4/ehci.4 +++ b/share/man/man4/ehci.4 @@ -70,10 +70,10 @@ but can be noticed since 2.0 devices plugged in to the same connector appear to connect to different USB busses. .Sh SEE ALSO -.Xr xhci 4 , .Xr ohci 4 , .Xr uhci 4 , -.Xr usb 4 +.Xr usb 4 , +.Xr xhci 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4 index c881f476ed0..8f42f1b1b00 100644 --- a/share/man/man4/geom.4 +++ b/share/man/man4/geom.4 @@ -450,8 +450,8 @@ Dump contents of gctl requests. .El .Sh SEE ALSO .Xr libgeom 3 , -.Xr disk 9 , .Xr DECLARE_GEOM_CLASS 9 , +.Xr disk 9 , .Xr g_access 9 , .Xr g_attach 9 , .Xr g_bio 9 , diff --git a/share/man/man4/hv_ata_pci_disengage.4 b/share/man/man4/hv_ata_pci_disengage.4 index 2123e8b7655..e7a33523333 100644 --- a/share/man/man4/hv_ata_pci_disengage.4 +++ b/share/man/man4/hv_ata_pci_disengage.4 @@ -70,10 +70,10 @@ If CDROM access is a must then users may use "set hw.ata.disk_enable=1" at boot time to prevent the ATA driver from being disabled. .Sh SEE ALSO -.Xr hv_vmbus 4 , -.Xr hv_utils 4 , .Xr hv_netvsc 4 , -.Xr hv_storvsc 4 +.Xr hv_storvsc 4 , +.Xr hv_utils 4 , +.Xr hv_vmbus 4 .Sh HISTORY Support for .Nm diff --git a/share/man/man4/hv_kvp.4 b/share/man/man4/hv_kvp.4 index 269eef728d7..9aaf985dcc2 100644 --- a/share/man/man4/hv_kvp.4 +++ b/share/man/man4/hv_kvp.4 @@ -74,11 +74,11 @@ guest's IP address to its original static value. On the other hand, the get IP functionality is used to update the guest IP address in the Hyper-V management console window. .Sh SEE ALSO -.Xr hv_vmbus 4 , -.Xr hv_utils 4 , +.Xr hv_ata_pci_disengage 4 , .Xr hv_netvsc 4 , .Xr hv_storvsc 4 , -.Xr hv_ata_pci_disengage 4 , +.Xr hv_utils 4 , +.Xr hv_vmbus 4 , .Xr hv_kvp_daemon 8 .Sh HISTORY Support for diff --git a/share/man/man4/hv_netvsc.4 b/share/man/man4/hv_netvsc.4 index 31325bb9e73..a619332d293 100644 --- a/share/man/man4/hv_netvsc.4 +++ b/share/man/man4/hv_netvsc.4 @@ -63,10 +63,10 @@ driver. The VSP in the root partition then forwards the network related requests to the physical network card. .Sh SEE ALSO -.Xr hv_vmbus 4 , -.Xr hv_utils 4 , +.Xr hv_ata_pci_disengage 4 , .Xr hv_storvsc 4 , -.Xr hv_ata_pci_disengage 4 +.Xr hv_utils 4 , +.Xr hv_vmbus 4 .Sh HISTORY Support for .Nm diff --git a/share/man/man4/hv_storvsc.4 b/share/man/man4/hv_storvsc.4 index 54805f101aa..0941703180c 100644 --- a/share/man/man4/hv_storvsc.4 +++ b/share/man/man4/hv_storvsc.4 @@ -69,10 +69,10 @@ CAM control blocks (CCBs) are converted into VSCSI protocol messages which are delivered to the root partition VSP over the Hyper-V VMBus. .Sh SEE ALSO -.Xr hv_vmbus 4 , -.Xr hv_utils 4 , +.Xr hv_ata_pci_disengage 4 , .Xr hv_netvsc 4 , -.Xr hv_ata_pci_disengage 4 +.Xr hv_utils 4 , +.Xr hv_vmbus 4 .Sh HISTORY Support for .Nm diff --git a/share/man/man4/hv_utils.4 b/share/man/man4/hv_utils.4 index 82439eaa674..e0053788b11 100644 --- a/share/man/man4/hv_utils.4 +++ b/share/man/man4/hv_utils.4 @@ -65,10 +65,10 @@ command. (c) Heartbeat: This feature allows the virtualization server to detect whether the guest partition is running and responsive. .Sh SEE ALSO -.Xr hv_vmbus 4 , +.Xr hv_ata_pci_disengage 4 , .Xr hv_netvsc 4 , .Xr hv_storvsc 4 , -.Xr hv_ata_pci_disengage 4 +.Xr hv_vmbus 4 .Sh HISTORY Support for .Nm diff --git a/share/man/man4/hv_vmbus.4 b/share/man/man4/hv_vmbus.4 index daafd5d505f..d992be521b4 100644 --- a/share/man/man4/hv_vmbus.4 +++ b/share/man/man4/hv_vmbus.4 @@ -73,10 +73,10 @@ the interface that facilitate high performance bi-directional communication between the VSCs and VSPs. All VSCs utilize the VMBus driver. .Sh SEE ALSO -.Xr hv_utils 4 , +.Xr hv_ata_pci_disengage 4 , .Xr hv_netvsc 4 , .Xr hv_storvsc 4 , -.Xr hv_ata_pci_disengage 4 +.Xr hv_utils 4 .Sh HISTORY Support for .Nm diff --git a/share/man/man4/igmp.4 b/share/man/man4/igmp.4 index 696fa7da667..2e820483a06 100644 --- a/share/man/man4/igmp.4 +++ b/share/man/man4/igmp.4 @@ -126,11 +126,11 @@ This sysctl is normally enabled by default. .\" .El .Sh SEE ALSO -.Xr ifmcstat 8 , +.Xr netstat 1 , +.Xr sourcefilter 3 , .Xr inet 4 , .Xr multicast 4 , -.Xr netstat 1 , -.Xr sourcefilter 3 +.Xr ifmcstat 8 .Sh HISTORY The .Nm diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index dba5e8de539..d28e37e3dcd 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -653,8 +653,8 @@ An ancillary data object was improperly formed. .Xr if_nametoindex 3 , .Xr bpf 4 , .Xr icmp6 4 , -.Xr ip 4 , .Xr inet6 4 , +.Xr ip 4 , .Xr netintro 4 , .Xr tcp 4 , .Xr udp 4 diff --git a/share/man/man4/ips.4 b/share/man/man4/ips.4 index b22b91ca5f4..a4b8c2cd725 100644 --- a/share/man/man4/ips.4 +++ b/share/man/man4/ips.4 @@ -187,9 +187,9 @@ driver does not use the subsystem. .Sh SEE ALSO .Xr aac 4 , -.Xr mfi 4 , .Xr ch 4 , .Xr da 4 , +.Xr mfi 4 , .Xr sysctl 8 .Sh AUTHORS The diff --git a/share/man/man4/lagg.4 b/share/man/man4/lagg.4 index 1b403159315..0b66c3df5e5 100644 --- a/share/man/man4/lagg.4 +++ b/share/man/man4/lagg.4 @@ -176,8 +176,8 @@ device will be used: device as a workaround.) .Sh SEE ALSO .Xr ng_one2many 4 , -.Xr sysctl 8 , -.Xr ifconfig 8 +.Xr ifconfig 8 , +.Xr sysctl 8 .Sh HISTORY The .Nm diff --git a/share/man/man4/man4.powerpc/smu.4 b/share/man/man4/man4.powerpc/smu.4 index 2e10160ee07..f5930d63c74 100644 --- a/share/man/man4/man4.powerpc/smu.4 +++ b/share/man/man4/man4.powerpc/smu.4 @@ -109,8 +109,8 @@ annunciator interface at .Pa /dev/led/sleepled . .Sh SEE ALSO .Xr acpi 4 , -.Xr pmu 4 , -.Xr led 4 +.Xr led 4 , +.Xr pmu 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/mmc.4 b/share/man/man4/mmc.4 index 95fe976833e..184ac90cddf 100644 --- a/share/man/man4/mmc.4 +++ b/share/man/man4/mmc.4 @@ -47,8 +47,8 @@ bus typically has only one slot, and only memory cards. MultiMediaCards exist only in memory. SD Cards exist as memory, I/O, or combination cards. .Sh SEE ALSO -.Xr mmcsd 4 , .Xr at91_mci 4 , +.Xr mmcsd 4 , .Xr sdhci 4 .Rs .%T "SD Specifications, Part 1, Physical Layer, Simplified Specification" diff --git a/share/man/man4/mmcsd.4 b/share/man/man4/mmcsd.4 index 646e032e63a..e25efa3fb8a 100644 --- a/share/man/man4/mmcsd.4 +++ b/share/man/man4/mmcsd.4 @@ -37,8 +37,8 @@ The .Nm driver implements direct access block device for MMC and SD memory cards. .Sh SEE ALSO -.Xr mmc 4 , .Xr at91_mci 4 , +.Xr mmc 4 , .Xr sdhci 4 .Rs .%T "SD Specifications, Part 1, Physical Layer, Simplified Specification" diff --git a/share/man/man4/mpt.4 b/share/man/man4/mpt.4 index d514cc93718..2e153250835 100644 --- a/share/man/man4/mpt.4 +++ b/share/man/man4/mpt.4 @@ -157,8 +157,8 @@ can take on - no separate compilation is required. .Xr sa 4 , .Xr scsi 4 , .Xr targ 4 , -.Xr mptutil 8 , -.Xr gmultipath 8 +.Xr gmultipath 8 , +.Xr mptutil 8 .Rs .%T "LSI Logic Website" .%U http://www.lsi.com/ diff --git a/share/man/man4/pflog.4 b/share/man/man4/pflog.4 index 803f1fdee5a..428bb5bd7f2 100644 --- a/share/man/man4/pflog.4 +++ b/share/man/man4/pflog.4 @@ -91,13 +91,13 @@ and monitor all packets logged on it: # tcpdump -n -e -ttt -i pflog1 .Ed .Sh SEE ALSO +.Xr tcpdump 1 , .Xr inet 4 , .Xr inet6 4 , .Xr netintro 4 , .Xr pf 4 , .Xr ifconfig 8 , -.Xr pflogd 8 , -.Xr tcpdump 1 +.Xr pflogd 8 .Sh HISTORY The .Nm diff --git a/share/man/man4/pfsync.4 b/share/man/man4/pfsync.4 index 0529b71e24c..c4c366f5efb 100644 --- a/share/man/man4/pfsync.4 +++ b/share/man/man4/pfsync.4 @@ -200,6 +200,7 @@ The following must also be added to net.inet.carp.preempt=1 .Ed .Sh SEE ALSO +.Xr tcpdump 1 , .Xr bpf 4 , .Xr carp 4 , .Xr enc 4 , @@ -211,8 +212,7 @@ net.inet.carp.preempt=1 .Xr pf.conf 5 , .Xr protocols 5 , .Xr rc.conf 5 , -.Xr ifconfig 8 , -.Xr tcpdump 1 +.Xr ifconfig 8 .Sh HISTORY The .Nm diff --git a/share/man/man4/ral.4 b/share/man/man4/ral.4 index c99902aca12..d9024b040f4 100644 --- a/share/man/man4/ral.4 +++ b/share/man/man4/ral.4 @@ -240,8 +240,8 @@ The driver will reset the hardware. This should not happen. .El .Sh SEE ALSO -.Xr intro 4 , .Xr cardbus 4 , +.Xr intro 4 , .Xr wlan 4 , .Xr wlan_ccmp 4 , .Xr wlan_tkip 4 , diff --git a/share/man/man4/rsu.4 b/share/man/man4/rsu.4 index 9d2854c9567..f9a8c9e790f 100644 --- a/share/man/man4/rsu.4 +++ b/share/man/man4/rsu.4 @@ -153,9 +153,9 @@ This should not happen. .El .Sh SEE ALSO .Xr intro 1 , -.Xr usb 4 , .Xr netintro 4 , .Xr rsufw 4 , +.Xr usb 4 , .Xr wlan 4 , .Xr arp 8 , .Xr hostapd 8 , diff --git a/share/man/man4/rum.4 b/share/man/man4/rum.4 index 3abcbcad876..89af445feea 100644 --- a/share/man/man4/rum.4 +++ b/share/man/man4/rum.4 @@ -162,8 +162,8 @@ This should not happen. .Xr wlan_tkip 4 , .Xr wlan_wep 4 , .Xr wlan_xauth 4 , -.Xr ifconfig 8 , .Xr hostapd 8 , +.Xr ifconfig 8 , .Xr wpa_supplicant 8 . .Rs .%T "Ralink Technology" diff --git a/share/man/man4/run.4 b/share/man/man4/run.4 index 52ce5442bc7..8a2b6bcda52 100644 --- a/share/man/man4/run.4 +++ b/share/man/man4/run.4 @@ -219,9 +219,9 @@ The driver will reset the hardware. This should not happen. .El .Sh SEE ALSO -.Xr runfw 4 , .Xr intro 4 , .Xr netintro 4 , +.Xr runfw 4 , .Xr usb 4 , .Xr wlan 4 , .Xr wlan_amrr 4 , @@ -229,8 +229,8 @@ This should not happen. .Xr wlan_tkip 4 , .Xr wlan_wep 4 , .Xr wlan_xauth 4 , -.Xr ifconfig 8 , .Xr hostapd 8 , +.Xr ifconfig 8 , .Xr wpa_supplicant 8 .Pp Ralink Technology: diff --git a/share/man/man4/uhci.4 b/share/man/man4/uhci.4 index 9fcd4d48428..90458cea9b3 100644 --- a/share/man/man4/uhci.4 +++ b/share/man/man4/uhci.4 @@ -50,9 +50,9 @@ Intel 82371SB (PIIX3) VIA 83C572 .El .Sh SEE ALSO -.Xr xhci 4 , .Xr ehci 4 , -.Xr ohci 4 +.Xr ohci 4 , +.Xr xhci 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/umass.4 b/share/man/man4/umass.4 index 4b0d0e417c8..badb97b0c60 100644 --- a/share/man/man4/umass.4 +++ b/share/man/man4/umass.4 @@ -240,11 +240,11 @@ when using .Xr mount 8 . .Sh SEE ALSO .Xr ehci 4 , -.Xr xhci 4 , .Xr ohci 4 , .Xr uhci 4 , .Xr usb 4 , .Xr vpo 4 , +.Xr xhci 4 , .Xr disktab 5 , .Xr bsdlabel 8 , .Xr camcontrol 8 From 6fbbb9be44660a84ba164c3988d47c595d7ba98d Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 22:34:15 +0000 Subject: [PATCH 194/207] Escape Do to prevent mdoc(7) parser to get confused with the "Do" macro Reported by: sjg --- contrib/libxo/libxo/xo_open_container.3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/libxo/libxo/xo_open_container.3 b/contrib/libxo/libxo/xo_open_container.3 index a872be207da..9ba32c98f6f 100644 --- a/contrib/libxo/libxo/xo_open_container.3 +++ b/contrib/libxo/libxo/xo_open_container.3 @@ -131,7 +131,7 @@ traditional C strings can be used directly. The close functions with the .Dq _d suffix are used in -.Dq The Right Thing +.Dq \&Do The Right Thing mode, where the name of the open containers, lists, and instances are maintained internally by .Em libxo @@ -161,7 +161,7 @@ Some user may find tracking the names of open containers, lists, and instances inconvenient. .Em libxo offers -.Dq The Right Thing +.Dq \&Do The Right Thing mode, where .Em libxo will track the names of open containers, lists, and instances so From e52a1af206d0541ccab94268f8a8c41f044cea60 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 22:41:10 +0000 Subject: [PATCH 195/207] sort SEE ALSO --- share/man/man3/makedev.3 | 4 ++-- share/man/man3/pthread.3 | 22 +++++++++---------- share/man/man3/pthread_attr.3 | 2 +- share/man/man3/pthread_cond_init.3 | 4 ++-- share/man/man3/pthread_mutex_init.3 | 4 ++-- share/man/man3/pthread_mutexattr_getkind_np.3 | 6 ++--- share/man/man3/pthread_rwlock_init.3 | 4 ++-- .../man/man3/pthread_rwlockattr_getpshared.3 | 4 ++-- share/man/man3/pthread_rwlockattr_init.3 | 4 ++-- .../man/man3/pthread_rwlockattr_setpshared.3 | 4 ++-- 10 files changed, 29 insertions(+), 29 deletions(-) diff --git a/share/man/man3/makedev.3 b/share/man/man3/makedev.3 index b32d69ef624..87ca953dc79 100644 --- a/share/man/man3/makedev.3 +++ b/share/man/man3/makedev.3 @@ -85,6 +85,6 @@ macro returns a device minor number whose value can span the complete range of an .Vt int . .Sh SEE ALSO -.Xr devfs 5 , +.Xr mknod 2 , .Xr devname 3 , -.Xr mknod 2 +.Xr devfs 5 diff --git a/share/man/man3/pthread.3 b/share/man/man3/pthread.3 index 78a9153f29a..9a0c5c80736 100644 --- a/share/man/man3/pthread.3 +++ b/share/man/man3/pthread.3 @@ -484,14 +484,14 @@ Threaded applications are linked with this library. .Xr pthread_cancel 3 , .Xr pthread_cleanup_pop 3 , .Xr pthread_cleanup_push 3 , -.Xr pthread_condattr_destroy 3 , -.Xr pthread_condattr_init 3 , .Xr pthread_cond_broadcast 3 , .Xr pthread_cond_destroy 3 , .Xr pthread_cond_init 3 , .Xr pthread_cond_signal 3 , .Xr pthread_cond_timedwait 3 , .Xr pthread_cond_wait 3 , +.Xr pthread_condattr_destroy 3 , +.Xr pthread_condattr_init 3 , .Xr pthread_create 3 , .Xr pthread_detach 3 , .Xr pthread_equal 3 , @@ -500,6 +500,11 @@ Threaded applications are linked with this library. .Xr pthread_join 3 , .Xr pthread_key_delete 3 , .Xr pthread_kill 3 , +.Xr pthread_mutex_destroy 3 , +.Xr pthread_mutex_init 3 , +.Xr pthread_mutex_lock 3 , +.Xr pthread_mutex_trylock 3 , +.Xr pthread_mutex_unlock 3 , .Xr pthread_mutexattr_destroy 3 , .Xr pthread_mutexattr_getprioceiling 3 , .Xr pthread_mutexattr_getprotocol 3 , @@ -508,21 +513,16 @@ Threaded applications are linked with this library. .Xr pthread_mutexattr_setprioceiling 3 , .Xr pthread_mutexattr_setprotocol 3 , .Xr pthread_mutexattr_settype 3 , -.Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_init 3 , -.Xr pthread_mutex_lock 3 , -.Xr pthread_mutex_trylock 3 , -.Xr pthread_mutex_unlock 3 , .Xr pthread_once 3 , -.Xr pthread_rwlockattr_destroy 3 , -.Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , .Xr pthread_rwlock_destroy 3 , .Xr pthread_rwlock_init 3 , .Xr pthread_rwlock_rdlock 3 , .Xr pthread_rwlock_unlock 3 , .Xr pthread_rwlock_wrlock 3 , +.Xr pthread_rwlockattr_destroy 3 , +.Xr pthread_rwlockattr_getpshared 3 , +.Xr pthread_rwlockattr_init 3 , +.Xr pthread_rwlockattr_setpshared 3 , .Xr pthread_self 3 , .Xr pthread_setcancelstate 3 , .Xr pthread_setcanceltype 3 , diff --git a/share/man/man3/pthread_attr.3 b/share/man/man3/pthread_attr.3 index a99d32d626c..d6d98012783 100644 --- a/share/man/man3/pthread_attr.3 +++ b/share/man/man3/pthread_attr.3 @@ -208,8 +208,8 @@ Invalid or unsupported value for .Fa contentionscope . .El .Sh SEE ALSO -.Xr pthread_attr_get_np 3 , .Xr pthread_attr_affinity_np 3 , +.Xr pthread_attr_get_np 3 , .Xr pthread_create 3 .Sh STANDARDS .Fn pthread_attr_init , diff --git a/share/man/man3/pthread_cond_init.3 b/share/man/man3/pthread_cond_init.3 index 38843a76fe7..415ce02efaa 100644 --- a/share/man/man3/pthread_cond_init.3 +++ b/share/man/man3/pthread_cond_init.3 @@ -70,12 +70,12 @@ The system temporarily lacks the resources to create another condition variable. .El .Sh SEE ALSO -.Xr pthread_condattr 3 , .Xr pthread_cond_broadcast 3 , .Xr pthread_cond_destroy 3 , .Xr pthread_cond_signal 3 , .Xr pthread_cond_timedwait 3 , -.Xr pthread_cond_wait 3 +.Xr pthread_cond_wait 3 , +.Xr pthread_condattr 3 .Sh STANDARDS The .Fn pthread_cond_init diff --git a/share/man/man3/pthread_mutex_init.3 b/share/man/man3/pthread_mutex_init.3 index 10a026b9dcb..a5a1eca0df1 100644 --- a/share/man/man3/pthread_mutex_init.3 +++ b/share/man/man3/pthread_mutex_init.3 @@ -66,11 +66,11 @@ is invalid. The process cannot allocate enough memory to create another mutex. .El .Sh SEE ALSO -.Xr pthread_mutexattr 3 , .Xr pthread_mutex_destroy 3 , .Xr pthread_mutex_lock 3 , .Xr pthread_mutex_trylock 3 , -.Xr pthread_mutex_unlock 3 +.Xr pthread_mutex_unlock 3 , +.Xr pthread_mutexattr 3 .Sh STANDARDS The .Fn pthread_mutex_init diff --git a/share/man/man3/pthread_mutexattr_getkind_np.3 b/share/man/man3/pthread_mutexattr_getkind_np.3 index 548045b5aac..fe5435f90c3 100644 --- a/share/man/man3/pthread_mutexattr_getkind_np.3 +++ b/share/man/man3/pthread_mutexattr_getkind_np.3 @@ -75,7 +75,7 @@ The value specified by is invalid. .El .Sh SEE ALSO -.Xr pthread_mutexattr_gettype 3 , -.Xr pthread_mutexattr_settype 3 , .Xr pthread_mutex_destroy 3 , -.Xr pthread_mutex_init 3 +.Xr pthread_mutex_init 3 , +.Xr pthread_mutexattr_gettype 3 , +.Xr pthread_mutexattr_settype 3 diff --git a/share/man/man3/pthread_rwlock_init.3 b/share/man/man3/pthread_rwlock_init.3 index cf8cc7e10ed..2617c436bc2 100644 --- a/share/man/man3/pthread_rwlock_init.3 +++ b/share/man/man3/pthread_rwlock_init.3 @@ -85,9 +85,9 @@ The value specified by is invalid. .El .Sh SEE ALSO +.Xr pthread_rwlock_destroy 3 , .Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_destroy 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlock_init diff --git a/share/man/man3/pthread_rwlockattr_getpshared.3 b/share/man/man3/pthread_rwlockattr_getpshared.3 index 3fe5de1ae0a..3e2f451dc72 100644 --- a/share/man/man3/pthread_rwlockattr_getpshared.3 +++ b/share/man/man3/pthread_rwlockattr_getpshared.3 @@ -71,9 +71,9 @@ The value specified by is invalid. .El .Sh SEE ALSO +.Xr pthread_rwlock_init 3 , .Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_init 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlockattr_getpshared diff --git a/share/man/man3/pthread_rwlockattr_init.3 b/share/man/man3/pthread_rwlockattr_init.3 index 54d319ff84e..1cce9cd0255 100644 --- a/share/man/man3/pthread_rwlockattr_init.3 +++ b/share/man/man3/pthread_rwlockattr_init.3 @@ -55,10 +55,10 @@ function will fail if: Insufficient memory exists to initialize the attribute object. .El .Sh SEE ALSO +.Xr pthread_rwlock_init 3 , .Xr pthread_rwlockattr_destroy 3 , .Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_setpshared 3 , -.Xr pthread_rwlock_init 3 +.Xr pthread_rwlockattr_setpshared 3 .Sh STANDARDS The .Fn pthread_rwlockattr_init diff --git a/share/man/man3/pthread_rwlockattr_setpshared.3 b/share/man/man3/pthread_rwlockattr_setpshared.3 index 36bcc690f46..ccfe8862ffd 100644 --- a/share/man/man3/pthread_rwlockattr_setpshared.3 +++ b/share/man/man3/pthread_rwlockattr_setpshared.3 @@ -75,9 +75,9 @@ or is invalid. .El .Sh SEE ALSO +.Xr pthread_rwlock_init 3 , .Xr pthread_rwlockattr_getpshared 3 , -.Xr pthread_rwlockattr_init 3 , -.Xr pthread_rwlock_init 3 +.Xr pthread_rwlockattr_init 3 .Sh STANDARDS The .Fn pthread_rwlockattr_setpshared From 6ae0d91a61ef9a8bfbb52343f202787a57b31a58 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 22:43:54 +0000 Subject: [PATCH 196/207] sort SEE ALSO --- share/man/man7/c99.7 | 4 ++-- share/man/man7/environ.7 | 2 +- share/man/man7/tuning.7 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/share/man/man7/c99.7 b/share/man/man7/c99.7 index fcf14769d0e..b968a4e510e 100644 --- a/share/man/man7/c99.7 +++ b/share/man/man7/c99.7 @@ -142,9 +142,9 @@ Most of the UNIX-like operating systems use GNU C as a system compiler, but those addition in GNU C should not be considered as standard features. .Sh SEE ALSO -.Xr cc 1 , .Xr c89 1 , -.Xr c99 1 +.Xr c99 1 , +.Xr cc 1 .Sh STANDARDS .Rs .%A ANSI diff --git a/share/man/man7/environ.7 b/share/man/man7/environ.7 index 826948838b2..2870d8e7880 100644 --- a/share/man/man7/environ.7 +++ b/share/man/man7/environ.7 @@ -250,8 +250,8 @@ built-in command in .Xr sh 1 , .Xr execve 2 , .Xr execle 3 , -.Xr getenv 3 , .Xr getbsize 3 , +.Xr getenv 3 , .Xr setenv 3 , .Xr setlocale 3 , .Xr system 3 , diff --git a/share/man/man7/tuning.7 b/share/man/man7/tuning.7 index baf0bcc650f..12b03c2b248 100644 --- a/share/man/man7/tuning.7 +++ b/share/man/man7/tuning.7 @@ -747,8 +747,8 @@ over services you export from your box (web services, email). .Xr login.conf 5 , .Xr rc.conf 5 , .Xr sysctl.conf 5 , -.Xr firewall 7 , .Xr eventtimers 7 , +.Xr firewall 7 , .Xr hier 7 , .Xr ports 7 , .Xr boot 8 , From 121f7af118547467096ff7d25f1ca9402eec7ac5 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Fri, 26 Dec 2014 22:44:27 +0000 Subject: [PATCH 197/207] Sort SEE ALSO --- share/man/man8/rc.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8 index ff0aa844b10..5d296cd1096 100644 --- a/share/man/man8/rc.8 +++ b/share/man/man8/rc.8 @@ -550,8 +550,8 @@ is unnecessary, but is often included. .Xr kill 1 , .Xr rc.conf 5 , .Xr init 8 , -.Xr rcorder 8 , .Xr rc.subr 8 , +.Xr rcorder 8 , .Xr reboot 8 , .Xr savecore 8 .Sh HISTORY From 628a446c6679ec47f2ed428132911ba96dc02ade Mon Sep 17 00:00:00 2001 From: Alfred Perlstein Date: Sat, 27 Dec 2014 01:06:19 +0000 Subject: [PATCH 198/207] Output strerror from xo_warn Reported by: bapt Reviewed by: bapt, ngie Differential Revision: https://reviews.freebsd.org/D1378 --- contrib/libxo/libxo/libxo.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contrib/libxo/libxo/libxo.c b/contrib/libxo/libxo/libxo.c index 89adc03fe2f..2c973377337 100644 --- a/contrib/libxo/libxo/libxo.c +++ b/contrib/libxo/libxo/libxo.c @@ -956,9 +956,6 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn, } memcpy(newfmt + plen, fmt, len); - /* Add a newline to the fmt string */ - if (!(xop->xo_flags & XOF_WARN_XML)) - newfmt[len++ + plen] = '\n'; newfmt[len + plen] = '\0'; if (xop->xo_flags & XOF_WARN_XML) { @@ -1010,6 +1007,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn, } else { vfprintf(stderr, newfmt, vap); + fprintf(stderr, ": %s\n", strerror(code)); } } From a09a539f068d7cdcb9554e390dbb039b25c29217 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sat, 27 Dec 2014 04:21:24 +0000 Subject: [PATCH 199/207] Support ALT_BREAK_TO_DEBUGGER in vt(4) Submitted by: Andre Albsmeier on -hackers --- sys/dev/vt/vt.h | 1 + sys/dev/vt/vt_core.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h index 262ffaf531e..67fcf1e0649 100644 --- a/sys/dev/vt/vt.h +++ b/sys/dev/vt/vt.h @@ -155,6 +155,7 @@ struct vt_device { int vd_keyboard; /* (G) Keyboard index. */ unsigned int vd_kbstate; /* (?) Device unit. */ unsigned int vd_unit; /* (c) Device unit. */ + int vd_altbrk; /* (?) Alt break seq. state */ }; #define VD_PASTEBUF(vd) ((vd)->vd_pastebuf.vpb_buf) diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c index 6d31faed779..51c4623eee6 100644 --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -825,7 +825,9 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c) terminal_input_char(vw->vw_terminal, 0x1b); } #endif - +#if defined(KDB) + kdb_alt_break(c, &vd->vd_altbrk); +#endif terminal_input_char(vw->vw_terminal, KEYCHAR(c)); } else terminal_input_raw(vw->vw_terminal, c); From 068b48d674ae8e2c007102173b93de9a9cb95ba9 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Sat, 27 Dec 2014 07:07:37 +0000 Subject: [PATCH 200/207] mdoc: improvements to SEE ALSO. --- share/man/man4/man4.i386/glxsb.4 | 2 +- share/man/man4/man4.powerpc/snd_ai2s.4 | 4 ++-- share/man/man4/man4.powerpc/snd_davbus.4 | 4 ++-- sys/boot/forth/brand.4th.8 | 2 +- sys/boot/forth/delay.4th.8 | 2 +- sys/boot/forth/menu.4th.8 | 4 ++-- sys/boot/forth/menusets.4th.8 | 4 ++-- sys/boot/forth/version.4th.8 | 4 ++-- sys/teken/libteken/teken.3 | 2 +- tools/tools/ether_reflect/ether_reflect.1 | 4 ++-- tools/tools/vimage/vimage.8 | 4 ++-- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/share/man/man4/man4.i386/glxsb.4 b/share/man/man4/man4.i386/glxsb.4 index a77b475e1dd..d2a30352fe7 100644 --- a/share/man/man4/man4.i386/glxsb.4 +++ b/share/man/man4/man4.i386/glxsb.4 @@ -70,8 +70,8 @@ device driver with AES keys of length != 128 bits. .Sh SEE ALSO .Xr crypto 4 , .Xr intro 4 , -.Xr pci 4 , .Xr ipsec 4 , +.Xr pci 4 , .Xr random 4 , .Xr crypto 9 .Sh HISTORY diff --git a/share/man/man4/man4.powerpc/snd_ai2s.4 b/share/man/man4/man4.powerpc/snd_ai2s.4 index 93566001a5c..2773b53c331 100644 --- a/share/man/man4/man4.powerpc/snd_ai2s.4 +++ b/share/man/man4/man4.powerpc/snd_ai2s.4 @@ -65,8 +65,8 @@ Apple Tumbler Audio Apple Snapper Audio .El .Sh SEE ALSO -.Xr sound 4 , -.Xr snd_davbus 4 +.Xr snd_davbus 4 , +.Xr sound 4 .Sh HISTORY The .Nm diff --git a/share/man/man4/man4.powerpc/snd_davbus.4 b/share/man/man4/man4.powerpc/snd_davbus.4 index 9949f9b8b50..ed3f3edea4f 100644 --- a/share/man/man4/man4.powerpc/snd_davbus.4 +++ b/share/man/man4/man4.powerpc/snd_davbus.4 @@ -63,8 +63,8 @@ Apple Burgundy Audio Apple Screamer Audio .El .Sh SEE ALSO -.Xr sound 4 , -.Xr snd_ai2s 4 +.Xr snd_ai2s 4 , +.Xr sound 4 .Sh HISTORY The .Nm diff --git a/sys/boot/forth/brand.4th.8 b/sys/boot/forth/brand.4th.8 index 64e68545fe1..dfd188d0ff8 100644 --- a/sys/boot/forth/brand.4th.8 +++ b/sys/boot/forth/brand.4th.8 @@ -111,7 +111,7 @@ loader_brand="fbsd" .Ed .Sh SEE ALSO .Xr loader.conf 5 , -.Xr loader 8 , +.Xr loader 8 .Sh HISTORY The .Nm diff --git a/sys/boot/forth/delay.4th.8 b/sys/boot/forth/delay.4th.8 index dd1680e2191..af31fd04bad 100644 --- a/sys/boot/forth/delay.4th.8 +++ b/sys/boot/forth/delay.4th.8 @@ -110,8 +110,8 @@ delay_execute .Ed .Sh SEE ALSO .Xr loader.conf 5 , -.Xr loader 8 , .Xr beastie.4th 8 , +.Xr loader 8 , .Xr loader.4th 8 .Sh HISTORY The diff --git a/sys/boot/forth/menu.4th.8 b/sys/boot/forth/menu.4th.8 index ab67d732117..3673eec74aa 100644 --- a/sys/boot/forth/menu.4th.8 +++ b/sys/boot/forth/menu.4th.8 @@ -336,9 +336,9 @@ menu-display .Ed .Sh SEE ALSO .Xr loader.conf 5 , +.Xr beastie.4th 8 , .Xr loader 8 , -.Xr loader.4th 8 , -.Xr beastie.4th 8 +.Xr loader.4th 8 .Sh HISTORY The .Nm diff --git a/sys/boot/forth/menusets.4th.8 b/sys/boot/forth/menusets.4th.8 index e05e4a7d023..f785ae18eab 100644 --- a/sys/boot/forth/menusets.4th.8 +++ b/sys/boot/forth/menusets.4th.8 @@ -355,10 +355,10 @@ set submenu_command[1]="1 goto_menu" .Ed .Sh SEE ALSO .Xr loader.conf 5 , +.Xr beastie.4th 8 , .Xr loader 8 , .Xr loader.4th 8 , -.Xr menu.4th 8 , -.Xr beastie.4th 8 +.Xr menu.4th 8 .Sh HISTORY The .Nm diff --git a/sys/boot/forth/version.4th.8 b/sys/boot/forth/version.4th.8 index fe8b61808c9..256df1ee5f8 100644 --- a/sys/boot/forth/version.4th.8 +++ b/sys/boot/forth/version.4th.8 @@ -113,8 +113,8 @@ loader_version="loader 1.1" .Ed .Sh SEE ALSO .Xr loader.conf 5 , -.Xr loader 8 , -.Xr color.4th 8 +.Xr color.4th 8 , +.Xr loader 8 .Sh HISTORY The .Nm diff --git a/sys/teken/libteken/teken.3 b/sys/teken/libteken/teken.3 index 1c2ebbe3b44..70bed07a57b 100644 --- a/sys/teken/libteken/teken.3 +++ b/sys/teken/libteken/teken.3 @@ -188,7 +188,7 @@ prior to 9.0. .Sh SEE ALSO .Xr ncurses 3 , .Xr termcap 3 , -.Xr syscons 4 . +.Xr syscons 4 .Sh HISTORY The .Nm diff --git a/tools/tools/ether_reflect/ether_reflect.1 b/tools/tools/ether_reflect/ether_reflect.1 index e6539b184f2..421136b5d2b 100644 --- a/tools/tools/ether_reflect/ether_reflect.1 +++ b/tools/tools/ether_reflect/ether_reflect.1 @@ -91,10 +91,10 @@ are seen on ineterface em0. The timeout is 1 millisecond. Rewrite the destination address in each packet to 00:00:00:aa:bb:cc before reflecting the packet. .Sh SEE ALSO -.Xr ifconfig 8 , .Xr tcpdump 1 , +.Xr bpf 2 , .Xr pcap 4 , -.Xr bpf 2 . +.Xr ifconfig 8 .Sh HISTORY The .Nm diff --git a/tools/tools/vimage/vimage.8 b/tools/tools/vimage/vimage.8 index 306bf83a90e..3ceb069b294 100644 --- a/tools/tools/vimage/vimage.8 +++ b/tools/tools/vimage/vimage.8 @@ -178,8 +178,8 @@ The .Nm command exits 0 on success, and >0 if an error occurs. .Sh SEE ALSO -.Xr jail 8 -.Xr jexec 8 +.Xr jail 8 , +.Xr jexec 8 , .Xr jls 8 .Sh HISTORY Network stack virtualization framework first appeared as a patchset From c09eb466019e8e22d04403a70ba3e07dc950ab61 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Sat, 27 Dec 2014 08:22:58 +0000 Subject: [PATCH 201/207] mdoc: improvements to SEE ALSO. --- lib/libdpv/dpv.3 | 4 ++-- lib/msun/man/cexp.3 | 2 +- lib/msun/man/complex.3 | 2 +- lib/msun/man/sin.3 | 2 +- sbin/dhclient/dhclient.conf.5 | 2 +- sbin/dhclient/dhclient.leases.5 | 2 +- sbin/ifconfig/ifconfig.8 | 2 +- sbin/iscontrol/iscontrol.8 | 4 ++-- sbin/mount/mount.8 | 2 +- sbin/mount_fusefs/mount_fusefs.8 | 4 ++-- sbin/newfs/newfs.8 | 4 ++-- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/libdpv/dpv.3 b/lib/libdpv/dpv.3 index 37e1f0759fd..d16e6499c4f 100644 --- a/lib/libdpv/dpv.3 +++ b/lib/libdpv/dpv.3 @@ -435,8 +435,8 @@ or desired values. .El .Sh SEE ALSO .Xr dialog 1 , -.Xr dialog 3 , -.Xr Xdialog 1 +.Xr Xdialog 1 , +.Xr dialog 3 .Sh HISTORY The .Nm diff --git a/lib/msun/man/cexp.3 b/lib/msun/man/cexp.3 index 97e36c176b5..776e6cee823 100644 --- a/lib/msun/man/cexp.3 +++ b/lib/msun/man/cexp.3 @@ -103,7 +103,7 @@ is not finite, the sign of the result is indeterminate. .Sh SEE ALSO .Xr complex 3 , .Xr exp 3 , -.Xr math 3 , +.Xr math 3 .Sh STANDARDS The .Fn cexp diff --git a/lib/msun/man/complex.3 b/lib/msun/man/complex.3 index 34eb03e5fc1..d2864944cf0 100644 --- a/lib/msun/man/complex.3 +++ b/lib/msun/man/complex.3 @@ -103,9 +103,9 @@ ctan tangent ctanh hyperbolic tangent .El .Sh SEE ALSO -.Xr math 3 , .Xr fenv 3 , .Xr ieee 3 , +.Xr math 3 , .Xr tgmath 3 .Rs .%T "ISO/IEC 9899:TC3" diff --git a/lib/msun/man/sin.3 b/lib/msun/man/sin.3 index c7daf094dd0..4a5352ed935 100644 --- a/lib/msun/man/sin.3 +++ b/lib/msun/man/sin.3 @@ -70,9 +70,9 @@ functions return the sine value. .Xr asin 3 , .Xr atan 3 , .Xr atan2 3 , -.Xr csin 3 , .Xr cos 3 , .Xr cosh 3 , +.Xr csin 3 , .Xr math 3 , .Xr sinh 3 , .Xr tan 3 , diff --git a/sbin/dhclient/dhclient.conf.5 b/sbin/dhclient/dhclient.conf.5 index 3b6ae044343..fb9d9f17048 100644 --- a/sbin/dhclient/dhclient.conf.5 +++ b/sbin/dhclient/dhclient.conf.5 @@ -524,8 +524,8 @@ In many cases, it is sufficient to just create an empty file - the defaults are usually fine. .Sh SEE ALSO .Xr dhclient.leases 5 , -.Xr dhcpd.conf 5 , .Xr dhcp-options 5 , +.Xr dhcpd.conf 5 , .Xr dhclient 8 , .Xr dhcpd 8 .Rs diff --git a/sbin/dhclient/dhclient.leases.5 b/sbin/dhclient/dhclient.leases.5 index f48b106287c..ebef81966ef 100644 --- a/sbin/dhclient/dhclient.leases.5 +++ b/sbin/dhclient/dhclient.leases.5 @@ -75,8 +75,8 @@ Current lease file. .El .Sh SEE ALSO .Xr dhclient.conf 5 , -.Xr dhcpd.conf 5 , .Xr dhcp-options 5 , +.Xr dhcpd.conf 5 , .Xr dhclient 8 , .Xr dhcpd 8 .Rs diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 90c8d7a8c1d..fdd398bdb2b 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -2819,9 +2819,9 @@ tried to alter an interface's configuration. .Xr devd.conf 5 , .\" .Xr eon 5 , .Xr devd 8 , +.Xr jail 8 , .Xr rc 8 , .Xr routed 8 , -.Xr jail 8 , .Xr sysctl 8 .Sh HISTORY The diff --git a/sbin/iscontrol/iscontrol.8 b/sbin/iscontrol/iscontrol.8 index eee877653a1..3fe17a08d2e 100644 --- a/sbin/iscontrol/iscontrol.8 +++ b/sbin/iscontrol/iscontrol.8 @@ -121,8 +121,8 @@ whatever options are specified, and start an iscsi-session. .Xr iscsi_initiator 4 , .Xr sa 4 , .Xr iscsi.conf 5 , -.Xr iscsictl 8 , -.Xr camcontrol 8 +.Xr camcontrol 8 , +.Xr iscsictl 8 .Sh STANDARDS RFC 3720 .\"Sh HISTORY diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8 index aa7acfd6103..55a45e76b7e 100644 --- a/sbin/mount/mount.8 +++ b/sbin/mount/mount.8 @@ -548,6 +548,7 @@ support for a particular file system might be provided either on a static .Xr ext2fs 5 , .Xr fstab 5 , .Xr procfs 5 , +.Xr tmpfs 5 , .Xr automount 8 , .Xr fstyp 8 , .Xr kldload 8 , @@ -558,7 +559,6 @@ support for a particular file system might be provided either on a static .Xr mount_smbfs 8 , .Xr mount_udf 8 , .Xr mount_unionfs 8 , -.Xr tmpfs 5 , .Xr umount 8 , .Xr zfs 8 , .Xr zpool 8 diff --git a/sbin/mount_fusefs/mount_fusefs.8 b/sbin/mount_fusefs/mount_fusefs.8 index 3e11cf19bd8..3faf61822e5 100644 --- a/sbin/mount_fusefs/mount_fusefs.8 +++ b/sbin/mount_fusefs/mount_fusefs.8 @@ -326,8 +326,8 @@ does not call any external utility and also provides a hacky .Sh SEE ALSO .Xr fstat 1 , .Xr mount 8 , -.Xr umount 8 , -.Xr sudo 8 +.Xr sudo 8 , +.Xr umount 8 .Sh HISTORY .Nm appears as the part of the FreeBSD implementation of the Fuse userspace filesystem diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8 index 6764adcf91c..a4c035814d6 100644 --- a/sbin/newfs/newfs.8 +++ b/sbin/newfs/newfs.8 @@ -310,10 +310,10 @@ on file systems that contain many small files. .Xr fsck 8 , .Xr gjournal 8 , .Xr growfs 8 , +.Xr gvinum 8 , .Xr makefs 8 , .Xr mount 8 , -.Xr tunefs 8 , -.Xr gvinum 8 +.Xr tunefs 8 .Rs .%A M. McKusick .%A W. Joy From 4990a1c0505bd4349462b165c6a1e4dedd349b16 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Sat, 27 Dec 2014 08:31:52 +0000 Subject: [PATCH 202/207] mdoc: improvements to SEE ALSO. --- cddl/usr.bin/ctfconvert/ctfconvert.1 | 4 ++-- lib/libc/iconv/iconvlist.3 | 4 ++-- lib/libc/locale/digittoint.3 | 2 +- lib/libc/locale/xlocale.3 | 2 +- lib/libc/rpc/rpc.3 | 2 +- lib/libc/rpc/rpc_svc_reg.3 | 2 +- lib/libpam/modules/pam_guest/pam_guest.8 | 2 +- lib/librtld_db/librtld_db.3 | 4 ++-- lib/libusb/libusb20.3 | 2 +- lib/libutil/quotafile.3 | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cddl/usr.bin/ctfconvert/ctfconvert.1 b/cddl/usr.bin/ctfconvert/ctfconvert.1 index 4de07ec17b4..c5def3ea5bd 100644 --- a/cddl/usr.bin/ctfconvert/ctfconvert.1 +++ b/cddl/usr.bin/ctfconvert/ctfconvert.1 @@ -74,8 +74,8 @@ Write the output to file in .Sh EXIT STATUS .Ex -std .Sh SEE ALSO -.Xr ctfmerge 1 , -.Xr ctfdump 1 +.Xr ctfdump 1 , +.Xr ctfmerge 1 .Sh HISTORY The .Nm diff --git a/lib/libc/iconv/iconvlist.3 b/lib/libc/iconv/iconvlist.3 index bef609b3136..b1a6e056434 100644 --- a/lib/libc/iconv/iconvlist.3 +++ b/lib/libc/iconv/iconvlist.3 @@ -78,9 +78,9 @@ If an error occurs, will be NULL when calling .Fn do_one . .Sh SEE ALSO -.Xr iconv 3 , +.Xr __iconv_free_list 3 , .Xr __iconv_get_list 3 , -.Xr __iconv_free_list 3 +.Xr iconv 3 .Sh STANDARDS The .Nm diff --git a/lib/libc/locale/digittoint.3 b/lib/libc/locale/digittoint.3 index 4a7f2e2107a..6670abe424a 100644 --- a/lib/libc/locale/digittoint.3 +++ b/lib/libc/locale/digittoint.3 @@ -64,5 +64,5 @@ the function will return 0. .Sh SEE ALSO .Xr ctype 3 , .Xr isdigit 3 , -.Xr isxdigit 3, +.Xr isxdigit 3 , .Xr xlocale 3 diff --git a/lib/libc/locale/xlocale.3 b/lib/libc/locale/xlocale.3 index d467a1004f2..da217c60110 100644 --- a/lib/libc/locale/xlocale.3 +++ b/lib/libc/locale/xlocale.3 @@ -71,7 +71,7 @@ function. .Xr localeconv 3 , .Xr newlocale 3 , .Xr querylocale 3 , -.Xr uselocale 3 , +.Xr uselocale 3 .Sh CONVENIENCE FUNCTIONS The xlocale API includes a number of .Fa _l diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3 index 4fa3e2cee58..988b5f1ec23 100644 --- a/lib/libc/rpc/rpc.3 +++ b/lib/libc/rpc/rpc.3 @@ -504,7 +504,6 @@ pages on which they are described: .Sh SEE ALSO .Xr getnetconfig 3 , .Xr getnetpath 3 , -.Xr rpcbind 3 , .Xr rpc_clnt_auth 3 , .Xr rpc_clnt_calls 3 , .Xr rpc_clnt_create 3 , @@ -513,5 +512,6 @@ pages on which they are described: .Xr rpc_svc_err 3 , .Xr rpc_svc_reg 3 , .Xr rpc_xdr 3 , +.Xr rpcbind 3 , .Xr xdr 3 , .Xr netconfig 5 diff --git a/lib/libc/rpc/rpc_svc_reg.3 b/lib/libc/rpc/rpc_svc_reg.3 index aed2ba127a1..81a749a107e 100644 --- a/lib/libc/rpc/rpc_svc_reg.3 +++ b/lib/libc/rpc/rpc_svc_reg.3 @@ -176,8 +176,8 @@ Service implementors usually do not need this routine. .Sh SEE ALSO .Xr select 2 , .Xr rpc 3 , -.Xr rpcbind 3 , .Xr rpc_svc_calls 3 , .Xr rpc_svc_create 3 , .Xr rpc_svc_err 3 , +.Xr rpcbind 3 , .Xr rpcbind 8 diff --git a/lib/libpam/modules/pam_guest/pam_guest.8 b/lib/libpam/modules/pam_guest/pam_guest.8 index 0bd175524f7..0b858d673d5 100644 --- a/lib/libpam/modules/pam_guest/pam_guest.8 +++ b/lib/libpam/modules/pam_guest/pam_guest.8 @@ -82,8 +82,8 @@ password. Requires the guest user to type in the guest account name as password. .El .Sh SEE ALSO -.Xr pam_getenv 3 , .Xr pam_get_item 3 , +.Xr pam_getenv 3 , .Xr pam.conf 5 , .Xr pam 8 .Sh AUTHORS diff --git a/lib/librtld_db/librtld_db.3 b/lib/librtld_db/librtld_db.3 index 211ce79d757..f310abf5414 100644 --- a/lib/librtld_db/librtld_db.3 +++ b/lib/librtld_db/librtld_db.3 @@ -167,8 +167,8 @@ You can get the error string using .Xr ld 1 , .Xr ld-elf.so.1 1 , .Xr ld.so 1 , -.Xr libproc 3 , -.Xr rtld 1 +.Xr rtld 1 , +.Xr libproc 3 .Sh HISTORY The .Nm librtld_db diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3 index f6004a534fd..590ff3c03c1 100644 --- a/lib/libusb/libusb20.3 +++ b/lib/libusb/libusb20.3 @@ -1053,8 +1053,8 @@ This function does not return NULL. .It Pa /dev/usb .El .Sh SEE ALSO -.Xr usb 4 , .Xr libusb 3 , +.Xr usb 4 , .Xr usbconfig 8 , .Xr usbdump 8 . diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index 001a66c0e18..362cf018554 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -273,8 +273,8 @@ and set to indicate the error. .Sh SEE ALSO .Xr quotactl 2 , -.Xr quota.user 5 , -.Xr quota.group 5 +.Xr quota.group 5 , +.Xr quota.user 5 .Sh HISTORY The .Nm quotafile From 559f9bfcb3f3e1c1d92ec4e43987a95536c8c01c Mon Sep 17 00:00:00 2001 From: Jens Schweikhardt Date: Sat, 27 Dec 2014 10:28:20 +0000 Subject: [PATCH 203/207] Correct a typo. --- share/man/man5/src.conf.5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 4232141b46f..1ebeb5c51a0 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1143,7 +1143,7 @@ support files (fonts and keymaps). Set this to not add warning flags to the compiler invocations. Useful as a temporary workaround when code enters the tree which triggers warnings in environments that differ from the -original develoepr. +original developer. .It Va WITHOUT_WIRELESS .\" from FreeBSD: head/tools/build/options/WITHOUT_WIRELESS 183242 2008-09-21 22:02:26Z sam Set to not build programs used for 802.11 wireless networks; especially From e9faba9d705f7955360b8be40fee3822efd03952 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sat, 27 Dec 2014 13:17:27 +0000 Subject: [PATCH 204/207] Make consistent use of the correct debug macros across the file. --- sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c index 7ea95a2fa12..686e80c7e0b 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c @@ -125,7 +125,7 @@ TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose); static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ; TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq); -#ifdef DEBUG +#ifdef PROP_DEBUG static void bcm2835_dump(const void *data, int len) { From 1432fa20f31c2eb9a1e64b882d9d3c52a258ad0f Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sat, 27 Dec 2014 13:52:33 +0000 Subject: [PATCH 205/207] On interrupt handler, save the actual data read from mbox. The previous macro wasn't needed and was being used with swapped arguments which always give the same result (0) defeating the overflow check. On initialization, do not use bcm_mbox_intr() to read the pending messages, with the new semaphore based implementation this will lead to semaphore being incremented on the channels that contain pending data and will make the first read for that channel return stale data. This fixes the hang that happens on boot while initializing the cpufreq on Raspberry Pi. --- sys/arm/broadcom/bcm2835/bcm2835_mbox.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c index 4c647fddaca..224a0d5a461 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c @@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$"); mtx_unlock(&(sc)->lock); \ } while(0) +#undef DEBUG #ifdef DEBUG #define dprintf(fmt, args...) printf(fmt, ##args) #else @@ -116,7 +117,7 @@ bcm_mbox_intr(void *arg) continue; } dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data); - sc->msg[chan] = MBOX_MSG(data, 0xf); + sc->msg[chan] = msg; sema_post(&sc->sema[chan]); } } @@ -174,7 +175,8 @@ bcm_mbox_attach(device_t dev) } /* Read all pending messages */ - bcm_mbox_intr(sc); + while ((mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY) == 0) + (void)mbox_read_4(sc, REG_READ); mbox_write_4(sc, REG_CONFIG, CONFIG_DATA_IRQ); From abba73f295f48d9506f5b13f0950e0ea0d7633b1 Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Sat, 27 Dec 2014 14:06:05 +0000 Subject: [PATCH 206/207] Remove the '#undef DEBUG' that should not be committed. --- sys/arm/broadcom/bcm2835/bcm2835_mbox.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c index 224a0d5a461..f87003f7d74 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c @@ -76,7 +76,6 @@ __FBSDID("$FreeBSD$"); mtx_unlock(&(sc)->lock); \ } while(0) -#undef DEBUG #ifdef DEBUG #define dprintf(fmt, args...) printf(fmt, ##args) #else From 40438c47610ea302b68b9715d861285385f4486f Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sat, 27 Dec 2014 14:26:18 +0000 Subject: [PATCH 207/207] - Make PCI_QUIRK_MSI_INTX_BUG work by using the ID of the actual PCI device for the lookup. - For devices affected by PCI_QUIRK_MSI_INTX_BUG, ensure PCIM_CMD_INTxDIS is cleared when using MSI/MSI-X. - Employ PCI_QUIRK_MSI_INTX_BUG for BCM5714(S)/BCM5715(S)/BCM5780(S) rather than clearing PCIM_CMD_INTxDIS unconditionally for all devices in bge(4). MFC after: 3 days --- sys/dev/bge/if_bge.c | 6 ++---- sys/dev/pci/pci.c | 29 +++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 838be4fdd80..58f529d9da0 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -1946,11 +1946,9 @@ bge_chipinit(struct bge_softc *sc) /* * Disable memory write invalidate. Apparently it is not supported - * properly by these devices. Also ensure that INTx isn't disabled, - * as these chips need it even when using MSI. + * properly by these devices. */ - PCI_CLRBIT(sc->bge_dev, BGE_PCI_CMD, - PCIM_CMD_INTxDIS | PCIM_CMD_MWIEN, 4); + PCI_CLRBIT(sc->bge_dev, BGE_PCI_CMD, PCIM_CMD_MWIEN, 4); /* Set the timer prescaler (always 66 MHz). */ CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ); diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index d2ac111372e..8f87851da6a 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -268,7 +268,7 @@ static const struct pci_quirk pci_quirks[] = { { 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 }, /* - * Atheros AR8161/AR8162/E2200 ethernet controller has a bug that + * Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that * MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the * command register is set. */ @@ -276,6 +276,17 @@ static const struct pci_quirk pci_quirks[] = { { 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, { 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, + /* + * Broadcom BCM5714(S)/BCM5715(S)/BCM5780(S) Ethernet MACs don't + * issue MSI interrupts with PCIM_CMD_INTxDIS set either. + */ + { 0x166814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714 */ + { 0x166914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714S */ + { 0x166a14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780 */ + { 0x166b14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780S */ + { 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715 */ + { 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715S */ + { 0 } }; @@ -3866,14 +3877,16 @@ pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, mte->mte_handlers++; } - if (!pci_has_quirk(pci_get_devid(dev), - PCI_QUIRK_MSI_INTX_BUG)) { - /* - * Make sure that INTx is disabled if we are - * using MSI/MSIX - */ + /* + * Make sure that INTx is disabled if we are using MSI/MSI-X, + * unless the device is affected by PCI_QUIRK_MSI_INTX_BUG, + * in which case we "enable" INTx so MSI/MSI-X actually works. + */ + if (!pci_has_quirk(pci_get_devid(child), + PCI_QUIRK_MSI_INTX_BUG)) pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS); - } + else + pci_clear_command_bit(dev, child, PCIM_CMD_INTxDIS); bad: if (error) { (void)bus_generic_teardown_intr(dev, child, irq,