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:
Poul-Henning Kamp 2004-12-06 18:18:35 +00:00
parent b8d0fc9581
commit 53a05b7c3f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=138467
2 changed files with 117 additions and 0 deletions

View File

@ -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

View File

@ -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 *);