summaryrefslogtreecommitdiffstats
path: root/lib/libspl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libspl')
-rw-r--r--lib/libspl/Makefile.am9
-rw-r--r--lib/libspl/include/os/Makefile.am4
-rw-r--r--lib/libspl/include/os/freebsd/Makefile.am1
-rw-r--r--lib/libspl/include/os/freebsd/sys/Makefile.am12
-rw-r--r--lib/libspl/include/os/freebsd/sys/byteorder.h311
-rw-r--r--lib/libspl/include/os/freebsd/sys/file.h42
-rw-r--r--lib/libspl/include/os/freebsd/sys/mnttab.h85
-rw-r--r--lib/libspl/include/os/freebsd/sys/mount.h108
-rw-r--r--lib/libspl/include/os/freebsd/sys/param.h70
-rw-r--r--lib/libspl/include/os/freebsd/sys/stat.h71
-rw-r--r--lib/libspl/include/os/freebsd/sys/sysmacros.h1
-rw-r--r--lib/libspl/include/os/freebsd/sys/uio.h98
-rw-r--r--lib/libspl/include/os/freebsd/sys/vfs.h37
-rw-r--r--lib/libspl/include/os/freebsd/sys/zfs_context_os.h38
-rw-r--r--lib/libspl/os/freebsd/getexecname.c70
-rw-r--r--lib/libspl/os/freebsd/gethostid.c36
-rw-r--r--lib/libspl/os/freebsd/getmntany.c67
-rw-r--r--lib/libspl/os/freebsd/mnttab.c216
18 files changed, 1276 insertions, 0 deletions
diff --git a/lib/libspl/Makefile.am b/lib/libspl/Makefile.am
index 3101b5fc5..77d8aba0e 100644
--- a/lib/libspl/Makefile.am
+++ b/lib/libspl/Makefile.am
@@ -42,6 +42,15 @@ USER_C += \
os/linux/getmntany.c
endif
+if BUILD_FREEBSD
+USER_C += \
+ os/freebsd/getexecname.c \
+ os/freebsd/gethostid.c \
+ os/freebsd/getmntany.c \
+ os/freebsd/mnttab.c
+
+endif
+
USER_ASM = atomic.S
nodist_libspl_la_SOURCES = \
diff --git a/lib/libspl/include/os/Makefile.am b/lib/libspl/include/os/Makefile.am
index 09c0beec4..7b362e02a 100644
--- a/lib/libspl/include/os/Makefile.am
+++ b/lib/libspl/include/os/Makefile.am
@@ -1,3 +1,7 @@
+if BUILD_FREEBSD
+SUBDIRS = freebsd
+endif
+
if BUILD_LINUX
SUBDIRS = linux
endif
diff --git a/lib/libspl/include/os/freebsd/Makefile.am b/lib/libspl/include/os/freebsd/Makefile.am
new file mode 100644
index 000000000..081839c48
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = sys
diff --git a/lib/libspl/include/os/freebsd/sys/Makefile.am b/lib/libspl/include/os/freebsd/sys/Makefile.am
new file mode 100644
index 000000000..896c93871
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/Makefile.am
@@ -0,0 +1,12 @@
+libspldir = $(includedir)/libspl/sys
+libspl_HEADERS = \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/byteorder.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/file.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/mnttab.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/mount.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/param.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/stat.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/sysmacros.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/uio.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/vfs.h \
+ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/zfs_context_os.h
diff --git a/lib/libspl/include/os/freebsd/sys/byteorder.h b/lib/libspl/include/os/freebsd/sys/byteorder.h
new file mode 100644
index 000000000..74649cc4e
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/byteorder.h
@@ -0,0 +1,311 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _SYS_BYTEORDER_H
+#define _SYS_BYTEORDER_H
+
+/*
+ * XXX FIXME
+ * on FreeBSD _BIG_ENDIAN is defined on all architectures so we have
+ * to exclude _MACHINE_ENDIAN_H_ and define the bulk of it here
+ */
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/*
+ * Define the order of 32-bit words in 64-bit words.
+ */
+#define _QUAD_HIGHWORD 1
+#define _QUAD_LOWWORD 0
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#undef _LITTLE_ENDIAN
+/* LSB first: i386, vax */
+#define _LITTLE_ENDIAN 1234
+/* LSB first in word, MSW first in long */
+#define _PDP_ENDIAN 3412
+
+#define _BYTE_ORDER _LITTLE_ENDIAN
+
+/*
+ * Deprecated variants that don't have enough underscores to be useful in more
+ * strict namespaces.
+ */
+#if __BSD_VISIBLE
+#define LITTLE_ENDIAN _LITTLE_ENDIAN
+#define PDP_ENDIAN _PDP_ENDIAN
+#define BYTE_ORDER _BYTE_ORDER
+#endif
+
+#define __bswap16_gen(x) (__uint16_t)((x) << 8 | (x) >> 8)
+#define __bswap32_gen(x) \
+ (((__uint32_t)__bswap16((x) & 0xffff) << 16) | __bswap16((x) >> 16))
+#define __bswap64_gen(x) \
+ (((__uint64_t)__bswap32((x) & 0xffffffff) << 32) | __bswap32((x) >> 32))
+
+#ifdef __GNUCLIKE_BUILTIN_CONSTANT_P
+#define __bswap16(x) \
+ ((__uint16_t)(__builtin_constant_p(x) ? \
+ __bswap16_gen((__uint16_t)(x)) : __bswap16_var(x)))
+#define __bswap32(x) \
+ (__builtin_constant_p(x) ? \
+ __bswap32_gen((__uint32_t)(x)) : __bswap32_var(x))
+#define __bswap64(x) \
+ (__builtin_constant_p(x) ? \
+ __bswap64_gen((__uint64_t)(x)) : __bswap64_var(x))
+#else
+/* XXX these are broken for use in static initializers. */
+#define __bswap16(x) __bswap16_var(x)
+#define __bswap32(x) __bswap32_var(x)
+#define __bswap64(x) __bswap64_var(x)
+#endif
+
+/* These are defined as functions to avoid multiple evaluation of x. */
+
+static __inline __uint16_t
+__bswap16_var(__uint16_t _x)
+{
+
+ return (__bswap16_gen(_x));
+}
+
+static __inline __uint32_t
+__bswap32_var(__uint32_t _x)
+{
+
+#ifdef __GNUCLIKE_ASM
+ __asm("bswap %0" : "+r" (_x));
+ return (_x);
+#else
+ return (__bswap32_gen(_x));
+#endif
+}
+#define __htonl(x) __bswap32(x)
+#define __htons(x) __bswap16(x)
+#define __ntohl(x) __bswap32(x)
+#define __ntohs(x) __bswap16(x)
+
+#include <sys/isa_defs.h>
+#include <sys/int_types.h>
+
+#if defined(__GNUC__) && defined(_ASM_INLINES) && \
+ (defined(__i386) || defined(__amd64))
+#include <asm/byteorder.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * macros for conversion between host and (internet) network byte order
+ */
+
+#if defined(_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint)
+/* big-endian */
+#if defined(_BIG_ENDIAN) && (defined(__amd64__) || defined(__amd64))
+#error "incompatible ENDIAN / ARCH combination"
+#endif
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+
+#elif !defined(ntohl) /* little-endian */
+
+#ifndef _IN_PORT_T
+#define _IN_PORT_T
+typedef uint16_t in_port_t;
+#endif
+
+#ifndef _IN_ADDR_T
+#define _IN_ADDR_T
+typedef uint32_t in_addr_t;
+#endif
+
+#if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5)
+extern uint32_t htonl(uint32_t);
+extern uint16_t htons(uint16_t);
+extern uint32_t ntohl(uint32_t);
+extern uint16_t ntohs(uint16_t);
+#else
+extern in_addr_t htonl(in_addr_t);
+extern in_port_t htons(in_port_t);
+extern in_addr_t ntohl(in_addr_t);
+extern in_port_t ntohs(in_port_t);
+#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */
+#endif
+
+#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
+
+/*
+ * Macros to reverse byte order
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+#define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
+
+#define BMASK_8(x) ((x) & 0xff)
+#define BMASK_16(x) ((x) & 0xffff)
+#define BMASK_32(x) ((x) & 0xffffffff)
+#define BMASK_64(x) (x)
+
+/*
+ * Macros to convert from a specific byte order to/from native byte order
+ */
+#ifdef _BIG_ENDIAN
+#define BE_8(x) BMASK_8(x)
+#define BE_16(x) BMASK_16(x)
+#define BE_32(x) BMASK_32(x)
+#define BE_64(x) BMASK_64(x)
+#define LE_8(x) BSWAP_8(x)
+#define LE_16(x) BSWAP_16(x)
+#define LE_32(x) BSWAP_32(x)
+#define LE_64(x) BSWAP_64(x)
+#else
+#define LE_8(x) BMASK_8(x)
+#define LE_16(x) BMASK_16(x)
+#define LE_32(x) BMASK_32(x)
+#define LE_64(x) BMASK_64(x)
+#define BE_8(x) BSWAP_8(x)
+#define BE_16(x) BSWAP_16(x)
+#define BE_32(x) BSWAP_32(x)
+#define BE_64(x) BSWAP_64(x)
+#endif
+
+#ifdef _BIG_ENDIAN
+static __inline__ uint64_t
+htonll(uint64_t n)
+{
+ return (n);
+}
+
+static __inline__ uint64_t
+ntohll(uint64_t n)
+{
+ return (n);
+}
+#else
+static __inline__ uint64_t
+htonll(uint64_t n)
+{
+ return ((((uint64_t)htonl(n)) << 32) + htonl(n >> 32));
+}
+
+static __inline__ uint64_t
+ntohll(uint64_t n)
+{
+ return ((((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32));
+}
+#endif
+
+/*
+ * Macros to read unaligned values from a specific byte order to
+ * native byte order
+ */
+
+#define BE_IN8(xa) \
+ *((uint8_t *)(xa))
+
+#define BE_IN16(xa) \
+ (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
+
+#define BE_IN32(xa) \
+ (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
+
+#define BE_IN64(xa) \
+ (((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4))
+
+#define LE_IN8(xa) \
+ *((uint8_t *)(xa))
+
+#define LE_IN16(xa) \
+ (((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa))
+
+#define LE_IN32(xa) \
+ (((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa))
+
+#define LE_IN64(xa) \
+ (((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa))
+
+/*
+ * Macros to write unaligned values from native byte order to a specific byte
+ * order.
+ */
+
+#define BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
+
+#define BE_OUT16(xa, yv) \
+ BE_OUT8((uint8_t *)(xa) + 1, yv); \
+ BE_OUT8((uint8_t *)(xa), (yv) >> 8);
+
+#define BE_OUT32(xa, yv) \
+ BE_OUT16((uint8_t *)(xa) + 2, yv); \
+ BE_OUT16((uint8_t *)(xa), (yv) >> 16);
+
+#define BE_OUT64(xa, yv) \
+ BE_OUT32((uint8_t *)(xa) + 4, yv); \
+ BE_OUT32((uint8_t *)(xa), (yv) >> 32);
+
+#define LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
+
+#define LE_OUT16(xa, yv) \
+ LE_OUT8((uint8_t *)(xa), yv); \
+ LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8);
+
+#define LE_OUT32(xa, yv) \
+ LE_OUT16((uint8_t *)(xa), yv); \
+ LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16);
+
+#define LE_OUT64(xa, yv) \
+ LE_OUT32((uint8_t *)(xa), yv); \
+ LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32);
+
+#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_BYTEORDER_H */
diff --git a/lib/libspl/include/os/freebsd/sys/file.h b/lib/libspl/include/os/freebsd/sys/file.h
new file mode 100644
index 000000000..27fd2888f
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/file.h
@@ -0,0 +1,42 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_FILE_H
+#define _LIBSPL_SYS_FILE_H
+
+#include_next <sys/file.h>
+
+#define FCREAT O_CREAT
+#define FTRUNC O_TRUNC
+#define FSYNC O_SYNC
+#define FDSYNC O_DSYNC
+#define FEXCL O_EXCL
+
+#define FNODSYNC 0x10000 /* fsync pseudo flag */
+#define FNOFOLLOW 0x20000 /* don't follow symlinks */
+#define FIGNORECASE 0x80000 /* request case-insensitive lookups */
+
+#endif
diff --git a/lib/libspl/include/os/freebsd/sys/mnttab.h b/lib/libspl/include/os/freebsd/sys/mnttab.h
new file mode 100644
index 000000000..eb6ea2433
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/mnttab.h
@@ -0,0 +1,85 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+/*
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+/* Copyright 2006 Ricardo Correia */
+
+#ifndef _SYS_MNTTAB_H
+#define _SYS_MNTTAB_H
+
+#include <stdio.h>
+#include <sys/types.h>
+
+#ifdef MNTTAB
+#undef MNTTAB
+#endif /* MNTTAB */
+
+#include <paths.h>
+#include <sys/mount.h>
+#define MNTTAB _PATH_DEVZERO
+#define MS_NOMNTTAB 0x0
+#define MS_RDONLY 0x1
+#define umount2(p, f) unmount(p, f)
+#define MNT_LINE_MAX 4096
+
+#define MNT_TOOLONG 1 /* entry exceeds MNT_LINE_MAX */
+#define MNT_TOOMANY 2 /* too many fields in line */
+#define MNT_TOOFEW 3 /* too few fields in line */
+
+struct mnttab {
+ char *mnt_special;
+ char *mnt_mountp;
+ char *mnt_fstype;
+ char *mnt_mntopts;
+};
+
+/*
+ * NOTE: fields in extmnttab should match struct mnttab till new fields
+ * are encountered, this allows hasmntopt to work properly when its arg is
+ * a pointer to an extmnttab struct cast to a mnttab struct pointer.
+ */
+
+struct extmnttab {
+ char *mnt_special;
+ char *mnt_mountp;
+ char *mnt_fstype;
+ char *mnt_mntopts;
+ uint_t mnt_major;
+ uint_t mnt_minor;
+};
+
+struct stat64;
+struct statfs;
+
+extern int getmntany(FILE *fp, struct mnttab *mp, struct mnttab *mpref);
+extern int _sol_getmntent(FILE *fp, struct mnttab *mp);
+extern int getextmntent(const char *path, struct extmnttab *entry,
+ struct stat64 *statbuf);
+extern void statfs2mnttab(struct statfs *sfs, struct mnttab *mp);
+char *hasmntopt(struct mnttab *mnt, char *opt);
+int getmntent(FILE *fp, struct mnttab *mp);
+
+#endif
diff --git a/lib/libspl/include/os/freebsd/sys/mount.h b/lib/libspl/include/os/freebsd/sys/mount.h
new file mode 100644
index 000000000..b40239100
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/mount.h
@@ -0,0 +1,108 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#ifndef _LIBSPL_SYS_MOUNT_H
+#define _LIBSPL_SYS_MOUNT_H
+
+#undef _SYS_MOUNT_H_
+#include_next <sys/mount.h>
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * Some old glibc headers don't define BLKGETSIZE64
+ * and we don't want to require the kernel headers
+ */
+#if !defined(BLKGETSIZE64)
+#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
+#endif
+
+/*
+ * Some old glibc headers don't correctly define MS_DIRSYNC and
+ * instead use the enum name S_WRITE. When using these older
+ * headers define MS_DIRSYNC to be S_WRITE.
+ */
+#if !defined(MS_DIRSYNC)
+#define MS_DIRSYNC S_WRITE
+#endif
+
+/*
+ * Some old glibc headers don't correctly define MS_POSIXACL and
+ * instead leave it undefined. When using these older headers define
+ * MS_POSIXACL to the reserved value of (1<<16).
+ */
+#if !defined(MS_POSIXACL)
+#define MS_POSIXACL (1<<16)
+#endif
+
+#define MS_NOSUID MNT_NOSUID
+#define MS_NOEXEC MNT_NOEXEC
+#define MS_NODEV 0
+#define S_WRITE 0
+#define MS_BIND 0
+#define MS_REMOUNT 0
+#define MS_SYNCHRONOUS MNT_SYNCHRONOUS
+
+#define MS_USERS (MS_NOEXEC|MS_NOSUID|MS_NODEV)
+#define MS_OWNER (MS_NOSUID|MS_NODEV)
+#define MS_GROUP (MS_NOSUID|MS_NODEV)
+#define MS_COMMENT 0
+
+/*
+ * Older glibc <sys/mount.h> headers did not define all the available
+ * umount2(2) flags. Both MNT_FORCE and MNT_DETACH are supported in the
+ * kernel back to 2.4.11 so we define them correctly if they are missing.
+ */
+#ifdef MNT_FORCE
+#define MS_FORCE MNT_FORCE
+#else
+#define MS_FORCE 0x00000001
+#endif /* MNT_FORCE */
+
+#ifdef MNT_DETACH
+#define MS_DETACH MNT_DETACH
+#else
+#define MS_DETACH 0x00000002
+#endif /* MNT_DETACH */
+
+/*
+ * Overlay mount is default in Linux, but for solaris/zfs
+ * compatibility, MS_OVERLAY is defined to explicitly have the user
+ * provide a flag (-O) to mount over a non empty directory.
+ */
+#define MS_OVERLAY 0x00000004
+
+/*
+ * MS_CRYPT indicates that encryption keys should be loaded if they are not
+ * already available. This is not defined in glibc, but it is never seen by
+ * the kernel so it will not cause any problems.
+ */
+#define MS_CRYPT 0x00000008
+
+#endif /* _LIBSPL_SYS_MOUNT_H */
diff --git a/lib/libspl/include/os/freebsd/sys/param.h b/lib/libspl/include/os/freebsd/sys/param.h
new file mode 100644
index 000000000..c0ad8d679
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/param.h
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBSPL_SYS_PARAM_H
+#define _LIBSPL_SYS_PARAM_H
+
+#include_next <sys/param.h>
+#include <unistd.h>
+
+/*
+ * File system parameters and macros.
+ *
+ * The file system is made out of blocks of at most MAXBSIZE units,
+ * with smaller units (fragments) only in the last direct block.
+ * MAXBSIZE primarily determines the size of buffers in the buffer
+ * pool. It may be made larger without any effect on existing
+ * file systems; however making it smaller may make some file
+ * systems unmountable.
+ *
+ * Note that the blocked devices are assumed to have DEV_BSIZE
+ * "sectors" and that fragments must be some multiple of this size.
+ */
+#define MAXNAMELEN 256
+
+#define UID_NOBODY 60001 /* user ID no body */
+#define GID_NOBODY UID_NOBODY
+#define UID_NOACCESS 60002 /* user ID no access */
+
+#define MAXUID UINT32_MAX /* max user id */
+#define MAXPROJID MAXUID /* max project id */
+
+#ifdef PAGESIZE
+#undef PAGESIZE
+#endif /* PAGESIZE */
+
+extern size_t spl_pagesize(void);
+#define PAGESIZE (spl_pagesize())
+
+extern int execvpe(const char *name, char * const argv[], char * const envp[]);
+
+struct zfs_handle;
+/*
+ * Attach/detach the given filesystem to/from the given jail.
+ */
+extern int zfs_jail(struct zfs_handle *zhp, int jailid, int attach);
+
+#endif
diff --git a/lib/libspl/include/os/freebsd/sys/stat.h b/lib/libspl/include/os/freebsd/sys/stat.h
new file mode 100644
index 000000000..82c86262f
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/stat.h
@@ -0,0 +1,71 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#ifndef _LIBSPL_SYS_STAT_H
+#define _LIBSPL_SYS_STAT_H
+
+#include_next <sys/stat.h>
+
+#include <sys/mount.h> /* for BLKGETSIZE64 */
+
+#define stat64 stat
+
+#define MAXOFFSET_T OFF_MAX
+
+#ifndef _KERNEL
+#include <sys/disk.h>
+
+static __inline int
+fstat64(int fd, struct stat *sb)
+{
+ int ret;
+
+ ret = fstat(fd, sb);
+ if (ret == 0) {
+ if (S_ISCHR(sb->st_mode))
+ (void) ioctl(fd, DIOCGMEDIASIZE, &sb->st_size);
+ }
+ return (ret);
+}
+#endif
+
+/*
+ * Emulate Solaris' behavior of returning the block device size in fstat64().
+ */
+static inline int
+fstat64_blk(int fd, struct stat64 *st)
+{
+ if (fstat64(fd, st) == -1)
+ return (-1);
+
+ /* In Linux we need to use an ioctl to get the size of a block device */
+ if (S_ISBLK(st->st_mode)) {
+ if (ioctl(fd, BLKGETSIZE64, &st->st_size) != 0)
+ return (-1);
+ }
+
+ return (0);
+}
+#endif /* _LIBSPL_SYS_STAT_H */
diff --git a/lib/libspl/include/os/freebsd/sys/sysmacros.h b/lib/libspl/include/os/freebsd/sys/sysmacros.h
new file mode 100644
index 000000000..d9639d27b
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/sysmacros.h
@@ -0,0 +1 @@
+/* keep me */
diff --git a/lib/libspl/include/os/freebsd/sys/uio.h b/lib/libspl/include/os/freebsd/sys/uio.h
new file mode 100644
index 000000000..d978b6ad0
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/uio.h
@@ -0,0 +1,98 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+#ifndef _LIBSPL_SYS_UIO_H
+#define _LIBSPL_SYS_UIO_H
+
+#include_next <sys/uio.h>
+
+typedef struct iovec iovec_t;
+typedef enum uio_seg uio_seg_t;
+
+typedef struct uio {
+ struct iovec *uio_iov; /* pointer to array of iovecs */
+ int uio_iovcnt; /* number of iovecs */
+ offset_t uio_loffset; /* file offset */
+ uio_seg_t uio_segflg; /* address space (kernel or user) */
+ uint16_t uio_fmode; /* file mode flags */
+ uint16_t uio_extflg; /* extended flags */
+ offset_t uio_limit; /* u-limit (maximum byte offset) */
+ ssize_t uio_resid; /* residual count */
+} uio_t;
+
+typedef enum xuio_type {
+ UIOTYPE_ASYNCIO,
+ UIOTYPE_ZEROCOPY,
+} xuio_type_t;
+
+#define UIOA_IOV_MAX 16
+
+typedef struct uioa_page_s { /* locked uio_iov state */
+ int uioa_pfncnt; /* count of pfn_t(s) in *uioa_ppp */
+ void **uioa_ppp; /* page_t or pfn_t array */
+ caddr_t uioa_base; /* address base */
+ size_t uioa_len; /* span length */
+} uioa_page_t;
+
+typedef struct xuio {
+ uio_t xu_uio; /* embedded UIO structure */
+
+ /* Extended uio fields */
+ enum xuio_type xu_type; /* uio type */
+ union {
+ struct {
+ uint32_t xu_a_state; /* state of async i/o */
+ ssize_t xu_a_mbytes; /* bytes moved */
+ uioa_page_t *xu_a_lcur; /* uioa_locked[] pointer */
+ void **xu_a_lppp; /* lcur->uioa_pppp[] pointer */
+ void *xu_a_hwst[4]; /* opaque hardware state */
+ uioa_page_t xu_a_locked[UIOA_IOV_MAX];
+ } xu_aio;
+
+ struct {
+ int xu_zc_rw; /* read or write buffer */
+ void *xu_zc_priv; /* fs specific */
+ } xu_zc;
+ } xu_ext;
+} xuio_t;
+
+#define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv
+#define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw
+
+#endif /* _SYS_UIO_H */
diff --git a/lib/libspl/include/os/freebsd/sys/vfs.h b/lib/libspl/include/os/freebsd/sys/vfs.h
new file mode 100644
index 000000000..55eb3c23b
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/vfs.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2020 iXsystems, Inc.
+ * 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 AUTHORS 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 AUTHORS 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 ZFS_SYS_VFS_H_
+#define ZFS_SYS_VFS_H_
+
+#include_next <sys/statvfs.h>
+
+int fsshare(const char *, const char *, const char *);
+int fsunshare(const char *, const char *);
+
+#endif /* !ZFS_SYS_VFS_H_ */
diff --git a/lib/libspl/include/os/freebsd/sys/zfs_context_os.h b/lib/libspl/include/os/freebsd/sys/zfs_context_os.h
new file mode 100644
index 000000000..25b5a47df
--- /dev/null
+++ b/lib/libspl/include/os/freebsd/sys/zfs_context_os.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020 iXsystems, Inc.
+ * 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 AUTHORS 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 AUTHORS 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 ZFS_CONTEXT_OS_H_
+#define ZFS_CONTEXT_OS_H_
+
+#if BYTE_ORDER != BIG_ENDIAN
+#undef _BIG_ENDIAN
+#endif
+
+#define ZFS_EXPORTS_PATH "/etc/zfs/exports"
+
+#endif
diff --git a/lib/libspl/os/freebsd/getexecname.c b/lib/libspl/os/freebsd/getexecname.c
new file mode 100644
index 000000000..13e50d324
--- /dev/null
+++ b/lib/libspl/os/freebsd/getexecname.c
@@ -0,0 +1,70 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <errno.h>
+
+const char *
+getexecname(void)
+{
+ static char execname[PATH_MAX + 1] = "";
+ static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+ char *ptr = NULL;
+ ssize_t rc;
+
+ (void) pthread_mutex_lock(&mtx);
+
+ if (strlen(execname) == 0) {
+ int error, name[4];
+ size_t len;
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC;
+ name[2] = KERN_PROC_PATHNAME;
+ name[3] = -1;
+ len = PATH_MAX;
+ error = sysctl(name, nitems(name), execname, &len, NULL, 0);
+ if (error != 0) {
+ rc = -1;
+ } else {
+ rc = len;
+ }
+ if (rc == -1) {
+ execname[0] = '\0';
+ } else {
+ execname[rc] = '\0';
+ ptr = execname;
+ }
+ } else {
+ ptr = execname;
+ }
+
+ (void) pthread_mutex_unlock(&mtx);
+ return (ptr);
+}
diff --git a/lib/libspl/os/freebsd/gethostid.c b/lib/libspl/os/freebsd/gethostid.c
new file mode 100644
index 000000000..7bd567fe6
--- /dev/null
+++ b/lib/libspl/os/freebsd/gethostid.c
@@ -0,0 +1,36 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2017, Lawrence Livermore National Security, LLC.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/systeminfo.h>
+
+unsigned long
+get_system_hostid(void)
+{
+ return (gethostid());
+}
diff --git a/lib/libspl/os/freebsd/getmntany.c b/lib/libspl/os/freebsd/getmntany.c
new file mode 100644
index 000000000..b41e763ce
--- /dev/null
+++ b/lib/libspl/os/freebsd/getmntany.c
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Ricardo Correia. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1988 AT&T */
+/* All Rights Reserved */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/errno.h>
+#include <sys/mnttab.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define BUFSIZE (MNT_LINE_MAX + 2)
+
+__thread char buf[BUFSIZE];
+
+int
+getextmntent(const char *path, struct extmnttab *entry, struct stat64 *statbuf)
+{
+ struct statfs sfs;
+
+ if (strlen(path) >= MAXPATHLEN) {
+ (void) fprintf(stderr, "invalid object; pathname too long\n");
+ return (-1);
+ }
+
+ if (stat64(path, statbuf) != 0) {
+ (void) fprintf(stderr, "cannot open '%s': %s\n",
+ path, strerror(errno));
+ return (-1);
+ }
+
+ if (statfs(path, &sfs) != 0) {
+ (void) fprintf(stderr, "%s: %s\n", path,
+ strerror(errno));
+ return (-1);
+ }
+ statfs2mnttab(&sfs, (struct mnttab *)entry);
+ return (0);
+}
diff --git a/lib/libspl/os/freebsd/mnttab.c b/lib/libspl/os/freebsd/mnttab.c
new file mode 100644
index 000000000..5b9e6429d
--- /dev/null
+++ b/lib/libspl/os/freebsd/mnttab.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2006 Pawel Jakub Dawidek <[email protected]>
+ * 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 AUTHORS 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 AUTHORS 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 implements Solaris compatible getmntany() and hasmntopt()
+ * functions.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/mntent.h>
+#include <sys/mnttab.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *
+mntopt(char **p)
+{
+ char *cp = *p;
+ char *retstr;
+
+ while (*cp && isspace(*cp))
+ cp++;
+
+ retstr = cp;
+ while (*cp && *cp != ',')
+ cp++;
+
+ if (*cp) {
+ *cp = '\0';
+ cp++;
+ }
+
+ *p = cp;
+ return (retstr);
+}
+
+char *
+hasmntopt(struct mnttab *mnt, char *opt)
+{
+ char tmpopts[MNT_LINE_MAX];
+ char *f, *opts = tmpopts;
+
+ if (mnt->mnt_mntopts == NULL)
+ return (NULL);
+ (void) strcpy(opts, mnt->mnt_mntopts);
+ f = mntopt(&opts);
+ for (; *f; f = mntopt(&opts)) {
+ if (strncmp(opt, f, strlen(opt)) == 0)
+ return (f - tmpopts + mnt->mnt_mntopts);
+ }
+ return (NULL);
+}
+
+static void
+optadd(char *mntopts, size_t size, const char *opt)
+{
+
+ if (mntopts[0] != '\0')
+ strlcat(mntopts, ",", size);
+ strlcat(mntopts, opt, size);
+}
+
+void
+statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
+{
+ static char mntopts[MNTMAXSTR];
+ long flags;
+
+ mntopts[0] = '\0';
+
+ flags = sfs->f_flags;
+#define OPTADD(opt) optadd(mntopts, sizeof (mntopts), (opt))
+ if (flags & MNT_RDONLY)
+ OPTADD(MNTOPT_RO);
+ else
+ OPTADD(MNTOPT_RW);
+ if (flags & MNT_NOSUID)
+ OPTADD(MNTOPT_NOSETUID);
+ else
+ OPTADD(MNTOPT_SETUID);
+ if (flags & MNT_UPDATE)
+ OPTADD(MNTOPT_REMOUNT);
+ if (flags & MNT_NOATIME)
+ OPTADD(MNTOPT_NOATIME);
+ else
+ OPTADD(MNTOPT_ATIME);
+ OPTADD(MNTOPT_NOXATTR);
+ if (flags & MNT_NOEXEC)
+ OPTADD(MNTOPT_NOEXEC);
+ else
+ OPTADD(MNTOPT_EXEC);
+#undef OPTADD
+ mp->mnt_special = strdup(sfs->f_mntfromname);
+ mp->mnt_mountp = strdup(sfs->f_mntonname);
+ mp->mnt_fstype = strdup(sfs->f_fstypename);
+ mp->mnt_mntopts = strdup(mntopts);
+}
+
+static struct statfs *gsfs = NULL;
+static int allfs = 0;
+
+static int
+statfs_init(void)
+{
+ struct statfs *sfs;
+ int error;
+
+ if (gsfs != NULL) {
+ free(gsfs);
+ gsfs = NULL;
+ }
+ allfs = getfsstat(NULL, 0, MNT_WAIT);
+ if (allfs == -1)
+ goto fail;
+ gsfs = malloc(sizeof (gsfs[0]) * allfs * 2);
+ if (gsfs == NULL)
+ goto fail;
+ allfs = getfsstat(gsfs, (long)(sizeof (gsfs[0]) * allfs * 2),
+ MNT_WAIT);
+ if (allfs == -1)
+ goto fail;
+ sfs = realloc(gsfs, allfs * sizeof (gsfs[0]));
+ if (sfs != NULL)
+ gsfs = sfs;
+ return (0);
+fail:
+ error = errno;
+ if (gsfs != NULL)
+ free(gsfs);
+ gsfs = NULL;
+ allfs = 0;
+ return (error);
+}
+
+int
+getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
+{
+ // struct statfs *sfs;
+ int i, error;
+
+ error = statfs_init();
+ if (error != 0)
+ return (error);
+
+ for (i = 0; i < allfs; i++) {
+ if (mrefp->mnt_special != NULL &&
+ strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
+ continue;
+ }
+ if (mrefp->mnt_mountp != NULL &&
+ strcmp(mrefp->mnt_mountp, gsfs[i].f_mntonname) != 0) {
+ continue;
+ }
+ if (mrefp->mnt_fstype != NULL &&
+ strcmp(mrefp->mnt_fstype, gsfs[i].f_fstypename) != 0) {
+ continue;
+ }
+ statfs2mnttab(&gsfs[i], mgetp);
+ return (0);
+ }
+ return (-1);
+}
+
+int
+getmntent(FILE *fp, struct mnttab *mp)
+{
+ // struct statfs *sfs;
+ int error, nfs;
+
+ nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
+ if (nfs == -1)
+ return (errno);
+ /* If nfs is 0, we want to refresh out cache. */
+ if (nfs == 0 || gsfs == NULL) {
+ error = statfs_init();
+ if (error != 0)
+ return (error);
+ }
+ if (nfs >= allfs)
+ return (-1);
+ statfs2mnttab(&gsfs[nfs], mp);
+ if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
+ return (errno);
+ return (0);
+}