diff options
author | phk <phk@FreeBSD.org> | 2004-07-27 22:32:01 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2004-07-27 22:32:01 +0000 |
commit | 8c9258b82e736184b4a7b3976b0ed47bc9fc245f (patch) | |
tree | 44f3ea5ab43e552a2396033056fa1b93e9c9c1b8 | |
parent | c8b0bad675274967afe2c519d05720601a6df0ad (diff) | |
download | FreeBSD-src-8c9258b82e736184b4a7b3976b0ed47bc9fc245f.zip FreeBSD-src-8c9258b82e736184b4a7b3976b0ed47bc9fc245f.tar.gz |
Convert the vfsconf list to a TAILQ.
Introduce vfs_byname() function to find things on it.
Staticize vfs_nmount() function under the name vfs_donmount().
Various cleanups.
-rw-r--r-- | sys/kern/vfs_init.c | 44 | ||||
-rw-r--r-- | sys/kern/vfs_mount.c | 156 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 31 | ||||
-rw-r--r-- | sys/libkern/iconv.c | 11 | ||||
-rw-r--r-- | sys/sys/mount.h | 19 |
5 files changed, 114 insertions, 147 deletions
diff --git a/sys/kern/vfs_init.c b/sys/kern/vfs_init.c index 9597519..999764a 100644 --- a/sys/kern/vfs_init.c +++ b/sys/kern/vfs_init.c @@ -57,7 +57,7 @@ int maxvfsconf = VFS_GENERIC + 1; * Single-linked list of configured VFSes. * New entries are added/deleted by vfs_register()/vfs_unregister() */ -struct vfsconf *vfsconf; +struct vfsconfhead vfsconf = TAILQ_HEAD_INITIALIZER(vfsconf); /* * vfs_init.c @@ -349,6 +349,17 @@ vfs_rm_vnodeops(const void *data) */ struct vattr va_null; +struct vfsconf * +vfs_byname(const char *name) +{ + struct vfsconf *vfsp; + + TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) + if (!strcmp(name, vfsp->vfc_name)) + return (vfsp); + return (NULL); +} + /* * Initialize the vnode structures and initialize each filesystem type. */ @@ -366,22 +377,13 @@ int vfs_register(struct vfsconf *vfc) { struct sysctl_oid *oidp; - struct vfsconf *vfsp; - struct vfsops *vfsops; - vfsp = NULL; - if (vfsconf) - for (vfsp = vfsconf; vfsp->vfc_next; vfsp = vfsp->vfc_next) - if (strcmp(vfc->vfc_name, vfsp->vfc_name) == 0) - return EEXIST; + if (vfs_byname(vfc->vfc_name) != NULL) + return EEXIST; vfc->vfc_typenum = maxvfsconf++; - if (vfsp) - vfsp->vfc_next = vfc; - else - vfsconf = vfc; - vfc->vfc_next = NULL; + TAILQ_INSERT_TAIL(&vfsconf, vfc, vfc_list); /* * If this filesystem has a sysctl node under vfs @@ -474,17 +476,12 @@ vfs_register(struct vfsconf *vfc) int vfs_unregister(struct vfsconf *vfc) { - struct vfsconf *vfsp, *prev_vfsp; + struct vfsconf *vfsp; int error, i, maxtypenum; i = vfc->vfc_typenum; - prev_vfsp = NULL; - for (vfsp = vfsconf; vfsp; - prev_vfsp = vfsp, vfsp = vfsp->vfc_next) { - if (!strcmp(vfc->vfc_name, vfsp->vfc_name)) - break; - } + vfsp = vfs_byname(vfc->vfc_name); if (vfsp == NULL) return EINVAL; if (vfsp->vfc_refcount) @@ -494,12 +491,9 @@ vfs_unregister(struct vfsconf *vfc) if (error) return (error); } - if (prev_vfsp) - prev_vfsp->vfc_next = vfsp->vfc_next; - else - vfsconf = vfsp->vfc_next; + TAILQ_REMOVE(&vfsconf, vfsp, vfc_list); maxtypenum = VFS_GENERIC; - for (vfsp = vfsconf; vfsp != NULL; vfsp = vfsp->vfc_next) + TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) if (maxtypenum < vfsp->vfc_typenum) maxtypenum = vfsp->vfc_typenum; maxvfsconf = maxtypenum + 1; diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index cf7b7c1..5694fa5 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -105,6 +105,8 @@ static int vfs_mount_alloc(struct vnode *dvp, struct vfsconf *vfsp, const char *fspath, struct thread *td, struct mount **mpp); static int vfs_mountroot_ask(void); static int vfs_mountroot_try(char *mountfrom); +static int vfs_donmount(struct thread *td, int fsflags, + struct uio *fsoptions); static int usermount = 0; SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, @@ -400,16 +402,13 @@ nmount(td, uap) } iov++; } - error = vfs_nmount(td, uap->flags, auio); + error = vfs_donmount(td, uap->flags, auio); free(auio, M_IOV); return (error); } int -kernel_mount(iovp, iovcnt, flags) - struct iovec *iovp; - unsigned int iovcnt; - int flags; +kernel_mount(struct iovec *iovp, u_int iovcnt, int flags) { struct uio auio; int error; @@ -425,7 +424,7 @@ kernel_mount(iovp, iovcnt, flags) auio.uio_iovcnt = iovcnt; auio.uio_segflg = UIO_SYSSPACE; - error = vfs_nmount(curthread, flags, &auio); + error = vfs_donmount(curthread, flags, &auio); return (error); } @@ -435,7 +434,7 @@ kernel_vmount(int flags, ...) struct iovec *iovp; struct uio auio; va_list ap; - unsigned int iovcnt, iovlen, len; + u_int iovcnt, iovlen, len; const char *cp; char *buf, *pos; size_t n; @@ -468,7 +467,7 @@ kernel_vmount(int flags, ...) auio.uio_iovcnt = iovcnt; auio.uio_segflg = UIO_SYSSPACE; - error = vfs_nmount(curthread, flags, &auio); + error = vfs_donmount(curthread, flags, &auio); FREE(iovp, M_MOUNT); FREE(buf, M_MOUNT); return (error); @@ -532,8 +531,8 @@ vfs_mount_destroy(struct mount *mp, struct thread *td) free(mp, M_MOUNT); } -int -vfs_nmount(struct thread *td, int fsflags, struct uio *fsoptions) +static int +vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) { struct vfsoptlist *optlist; char *fstype, *fspath; @@ -746,88 +745,83 @@ vfs_domount( mp->mnt_optnew = fsdata; vfs_mergeopts(mp->mnt_optnew, mp->mnt_opt); } - goto update; - } - /* - * If the user is not root, ensure that they own the directory - * onto which we are attempting to mount. - */ - error = VOP_GETATTR(vp, &va, td->td_ucred, td); - if (error) { - vput(vp); - return (error); - } - if (va.va_uid != td->td_ucred->cr_uid) { - if ((error = suser(td)) != 0) { + } else { + /* + * If the user is not root, ensure that they own the directory + * onto which we are attempting to mount. + */ + error = VOP_GETATTR(vp, &va, td->td_ucred, td); + if (error) { vput(vp); return (error); } - } - if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) { - vput(vp); - return (error); - } - if (vp->v_type != VDIR) { - vput(vp); - return (ENOTDIR); - } - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (strcmp(vfsp->vfc_name, fstype) == 0) - break; - if (vfsp == NULL) { - /* Only load modules for root (very important!). */ - if ((error = suser(td)) != 0) { - vput(vp); - return (error); + if (va.va_uid != td->td_ucred->cr_uid) { + if ((error = suser(td)) != 0) { + vput(vp); + return (error); + } } - error = securelevel_gt(td->td_ucred, 0); - if (error) { + if ((error = vinvalbuf(vp, V_SAVE, td->td_ucred, td, 0, 0)) != 0) { vput(vp); return (error); } - error = linker_load_module(NULL, fstype, NULL, NULL, &lf); - if (error || lf == NULL) { + if (vp->v_type != VDIR) { vput(vp); - if (lf == NULL) - error = ENODEV; - return (error); + return (ENOTDIR); } - lf->userrefs++; - /* Look up again to see if the VFS was loaded. */ - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (strcmp(vfsp->vfc_name, fstype) == 0) - break; + vfsp = vfs_byname(fstype); if (vfsp == NULL) { - lf->userrefs--; - linker_file_unload(lf, LINKER_UNLOAD_FORCE); + /* Only load modules for root (very important!). */ + if ((error = suser(td)) != 0) { + vput(vp); + return (error); + } + error = securelevel_gt(td->td_ucred, 0); + if (error) { + vput(vp); + return (error); + } + error = linker_load_module(NULL, fstype, NULL, NULL, &lf); + if (error || lf == NULL) { + vput(vp); + if (lf == NULL) + error = ENODEV; + return (error); + } + lf->userrefs++; + /* Look up again to see if the VFS was loaded. */ + vfsp = vfs_byname(fstype); + if (vfsp == NULL) { + lf->userrefs--; + linker_file_unload(lf, LINKER_UNLOAD_FORCE); + vput(vp); + return (ENODEV); + } + } + VI_LOCK(vp); + if ((vp->v_iflag & VI_MOUNT) != 0 || + vp->v_mountedhere != NULL) { + VI_UNLOCK(vp); vput(vp); - return (ENODEV); + return (EBUSY); } - } - VI_LOCK(vp); - if ((vp->v_iflag & VI_MOUNT) != 0 || - vp->v_mountedhere != NULL) { + vp->v_iflag |= VI_MOUNT; VI_UNLOCK(vp); - vput(vp); - return (EBUSY); - } - vp->v_iflag |= VI_MOUNT; - VI_UNLOCK(vp); - /* - * Allocate and initialize the filesystem. - */ - error = vfs_mount_alloc(vp, vfsp, fspath, td, &mp); - if (error) { - vput(vp); - return (error); - } - VOP_UNLOCK(vp, 0, td); + /* + * Allocate and initialize the filesystem. + */ + error = vfs_mount_alloc(vp, vfsp, fspath, td, &mp); + if (error) { + vput(vp); + return (error); + } + VOP_UNLOCK(vp, 0, td); - /* XXXMAC: pass to vfs_mount_alloc? */ - if (compat == 0) - mp->mnt_optnew = fsdata; -update: + /* XXXMAC: pass to vfs_mount_alloc? */ + if (compat == 0) + mp->mnt_optnew = fsdata; + } /* * Check if the fs implements the type VFS_[N]MOUNT() * function we are looking for. @@ -1182,9 +1176,7 @@ vfs_rootmountalloc(fstypename, devname, mpp) if (fstypename == NULL) return (ENODEV); - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (!strcmp(vfsp->vfc_name, fstypename)) - break; + vfsp = vfs_byname(fstypename); if (vfsp == NULL) return (ENODEV); error = vfs_mount_alloc(NULLVP, vfsp, "/", td, &mp); @@ -1450,10 +1442,8 @@ getdiskbyname(char *name) if (!bcmp(cp, "/dev/", 5)) cp += 5; - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) - if (!strcmp(vfsp->vfc_name, "devfs")) - break; do { + vfsp = vfs_byname("devfs"); if (vfsp == NULL) break; error = vfs_mount_alloc(NULLVP, vfsp, "/dev", td, &mp); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 846ae76..c89c9ea 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2882,27 +2882,16 @@ static int sysctl_vfs_conflist(SYSCTL_HANDLER_ARGS) { struct vfsconf *vfsp; - struct xvfsconf *xvfsp; - int cnt, error, i; + struct xvfsconf xvfsp; + int error; - 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 = 0; + TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) { + vfsconf2x(vfsp, &xvfsp); + error = SYSCTL_OUT(req, &xvfsp, sizeof xvfsp); + if (error) + break; } - error = SYSCTL_OUT(req, xvfsp, sizeof(struct xvfsconf) * i); - free(xvfsp, M_TEMP); return (error); } @@ -2937,7 +2926,7 @@ vfs_sysctl(SYSCTL_HANDLER_ARGS) case VFS_CONF: if (namelen != 3) return (ENOTDIR); /* overloaded */ - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) + TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) if (vfsp->vfc_typenum == name[2]) break; if (vfsp == NULL) @@ -2960,7 +2949,7 @@ sysctl_ovfs_conf(SYSCTL_HANDLER_ARGS) struct vfsconf *vfsp; struct ovfsconf ovfs; - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) { + TAILQ_FOREACH(vfsp, &vfsconf, vfc_list) { ovfs.vfc_vfsops = vfsp->vfc_vfsops; /* XXX used as flag */ strcpy(ovfs.vfc_name, vfsp->vfc_name); ovfs.vfc_index = vfsp->vfc_typenum; diff --git a/sys/libkern/iconv.c b/sys/libkern/iconv.c index 462a2cf..cfdc28a 100644 --- a/sys/libkern/iconv.c +++ b/sys/libkern/iconv.c @@ -518,13 +518,8 @@ iconv_vfs_refcount(const char *fsname) { struct vfsconf *vfsp; - for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) { - if (!strcmp(vfsp->vfc_name, fsname)) { - if (vfsp->vfc_refcount > 0) - return (EBUSY); - else - return (0); - } - } + vfsp = vfs_byname(fsname); + if (vfsp != NULL && vfsp->vfc_refcount > 0) + return (EBUSY); return (0); } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index a9b7081..fc66ae3 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -346,7 +346,7 @@ struct vfsconf { 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 */ + TAILQ_ENTRY(vfsconf) vfc_list; /* list of vfscons */ }; /* Userland version of the struct vfsconf. */ @@ -451,7 +451,9 @@ MALLOC_DECLARE(M_MOUNT); #endif extern int maxvfsconf; /* highest defined filesystem type */ extern int nfs_mount_type; /* vfc_typenum for nfs, or -1 */ -extern struct vfsconf *vfsconf; /* head of list of filesystem types */ + +TAILQ_HEAD(vfsconfhead, vfsconf); +extern struct vfsconfhead vfsconf; /* * Operations supported on mounted filesystem. @@ -532,13 +534,10 @@ struct vfsops { #define VFS_SET(vfsops, fsname, flags) \ static struct vfsconf fsname ## _vfsconf = { \ - &vfsops, \ - #fsname, \ - -1, \ - 0, \ - flags, \ - NULL, \ - NULL \ + .vfc_vfsops = &vfsops, \ + .vfc_name = #fsname, \ + .vfc_typenum = -1, \ + .vfc_flags = flags, \ }; \ static moduledata_t fsname ## _mod = { \ #fsname, \ @@ -555,11 +554,11 @@ extern char *mountrootfsname; int dounmount(struct mount *, int, struct thread *); int kernel_mount(struct iovec *, u_int, int); int kernel_vmount(int flags, ...); +struct vfsconf *vfs_byname(const char *); void vfs_event_signal(fsid_t *, u_int32_t, intptr_t); int vfs_getopt(struct vfsoptlist *, const char *, void **, int *); int vfs_copyopt(struct vfsoptlist *, const char *, void *, int); int vfs_mount(struct thread *, const char *, char *, int, void *); -int vfs_nmount(struct thread *, int, struct uio *); int vfs_setpublicfs /* set publicly exported fs */ (struct mount *, struct netexport *, struct export_args *); int vfs_lock(struct mount *); /* lock a vfs */ |