Date: Sat, 10 Feb 2018 04:37:44 +0000 (UTC) From: Kyle Evans <kevans@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r329099 - in stable/11: lib/libstand sys/boot/common sys/boot/efi/include sys/boot/efi/libefi sys/boot/efi/loader sys/boot/forth sys/boot/geli sys/boot/i386/boot2 sys/boot/i386/btx/lib ... Message-ID: <201802100437.w1A4biOi009170@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kevans Date: Sat Feb 10 04:37:44 2018 New Revision: 329099 URL: https://svnweb.freebsd.org/changeset/base/329099 Log: MFC Loader Fixes 2017q1: r311458,r312237,r312314,r312374,r312947,r313042, r313047,r313166,r313328,r313332,r313333,r313337,r313348,r313349,r313389, r313442,r313451,r313575,r313645,r313710,r314114,r314213,r314275,r314945, r314948,r315008,r315408,r315427,r315645,r315646,r315648,r315653,r315850, r316064,r316078,r316079,r316100,r316104,r316111,r316112,r316171,r316279, r316280,r316287,r316311,r316343,r316424,r316436 r311458: Use compiler driver to link BERI boot loaders r312237: loader.efi: find_currdev() can leak memory r312314: loader: move device path definitions to include/efidevp.h r312374: loader: efi devpath api usage should be more aware of NULL pointers r312947: Remove "-Xassembler -G0" from CFLAGS. r313042: loader.efi environment related cleanups r313047: loader: disk/part api needs to use uint64_t offsets r313166: loader: libefi/env.c warnings in arm build r313328: loader: Implement disk_ioctl() to support DIOCGSECTORSIZE and DIOCGMEDIASIZE. r313332: loader: bcache read ahead block count should take account the large sectors r313333: loader: Replace EFI part devices. r313337: loader: 313329 missed ZFS guard in loader/main.c r313348: loader: biosdisk fix for 2+TB disks r313349: loader: disk io should not use alloca() r313389: efipart is also using the '%S' printf format, add -Wno-format for it. r313442: loader: possible NULL pointer dereference in efipart.c r313451: loader: possible NULL pointer dereference in bcache.c r313575: makefs: make the buffer functions look exactly like the kernel ones r313645: loader: implement MEDIA_FILEPATH_DP support in efipart r313710: loader: cstyle fixes and DIOCGMEDIASIZE should use uint64_t r314114: Use LDFLAGS with CC instead of _LDFLAGS. r314213: Remove control+r handling from geliboot's pwgets() r314275: Remove unused macro from common/drv.c. r314945: Some style(9) fixes. No functional changes. r314948: Try to extract the RFC1048 data from PXE. r315008: r314948 seems to be missing a variable or two that will break r315408: loader: remove open_disk cache r315427: loader: biosdisk should report IO error from INT13 r315645: loader: disk_cleanup was left in userboot_disk.c r315646: loader: pxe.h constants have wrong values r315648: libstand: verify value provided by nfs.read_size r315653: loader: verify the value from dhcp.interface-mtu and use snprintf o set mtu r315850: The original author abused Nd (one-line description, used by makewhatis) r316064: Fix build with path names with 'align' or 'nop' in them. r316078: gpt*boot: Save a bit more memory when LOADER_NO_GELI_SUPPORT is specified r316079: Simply retire the sedification of the boot2.s file. r316100: Remove -fno-guess-branch-probability and -fno-unit-at-a-time. r316104: Use `NO_WCAST_ALIGN` instead of spelling it out as -Wno-cast-align in CFLAGS r316111: loader: move bios getsecs into time.c r316112: loader: ls command should display file types properly r316171: xfsread inlined uses more space, so remove the inline tag. r316279: loader: efipart should check disk size from partition table r316280: loader: simplify efi_zfs_probe and avoid double probing for zfs. r316287: Remove OLD_NFSV2 from loader and libstand r316311: Add explicit_bzero() to libstand, and switch GELIBoot to using it r316343: Implement boot-time encryption key passing (keybuf) r316424: Fix sparc64 build broken by r316343 and r316076 r316436: Restore EFI boot environment functionality broken in r313333 PR: 216940 217298 217935 Added: stable/11/sys/boot/efi/libefi/wchar.c - copied unchanged from r313042, head/sys/boot/efi/libefi/wchar.c stable/11/sys/boot/geli/geliboot_internal.h - copied unchanged from r316343, head/sys/boot/geli/geliboot_internal.h stable/11/sys/crypto/intake.h - copied unchanged from r316343, head/sys/crypto/intake.h Modified: stable/11/lib/libstand/Makefile stable/11/lib/libstand/bootp.c stable/11/lib/libstand/bootp.h stable/11/lib/libstand/nfs.c stable/11/lib/libstand/nfsv2.h stable/11/lib/libstand/stand.h stable/11/sys/boot/common/bcache.c stable/11/sys/boot/common/bootstrap.h stable/11/sys/boot/common/dev_net.c stable/11/sys/boot/common/disk.c stable/11/sys/boot/common/disk.h stable/11/sys/boot/common/ls.c stable/11/sys/boot/common/part.c stable/11/sys/boot/common/part.h stable/11/sys/boot/efi/include/efidevp.h stable/11/sys/boot/efi/include/efilib.h stable/11/sys/boot/efi/libefi/Makefile stable/11/sys/boot/efi/libefi/devpath.c stable/11/sys/boot/efi/libefi/efinet.c stable/11/sys/boot/efi/libefi/efipart.c stable/11/sys/boot/efi/libefi/env.c stable/11/sys/boot/efi/loader/conf.c stable/11/sys/boot/efi/loader/devicename.c stable/11/sys/boot/efi/loader/main.c stable/11/sys/boot/forth/beastie.4th.8 stable/11/sys/boot/forth/loader.4th stable/11/sys/boot/geli/Makefile stable/11/sys/boot/geli/geliboot.c stable/11/sys/boot/geli/geliboot.h stable/11/sys/boot/geli/geliboot_crypto.c stable/11/sys/boot/geli/pwgets.c stable/11/sys/boot/i386/boot2/Makefile stable/11/sys/boot/i386/boot2/boot2.c stable/11/sys/boot/i386/btx/lib/btxv86.h stable/11/sys/boot/i386/common/bootargs.h stable/11/sys/boot/i386/common/drv.c stable/11/sys/boot/i386/gptboot/Makefile stable/11/sys/boot/i386/gptboot/gptboot.c stable/11/sys/boot/i386/gptzfsboot/Makefile stable/11/sys/boot/i386/libi386/bioscd.c stable/11/sys/boot/i386/libi386/biosdisk.c stable/11/sys/boot/i386/libi386/bootinfo32.c stable/11/sys/boot/i386/libi386/bootinfo64.c stable/11/sys/boot/i386/libi386/pxe.c stable/11/sys/boot/i386/libi386/pxe.h stable/11/sys/boot/i386/libi386/time.c stable/11/sys/boot/i386/loader/Makefile stable/11/sys/boot/i386/loader/main.c stable/11/sys/boot/i386/zfsboot/zfsboot.c stable/11/sys/boot/mips/beri/boot2/Makefile stable/11/sys/boot/mips/beri/common/common.ldscript stable/11/sys/boot/mips/beri/loader/beri_disk_cfi.c stable/11/sys/boot/mips/beri/loader/beri_disk_sdcard.c stable/11/sys/boot/mips/beri/loader/loader.ldscript stable/11/sys/boot/sparc64/loader/Makefile stable/11/sys/boot/uboot/lib/disk.c stable/11/sys/boot/usb/storage/umass_loader.c stable/11/sys/boot/userboot/userboot/userboot_disk.c stable/11/sys/boot/zfs/libzfs.h stable/11/sys/boot/zfs/zfs.c stable/11/sys/geom/eli/g_eli.c stable/11/sys/geom/eli/g_eli.h stable/11/sys/opencrypto/crypto.c stable/11/sys/sys/linker.h stable/11/usr.sbin/makefs/ffs.c stable/11/usr.sbin/makefs/ffs/buf.c stable/11/usr.sbin/makefs/ffs/buf.h stable/11/usr.sbin/makefs/ffs/ffs_alloc.c stable/11/usr.sbin/makefs/ffs/ffs_balloc.c Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libstand/Makefile ============================================================================== --- stable/11/lib/libstand/Makefile Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/lib/libstand/Makefile Sat Feb 10 04:37:44 2018 (r329099) @@ -155,5 +155,9 @@ SRCS+= pkgfs.c SRCS+= nandfs.c .endif +# explicit_bzero +.PATH: ${SRCTOP}/sys/libkern +SRCS+= explicit_bzero.c + .include <bsd.stand.mk> .include <bsd.lib.mk> Modified: stable/11/lib/libstand/bootp.c ============================================================================== --- stable/11/lib/libstand/bootp.c Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/lib/libstand/bootp.c Sat Feb 10 04:37:44 2018 (r329099) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> +#include <sys/limits.h> #include <sys/endian.h> #include <netinet/in.h> #include <netinet/in_systm.h> @@ -344,6 +345,17 @@ bad: return (-1); } +int +dhcp_try_rfc1048(u_char *cp, u_int len) +{ + + expected_dhcpmsgtype = DHCPACK; + if (bcmp(vm_rfc1048, cp, sizeof(vm_rfc1048)) == 0) { + return (vend_rfc1048(cp, len)); + } + return (-1); +} + static int vend_rfc1048(cp, len) u_char *cp; @@ -392,11 +404,29 @@ vend_rfc1048(cp, len) strlcpy(hostname, val, sizeof(hostname)); } if (tag == TAG_INTF_MTU) { + intf_mtu = 0; if ((val = getenv("dhcp.interface-mtu")) != NULL) { - intf_mtu = (u_int)strtoul(val, NULL, 0); - } else { - intf_mtu = be16dec(cp); + unsigned long tmp; + char *end; + + errno = 0; + /* + * Do not allow MTU to exceed max IPv4 packet + * size, max value of 16-bit word. + */ + tmp = strtoul(val, &end, 0); + if (errno != 0 || + *val == '\0' || *end != '\0' || + tmp > USHRT_MAX) { + printf("%s: bad value: \"%s\", " + "ignoring\n", + "dhcp.interface-mtu", val); + } else { + intf_mtu = (u_int)tmp; + } } + if (intf_mtu <= 0) + intf_mtu = be16dec(cp); } #ifdef SUPPORT_DHCP if (tag == TAG_DHCP_MSGTYPE) { Modified: stable/11/lib/libstand/bootp.h ============================================================================== --- stable/11/lib/libstand/bootp.h Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/lib/libstand/bootp.h Sat Feb 10 04:37:44 2018 (r329099) @@ -22,6 +22,8 @@ * $FreeBSD$ */ +#ifndef _BOOTP_H_ +#define _BOOTP_H_ struct bootp { unsigned char bp_op; /* packet opcode type */ @@ -145,3 +147,7 @@ struct cmu_vend { /* v_flags values */ #define VF_SMASK 1 /* Subnet mask field contains valid data */ + +int dhcp_try_rfc1048(u_char *cp, u_int len); + +#endif /* _BOOTP_H_ */ Modified: stable/11/lib/libstand/nfs.c ============================================================================== --- stable/11/lib/libstand/nfs.c Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/lib/libstand/nfs.c Sat Feb 10 04:37:44 2018 (r329099) @@ -54,73 +54,6 @@ __FBSDID("$FreeBSD$"); #define NFSREAD_MIN_SIZE 1024 #define NFSREAD_MAX_SIZE 4096 -/* Define our own NFS attributes without NQNFS stuff. */ -#ifdef OLD_NFSV2 -struct nfsv2_fattrs { - n_long fa_type; - n_long fa_mode; - n_long fa_nlink; - n_long fa_uid; - n_long fa_gid; - n_long fa_size; - n_long fa_blocksize; - n_long fa_rdev; - n_long fa_blocks; - n_long fa_fsid; - n_long fa_fileid; - struct nfsv2_time fa_atime; - struct nfsv2_time fa_mtime; - struct nfsv2_time fa_ctime; -}; - -struct nfs_read_args { - u_char fh[NFS_FHSIZE]; - n_long off; - n_long len; - n_long xxx; /* XXX what's this for? */ -}; - -/* Data part of nfs rpc reply (also the largest thing we receive) */ -struct nfs_read_repl { - n_long errno; - struct nfsv2_fattrs fa; - n_long count; - u_char data[NFSREAD_MAX_SIZE]; -}; - -#ifndef NFS_NOSYMLINK -struct nfs_readlnk_repl { - n_long errno; - n_long len; - char path[NFS_MAXPATHLEN]; -}; -#endif - -struct nfs_readdir_args { - u_char fh[NFS_FHSIZE]; - n_long cookie; - n_long count; -}; - -struct nfs_readdir_data { - n_long fileid; - n_long len; - char name[0]; -}; - -struct nfs_readdir_off { - n_long cookie; - n_long follows; -}; - -struct nfs_iodesc { - struct iodesc *iodesc; - off_t off; - u_char fh[NFS_FHSIZE]; - struct nfsv2_fattrs fa; /* all in network order */ -}; -#else /* !OLD_NFSV2 */ - /* NFSv3 definitions */ #define NFS_V3MAXFHSIZE 64 #define NFS_VER3 3 @@ -185,7 +118,6 @@ struct nfs_iodesc { struct nfsv3_fattrs fa; /* all in network order */ uint64_t cookie; }; -#endif /* OLD_NFSV2 */ /* * XXX interactions with tftp? See nfswrapper.c for a confusing @@ -214,622 +146,39 @@ struct fs_ops nfs_fsops = { static int nfs_read_size = NFSREAD_MIN_SIZE; -#ifdef OLD_NFSV2 /* - * Fetch the root file handle (call mount daemon) - * Return zero or error number. + * Improve boot performance over NFS */ -int -nfs_getrootfh(struct iodesc *d, char *path, u_char *fhp) +static void +set_nfs_read_size(void) { - int len; - struct args { - n_long len; - char path[FNAME_SIZE]; - } *args; - struct repl { - n_long errno; - u_char fh[NFS_FHSIZE]; - } *repl; - struct { - n_long h[RPC_HEADER_WORDS]; - struct args d; - } sdata; - struct { - n_long h[RPC_HEADER_WORDS]; - struct repl d; - } rdata; - size_t cc; + char *env, *end; + char buf[10]; -#ifdef NFS_DEBUG - if (debug) - printf("nfs_getrootfh: %s\n", path); -#endif - - args = &sdata.d; - repl = &rdata.d; - - bzero(args, sizeof(*args)); - len = strlen(path); - if (len > sizeof(args->path)) - len = sizeof(args->path); - args->len = htonl(len); - bcopy(path, args->path, len); - len = 4 + roundup(len, 4); - - cc = rpc_call(d, RPCPROG_MNT, RPCMNT_VER1, RPCMNT_MOUNT, - args, len, repl, sizeof(*repl)); - if (cc == -1) { - /* errno was set by rpc_call */ - return (errno); + if ((env = getenv("nfs.read_size")) != NULL) { + errno = 0; + nfs_read_size = (int)strtol(env, &end, 0); + if (errno != 0 || *env == '\0' || *end != '\0') { + printf("%s: bad value: \"%s\", defaulting to %d\n", + "nfs.read_size", env, NFSREAD_MIN_SIZE); + nfs_read_size = NFSREAD_MIN_SIZE; + } } - if (cc < 4) - return (EBADRPC); - if (repl->errno) - return (ntohl(repl->errno)); - bcopy(repl->fh, fhp, sizeof(repl->fh)); - - /* - * Improve boot performance over NFS - */ - if (getenv("nfs.read_size") != NULL) - nfs_read_size = strtol(getenv("nfs.read_size"), NULL, 0); - if (nfs_read_size < NFSREAD_MIN_SIZE) + if (nfs_read_size < NFSREAD_MIN_SIZE) { + printf("%s: bad value: \"%d\", defaulting to %d\n", + "nfs.read_size", nfs_read_size, NFSREAD_MIN_SIZE); nfs_read_size = NFSREAD_MIN_SIZE; - if (nfs_read_size > NFSREAD_MAX_SIZE) + } + if (nfs_read_size > NFSREAD_MAX_SIZE) { + printf("%s: bad value: \"%d\", defaulting to %d\n", + "nfs.read_size", nfs_read_size, NFSREAD_MIN_SIZE); nfs_read_size = NFSREAD_MAX_SIZE; - - return (0); -} - -/* - * Lookup a file. Store handle and attributes. - * Return zero or error number. - */ -int -nfs_lookupfh(struct nfs_iodesc *d, const char *name, struct nfs_iodesc *newfd) -{ - int len, rlen; - struct args { - u_char fh[NFS_FHSIZE]; - n_long len; - char name[FNAME_SIZE]; - } *args; - struct repl { - n_long errno; - u_char fh[NFS_FHSIZE]; - struct nfsv2_fattrs fa; - } *repl; - struct { - n_long h[RPC_HEADER_WORDS]; - struct args d; - } sdata; - struct { - n_long h[RPC_HEADER_WORDS]; - struct repl d; - } rdata; - ssize_t cc; - -#ifdef NFS_DEBUG - if (debug) - printf("lookupfh: called\n"); -#endif - - args = &sdata.d; - repl = &rdata.d; - - bzero(args, sizeof(*args)); - bcopy(d->fh, args->fh, sizeof(args->fh)); - len = strlen(name); - if (len > sizeof(args->name)) - len = sizeof(args->name); - bcopy(name, args->name, len); - args->len = htonl(len); - len = 4 + roundup(len, 4); - len += NFS_FHSIZE; - - rlen = sizeof(*repl); - - cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_LOOKUP, - args, len, repl, rlen); - if (cc == -1) - return (errno); /* XXX - from rpc_call */ - if (cc < 4) - return (EIO); - if (repl->errno) { - /* saerrno.h now matches NFS error numbers. */ - return (ntohl(repl->errno)); } - bcopy( repl->fh, &newfd->fh, sizeof(newfd->fh)); - bcopy(&repl->fa, &newfd->fa, sizeof(newfd->fa)); - return (0); + snprintf(buf, sizeof (buf), "%d", nfs_read_size); + setenv("nfs.read_size", buf, 1); } -#ifndef NFS_NOSYMLINK /* - * Get the destination of a symbolic link. - */ -int -nfs_readlink(struct nfs_iodesc *d, char *buf) -{ - struct { - n_long h[RPC_HEADER_WORDS]; - u_char fh[NFS_FHSIZE]; - } sdata; - struct { - n_long h[RPC_HEADER_WORDS]; - struct nfs_readlnk_repl d; - } rdata; - ssize_t cc; - -#ifdef NFS_DEBUG - if (debug) - printf("readlink: called\n"); -#endif - - bcopy(d->fh, sdata.fh, NFS_FHSIZE); - cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READLINK, - sdata.fh, NFS_FHSIZE, - &rdata.d, sizeof(rdata.d)); - if (cc == -1) - return (errno); - - if (cc < 4) - return (EIO); - - if (rdata.d.errno) - return (ntohl(rdata.d.errno)); - - rdata.d.len = ntohl(rdata.d.len); - if (rdata.d.len > NFS_MAXPATHLEN) - return (ENAMETOOLONG); - - bcopy(rdata.d.path, buf, rdata.d.len); - buf[rdata.d.len] = 0; - return (0); -} -#endif - -/* - * Read data from a file. - * Return transfer count or -1 (and set errno) - */ -ssize_t -nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len) -{ - struct nfs_read_args *args; - struct nfs_read_repl *repl; - struct { - n_long h[RPC_HEADER_WORDS]; - struct nfs_read_args d; - } sdata; - struct { - n_long h[RPC_HEADER_WORDS]; - struct nfs_read_repl d; - } rdata; - size_t cc; - long x; - int hlen, rlen; - - args = &sdata.d; - repl = &rdata.d; - - bcopy(d->fh, args->fh, NFS_FHSIZE); - args->off = htonl((n_long)off); - if (len > nfs_read_size) - len = nfs_read_size; - args->len = htonl((n_long)len); - args->xxx = htonl((n_long)0); - hlen = offsetof(struct nfs_read_rpl, data[0]); - - cc = rpc_call(d->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READ, - args, sizeof(*args), - repl, sizeof(*repl)); - if (cc == -1) { - /* errno was already set by rpc_call */ - return (-1); - } - if (cc < hlen) { - errno = EBADRPC; - return (-1); - } - if (repl->errno) { - errno = ntohl(repl->errno); - return (-1); - } - rlen = cc - hlen; - x = ntohl(repl->count); - if (rlen < x) { - printf("nfsread: short packet, %d < %ld\n", rlen, x); - errno = EBADRPC; - return(-1); - } - bcopy(repl->data, addr, x); - return (x); -} - -/* - * Open a file. - * return zero or error number - */ -int -nfs_open(const char *upath, struct open_file *f) -{ - struct iodesc *desc; - struct nfs_iodesc *currfd; - char buf[2 * NFS_FHSIZE + 3]; - u_char *fh; - char *cp; - int i; -#ifndef NFS_NOSYMLINK - struct nfs_iodesc *newfd; - struct nfsv2_fattrs *fa; - char *ncp; - int c; - char namebuf[NFS_MAXPATHLEN + 1]; - char linkbuf[NFS_MAXPATHLEN + 1]; - int nlinks = 0; -#endif - int error; - char *path; - - if (netproto != NET_NFS) - return (EINVAL); - -#ifdef NFS_DEBUG - if (debug) - printf("nfs_open: %s (rootpath=%s)\n", upath, rootpath); -#endif - if (!rootpath[0]) { - printf("no rootpath, no nfs\n"); - return (ENXIO); - } - - /* - * This is silly - we should look at dv_type but that value is - * arch dependant and we can't use it here. - */ -#ifndef __i386__ - if (strcmp(f->f_dev->dv_name, "net") != 0) - return(EINVAL); -#else - if (strcmp(f->f_dev->dv_name, "pxe") != 0) - return(EINVAL); -#endif - - if (!(desc = socktodesc(*(int *)(f->f_devdata)))) - return(EINVAL); - - /* Bind to a reserved port. */ - desc->myport = htons(--rpc_port); - desc->destip = rootip; - if ((error = nfs_getrootfh(desc, rootpath, nfs_root_node.fh))) - return (error); - nfs_root_node.fa.fa_type = htonl(NFDIR); - nfs_root_node.fa.fa_mode = htonl(0755); - nfs_root_node.fa.fa_nlink = htonl(2); - nfs_root_node.iodesc = desc; - - fh = &nfs_root_node.fh[0]; - buf[0] = 'X'; - cp = &buf[1]; - for (i = 0; i < NFS_FHSIZE; i++, cp += 2) - sprintf(cp, "%02x", fh[i]); - sprintf(cp, "X"); - setenv("boot.nfsroot.server", inet_ntoa(rootip), 1); - setenv("boot.nfsroot.path", rootpath, 1); - setenv("boot.nfsroot.nfshandle", buf, 1); - - /* Allocate file system specific data structure */ - currfd = malloc(sizeof(*newfd)); - if (currfd == NULL) { - error = ENOMEM; - goto out; - } - -#ifndef NFS_NOSYMLINK - bcopy(&nfs_root_node, currfd, sizeof(*currfd)); - newfd = NULL; - - cp = path = strdup(upath); - if (path == NULL) { - error = ENOMEM; - goto out; - } - while (*cp) { - /* - * Remove extra separators - */ - while (*cp == '/') - cp++; - - if (*cp == '\0') - break; - /* - * Check that current node is a directory. - */ - if (currfd->fa.fa_type != htonl(NFDIR)) { - error = ENOTDIR; - goto out; - } - - /* allocate file system specific data structure */ - newfd = malloc(sizeof(*newfd)); - newfd->iodesc = currfd->iodesc; - - /* - * Get next component of path name. - */ - { - int len = 0; - - ncp = cp; - while ((c = *cp) != '\0' && c != '/') { - if (++len > NFS_MAXNAMLEN) { - error = ENOENT; - goto out; - } - cp++; - } - *cp = '\0'; - } - - /* lookup a file handle */ - error = nfs_lookupfh(currfd, ncp, newfd); - *cp = c; - if (error) - goto out; - - /* - * Check for symbolic link - */ - if (newfd->fa.fa_type == htonl(NFLNK)) { - int link_len, len; - - error = nfs_readlink(newfd, linkbuf); - if (error) - goto out; - - link_len = strlen(linkbuf); - len = strlen(cp); - - if (link_len + len > MAXPATHLEN - || ++nlinks > MAXSYMLINKS) { - error = ENOENT; - goto out; - } - - bcopy(cp, &namebuf[link_len], len + 1); - bcopy(linkbuf, namebuf, link_len); - - /* - * If absolute pathname, restart at root. - * If relative pathname, restart at parent directory. - */ - cp = namebuf; - if (*cp == '/') - bcopy(&nfs_root_node, currfd, sizeof(*currfd)); - - free(newfd); - newfd = NULL; - - continue; - } - - free(currfd); - currfd = newfd; - newfd = NULL; - } - - error = 0; - -out: - free(newfd); - free(path); -#else - currfd->iodesc = desc; - - error = nfs_lookupfh(&nfs_root_node, upath, currfd); -#endif - if (!error) { - currfd->off = 0; - f->f_fsdata = (void *)currfd; - return (0); - } - -#ifdef NFS_DEBUG - if (debug) - printf("nfs_open: %s lookupfh failed: %s\n", - path, strerror(error)); -#endif - free(currfd); - - return (error); -} - -int -nfs_close(struct open_file *f) -{ - struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; - -#ifdef NFS_DEBUG - if (debug) - printf("nfs_close: fp=0x%lx\n", (u_long)fp); -#endif - - if (fp) - free(fp); - f->f_fsdata = (void *)0; - - return (0); -} - -/* - * read a portion of a file - */ -int -nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid) -{ - struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; - ssize_t cc; - char *addr = buf; - -#ifdef NFS_DEBUG - if (debug) - printf("nfs_read: size=%lu off=%d\n", (u_long)size, - (int)fp->off); -#endif - while ((int)size > 0) { - twiddle(16); - cc = nfs_readdata(fp, fp->off, (void *)addr, size); - /* XXX maybe should retry on certain errors */ - if (cc == -1) { -#ifdef NFS_DEBUG - if (debug) - printf("nfs_read: read: %s", strerror(errno)); -#endif - return (errno); /* XXX - from nfs_readdata */ - } - if (cc == 0) { -#ifdef NFS_DEBUG - if (debug) - printf("nfs_read: hit EOF unexpectantly"); -#endif - goto ret; - } - fp->off += cc; - addr += cc; - size -= cc; - } -ret: - if (resid) - *resid = size; - - return (0); -} - -/* - * Not implemented. - */ -int -nfs_write(struct open_file *f, void *buf, size_t size, size_t *resid) -{ - return (EROFS); -} - -off_t -nfs_seek(struct open_file *f, off_t offset, int where) -{ - struct nfs_iodesc *d = (struct nfs_iodesc *)f->f_fsdata; - n_long size = ntohl(d->fa.fa_size); - - switch (where) { - case SEEK_SET: - d->off = offset; - break; - case SEEK_CUR: - d->off += offset; - break; - case SEEK_END: - d->off = size - offset; - break; - default: - errno = EINVAL; - return (-1); - } - - return (d->off); -} - -/* NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5 */ -int nfs_stat_types[8] = { - 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, 0 }; - -int -nfs_stat(struct open_file *f, struct stat *sb) -{ - struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; - n_long ftype, mode; - - ftype = ntohl(fp->fa.fa_type); - mode = ntohl(fp->fa.fa_mode); - mode |= nfs_stat_types[ftype & 7]; - - sb->st_mode = mode; - sb->st_nlink = ntohl(fp->fa.fa_nlink); - sb->st_uid = ntohl(fp->fa.fa_uid); - sb->st_gid = ntohl(fp->fa.fa_gid); - sb->st_size = ntohl(fp->fa.fa_size); - - return (0); -} - -static int -nfs_readdir(struct open_file *f, struct dirent *d) -{ - struct nfs_iodesc *fp = (struct nfs_iodesc *)f->f_fsdata; - struct nfs_readdir_args *args; - struct nfs_readdir_data *rd; - struct nfs_readdir_off *roff = NULL; - static char *buf; - static struct nfs_iodesc *pfp = NULL; - static n_long cookie = 0; - size_t cc; - n_long eof; - - struct { - n_long h[RPC_HEADER_WORDS]; - struct nfs_readdir_args d; - } sdata; - static struct { - n_long h[RPC_HEADER_WORDS]; - u_char d[NFS_READDIRSIZE]; - } rdata; - - if (fp != pfp || fp->off != cookie) { - pfp = NULL; - refill: - args = &sdata.d; - bzero(args, sizeof(*args)); - - bcopy(fp->fh, args->fh, NFS_FHSIZE); - args->cookie = htonl(fp->off); - args->count = htonl(NFS_READDIRSIZE); - - cc = rpc_call(fp->iodesc, NFS_PROG, NFS_VER2, NFSPROC_READDIR, - args, sizeof(*args), - rdata.d, sizeof(rdata.d)); - buf = rdata.d; - roff = (struct nfs_readdir_off *)buf; - if (ntohl(roff->cookie) != 0) - return EIO; - pfp = fp; - cookie = fp->off; - } - roff = (struct nfs_readdir_off *)buf; - - if (ntohl(roff->follows) == 0) { - eof = ntohl((roff+1)->cookie); - if (eof) { - cookie = 0; - return ENOENT; - } - goto refill; - } - - buf += sizeof(struct nfs_readdir_off); - rd = (struct nfs_readdir_data *)buf; - d->d_namlen = ntohl(rd->len); - bcopy(rd->name, d->d_name, d->d_namlen); - d->d_name[d->d_namlen] = '\0'; - - buf += (sizeof(struct nfs_readdir_data) + roundup(htonl(rd->len),4)); - roff = (struct nfs_readdir_off *)buf; - fp->off = cookie = ntohl(roff->cookie); - return 0; -} -#else /* !OLD_NFSV2 */ -/* * Fetch the root file handle (call mount daemon) * Return zero or error number. */ @@ -885,6 +234,8 @@ nfs_getrootfh(struct iodesc *d, char *path, uint32_t * return (ntohl(repl->errno)); *fhlenp = ntohl(repl->fhsize); bcopy(repl->fh, fhp, *fhlenp); + + set_nfs_read_size(); return (0); } @@ -1492,4 +843,3 @@ nfs_readdir(struct open_file *f, struct dirent *d) buf = (u_char *)&rent->nameplus[pos]; return (0); } -#endif /* OLD_NFSV2 */ Modified: stable/11/lib/libstand/nfsv2.h ============================================================================== --- stable/11/lib/libstand/nfsv2.h Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/lib/libstand/nfsv2.h Sat Feb 10 04:37:44 2018 (r329099) @@ -119,46 +119,3 @@ typedef enum { NFCHR=4, NFLNK=5 } nfstype; - -/* Structs for common parts of the rpc's */ -struct nfsv2_time { - n_long nfs_sec; - n_long nfs_usec; -}; - -/* - * File attributes and setable attributes. - */ -struct nfsv2_fattr { - n_long fa_type; - n_long fa_mode; - n_long fa_nlink; - n_long fa_uid; - n_long fa_gid; - n_long fa_size; - n_long fa_blocksize; - n_long fa_rdev; - n_long fa_blocks; - n_long fa_fsid; - n_long fa_fileid; - struct nfsv2_time fa_atime; - struct nfsv2_time fa_mtime; - struct nfsv2_time fa_ctime; -}; - -struct nfsv2_sattr { - n_long sa_mode; - n_long sa_uid; - n_long sa_gid; - n_long sa_size; - struct nfsv2_time sa_atime; - struct nfsv2_time sa_mtime; -}; - -struct nfsv2_statfs { - n_long sf_tsize; - n_long sf_bsize; - n_long sf_blocks; - n_long sf_bfree; - n_long sf_bavail; -}; Modified: stable/11/lib/libstand/stand.h ============================================================================== --- stable/11/lib/libstand/stand.h Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/lib/libstand/stand.h Sat Feb 10 04:37:44 2018 (r329099) @@ -168,6 +168,7 @@ struct devdesc #define DEVT_NET 2 #define DEVT_CD 3 #define DEVT_ZFS 4 +#define DEVT_FD 5 int d_unit; void *d_opendata; }; Modified: stable/11/sys/boot/common/bcache.c ============================================================================== --- stable/11/sys/boot/common/bcache.c Sat Feb 10 01:52:58 2018 (r329098) +++ stable/11/sys/boot/common/bcache.c Sat Feb 10 04:37:44 2018 (r329099) @@ -64,7 +64,7 @@ struct bcachectl struct bcache { struct bcachectl *bcache_ctl; caddr_t bcache_data; - u_int bcache_nblks; + size_t bcache_nblks; size_t ra; }; @@ -86,6 +86,7 @@ static u_int bcache_rablks; ((bc)->bcache_ctl[BHASH((bc), (blkno))].bc_blkno != (blkno)) #define BCACHE_READAHEAD 256 #define BCACHE_MINREADAHEAD 32 +#define BCACHE_MARKER 0xdeadbeef static void bcache_invalidate(struct bcache *bc, daddr_t blkno); static void bcache_insert(struct bcache *bc, daddr_t blkno); @@ -95,7 +96,7 @@ static void bcache_free_instance(struct bcache *bc); * Initialise the cache for (nblks) of (bsize). */ void -bcache_init(u_int nblks, size_t bsize) +bcache_init(size_t nblks, size_t bsize) { /* set up control data */ bcache_total_nblks = nblks; @@ -122,6 +123,7 @@ bcache_allocate(void) u_int i; struct bcache *bc = malloc(sizeof (struct bcache)); int disks = bcache_numdev; + uint32_t *marker; if (disks == 0) disks = 1; /* safe guard */ @@ -140,11 +142,13 @@ bcache_allocate(void) bc->bcache_nblks = bcache_total_nblks >> i; bcache_unit_nblks = bc->bcache_nblks; - bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize); + bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize + + sizeof(uint32_t)); if (bc->bcache_data == NULL) { /* dont error out yet. fall back to 32 blocks and try again */ bc->bcache_nblks = 32; - bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize); + bc->bcache_data = malloc(bc->bcache_nblks * bcache_blksize + + sizeof(uint32_t)); } bc->bcache_ctl = malloc(bc->bcache_nblks * sizeof(struct bcachectl)); @@ -152,8 +156,11 @@ bcache_allocate(void) if ((bc->bcache_data == NULL) || (bc->bcache_ctl == NULL)) { bcache_free_instance(bc); errno = ENOMEM; - return(NULL); + return (NULL); } + /* Insert cache end marker. */ + marker = (uint32_t *)(bc->bcache_data + bc->bcache_nblks * bcache_blksize); + *marker = BCACHE_MARKER; /* Flush the cache */ for (i = 0; i < bc->bcache_nblks; i++) { @@ -215,12 +222,15 @@ read_strategy(void *devdata, int rw, daddr_t blk, size int result; daddr_t p_blk; caddr_t p_buf; + uint32_t *marker; if (bc == NULL) { errno = ENODEV; return (-1); } + marker = (uint32_t *)(bc->bcache_data + bc->bcache_nblks * bcache_blksize); + if (rsize != NULL) *rsize = 0; @@ -261,9 +271,34 @@ read_strategy(void *devdata, int rw, daddr_t blk, size p_size = MIN(r_size, nblk - i); /* read at least those blocks */ + /* + * The read ahead size setup. + * While the read ahead can save us IO, it also can complicate things: + * 1. We do not want to read ahead by wrapping around the + * bcache end - this would complicate the cache management. + * 2. We are using bc->ra as dynamic hint for read ahead size, + * detected cache hits will increase the read-ahead block count, and + * misses will decrease, see the code above. + * 3. The bcache is sized by 512B blocks, however, the underlying device + * may have a larger sector size, and we should perform the IO by + * taking into account these larger sector sizes. We could solve this by + * passing the sector size to bcache_allocate(), or by using ioctl(), but + * in this version we are using the constant, 16 blocks, and are rounding + * read ahead block count down to multiple of 16. + * Using the constant has two reasons, we are not entirely sure if the + * BIOS disk interface is providing the correct value for sector size. + * And secondly, this way we get the most conservative setup for the ra. + * + * The selection of multiple of 16 blocks (8KB) is quite arbitrary, however, + * we want to cover CDs (2K) and 4K disks. + * bcache_allocate() will always fall back to a minimum of 32 blocks. *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802100437.w1A4biOi009170>