Extend the "vfsopt" mount options for more general use. Make struct
vfsopt and the vfs_buildopts function public, and add some new fields to struct vfsopt (pos and seen), and new functions vfs_getopt_pos and vfs_opterror. Further extend the interface to allow reading options from the kernel in addition to sending them to the kernel, with vfs_setopt and related functions. While this allows the "name=value" option interface to be used for more than just FS mounts (planned use is for jails), it retains the current "vfsopt" name and <sys/mount.h> requirement. Approved by: bz (mentor)
This commit is contained in:
parent
12e34d9850
commit
63f98fcc6a
@ -1243,7 +1243,10 @@ MLINKS+=vfs_getopt.9 vfs_copyopt.9 \
|
||||
vfs_getopt.9 vfs_filteropt.9 \
|
||||
vfs_getopt.9 vfs_flagopt.9 \
|
||||
vfs_getopt.9 vfs_getopts.9 \
|
||||
vfs_getopt.9 vfs_scanopt.9
|
||||
vfs_getopt.9 vfs_scanopt.9 \
|
||||
vfs_getopt.9 vfs_setopt.9 \
|
||||
vfs_getopt.9 vfs_setopt_part.9 \
|
||||
vfs_getopt.9 vfs_setopts.9
|
||||
MLINKS+=VFS_LOCK_GIANT.9 VFS_UNLOCK_GIANT.9
|
||||
MLINKS+=vgone.9 vgonel.9
|
||||
MLINKS+=vhold.9 vdrop.9 \
|
||||
|
@ -26,7 +26,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 28, 2007
|
||||
.Dd March 2, 2009
|
||||
.Dt VFS_GETOPT 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -35,7 +35,10 @@
|
||||
.Nm vfs_flagopt ,
|
||||
.Nm vfs_scanopt ,
|
||||
.Nm vfs_copyopt ,
|
||||
.Nm vfs_filteropt
|
||||
.Nm vfs_filteropt ,
|
||||
.Nm vfs_setopt ,
|
||||
.Nm vfs_setopt_part ,
|
||||
.Nm vfs_setopts
|
||||
.Nd "manipulate mount options and their values"
|
||||
.Sh SYNOPSIS
|
||||
.In sys/param.h
|
||||
@ -62,6 +65,18 @@
|
||||
.Fo vfs_filteropt
|
||||
.Fa "struct vfsoptlist *opts" "const char **legal"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo vfs_setopt
|
||||
.Fa "struct vfsoptlist *opts" "const char *name" "void *value" "int len"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo vfs_setopt_part
|
||||
.Fa "struct vfsoptlist *opts" "const char *name" "void *value" "int len"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo vfs_setopts
|
||||
.Fa "struct vfsoptlist *opts" "const char *name" "const char *value"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn vfs_getopt
|
||||
@ -111,7 +126,7 @@ The
|
||||
.Fn vfs_scanopt
|
||||
function performs a
|
||||
.Xr vsscanf 3
|
||||
with the options value, using the given format,
|
||||
with the option's value, using the given format,
|
||||
into the specified variable arguments.
|
||||
The value must be a string (i.e.,
|
||||
.Dv NUL
|
||||
@ -119,10 +134,10 @@ terminated).
|
||||
.Pp
|
||||
The
|
||||
.Fn vfs_copyopt
|
||||
function creates a copy of the options value.
|
||||
function creates a copy of the option's value.
|
||||
The
|
||||
.Fa len
|
||||
argument must match the length of the options value exactly
|
||||
argument must match the length of the option's value exactly
|
||||
(i.e., a larger buffer will still cause
|
||||
.Fn vfs_copyout
|
||||
to fail with
|
||||
@ -134,6 +149,28 @@ function ensures that no unknown options were specified.
|
||||
A option is valid if its name matches one of the names in the
|
||||
list of legal names.
|
||||
An option may be prefixed with 'no', and still be considered valid.
|
||||
.Pp
|
||||
The
|
||||
.Fn vfs_setopt
|
||||
and
|
||||
.Fn vfs_setopt_part
|
||||
functions copy new data into the option's value.
|
||||
In
|
||||
.Fn vfs_setopt ,
|
||||
the
|
||||
.Fa len
|
||||
argument must match the length of the option's value exactly
|
||||
(i.e., a larger buffer will still cause
|
||||
.Fn vfs_copyout
|
||||
to fail with
|
||||
.Er EINVAL ) .
|
||||
.Pp
|
||||
The
|
||||
.Fn vfs_setopts
|
||||
function copies a new string into the option's value.
|
||||
The string, including
|
||||
.Dv NUL
|
||||
byte, must be no longer than the option's length.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn vfs_getopt
|
||||
@ -179,7 +216,9 @@ not always mean the option does not exist, or is not a valid string.
|
||||
.Pp
|
||||
The
|
||||
.Fn vfs_copyopt
|
||||
function returns 0 if the copy was successful,
|
||||
and
|
||||
.Fn vfs_setopt
|
||||
functions return 0 if the copy was successful,
|
||||
.Er EINVAL
|
||||
if the option was found but the lengths did not match, and
|
||||
.Er ENOENT
|
||||
@ -190,6 +229,14 @@ The
|
||||
function returns 0 if all of the options are legal; otherwise,
|
||||
.Er EINVAL
|
||||
is returned.
|
||||
.Pp
|
||||
The
|
||||
.Fn vfs_setopts
|
||||
function returns 0 if the copy was successful,
|
||||
.Er EINVAL
|
||||
if the option was found but the string was too long, and
|
||||
.Er ENOENT
|
||||
if the option was not found.
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
This manual page was written by
|
||||
|
@ -39,14 +39,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
MALLOC_DECLARE(M_MOUNT);
|
||||
|
||||
TAILQ_HEAD(vfsoptlist, vfsopt);
|
||||
struct vfsopt {
|
||||
TAILQ_ENTRY(vfsopt) link;
|
||||
char *name;
|
||||
void *value;
|
||||
int len;
|
||||
};
|
||||
|
||||
void
|
||||
vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
|
||||
int flags __unused)
|
||||
@ -64,6 +56,8 @@ vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
|
||||
namesize = strlen(name) + 1;
|
||||
opt->name = malloc(namesize, M_MOUNT, M_WAITOK);
|
||||
strlcpy(opt->name, name, namesize);
|
||||
opt->pos = -1;
|
||||
opt->seen = 1;
|
||||
|
||||
if (arg == NULL) {
|
||||
opt->value = NULL;
|
||||
@ -80,22 +74,9 @@ vfs_setmntopt(vfs_t *vfsp, const char *name, const char *arg,
|
||||
void
|
||||
vfs_clearmntopt(vfs_t *vfsp, const char *name)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
|
||||
if (vfsp->mnt_opt == NULL)
|
||||
return;
|
||||
/* TODO: Locking. */
|
||||
TAILQ_FOREACH(opt, vfsp->mnt_opt, link) {
|
||||
if (strcmp(opt->name, name) == 0)
|
||||
break;
|
||||
}
|
||||
if (opt != NULL) {
|
||||
TAILQ_REMOVE(vfsp->mnt_opt, opt, link);
|
||||
free(opt->name, M_MOUNT);
|
||||
if (opt->value != NULL)
|
||||
free(opt->value, M_MOUNT);
|
||||
free(opt, M_MOUNT);
|
||||
}
|
||||
vfs_deleteopt(vfsp->mnt_opt, name);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -2639,8 +2639,7 @@ freebsd32_nmount(struct thread *td,
|
||||
} */ *uap)
|
||||
{
|
||||
struct uio *auio;
|
||||
struct iovec *iov;
|
||||
int error, k;
|
||||
int error;
|
||||
|
||||
AUDIT_ARG(fflags, uap->flags);
|
||||
|
||||
@ -2662,14 +2661,8 @@ freebsd32_nmount(struct thread *td,
|
||||
error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
|
||||
if (error)
|
||||
return (error);
|
||||
for (iov = auio->uio_iov, k = 0; k < uap->iovcnt; ++k, ++iov) {
|
||||
if (iov->iov_len > MMAXOPTIONLEN) {
|
||||
free(auio, M_IOV);
|
||||
return (EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
error = vfs_donmount(td, uap->flags, auio);
|
||||
|
||||
free(auio, M_IOV);
|
||||
return error;
|
||||
}
|
||||
|
@ -78,7 +78,6 @@ static int vfs_domount(struct thread *td, const char *fstype,
|
||||
static int vfs_mountroot_ask(void);
|
||||
static int vfs_mountroot_try(const char *mountfrom);
|
||||
static void free_mntarg(struct mntarg *ma);
|
||||
static int vfs_getopt_pos(struct vfsoptlist *opts, const char *name);
|
||||
|
||||
static int usermount = 0;
|
||||
SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0,
|
||||
@ -95,14 +94,6 @@ struct mntlist mountlist = TAILQ_HEAD_INITIALIZER(mountlist);
|
||||
struct mtx mountlist_mtx;
|
||||
MTX_SYSINIT(mountlist, &mountlist_mtx, "mountlist", MTX_DEF);
|
||||
|
||||
TAILQ_HEAD(vfsoptlist, vfsopt);
|
||||
struct vfsopt {
|
||||
TAILQ_ENTRY(vfsopt) link;
|
||||
char *name;
|
||||
void *value;
|
||||
int len;
|
||||
};
|
||||
|
||||
/*
|
||||
* The vnode of the system's root (/ in the filesystem, without chroot
|
||||
* active.)
|
||||
@ -164,11 +155,6 @@ vfs_freeopt(struct vfsoptlist *opts, struct vfsopt *opt)
|
||||
free(opt->name, M_MOUNT);
|
||||
if (opt->value != NULL)
|
||||
free(opt->value, M_MOUNT);
|
||||
#ifdef INVARIANTS
|
||||
else if (opt->len != 0)
|
||||
panic("%s: mount option with NULL value but length != 0",
|
||||
__func__);
|
||||
#endif
|
||||
free(opt, M_MOUNT);
|
||||
}
|
||||
|
||||
@ -204,6 +190,7 @@ vfs_deleteopt(struct vfsoptlist *opts, const char *name)
|
||||
static int
|
||||
vfs_equalopts(const char *opt1, const char *opt2)
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* "opt" vs. "opt" or "noopt" vs. "noopt" */
|
||||
if (strcmp(opt1, opt2) == 0)
|
||||
@ -214,6 +201,17 @@ vfs_equalopts(const char *opt1, const char *opt2)
|
||||
/* "opt" vs. "noopt" */
|
||||
if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0)
|
||||
return (1);
|
||||
while ((p = strchr(opt1, '.')) != NULL &&
|
||||
!strncmp(opt1, opt2, ++p - opt1)) {
|
||||
opt2 += p - opt1;
|
||||
opt1 = p;
|
||||
/* "foo.noopt" vs. "foo.opt" */
|
||||
if (strncmp(opt1, "no", 2) == 0 && strcmp(opt1 + 2, opt2) == 0)
|
||||
return (1);
|
||||
/* "foo.opt" vs. "foo.noopt" */
|
||||
if (strncmp(opt2, "no", 2) == 0 && strcmp(opt1, opt2 + 2) == 0)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -244,34 +242,23 @@ vfs_sanitizeopts(struct vfsoptlist *opts)
|
||||
/*
|
||||
* Build a linked list of mount options from a struct uio.
|
||||
*/
|
||||
static int
|
||||
int
|
||||
vfs_buildopts(struct uio *auio, struct vfsoptlist **options)
|
||||
{
|
||||
struct vfsoptlist *opts;
|
||||
struct vfsopt *opt;
|
||||
size_t memused;
|
||||
size_t memused, namelen, optlen;
|
||||
unsigned int i, iovcnt;
|
||||
int error, namelen, optlen;
|
||||
int error;
|
||||
|
||||
opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK);
|
||||
TAILQ_INIT(opts);
|
||||
memused = 0;
|
||||
iovcnt = auio->uio_iovcnt;
|
||||
for (i = 0; i < iovcnt; i += 2) {
|
||||
opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
|
||||
namelen = auio->uio_iov[i].iov_len;
|
||||
optlen = auio->uio_iov[i + 1].iov_len;
|
||||
opt->name = malloc(namelen, M_MOUNT, M_WAITOK);
|
||||
opt->value = NULL;
|
||||
opt->len = 0;
|
||||
|
||||
/*
|
||||
* Do this early, so jumps to "bad" will free the current
|
||||
* option.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(opts, opt, link);
|
||||
memused += sizeof(struct vfsopt) + optlen + namelen;
|
||||
|
||||
/*
|
||||
* Avoid consuming too much memory, and attempts to overflow
|
||||
* memused.
|
||||
@ -283,6 +270,19 @@ vfs_buildopts(struct uio *auio, struct vfsoptlist **options)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
opt = malloc(sizeof(struct vfsopt), M_MOUNT, M_WAITOK);
|
||||
opt->name = malloc(namelen, M_MOUNT, M_WAITOK);
|
||||
opt->value = NULL;
|
||||
opt->len = 0;
|
||||
opt->pos = i / 2;
|
||||
opt->seen = 0;
|
||||
|
||||
/*
|
||||
* Do this early, so jumps to "bad" will free the current
|
||||
* option.
|
||||
*/
|
||||
TAILQ_INSERT_TAIL(opts, opt, link);
|
||||
|
||||
if (auio->uio_segflg == UIO_SYSSPACE) {
|
||||
bcopy(auio->uio_iov[i].iov_base, opt->name, namelen);
|
||||
} else {
|
||||
@ -292,7 +292,7 @@ vfs_buildopts(struct uio *auio, struct vfsoptlist **options)
|
||||
goto bad;
|
||||
}
|
||||
/* Ensure names are null-terminated strings. */
|
||||
if (opt->name[namelen - 1] != '\0') {
|
||||
if (namelen == 0 || opt->name[namelen - 1] != '\0') {
|
||||
error = EINVAL;
|
||||
goto bad;
|
||||
}
|
||||
@ -361,6 +361,7 @@ vfs_mergeopts(struct vfsoptlist *toopts, struct vfsoptlist *opts)
|
||||
new->value = NULL;
|
||||
}
|
||||
new->len = opt->len;
|
||||
new->seen = opt->seen;
|
||||
TAILQ_INSERT_TAIL(toopts, new, link);
|
||||
next:
|
||||
continue;
|
||||
@ -380,8 +381,6 @@ nmount(td, uap)
|
||||
} */ *uap;
|
||||
{
|
||||
struct uio *auio;
|
||||
struct iovec *iov;
|
||||
unsigned int i;
|
||||
int error;
|
||||
u_int iovcnt;
|
||||
|
||||
@ -414,16 +413,6 @@ nmount(td, uap)
|
||||
__func__, error);
|
||||
return (error);
|
||||
}
|
||||
iov = auio->uio_iov;
|
||||
for (i = 0; i < iovcnt; i++) {
|
||||
if (iov->iov_len > MMAXOPTIONLEN) {
|
||||
free(auio, M_IOV);
|
||||
CTR1(KTR_VFS, "%s: failed for invalid new auio",
|
||||
__func__);
|
||||
return (EINVAL);
|
||||
}
|
||||
iov++;
|
||||
}
|
||||
error = vfs_donmount(td, uap->flags, auio);
|
||||
|
||||
free(auio, M_IOV);
|
||||
@ -692,6 +681,8 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions)
|
||||
noro_opt->name = strdup("noro", M_MOUNT);
|
||||
noro_opt->value = NULL;
|
||||
noro_opt->len = 0;
|
||||
noro_opt->pos = -1;
|
||||
noro_opt->seen = 1;
|
||||
TAILQ_INSERT_TAIL(optlist, noro_opt, link);
|
||||
}
|
||||
|
||||
@ -1611,6 +1602,22 @@ vfs_mount_error(struct mount *mp, const char *fmt, ...)
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int error, len;
|
||||
char *errmsg;
|
||||
|
||||
error = vfs_getopt(opts, "errmsg", (void **)&errmsg, &len);
|
||||
if (error || errmsg == NULL || len <= 0)
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(errmsg, (size_t)len, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find and mount the root filesystem
|
||||
*/
|
||||
@ -1880,6 +1887,7 @@ vfs_getopt(opts, name, buf, len)
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) == 0) {
|
||||
opt->seen = 1;
|
||||
if (len != NULL)
|
||||
*len = opt->len;
|
||||
if (buf != NULL)
|
||||
@ -1890,20 +1898,19 @@ vfs_getopt(opts, name, buf, len)
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
static int
|
||||
int
|
||||
vfs_getopt_pos(struct vfsoptlist *opts, const char *name)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
int i;
|
||||
|
||||
if (opts == NULL)
|
||||
return (-1);
|
||||
|
||||
i = 0;
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) == 0)
|
||||
return (i);
|
||||
++i;
|
||||
if (strcmp(name, opt->name) == 0) {
|
||||
opt->seen = 1;
|
||||
return (opt->pos);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
@ -1917,7 +1924,9 @@ vfs_getopts(struct vfsoptlist *opts, const char *name, int *error)
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
if (((char *)opt->value)[opt->len - 1] != '\0') {
|
||||
opt->seen = 1;
|
||||
if (opt->len == 0 ||
|
||||
((char *)opt->value)[opt->len - 1] != '\0') {
|
||||
*error = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
@ -1934,6 +1943,7 @@ vfs_flagopt(struct vfsoptlist *opts, const char *name, u_int *w, u_int val)
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) == 0) {
|
||||
opt->seen = 1;
|
||||
if (w != NULL)
|
||||
*w |= val;
|
||||
return (1);
|
||||
@ -1956,6 +1966,7 @@ vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...)
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
opt->seen = 1;
|
||||
if (opt->len == 0 || opt->value == NULL)
|
||||
return (0);
|
||||
if (((char *)opt->value)[opt->len - 1] != '\0')
|
||||
@ -1968,6 +1979,67 @@ vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_setopt(struct vfsoptlist *opts, const char *name, void *value, int len)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
opt->seen = 1;
|
||||
if (opt->value == NULL)
|
||||
opt->len = len;
|
||||
else {
|
||||
if (opt->len != len)
|
||||
return (EINVAL);
|
||||
bcopy(value, opt->value, len);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_setopt_part(struct vfsoptlist *opts, const char *name, void *value, int len)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
opt->seen = 1;
|
||||
if (opt->value == NULL)
|
||||
opt->len = len;
|
||||
else {
|
||||
if (opt->len < len)
|
||||
return (EINVAL);
|
||||
opt->len = len;
|
||||
bcopy(value, opt->value, len);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_setopts(struct vfsoptlist *opts, const char *name, const char *value)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
opt->seen = 1;
|
||||
if (opt->value == NULL)
|
||||
opt->len = strlen(value) + 1;
|
||||
else if (strlcpy(opt->value, value, opt->len) >= opt->len)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find and copy a mount option.
|
||||
*
|
||||
@ -1989,6 +2061,7 @@ vfs_copyopt(opts, name, dest, len)
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) == 0) {
|
||||
opt->seen = 1;
|
||||
if (len != opt->len)
|
||||
return (EINVAL);
|
||||
bcopy(opt->value, dest, opt->len);
|
||||
|
@ -127,12 +127,18 @@ struct ostatfs {
|
||||
long f_spare[2]; /* unused spare */
|
||||
};
|
||||
|
||||
#define MMAXOPTIONLEN 65536 /* maximum length of a mount option */
|
||||
|
||||
TAILQ_HEAD(vnodelst, vnode);
|
||||
|
||||
struct vfsoptlist;
|
||||
struct vfsopt;
|
||||
/* Mount options list */
|
||||
TAILQ_HEAD(vfsoptlist, vfsopt);
|
||||
struct vfsopt {
|
||||
TAILQ_ENTRY(vfsopt) link;
|
||||
char *name;
|
||||
void *value;
|
||||
int len;
|
||||
int pos;
|
||||
int seen;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure per mounted filesystem. Each mounted filesystem has an
|
||||
@ -702,12 +708,21 @@ void vfs_mount_destroy(struct mount *);
|
||||
void vfs_event_signal(fsid_t *, u_int32_t, intptr_t);
|
||||
void vfs_freeopts(struct vfsoptlist *opts);
|
||||
void vfs_deleteopt(struct vfsoptlist *opts, const char *name);
|
||||
int vfs_buildopts(struct uio *auio, struct vfsoptlist **options);
|
||||
int vfs_flagopt(struct vfsoptlist *opts, const char *name, u_int *w, u_int val);
|
||||
int vfs_getopt(struct vfsoptlist *, const char *, void **, int *);
|
||||
int vfs_getopt_pos(struct vfsoptlist *opts, const char *name);
|
||||
char *vfs_getopts(struct vfsoptlist *, const char *, int *error);
|
||||
int vfs_copyopt(struct vfsoptlist *, const char *, void *, int);
|
||||
int vfs_filteropt(struct vfsoptlist *, const char **legal);
|
||||
void vfs_opterror(struct vfsoptlist *opts, const char *fmt, ...);
|
||||
int vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...);
|
||||
int vfs_setopt(struct vfsoptlist *opts, const char *name, void *value,
|
||||
int len);
|
||||
int vfs_setopt_part(struct vfsoptlist *opts, const char *name, void *value,
|
||||
int len);
|
||||
int vfs_setopts(struct vfsoptlist *opts, const char *name,
|
||||
const char *value);
|
||||
int vfs_setpublicfs /* set publicly exported fs */
|
||||
(struct mount *, struct netexport *, struct export_args *);
|
||||
void vfs_msync(struct mount *, int);
|
||||
|
Loading…
x
Reference in New Issue
Block a user