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.
This commit is contained in:
parent
28045e8444
commit
8c14bf40a1
@ -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)
|
||||
|
@ -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 @@ union_dircache(vp, p)
|
||||
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);
|
||||
|
@ -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 @@ ogetdirentries(p, uap)
|
||||
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 @@ getdirentries(p, uap)
|
||||
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),
|
||||
|
@ -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 @@ ogetdirentries(p, uap)
|
||||
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 @@ getdirentries(p, uap)
|
||||
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),
|
||||
|
@ -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)
|
||||
|
@ -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 @@ union_dircache(vp, p)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user