Add more functions for handling mount arguments in VFS_MOUNT():
vfs_flagopt() for binary/boolean options. vfs_getopts() for string options vfs_filteropt() to check for unknown options. vfs_scanopt() for scanf() like processing of options. Also add function for setting the stat.f_mntfromname field.
This commit is contained in:
parent
b8d0fc9581
commit
53a05b7c3f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138467
@ -121,6 +121,18 @@ struct vnode *rootvnode;
|
||||
* to locate its physical store
|
||||
*/
|
||||
|
||||
/*
|
||||
* Global opts, taken by all filesystems
|
||||
*/
|
||||
static const char *global_opts[] = {
|
||||
"fstype",
|
||||
"fspath",
|
||||
"ro",
|
||||
"suid",
|
||||
"exec",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* The root specifiers we will try if RB_CDROM is specified.
|
||||
*/
|
||||
@ -1381,6 +1393,41 @@ DB_SHOW_COMMAND(disk, db_getdiskbyname)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------
|
||||
* Functions for querying mount options/arguments from filesystems.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check that no unknown options are given
|
||||
*/
|
||||
int
|
||||
vfs_filteropt(struct vfsoptlist *opts, const char **legal)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
const char **t, *p;
|
||||
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
p = opt->name;
|
||||
if (p[0] == 'n' && p[1] == 'o')
|
||||
p += 2;
|
||||
for(t = global_opts; *t != NULL; t++)
|
||||
if (!strcmp(*t, p))
|
||||
break;
|
||||
if (*t != NULL)
|
||||
continue;
|
||||
for(t = legal; *t != NULL; t++)
|
||||
if (!strcmp(*t, p))
|
||||
break;
|
||||
if (*t != NULL)
|
||||
continue;
|
||||
printf("mount option <%s> is unknown\n", p);
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a mount option by its name.
|
||||
*
|
||||
@ -1412,6 +1459,62 @@ vfs_getopt(opts, name, buf, len)
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
char *
|
||||
vfs_getopts(struct vfsoptlist *opts, const char *name, int *error)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
|
||||
*error = 0;
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
if (((char *)opt->value)[opt->len - 1] != '\0') {
|
||||
*error = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
return (opt->value);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_flagopt(struct vfsoptlist *opts, const char *name, u_int *w, u_int val)
|
||||
{
|
||||
struct vfsopt *opt;
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) == 0) {
|
||||
if (w != NULL)
|
||||
*w |= val;
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
if (w != NULL)
|
||||
*w &= ~val;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct vfsopt *opt;
|
||||
int ret;
|
||||
|
||||
KASSERT(opts != NULL, ("vfs_getopt: caller passed 'opts' as NULL"));
|
||||
|
||||
TAILQ_FOREACH(opt, opts, link) {
|
||||
if (strcmp(name, opt->name) != 0)
|
||||
continue;
|
||||
if (((char *)opt->value)[opt->len - 1] != '\0')
|
||||
return (0);
|
||||
va_start(ap, fmt);
|
||||
ret = vsscanf(opt->value, fmt, ap);
|
||||
va_end(ap);
|
||||
return (ret);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* Find and copy a mount option.
|
||||
*
|
||||
@ -1481,6 +1584,15 @@ __vfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
vfs_mountedfrom(struct mount *mp, const char *from)
|
||||
{
|
||||
|
||||
bzero(mp->mnt_stat.f_mntfromname, sizeof mp->mnt_stat.f_mntfromname);
|
||||
strlcpy(mp->mnt_stat.f_mntfromname, from,
|
||||
sizeof mp->mnt_stat.f_mntfromname);
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------------
|
||||
* This is the api for building mount args and mounting filesystems from
|
||||
|
@ -571,8 +571,12 @@ struct mntarg *mount_argsu(struct mntarg *ma, const char *name, const void *val,
|
||||
struct vfsconf *vfs_byname(const char *);
|
||||
struct vfsconf *vfs_byname_kld(const char *, struct thread *td, int *);
|
||||
void vfs_event_signal(fsid_t *, u_int32_t, intptr_t);
|
||||
int vfs_flagopt(struct vfsoptlist *opts, const char *name, u_int *w, u_int val);
|
||||
int vfs_getopt(struct vfsoptlist *, const char *, void **, int *);
|
||||
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);
|
||||
int vfs_scanopt(struct vfsoptlist *opts, const char *name, const char *fmt, ...);
|
||||
int vfs_setpublicfs /* set publicly exported fs */
|
||||
(struct mount *, struct netexport *, struct export_args *);
|
||||
int vfs_lock(struct mount *); /* lock a vfs */
|
||||
@ -589,6 +593,7 @@ struct cdev *vfs_getrootfsid(struct mount *);
|
||||
struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */
|
||||
int vfs_modevent(module_t, int, void *);
|
||||
void vfs_mountroot(void); /* mount our root filesystem */
|
||||
void vfs_mountedfrom(struct mount *, const char *from);
|
||||
void vfs_mount_destroy(struct mount *, struct thread *);
|
||||
int vfs_suser(struct mount *, struct thread *);
|
||||
void vfs_unbusy(struct mount *, struct thread *);
|
||||
|
Loading…
Reference in New Issue
Block a user