diff options
author | peter <peter@FreeBSD.org> | 1998-11-03 08:01:48 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1998-11-03 08:01:48 +0000 |
commit | 7819a9450ea8a3c51cd84b12f32ee698bca2da34 (patch) | |
tree | 8dd795b23499327af179132647fef4d1e83944fd /sys | |
parent | da2bac6a4930ddeb7bbc0c9c2135009d3a9590eb (diff) | |
download | FreeBSD-src-7819a9450ea8a3c51cd84b12f32ee698bca2da34.zip FreeBSD-src-7819a9450ea8a3c51cd84b12f32ee698bca2da34.tar.gz |
Change the #ifdef UNION code into a callable hook. Arrange to have this
set up when unionfs is present, either statically or as a kld module.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/fs/unionfs/union.h | 5 | ||||
-rw-r--r-- | sys/fs/unionfs/union_subr.c | 80 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 129 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 129 | ||||
-rw-r--r-- | sys/miscfs/union/union.h | 5 | ||||
-rw-r--r-- | sys/miscfs/union/union_subr.c | 80 |
6 files changed, 196 insertions, 232 deletions
diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h index 4deb6d4..6a4aa22 100644 --- a/sys/fs/unionfs/union.h +++ b/sys/fs/unionfs/union.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)union.h 8.9 (Berkeley) 12/10/94 - * $Id: union.h,v 1.11 1998/02/10 03:32:03 kato Exp $ + * $Id: union.h,v 1.12 1998/02/26 03:23:51 kato Exp $ */ struct union_args { @@ -114,6 +114,9 @@ extern void union_removed_upper __P((struct union_node *un)); extern struct vnode *union_lowervp __P((struct vnode *)); extern void union_newsize __P((struct vnode *, off_t, off_t)); +extern int (*union_dircheckp) __P((struct proc *, struct vnode **, + struct file *)); + #define MOUNTTOUNIONMOUNT(mp) ((struct union_mount *)((mp)->mnt_data)) #define VTOUNION(vp) ((struct union_node *)(vp)->v_data) #define UNIONTOV(un) ((un)->un_vnode) diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index c54d86b..96df62d 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/union_subr.c @@ -35,16 +35,19 @@ * SUCH DAMAGE. * * @(#)union_subr.c 8.20 (Berkeley) 5/20/95 - * $Id: union_subr.c,v 1.30 1998/05/07 04:58:36 msmith Exp $ + * $Id: union_subr.c,v 1.31 1998/07/15 04:17:44 bde Exp $ */ #include <sys/param.h> #include <sys/systm.h> +#include <sys/kernel.h> #include <sys/vnode.h> #include <sys/namei.h> #include <sys/malloc.h> #include <sys/fcntl.h> +#include <sys/file.h> #include <sys/filedesc.h> +#include <sys/module.h> #include <sys/mount.h> #include <sys/stat.h> #include <vm/vm.h> @@ -1138,3 +1141,78 @@ out: VOP_UNLOCK(vp, 0, p); return (nvp); } + +/* + * Module glue to remove #ifdef UNION from vfs_syscalls.c + */ +static int +union_dircheck(struct proc *p, struct vnode **vp, struct file *fp) +{ + int error = 0; + + if ((*vp)->v_op == union_vnodeop_p) { + struct vnode *lvp; + + lvp = union_dircache(*vp, p); + if (lvp != NULLVP) { + struct vattr va; + + /* + * If the directory is opaque, + * then don't show lower entries + */ + error = VOP_GETATTR(*vp, &va, fp->f_cred, p); + if (va.va_flags & OPAQUE) { + vput(lvp); + lvp = NULL; + } + } + + if (lvp != NULLVP) { + error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); + if (error) { + vput(lvp); + return (error); + } + VOP_UNLOCK(lvp, 0, p); + fp->f_data = (caddr_t) lvp; + fp->f_offset = 0; + error = vn_close(*vp, FREAD, fp->f_cred, p); + if (error) + return (error); + *vp = lvp; + return -1; /* goto unionread */ + } + } + if (((*vp)->v_flag & VROOT) && ((*vp)->v_mount->mnt_flag & MNT_UNION)) { + struct vnode *tvp = *vp; + *vp = (*vp)->v_mount->mnt_vnodecovered; + VREF(*vp); + fp->f_data = (caddr_t) *vp; + fp->f_offset = 0; + vrele(tvp); + return -1; /* goto unionread */ + } + return error; +} + +static int union_modevent(module_t mod, modeventtype_t type, void *data) +{ + switch (type) { + case MOD_LOAD: + union_dircheckp = union_dircheck; + break; + case MOD_UNLOAD: + union_dircheckp = NULL; + break; + default: + break; + } + return 0; +} +static moduledata_t union_mod = { + "union_dircheck", + union_modevent, + NULL +}; +DECLARE_MODULE(union_dircheck, union_mod, SI_SUB_VFS, SI_ORDER_ANY); diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 4cf124f..43f7856 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -36,21 +36,12 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.107 1998/09/24 15:02:46 luoqi Exp $ + * $Id: vfs_syscalls.c,v 1.108 1998/10/31 07:42:04 peter Exp $ */ /* For 4.3 integer FS ID compatibility */ #include "opt_compat.h" -/* - * XXX - The following is required because of some magic done - * in getdirentries() below which is only done if the translucent - * filesystem `UNION' is compiled into the kernel. This is broken, - * but I don't have time to study the code deeply enough to understand - * what's going on and determine an appropriate fix. -GAW - */ -#include "opt_union.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/sysent.h> @@ -68,9 +59,7 @@ #include <sys/proc.h> #include <sys/dirent.h> -#ifdef UNION #include <miscfs/union/union.h> -#endif #include <vm/vm.h> #include <vm/vm_object.h> @@ -86,6 +75,8 @@ static int setfflags __P((struct proc *, struct vnode *, int)); static int setutimes __P((struct proc *, struct vnode *, struct timeval *, int)); static int usermount = 0; /* if 1, non-root can mount fs. */ +int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *)); + SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); /* @@ -2653,7 +2644,7 @@ ogetdirentries(p, uap) syscallarg(long *) basep; } */ *uap; { - register struct vnode *vp; + struct vnode *vp; struct file *fp; struct uio auio, kuio; struct iovec aiov, kiov; @@ -2734,57 +2725,12 @@ unionread: VOP_UNLOCK(vp, 0, p); if (error) return (error); - -#ifdef UNION -{ - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_op == union_vnodeop_p)) { - struct vnode *lvp; - - lvp = union_dircache(vp, p); - if (lvp != NULLVP) { - struct vattr va; - - /* - * If the directory is opaque, - * then don't show lower entries - */ - error = VOP_GETATTR(vp, &va, fp->f_cred, p); - if (va.va_flags & OPAQUE) { - vput(lvp); - lvp = NULL; - } - } - - if (lvp != NULLVP) { - error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); - if (error) { - vput(lvp); - return (error); - } - VOP_UNLOCK(lvp, 0, p); - fp->f_data = (caddr_t) lvp; - fp->f_offset = 0; - error = vn_close(vp, FREAD, fp->f_cred, p); - if (error) - return (error); - vp = lvp; + if (union_dircheckp && SCARG(uap, count) == auio.uio_resid) { + error = union_dircheckp(p, &vp, fp); + if (error == -1) goto unionread; - } - } -} -#endif /* UNION */ - - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_flag & VROOT) && - (vp->v_mount->mnt_flag & MNT_UNION)) { - struct vnode *tvp = vp; - vp = vp->v_mount->mnt_vnodecovered; - VREF(vp); - fp->f_data = (caddr_t) vp; - fp->f_offset = 0; - vrele(tvp); - goto unionread; + if (error) + return (error); } error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), sizeof(long)); @@ -2814,7 +2760,7 @@ getdirentries(p, uap) syscallarg(long *) basep; } */ *uap; { - register struct vnode *vp; + struct vnode *vp; struct file *fp; struct uio auio; struct iovec aiov; @@ -2845,57 +2791,12 @@ unionread: VOP_UNLOCK(vp, 0, p); if (error) return (error); - -#ifdef UNION -{ - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_op == union_vnodeop_p)) { - struct vnode *lvp; - - lvp = union_dircache(vp, p); - if (lvp != NULLVP) { - struct vattr va; - - /* - * If the directory is opaque, - * then don't show lower entries - */ - error = VOP_GETATTR(vp, &va, fp->f_cred, p); - if (va.va_flags & OPAQUE) { - vput(lvp); - lvp = NULL; - } - } - - if (lvp != NULLVP) { - error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); - if (error) { - vput(lvp); - return (error); - } - VOP_UNLOCK(lvp, 0, p); - fp->f_data = (caddr_t) lvp; - fp->f_offset = 0; - error = vn_close(vp, FREAD, fp->f_cred, p); - if (error) - return (error); - vp = lvp; + if (union_dircheckp && SCARG(uap, count) == auio.uio_resid) { + error = union_dircheckp(p, &vp, fp); + if (error == -1) goto unionread; - } - } -} -#endif /* UNION */ - - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_flag & VROOT) && - (vp->v_mount->mnt_flag & MNT_UNION)) { - struct vnode *tvp = vp; - vp = vp->v_mount->mnt_vnodecovered; - VREF(vp); - fp->f_data = (caddr_t) vp; - fp->f_offset = 0; - vrele(tvp); - goto unionread; + if (error) + return (error); } if (SCARG(uap, basep) != NULL) { error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 4cf124f..43f7856 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -36,21 +36,12 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 - * $Id: vfs_syscalls.c,v 1.107 1998/09/24 15:02:46 luoqi Exp $ + * $Id: vfs_syscalls.c,v 1.108 1998/10/31 07:42:04 peter Exp $ */ /* For 4.3 integer FS ID compatibility */ #include "opt_compat.h" -/* - * XXX - The following is required because of some magic done - * in getdirentries() below which is only done if the translucent - * filesystem `UNION' is compiled into the kernel. This is broken, - * but I don't have time to study the code deeply enough to understand - * what's going on and determine an appropriate fix. -GAW - */ -#include "opt_union.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/sysent.h> @@ -68,9 +59,7 @@ #include <sys/proc.h> #include <sys/dirent.h> -#ifdef UNION #include <miscfs/union/union.h> -#endif #include <vm/vm.h> #include <vm/vm_object.h> @@ -86,6 +75,8 @@ static int setfflags __P((struct proc *, struct vnode *, int)); static int setutimes __P((struct proc *, struct vnode *, struct timeval *, int)); static int usermount = 0; /* if 1, non-root can mount fs. */ +int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *)); + SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, ""); /* @@ -2653,7 +2644,7 @@ ogetdirentries(p, uap) syscallarg(long *) basep; } */ *uap; { - register struct vnode *vp; + struct vnode *vp; struct file *fp; struct uio auio, kuio; struct iovec aiov, kiov; @@ -2734,57 +2725,12 @@ unionread: VOP_UNLOCK(vp, 0, p); if (error) return (error); - -#ifdef UNION -{ - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_op == union_vnodeop_p)) { - struct vnode *lvp; - - lvp = union_dircache(vp, p); - if (lvp != NULLVP) { - struct vattr va; - - /* - * If the directory is opaque, - * then don't show lower entries - */ - error = VOP_GETATTR(vp, &va, fp->f_cred, p); - if (va.va_flags & OPAQUE) { - vput(lvp); - lvp = NULL; - } - } - - if (lvp != NULLVP) { - error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); - if (error) { - vput(lvp); - return (error); - } - VOP_UNLOCK(lvp, 0, p); - fp->f_data = (caddr_t) lvp; - fp->f_offset = 0; - error = vn_close(vp, FREAD, fp->f_cred, p); - if (error) - return (error); - vp = lvp; + if (union_dircheckp && SCARG(uap, count) == auio.uio_resid) { + error = union_dircheckp(p, &vp, fp); + if (error == -1) goto unionread; - } - } -} -#endif /* UNION */ - - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_flag & VROOT) && - (vp->v_mount->mnt_flag & MNT_UNION)) { - struct vnode *tvp = vp; - vp = vp->v_mount->mnt_vnodecovered; - VREF(vp); - fp->f_data = (caddr_t) vp; - fp->f_offset = 0; - vrele(tvp); - goto unionread; + if (error) + return (error); } error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), sizeof(long)); @@ -2814,7 +2760,7 @@ getdirentries(p, uap) syscallarg(long *) basep; } */ *uap; { - register struct vnode *vp; + struct vnode *vp; struct file *fp; struct uio auio; struct iovec aiov; @@ -2845,57 +2791,12 @@ unionread: VOP_UNLOCK(vp, 0, p); if (error) return (error); - -#ifdef UNION -{ - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_op == union_vnodeop_p)) { - struct vnode *lvp; - - lvp = union_dircache(vp, p); - if (lvp != NULLVP) { - struct vattr va; - - /* - * If the directory is opaque, - * then don't show lower entries - */ - error = VOP_GETATTR(vp, &va, fp->f_cred, p); - if (va.va_flags & OPAQUE) { - vput(lvp); - lvp = NULL; - } - } - - if (lvp != NULLVP) { - error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); - if (error) { - vput(lvp); - return (error); - } - VOP_UNLOCK(lvp, 0, p); - fp->f_data = (caddr_t) lvp; - fp->f_offset = 0; - error = vn_close(vp, FREAD, fp->f_cred, p); - if (error) - return (error); - vp = lvp; + if (union_dircheckp && SCARG(uap, count) == auio.uio_resid) { + error = union_dircheckp(p, &vp, fp); + if (error == -1) goto unionread; - } - } -} -#endif /* UNION */ - - if ((SCARG(uap, count) == auio.uio_resid) && - (vp->v_flag & VROOT) && - (vp->v_mount->mnt_flag & MNT_UNION)) { - struct vnode *tvp = vp; - vp = vp->v_mount->mnt_vnodecovered; - VREF(vp); - fp->f_data = (caddr_t) vp; - fp->f_offset = 0; - vrele(tvp); - goto unionread; + if (error) + return (error); } if (SCARG(uap, basep) != NULL) { error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep), diff --git a/sys/miscfs/union/union.h b/sys/miscfs/union/union.h index 4deb6d4..6a4aa22 100644 --- a/sys/miscfs/union/union.h +++ b/sys/miscfs/union/union.h @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * @(#)union.h 8.9 (Berkeley) 12/10/94 - * $Id: union.h,v 1.11 1998/02/10 03:32:03 kato Exp $ + * $Id: union.h,v 1.12 1998/02/26 03:23:51 kato Exp $ */ struct union_args { @@ -114,6 +114,9 @@ extern void union_removed_upper __P((struct union_node *un)); extern struct vnode *union_lowervp __P((struct vnode *)); extern void union_newsize __P((struct vnode *, off_t, off_t)); +extern int (*union_dircheckp) __P((struct proc *, struct vnode **, + struct file *)); + #define MOUNTTOUNIONMOUNT(mp) ((struct union_mount *)((mp)->mnt_data)) #define VTOUNION(vp) ((struct union_node *)(vp)->v_data) #define UNIONTOV(un) ((un)->un_vnode) diff --git a/sys/miscfs/union/union_subr.c b/sys/miscfs/union/union_subr.c index c54d86b..96df62d 100644 --- a/sys/miscfs/union/union_subr.c +++ b/sys/miscfs/union/union_subr.c @@ -35,16 +35,19 @@ * SUCH DAMAGE. * * @(#)union_subr.c 8.20 (Berkeley) 5/20/95 - * $Id: union_subr.c,v 1.30 1998/05/07 04:58:36 msmith Exp $ + * $Id: union_subr.c,v 1.31 1998/07/15 04:17:44 bde Exp $ */ #include <sys/param.h> #include <sys/systm.h> +#include <sys/kernel.h> #include <sys/vnode.h> #include <sys/namei.h> #include <sys/malloc.h> #include <sys/fcntl.h> +#include <sys/file.h> #include <sys/filedesc.h> +#include <sys/module.h> #include <sys/mount.h> #include <sys/stat.h> #include <vm/vm.h> @@ -1138,3 +1141,78 @@ out: VOP_UNLOCK(vp, 0, p); return (nvp); } + +/* + * Module glue to remove #ifdef UNION from vfs_syscalls.c + */ +static int +union_dircheck(struct proc *p, struct vnode **vp, struct file *fp) +{ + int error = 0; + + if ((*vp)->v_op == union_vnodeop_p) { + struct vnode *lvp; + + lvp = union_dircache(*vp, p); + if (lvp != NULLVP) { + struct vattr va; + + /* + * If the directory is opaque, + * then don't show lower entries + */ + error = VOP_GETATTR(*vp, &va, fp->f_cred, p); + if (va.va_flags & OPAQUE) { + vput(lvp); + lvp = NULL; + } + } + + if (lvp != NULLVP) { + error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); + if (error) { + vput(lvp); + return (error); + } + VOP_UNLOCK(lvp, 0, p); + fp->f_data = (caddr_t) lvp; + fp->f_offset = 0; + error = vn_close(*vp, FREAD, fp->f_cred, p); + if (error) + return (error); + *vp = lvp; + return -1; /* goto unionread */ + } + } + if (((*vp)->v_flag & VROOT) && ((*vp)->v_mount->mnt_flag & MNT_UNION)) { + struct vnode *tvp = *vp; + *vp = (*vp)->v_mount->mnt_vnodecovered; + VREF(*vp); + fp->f_data = (caddr_t) *vp; + fp->f_offset = 0; + vrele(tvp); + return -1; /* goto unionread */ + } + return error; +} + +static int union_modevent(module_t mod, modeventtype_t type, void *data) +{ + switch (type) { + case MOD_LOAD: + union_dircheckp = union_dircheck; + break; + case MOD_UNLOAD: + union_dircheckp = NULL; + break; + default: + break; + } + return 0; +} +static moduledata_t union_mod = { + "union_dircheck", + union_modevent, + NULL +}; +DECLARE_MODULE(union_dircheck, union_mod, SI_SUB_VFS, SI_ORDER_ANY); |