summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1998-11-03 08:01:48 +0000
committerpeter <peter@FreeBSD.org>1998-11-03 08:01:48 +0000
commit7819a9450ea8a3c51cd84b12f32ee698bca2da34 (patch)
tree8dd795b23499327af179132647fef4d1e83944fd /sys
parentda2bac6a4930ddeb7bbc0c9c2135009d3a9590eb (diff)
downloadFreeBSD-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.h5
-rw-r--r--sys/fs/unionfs/union_subr.c80
-rw-r--r--sys/kern/vfs_extattr.c129
-rw-r--r--sys/kern/vfs_syscalls.c129
-rw-r--r--sys/miscfs/union/union.h5
-rw-r--r--sys/miscfs/union/union_subr.c80
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);
OpenPOWER on IntegriCloud