mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Add a few convenient functions in the mount_arg() family and collect the
entire family at the end of the source file.
This commit is contained in:
parent
5cb0b08e40
commit
49bfeeb848
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138448
@ -377,76 +377,6 @@ nmount(td, uap)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mntarg {
|
|
||||||
struct iovec *v;
|
|
||||||
int len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mntarg *
|
|
||||||
mount_arg(struct mntarg *ma, const char *name, const void *val, int len)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (ma == NULL)
|
|
||||||
ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
|
|
||||||
|
|
||||||
ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2),
|
|
||||||
M_MOUNT, M_WAITOK);
|
|
||||||
ma->v[ma->len].iov_base = (void *)(uintptr_t)name;
|
|
||||||
ma->v[ma->len].iov_len = strlen(name) + 1;
|
|
||||||
ma->len++;
|
|
||||||
|
|
||||||
ma->v[ma->len].iov_base = (void *)(uintptr_t)val;
|
|
||||||
if (len < 0)
|
|
||||||
ma->v[ma->len].iov_len = strlen(val) + 1;
|
|
||||||
else
|
|
||||||
ma->v[ma->len].iov_len = len;
|
|
||||||
ma->len++;
|
|
||||||
return (ma);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
kernel_mount(struct mntarg *ma, int flags)
|
|
||||||
{
|
|
||||||
struct uio auio;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
KASSERT(ma != NULL, ("kernel_mount NULL ma"));
|
|
||||||
KASSERT(ma->v != NULL, ("kernel_mount NULL ma->v"));
|
|
||||||
KASSERT(!(ma->len & 1), ("kernel_mount odd ma->len (%d)", ma->len));
|
|
||||||
|
|
||||||
auio.uio_iov = ma->v;
|
|
||||||
auio.uio_iovcnt = ma->len;
|
|
||||||
auio.uio_segflg = UIO_SYSSPACE;
|
|
||||||
|
|
||||||
error = vfs_donmount(curthread, flags, &auio);
|
|
||||||
free(ma->v, M_MOUNT);
|
|
||||||
free(ma, M_MOUNT);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
kernel_vmount(int flags, ...)
|
|
||||||
{
|
|
||||||
struct mntarg *ma = NULL;
|
|
||||||
va_list ap;
|
|
||||||
const char *cp;
|
|
||||||
const void *vp;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
va_start(ap, flags);
|
|
||||||
for (;;) {
|
|
||||||
cp = va_arg(ap, const char *);
|
|
||||||
if (cp == NULL)
|
|
||||||
break;
|
|
||||||
vp = va_arg(ap, const void *);
|
|
||||||
ma = mount_arg(ma, cp, vp, -1);
|
|
||||||
}
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
error = kernel_mount(ma, flags);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate and initialize the mount point struct.
|
* Allocate and initialize the mount point struct.
|
||||||
*/
|
*/
|
||||||
@ -1543,3 +1473,207 @@ __vfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
|
|||||||
memcpy(sbp, &mp->mnt_stat, sizeof sbp);
|
memcpy(sbp, &mp->mnt_stat, sizeof sbp);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ---------------------------------------------------------------------
|
||||||
|
* This is the api for building mount args and mounting filesystems from
|
||||||
|
* inside the kernel.
|
||||||
|
*
|
||||||
|
* The API works by accumulation of individual args. First error is
|
||||||
|
* latched.
|
||||||
|
*
|
||||||
|
* XXX: should be documented in new manpage kernel_mount(9)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* A memory allocation which must be freed when we are done */
|
||||||
|
struct mntaarg {
|
||||||
|
SLIST_ENTRY(mntaarg) next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The header for the mount arguments */
|
||||||
|
struct mntarg {
|
||||||
|
struct iovec *v;
|
||||||
|
int len;
|
||||||
|
int error;
|
||||||
|
SLIST_HEAD(, mntaarg) list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a boolean argument.
|
||||||
|
*
|
||||||
|
* flag is the boolean value.
|
||||||
|
* name must start with "no".
|
||||||
|
*/
|
||||||
|
struct mntarg *
|
||||||
|
mount_argb(struct mntarg *ma, int flag, const char *name)
|
||||||
|
{
|
||||||
|
|
||||||
|
KASSERT(name[0] == 'n' && name[1] == 'o',
|
||||||
|
("mount_argb(...,%s): name must start with 'no'", name));
|
||||||
|
|
||||||
|
return (mount_arg(ma, name + (flag ? 2 : 0), NULL, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an argument printf style
|
||||||
|
*/
|
||||||
|
struct mntarg *
|
||||||
|
mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
struct mntaarg *maa;
|
||||||
|
struct sbuf *sb;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (ma == NULL) {
|
||||||
|
ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
|
||||||
|
SLIST_INIT(&ma->list);
|
||||||
|
}
|
||||||
|
if (ma->error)
|
||||||
|
return (ma);
|
||||||
|
|
||||||
|
ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2),
|
||||||
|
M_MOUNT, M_WAITOK);
|
||||||
|
ma->v[ma->len].iov_base = (void *)(uintptr_t)name;
|
||||||
|
ma->v[ma->len].iov_len = strlen(name) + 1;
|
||||||
|
ma->len++;
|
||||||
|
|
||||||
|
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
|
||||||
|
va_start(ap, fmt);
|
||||||
|
sbuf_vprintf(sb, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
sbuf_finish(sb);
|
||||||
|
len = sbuf_len(sb) + 1;
|
||||||
|
maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO);
|
||||||
|
SLIST_INSERT_HEAD(&ma->list, maa, next);
|
||||||
|
bcopy(sbuf_data(sb), maa + 1, len);
|
||||||
|
sbuf_delete(sb);
|
||||||
|
|
||||||
|
ma->v[ma->len].iov_base = maa + 1;
|
||||||
|
ma->v[ma->len].iov_len = len;
|
||||||
|
ma->len++;
|
||||||
|
|
||||||
|
return (ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an argument which is a userland string.
|
||||||
|
*/
|
||||||
|
struct mntarg *
|
||||||
|
mount_argsu(struct mntarg *ma, const char *name, const void *val, int len)
|
||||||
|
{
|
||||||
|
struct mntaarg *maa;
|
||||||
|
char *tbuf;
|
||||||
|
|
||||||
|
if (val == NULL)
|
||||||
|
return (ma);
|
||||||
|
if (ma == NULL) {
|
||||||
|
ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
|
||||||
|
SLIST_INIT(&ma->list);
|
||||||
|
}
|
||||||
|
if (ma->error)
|
||||||
|
return (ma);
|
||||||
|
maa = malloc(sizeof *maa + len, M_MOUNT, M_WAITOK | M_ZERO);
|
||||||
|
SLIST_INSERT_HEAD(&ma->list, maa, next);
|
||||||
|
tbuf = (void *)(maa + 1);
|
||||||
|
ma->error = copyinstr(val, tbuf, len, NULL);
|
||||||
|
return (mount_arg(ma, name, tbuf, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Plain argument.
|
||||||
|
*
|
||||||
|
* If length is -1, use printf.
|
||||||
|
*/
|
||||||
|
struct mntarg *
|
||||||
|
mount_arg(struct mntarg *ma, const char *name, const void *val, int len)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ma == NULL) {
|
||||||
|
ma = malloc(sizeof *ma, M_MOUNT, M_WAITOK | M_ZERO);
|
||||||
|
SLIST_INIT(&ma->list);
|
||||||
|
}
|
||||||
|
if (ma->error)
|
||||||
|
return (ma);
|
||||||
|
|
||||||
|
ma->v = realloc(ma->v, sizeof *ma->v * (ma->len + 2),
|
||||||
|
M_MOUNT, M_WAITOK);
|
||||||
|
ma->v[ma->len].iov_base = (void *)(uintptr_t)name;
|
||||||
|
ma->v[ma->len].iov_len = strlen(name) + 1;
|
||||||
|
ma->len++;
|
||||||
|
|
||||||
|
ma->v[ma->len].iov_base = (void *)(uintptr_t)val;
|
||||||
|
if (len < 0)
|
||||||
|
ma->v[ma->len].iov_len = strlen(val) + 1;
|
||||||
|
else
|
||||||
|
ma->v[ma->len].iov_len = len;
|
||||||
|
ma->len++;
|
||||||
|
return (ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free a mntarg structure
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
free_mntarg(struct mntarg *ma)
|
||||||
|
{
|
||||||
|
struct mntaarg *maa;
|
||||||
|
|
||||||
|
while (!SLIST_EMPTY(&ma->list)) {
|
||||||
|
maa = SLIST_FIRST(&ma->list);
|
||||||
|
SLIST_REMOVE_HEAD(&ma->list, next);
|
||||||
|
free(maa, M_MOUNT);
|
||||||
|
}
|
||||||
|
free(ma->v, M_MOUNT);
|
||||||
|
free(ma, M_MOUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mount a filesystem
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
kernel_mount(struct mntarg *ma, int flags)
|
||||||
|
{
|
||||||
|
struct uio auio;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
KASSERT(ma != NULL, ("kernel_mount NULL ma"));
|
||||||
|
KASSERT(ma->v != NULL, ("kernel_mount NULL ma->v"));
|
||||||
|
KASSERT(!(ma->len & 1), ("kernel_mount odd ma->len (%d)", ma->len));
|
||||||
|
|
||||||
|
auio.uio_iov = ma->v;
|
||||||
|
auio.uio_iovcnt = ma->len;
|
||||||
|
auio.uio_segflg = UIO_SYSSPACE;
|
||||||
|
|
||||||
|
error = ma->error;
|
||||||
|
if (!error)
|
||||||
|
error = vfs_donmount(curthread, flags, &auio);
|
||||||
|
free_mntarg(ma);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A printflike function to mount a filesystem.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
kernel_vmount(int flags, ...)
|
||||||
|
{
|
||||||
|
struct mntarg *ma = NULL;
|
||||||
|
va_list ap;
|
||||||
|
const char *cp;
|
||||||
|
const void *vp;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
va_start(ap, flags);
|
||||||
|
for (;;) {
|
||||||
|
cp = va_arg(ap, const char *);
|
||||||
|
if (cp == NULL)
|
||||||
|
break;
|
||||||
|
vp = va_arg(ap, const void *);
|
||||||
|
ma = mount_arg(ma, cp, vp, -1);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
error = kernel_mount(ma, flags);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
@ -459,6 +459,7 @@ extern struct vfsconfhead vfsconf;
|
|||||||
struct mount_args;
|
struct mount_args;
|
||||||
struct nameidata;
|
struct nameidata;
|
||||||
struct sysctl_req;
|
struct sysctl_req;
|
||||||
|
struct mntarg;
|
||||||
|
|
||||||
typedef int vfs_cmount_t(char *path, void *data, int flags, struct thread *td);
|
typedef int vfs_cmount_t(char *path, void *data, int flags, struct thread *td);
|
||||||
typedef int vfs_omount_t(struct mount *mp, char *path, caddr_t data,
|
typedef int vfs_omount_t(struct mount *mp, char *path, caddr_t data,
|
||||||
@ -559,10 +560,14 @@ extern char *mountrootfsname;
|
|||||||
* exported vnode operations
|
* exported vnode operations
|
||||||
*/
|
*/
|
||||||
int dounmount(struct mount *, int, struct thread *);
|
int dounmount(struct mount *, int, struct thread *);
|
||||||
struct mntarg;
|
|
||||||
struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len);
|
void free_mntarg(struct mntarg *ma);
|
||||||
|
struct mntarg *mount_argb(struct mntarg *ma, int flag, const char *name);
|
||||||
int kernel_mount(struct mntarg *ma, int flags);
|
int kernel_mount(struct mntarg *ma, int flags);
|
||||||
int kernel_vmount(int flags, ...);
|
int kernel_vmount(int flags, ...);
|
||||||
|
struct mntarg *mount_arg(struct mntarg *ma, const char *name, const void *val, int len);
|
||||||
|
struct mntarg *mount_argf(struct mntarg *ma, const char *name, const char *fmt, ...);
|
||||||
|
struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val, int len);
|
||||||
struct vfsconf *vfs_byname(const char *);
|
struct vfsconf *vfs_byname(const char *);
|
||||||
struct vfsconf *vfs_byname_kld(const char *, struct thread *td, int *);
|
struct vfsconf *vfs_byname_kld(const char *, struct thread *td, int *);
|
||||||
void vfs_event_signal(fsid_t *, u_int32_t, intptr_t);
|
void vfs_event_signal(fsid_t *, u_int32_t, intptr_t);
|
||||||
|
Loading…
Reference in New Issue
Block a user