diff options
-rw-r--r-- | bin/df/df.c | 33 | ||||
-rw-r--r-- | lib/libc/gen/getvfsbyname.3 | 27 | ||||
-rw-r--r-- | lib/libc/gen/getvfsbyname.c | 40 | ||||
-rw-r--r-- | lib/libc/gen/getvfsent.c | 31 | ||||
-rw-r--r-- | sbin/nfsiod/Makefile | 1 | ||||
-rw-r--r-- | sbin/nfsiod/nfsiod.8 | 6 | ||||
-rw-r--r-- | sbin/nfsiod/nfsiod.c | 10 | ||||
-rw-r--r-- | sbin/umount/umount.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 74 | ||||
-rw-r--r-- | sys/sys/mount.h | 27 | ||||
-rw-r--r-- | usr.bin/find/function.c | 2 | ||||
-rw-r--r-- | usr.bin/lsvfs/Makefile | 1 | ||||
-rw-r--r-- | usr.bin/lsvfs/lsvfs.c | 28 |
13 files changed, 173 insertions, 109 deletions
diff --git a/bin/df/df.c b/bin/df/df.c index b91dc66..9bb5204 100644 --- a/bin/df/df.c +++ b/bin/df/df.c @@ -491,31 +491,40 @@ static char * makenetvfslist(void) { char *str, *strptr, **listptr; - int mib[3], maxvfsconf, cnt=0, i; - size_t miblen; - struct ovfsconf *ptr; - - mib[0] = CTL_VFS; mib[1] = VFS_GENERIC; mib[2] = VFS_MAXTYPENUM; - miblen=sizeof(maxvfsconf); - if (sysctl(mib, (unsigned int)(sizeof(mib) / sizeof(mib[0])), - &maxvfsconf, &miblen, NULL, 0)) { - warnx("sysctl failed"); + struct xvfsconf *xvfsp; + size_t buflen; + int cnt, i, maxvfsconf; + + if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) { + warn("sysctl(vfs.conflist)"); + return (NULL); + } + xvfsp = malloc(buflen); + if (xvfsp == NULL) { + warnx("malloc failed"); return (NULL); } + if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { + warn("sysctl(vfs.conflist)"); + return (NULL); + } + maxvfsconf = buflen / sizeof(struct xvfsconf); if ((listptr = malloc(sizeof(char*) * maxvfsconf)) == NULL) { warnx("malloc failed"); return (NULL); } - for (ptr = getvfsent(); ptr; ptr = getvfsent()) - if (ptr->vfc_flags & VFCF_NETWORK) { - listptr[cnt++] = strdup(ptr->vfc_name); + for (cnt = 0, i = 0; i < maxvfsconf; i++) { + if (xvfsp->vfc_flags & VFCF_NETWORK) { + listptr[cnt++] = strdup(xvfsp->vfc_name); if (listptr[cnt-1] == NULL) { warnx("malloc failed"); return (NULL); } } + xvfsp++; + } if (cnt == 0 || (str = malloc(sizeof(char) * (32 * cnt + cnt + 2))) == NULL) { diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3 index da115ec..277b964 100644 --- a/lib/libc/gen/getvfsbyname.3 +++ b/lib/libc/gen/getvfsbyname.3 @@ -44,7 +44,7 @@ .In sys/param.h .In sys/mount.h .Ft int -.Fn getvfsbyname "const char *name" "struct vfsconf *vfc" +.Fn getvfsbyname "const char *name" "struct xvfsconf *vfc" .Sh DESCRIPTION The .Fn getvfsbyname @@ -52,11 +52,11 @@ function provides access to information about a filesystem module that is configured in the kernel. If successful, the requested filesystem -.Fa vfsconf +.Fa xvfsconf is returned in the location pointed to by .Fa vfc . The fields in a -.Dq Li struct vfsconf +.Dq Li struct xvfsconf are defined as follows: .Pp .Bl -tag -compact -width vfc_refcount @@ -67,8 +67,24 @@ the filesystem type number assigned by the kernel .It vfc_refcount the number of active mount points using the filesystem .It vfc_flags -flag bits as described in -.Xr getvfsent 3 +flag bits, as described below +.El +.Pp +The flags are defined as follows: +.Pp +.Bl -tag -width VFCF_SYNTHETIC -compact +.It Dv VFCF_STATIC +statically compiled into kernel +.It Dv VFCF_NETWORK +may get data over the network +.It Dv VFCF_READONLY +writes are not implemented +.It Dv VFCF_SYNTHETIC +data does not represent real files +.It Dv VFCF_LOOPBACK +aliases some other mounted FS +.It Dv VFCF_UNICODE +stores file names as Unicode .El .Sh RETURN VALUES .Rv -std getvfsbyname @@ -86,7 +102,6 @@ specifies a filesystem that is unknown or not configured in the kernel. .El .Sh SEE ALSO .Xr mount 2 , -.Xr getvfsent 3 , .Xr sysctl 3 , .Xr mount 8 , .Xr sysctl 8 diff --git a/lib/libc/gen/getvfsbyname.c b/lib/libc/gen/getvfsbyname.c index eb6f26f..3ab03f4 100644 --- a/lib/libc/gen/getvfsbyname.c +++ b/lib/libc/gen/getvfsbyname.c @@ -41,39 +41,43 @@ __FBSDID("$FreeBSD$"); #include <sys/mount.h> #include <sys/sysctl.h> #include <errno.h> +#include <stdlib.h> +#include <string.h> /* * Given a filesystem name, determine if it is resident in the kernel, - * and if it is resident, return its vfsconf structure. + * and if it is resident, return its xvfsconf structure. */ +int getvfsbyname(fsname, vfcp) const char *fsname; - struct vfsconf *vfcp; + struct xvfsconf *vfcp; { #ifdef __NETBSD_SYSCALLS errno = ENOSYS; #else - int name[4], maxtypenum, cnt; + struct xvfsconf *xvfsp; size_t buflen; + int cnt, i; - name[0] = CTL_VFS; - name[1] = VFS_GENERIC; - name[2] = VFS_MAXTYPENUM; - buflen = 4; - if (sysctl(name, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0) + if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) return (-1); - name[2] = VFS_CONF; - buflen = sizeof *vfcp; - for (cnt = 0; cnt < maxtypenum; cnt++) { - name[3] = cnt; - if (sysctl(name, 4, vfcp, &buflen, (void *)0, (size_t)0) < 0) { - if (errno != EOPNOTSUPP) - return (-1); - continue; - } - if (!strcmp(fsname, vfcp->vfc_name)) + xvfsp = malloc(buflen); + if (xvfsp == NULL) + return (-1); + if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) { + free(xvfsp); + return (-1); + } + cnt = buflen / sizeof(struct xvfsconf); + for (i = 0; i < cnt; i++) { + if (strcmp(fsname, xvfsp[i].vfc_name) == 0) { + memcpy(vfcp, xvfsp + i, sizeof(struct xvfsconf)); + free(xvfsp); return (0); + } } + free(xvfsp); errno = ENOENT; #endif return (-1); diff --git a/lib/libc/gen/getvfsent.c b/lib/libc/gen/getvfsent.c index 140664b..3ca3eac 100644 --- a/lib/libc/gen/getvfsent.c +++ b/lib/libc/gen/getvfsent.c @@ -21,7 +21,6 @@ __FBSDID("$FreeBSD$"); #include <paths.h> /* XXX hide some compatibility problems. */ -#undef getvfsbyname #define vfsconf ovfsconf static struct vfsconf *_vfslist = 0; @@ -81,36 +80,6 @@ getvfsent(void) } struct vfsconf * -getvfsbyname(const char *name) -{ - int i; - - if(!_vfslist && !initvfs()) { - return 0; - } - - for(i = 0; i < _vfslistlen; i++) { - if( ! strcmp(_vfslist[i].vfc_name, name) ) - break; - } - - if(i < _vfslistlen) { - _vfsconf = _vfslist[i]; - } - - if(!_vfs_keeplist) { - free(_vfslist); - _vfslist = 0; - } - - if(i < _vfslistlen) { - return &_vfsconf; - } else { - return 0; - } -} - -struct vfsconf * getvfsbytype(int type) { int i; diff --git a/sbin/nfsiod/Makefile b/sbin/nfsiod/Makefile index 47cd290..22717c5 100644 --- a/sbin/nfsiod/Makefile +++ b/sbin/nfsiod/Makefile @@ -2,6 +2,7 @@ # $FreeBSD$ PROG= nfsiod +WARNS?= 6 MAN= nfsiod.8 .include <bsd.prog.mk> diff --git a/sbin/nfsiod/nfsiod.8 b/sbin/nfsiod/nfsiod.8 index 281c675..9131f41 100644 --- a/sbin/nfsiod/nfsiod.8 +++ b/sbin/nfsiod/nfsiod.8 @@ -69,9 +69,7 @@ detects that the running kernel does not include support, it will attempt to load a loadable kernel module containing .Tn NFS code, using -.Xr kldload 8 -by way of -.Xr vfsload 3 . +.Xr kldload 2 . If this fails, or no .Tn NFS KLD was available, @@ -81,8 +79,8 @@ exits with an error. .Ex -std .Sh SEE ALSO .Xr nfsstat 1 , +.Xr kldload 2 , .Xr nfssvc 2 , -.Xr kldload 8 , .Xr mountd 8 , .Xr nfsd 8 , .Xr rpcbind 8 diff --git a/sbin/nfsiod/nfsiod.c b/sbin/nfsiod/nfsiod.c index 547e238..15e5f76 100644 --- a/sbin/nfsiod/nfsiod.c +++ b/sbin/nfsiod/nfsiod.c @@ -51,6 +51,7 @@ static const char rcsid[] = #include <sys/param.h> #include <sys/syslog.h> #include <sys/wait.h> +#include <sys/linker.h> #include <sys/mount.h> #include <sys/time.h> #include <sys/sysctl.h> @@ -73,16 +74,15 @@ int main(int argc, char *argv[]) { int ch; - struct vfsconf vfc; + struct xvfsconf vfc; int error; unsigned int iodmin, iodmax, num_servers; size_t len; error = getvfsbyname("nfs", &vfc); - if (error && vfsisloadable("nfs")) { - if (vfsload("nfs")) - err(1, "vfsload(nfs)"); - endvfsent(); /* flush cache */ + if (error) { + if (kldload("nfs")) + err(1, "kldload(nfs)"); error = getvfsbyname("nfs", &vfc); } if (error) diff --git a/sbin/umount/umount.c b/sbin/umount/umount.c index cd1a6c6..0406d28 100644 --- a/sbin/umount/umount.c +++ b/sbin/umount/umount.c @@ -200,7 +200,7 @@ main(int argc, char *argv[]) int umountall(char **typelist) { - struct vfsconf vfc; + struct xvfsconf vfc; struct fstab *fs; int rval; char *cp; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index bf71d04..095716f 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2630,6 +2630,56 @@ DB_SHOW_COMMAND(lockedvnods, lockedvnodes) #endif /* + * Fill in a struct xvfsconf based on a struct vfsconf. + */ +static void +vfsconf2x(struct vfsconf *vfsp, struct xvfsconf *xvfsp) +{ + + strcpy(xvfsp->vfc_name, vfsp->vfc_name); + xvfsp->vfc_typenum = vfsp->vfc_typenum; + xvfsp->vfc_refcount = vfsp->vfc_refcount; + xvfsp->vfc_flags = vfsp->vfc_flags; + /* + * These are unused in userland, we keep them + * to not break binary compatibility. + */ + xvfsp->vfc_vfsops = NULL; + xvfsp->vfc_next = NULL; +} + +static int +sysctl_vfs_conflist(SYSCTL_HANDLER_ARGS) +{ + struct vfsconf *vfsp; + struct xvfsconf *xvfsp; + int cnt, error, i; + + cnt = 0; + for (vfsp = vfsconf; vfsp != NULL; vfsp = vfsp->vfc_next) + cnt++; + xvfsp = malloc(sizeof(struct xvfsconf) * cnt, M_TEMP, M_WAITOK); + /* + * Handle the race that we will have here when struct vfsconf + * will be locked down by using both cnt and checking vfc_next + * against NULL to determine the end of the loop. The race will + * happen because we will have to unlock before calling malloc(). + * We are protected by Giant for now. + */ + i = 0; + for (vfsp = vfsconf; vfsp != NULL && i < cnt; vfsp = vfsp->vfc_next) { + vfsconf2x(vfsp, xvfsp + i); + i++; + } + error = SYSCTL_OUT(req, xvfsp, sizeof(struct xvfsconf) * i); + free(xvfsp, M_TEMP); + return (error); +} + +SYSCTL_PROC(_vfs, OID_AUTO, conflist, CTLFLAG_RD, NULL, 0, sysctl_vfs_conflist, + "S,xvfsconf", "List of all configured filesystems"); + +/* * Top level filesystem related information gathering. */ static int sysctl_ovfs_conf(SYSCTL_HANDLER_ARGS); @@ -2640,6 +2690,10 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS) int *name = (int *)arg1 - 1; /* XXX */ u_int namelen = arg2 + 1; /* XXX */ struct vfsconf *vfsp; + struct xvfsconf xvfsp; + + printf("WARNING: userland calling deprecated sysctl, " + "please rebuild world\n"); #if 1 || defined(COMPAT_PRELITE2) /* Resolve ambiguity between VFS_VFSCONF and VFS_GENERIC. */ @@ -2647,21 +2701,6 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS) return (sysctl_ovfs_conf(oidp, arg1, arg2, req)); #endif - /* XXX the below code does not compile; vfs_sysctl does not exist. */ -#ifdef notyet - /* all sysctl names at this level are at least name and field */ - if (namelen < 2) - return (ENOTDIR); /* overloaded */ - if (name[0] != VFS_GENERIC) { - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (vfsp->vfc_typenum == name[0]) - break; - if (vfsp == NULL) - return (EOPNOTSUPP); - return ((*vfsp->vfc_vfsops->vfs_sysctl)(&name[1], namelen - 1, - oldp, oldlenp, newp, newlen, td)); - } -#endif switch (name[1]) { case VFS_MAXTYPENUM: if (namelen != 2) @@ -2675,12 +2714,13 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS) break; if (vfsp == NULL) return (EOPNOTSUPP); - return (SYSCTL_OUT(req, vfsp, sizeof *vfsp)); + vfsconf2x(vfsp, &xvfsp); + return (SYSCTL_OUT(req, &xvfsp, sizeof(xvfsp))); } return (EOPNOTSUPP); } -SYSCTL_NODE(_vfs, VFS_GENERIC, generic, CTLFLAG_RD, vfs_sysctl, +SYSCTL_NODE(_vfs, VFS_GENERIC, generic, CTLFLAG_RD | CTLFLAG_SKIP, vfs_sysctl, "Generic filesystem"); #if 1 || defined(COMPAT_PRELITE2) diff --git a/sys/sys/mount.h b/sys/sys/mount.h index ba1b071..1909a4d 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -319,12 +319,35 @@ struct nfs_public { * type of filesystem supported by the kernel. These are searched at * mount time to identify the requested filesystem. */ +#ifdef _KERNEL struct vfsconf { struct vfsops *vfc_vfsops; /* filesystem operations vector */ char vfc_name[MFSNAMELEN]; /* filesystem type name */ int vfc_typenum; /* historic filesystem type number */ int vfc_refcount; /* number mounted of this type */ int vfc_flags; /* permanent flags */ + struct vfsoptdecl *vfc_opts; /* mount options */ + struct vfsconf *vfc_next; /* next in list */ +}; +#endif /* _KERNEL */ + +/* Userland version of the struct vfsconf. */ +struct xvfsconf { + struct vfsops *vfc_vfsops; /* filesystem operations vector */ + char vfc_name[MFSNAMELEN]; /* filesystem type name */ + int vfc_typenum; /* historic filesystem type number */ + int vfc_refcount; /* number mounted of this type */ + int vfc_flags; /* permanent flags */ + struct vfsconf *vfc_next; /* next in list */ +}; + +/* Userland version of the struct vfsconf. */ +struct xvfsconf { + struct vfsops *vfc_vfsops; /* filesystem operations vector */ + char vfc_name[MFSNAMELEN]; /* filesystem type name */ + int vfc_typenum; /* historic filesystem type number */ + int vfc_refcount; /* number mounted of this type */ + int vfc_flags; /* permanent flags */ struct vfsconf *vfc_next; /* next in list */ }; @@ -516,11 +539,9 @@ int unmount(const char *, int); /* C library stuff */ void endvfsent(void); -struct ovfsconf *getvfsbyname(const char *); struct ovfsconf *getvfsbytype(int); struct ovfsconf *getvfsent(void); -#define getvfsbyname new_getvfsbyname -int new_getvfsbyname(const char *, struct vfsconf *); +int getvfsbyname(const char *, struct xvfsconf *); void setvfsent(int); int vfsisloadable(const char *); int vfsload(const char *); diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index 66f92b1..31e1a65 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -834,7 +834,7 @@ c_fstype(option, argvp) { char *fsname; PLAN *new; - struct vfsconf vfc; + struct xvfsconf vfc; fsname = nextarg(option, argvp); ftsoptions &= ~FTS_NOSTAT; diff --git a/usr.bin/lsvfs/Makefile b/usr.bin/lsvfs/Makefile index 324b6fd..0c33583 100644 --- a/usr.bin/lsvfs/Makefile +++ b/usr.bin/lsvfs/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ PROG= lsvfs +WARNS?= 6 .include <bsd.prog.mk> diff --git a/usr.bin/lsvfs/lsvfs.c b/usr.bin/lsvfs/lsvfs.c index 909636e..6ea7f1f 100644 --- a/usr.bin/lsvfs/lsvfs.c +++ b/usr.bin/lsvfs/lsvfs.c @@ -8,13 +8,12 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#define _NEW_VFSCONF - #include <sys/param.h> #include <sys/mount.h> #include <err.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #define FMT "%-32.32s %5d %s\n" @@ -26,13 +25,11 @@ static const char *fmt_flags(int); int main(int argc, char **argv) { - int rv = 0; - struct vfsconf vfc; - struct ovfsconf *ovfcp; + int cnt, rv = 0, i; + struct xvfsconf vfc, *xvfsp; + size_t buflen; argc--, argv++; - setvfsent(1); - printf(HDRFMT, "Filesystem", "Refs", "Flags"); fputs(DASHES, stdout); @@ -46,13 +43,22 @@ main(int argc, char **argv) } } } else { - while ((ovfcp = getvfsent()) != NULL) { - printf(FMT, ovfcp->vfc_name, ovfcp->vfc_refcount, - fmt_flags(ovfcp->vfc_flags)); + if (sysctlbyname("vfs.conflist", NULL, &buflen, NULL, 0) < 0) + err(1, "sysctl(vfs.conflist)"); + xvfsp = malloc(buflen); + if (xvfsp == NULL) + errx(1, "malloc failed"); + if (sysctlbyname("vfs.conflist", xvfsp, &buflen, NULL, 0) < 0) + err(1, "sysctl(vfs.conflist)"); + cnt = buflen / sizeof(struct xvfsconf); + + for (i = 0; i < cnt; i++) { + printf(FMT, xvfsp[i].vfc_name, xvfsp[i].vfc_refcount, + fmt_flags(xvfsp[i].vfc_flags)); } + free(xvfsp); } - endvfsent(); return rv; } |