-/* $OpenBSD: vfs_syscalls_43.c,v 1.3 1996/09/06 10:37:48 niklas Exp $ */
+/* $OpenBSD: vfs_syscalls_43.c,v 1.4 1997/01/02 12:20:42 mickey Exp $ */
/* $NetBSD: vfs_syscalls_43.c,v 1.4 1996/03/14 19:31:52 christos Exp $ */
/*
static void cvtstat __P((struct stat *, struct ostat *));
+/*
+ * Redirection info so we don't have to include the union fs routines in
+ * the kernel directly. This way, we can build unionfs as an LKM. The
+ * pointer gets replaced later, when we modload the LKM, or when the
+ * compiled-in unionfs code gets initialized. Initial, stub routine
+ * value is compiled in from kern/vfs_syscalls.c
+ */
+
+extern int (*union_check_p) __P((struct proc *, struct vnode **,
+ struct file *, struct uio, int *));
+
/*
* Convert from an old to a new stat structure.
*/
syscallarg(u_int) count;
syscallarg(long *) basep;
} */ *uap = v;
- register struct vnode *vp;
+ struct vnode *vp;
struct file *fp;
struct uio auio, kuio;
struct iovec aiov, kiov;
VOP_UNLOCK(vp);
if (error)
return (error);
-
-#ifdef UNION
-{
- extern int (**union_vnodeop_p) __P((void *));
- extern struct vnode *union_dircache __P((struct vnode *));
-
if ((SCARG(uap, count) == auio.uio_resid) &&
- (vp->v_op == union_vnodeop_p)) {
- struct vnode *lvp;
-
- lvp = union_dircache(vp);
- 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);
- VOP_UNLOCK(lvp);
-
- if (error) {
- vrele(lvp);
- return (error);
- }
- 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;
- goto unionread;
- }
- }
-}
-#endif /* UNION */
+ union_check_p &&
+ (union_check_p(p, &vp, fp, auio, &error) != 0))
+ goto unionread;
+ if (error)
+ return (error);
if ((SCARG(uap, count) == auio.uio_resid) &&
(vp->v_flag & VROOT) &&
-/* $OpenBSD: vfs_syscalls.c,v 1.17 1996/10/27 08:02:32 tholo Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.18 1997/01/02 12:20:40 mickey Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
void checkdirs __P((struct vnode *));
int dounmount __P((struct mount *, int, struct proc *));
+/*
+ * Redirection info so we don't have to include the union fs routines in
+ * the kernel directly. This way, we can build unionfs as an LKM. The
+ * pointer gets filled in later, when we modload the LKM, or when the
+ * compiled-in unionfs code gets initialized. For now, we just set
+ * it to a stub routine.
+ */
+
+int (*union_check_p) __P((struct proc *, struct vnode **,
+ struct file *, struct uio, int *)) = NULL;
+
/*
* Virtual File System System Calls
*/
syscallarg(u_int) count;
syscallarg(long *) basep;
} */ *uap = v;
- register struct vnode *vp;
+ struct vnode *vp;
struct file *fp;
struct uio auio;
struct iovec aiov;
VOP_UNLOCK(vp);
if (error)
return (error);
-
-#ifdef UNION
-{
- extern int (**union_vnodeop_p) __P((void *));
- extern struct vnode *union_dircache __P((struct vnode *));
-
if ((SCARG(uap, count) == auio.uio_resid) &&
- (vp->v_op == union_vnodeop_p)) {
- struct vnode *lvp;
-
- lvp = union_dircache(vp);
- 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);
- VOP_UNLOCK(lvp);
-
- if (error) {
- vrele(lvp);
- return (error);
- }
- 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;
- goto unionread;
- }
- }
-}
-#endif /* UNION */
+ union_check_p &&
+ (union_check_p(p, &vp, fp, auio, &error) != 0))
+ goto unionread;
+ if (error)
+ return (error);
if ((SCARG(uap, count) == auio.uio_resid) &&
(vp->v_flag & VROOT) &&
-/* $OpenBSD: union_subr.c,v 1.3 1996/12/07 13:00:16 deraadt Exp $ */
+/* $OpenBSD: union_subr.c,v 1.4 1997/01/02 12:20:43 mickey Exp $ */
/* $NetBSD: union_subr.c,v 1.18 1996/02/09 22:41:10 christos Exp $ */
/*
static void union_dircache_r __P((struct vnode *, struct vnode ***, int *));
struct vnode *union_dircache __P((struct vnode *));
+/*
+ * This variable is used to hold a pointer to a function
+ * that is called from vfs_syscalls.c and vfs_syscalls_43.c
+ * - by keeping a pointer to the function we enable the real
+ * union filesystem code to replace the stub value provided
+ * by vfs_syscalls.c and thus vfs_syscalls.c no longer needs
+ * to know if UNION is built in, lkm'ed, or not even there.
+ */
+extern
+int (*union_check_p) __P((struct proc *, struct vnode **,
+ struct file *, struct uio, int *));
+
+int union_check(struct proc *, struct vnode **, struct file *,
+ struct uio, int *);
+
+int union_check(p, vpp, fp, auio, error)
+ struct proc *p;
+ struct vnode **vpp;
+ struct file *fp;
+ struct uio auio;
+ int *error;
+{
+ if ((*vpp)->v_op == union_vnodeop_p) {
+ struct vnode *lvp;
+
+ lvp = union_dircache(*vpp);
+ if (lvp != NULLVP) {
+ struct vattr va;
+
+ /*
+ * If the directory is opaque,
+ * then don't show lower entries
+ */
+ *error = VOP_GETATTR(*vpp, &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);
+ VOP_UNLOCK(lvp);
+
+ if (*error) {
+ vrele(lvp);
+ return (0);
+ }
+ fp->f_data = (caddr_t) lvp;
+ fp->f_offset = 0;
+ *error = vn_close(*vpp, FREAD, fp->f_cred, p);
+ if (*error)
+ return (0);
+ *vpp = lvp;
+ return (1);
+ }
+ }
+ return (0);
+};
+
void
union_init()
{
for (i = 0; i < NHASH; i++)
LIST_INIT(&unhead[i]);
bzero((caddr_t) unvplock, sizeof(unvplock));
+ union_check_p = union_check;
}
static int