make it possible for UNION fs to be loaded via LKM - instead of
having some #ifdef UNION code in vfs_vnops.c, introduce variable 'vn_union_readdir_hook' which is set to address of appropriate vn_readdir() hook by union filesystem when it's loaded & mounted
This commit is contained in:
parent
0e2c1bbb82
commit
46eb0d5bf0
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: union.h,v 1.1 2003/03/16 08:26:51 jdolecek Exp $ */
|
/* $NetBSD: union.h,v 1.2 2003/03/17 09:11:30 jdolecek Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 The Regents of the University of California.
|
* Copyright (c) 1994 The Regents of the University of California.
|
||||||
|
@ -122,6 +122,7 @@ extern struct vnode *union_lowervp __P((struct vnode *));
|
||||||
extern void union_newlower __P((struct union_node *, struct vnode *));
|
extern void union_newlower __P((struct union_node *, struct vnode *));
|
||||||
extern void union_newupper __P((struct union_node *, struct vnode *));
|
extern void union_newupper __P((struct union_node *, struct vnode *));
|
||||||
extern void union_newsize __P((struct vnode *, off_t, off_t));
|
extern void union_newsize __P((struct vnode *, off_t, off_t));
|
||||||
|
int union_readdirhook(struct vnode **, struct file *, struct proc *);
|
||||||
|
|
||||||
#define MOUNTTOUNIONMOUNT(mp) ((struct union_mount *)((mp)->mnt_data))
|
#define MOUNTTOUNIONMOUNT(mp) ((struct union_mount *)((mp)->mnt_data))
|
||||||
#define VTOUNION(vp) ((struct union_node *)(vp)->v_data)
|
#define VTOUNION(vp) ((struct union_node *)(vp)->v_data)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: union_subr.c,v 1.1 2003/03/16 08:26:52 jdolecek Exp $ */
|
/* $NetBSD: union_subr.c,v 1.2 2003/03/17 09:11:30 jdolecek Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 Jan-Simon Pendry
|
* Copyright (c) 1994 Jan-Simon Pendry
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.1 2003/03/16 08:26:52 jdolecek Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: union_subr.c,v 1.2 2003/03/17 09:11:30 jdolecek Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -100,7 +100,9 @@ union_init()
|
||||||
void
|
void
|
||||||
union_done()
|
union_done()
|
||||||
{
|
{
|
||||||
/* Nothing */
|
|
||||||
|
/* Make sure to unset the readdir hook. */
|
||||||
|
vn_union_readdir_hook = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1153,3 +1155,45 @@ union_diruncache(un)
|
||||||
un->un_dircache = 0;
|
un->un_dircache = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This hook is called from vn_readdir() to switch to lower directory
|
||||||
|
* entry after the upper directory is read.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
union_readdirhook(struct vnode **vpp, struct file *fp, struct proc *p)
|
||||||
|
{
|
||||||
|
struct vnode *vp = *vpp, *lvp;
|
||||||
|
struct vattr va;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (vp->v_op != union_vnodeop_p)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if ((lvp = union_dircache(vp, p)) == NULLVP)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the directory is opaque,
|
||||||
|
* then don't show lower entries
|
||||||
|
*/
|
||||||
|
error = VOP_GETATTR(vp, &va, fp->f_cred, p);
|
||||||
|
if (error || (va.va_flags & OPAQUE)) {
|
||||||
|
vput(lvp);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = VOP_OPEN(lvp, FREAD, fp->f_cred, p);
|
||||||
|
if (error) {
|
||||||
|
vput(lvp);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
VOP_UNLOCK(lvp, 0);
|
||||||
|
fp->f_data = (caddr_t) lvp;
|
||||||
|
fp->f_offset = 0;
|
||||||
|
error = vn_close(vp, FREAD, fp->f_cred, p);
|
||||||
|
if (error)
|
||||||
|
return (error);
|
||||||
|
*vpp = lvp;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: union_vfsops.c,v 1.1 2003/03/16 08:26:54 jdolecek Exp $ */
|
/* $NetBSD: union_vfsops.c,v 1.2 2003/03/17 09:11:31 jdolecek Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1994 The Regents of the University of California.
|
* Copyright (c) 1994 The Regents of the University of California.
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.1 2003/03/16 08:26:54 jdolecek Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: union_vfsops.c,v 1.2 2003/03/17 09:11:31 jdolecek Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -259,6 +259,11 @@ union_mount(mp, path, data, ndp, p)
|
||||||
printf("union_mount: from %s, on %s\n",
|
printf("union_mount: from %s, on %s\n",
|
||||||
mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
|
mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Setup the readdir hook if it's not set already */
|
||||||
|
if (!vn_union_readdir_hook)
|
||||||
|
vn_union_readdir_hook = union_readdirhook;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: vfs_vnops.c,v 1.65 2003/03/16 08:26:48 jdolecek Exp $ */
|
/* $NetBSD: vfs_vnops.c,v 1.66 2003/03/17 09:11:30 jdolecek Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1982, 1986, 1989, 1993
|
* Copyright (c) 1982, 1986, 1989, 1993
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.65 2003/03/16 08:26:48 jdolecek Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.66 2003/03/17 09:11:30 jdolecek Exp $");
|
||||||
|
|
||||||
#include "fs_union.h"
|
#include "fs_union.h"
|
||||||
|
|
||||||
|
@ -65,6 +65,10 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_vnops.c,v 1.65 2003/03/16 08:26:48 jdolecek Exp
|
||||||
#include <fs/union/union.h>
|
#include <fs/union/union.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(LKM) || defined(UNION)
|
||||||
|
int (*vn_union_readdir_hook) (struct vnode **, struct file *, struct proc *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VERIFIED_EXEC
|
#ifdef VERIFIED_EXEC
|
||||||
#include <sys/verified_exec.h>
|
#include <sys/verified_exec.h>
|
||||||
|
|
||||||
|
@ -440,46 +444,17 @@ unionread:
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
#ifdef UNION
|
#if defined(UNION) || defined(LKM)
|
||||||
{
|
if (count == auio.uio_resid && vn_union_readdir_hook) {
|
||||||
extern struct vnode *union_dircache __P((struct vnode *));
|
struct vnode *ovp = vp;
|
||||||
|
|
||||||
if (count == auio.uio_resid && (vp->v_op == union_vnodeop_p)) {
|
error = (*vn_union_readdir_hook)(&vp, fp, 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);
|
|
||||||
if (error) {
|
|
||||||
vput(lvp);
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
VOP_UNLOCK(lvp, 0);
|
|
||||||
fp->f_data = (caddr_t) lvp;
|
|
||||||
fp->f_offset = 0;
|
|
||||||
error = vn_close(vp, FREAD, fp->f_cred, p);
|
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
vp = lvp;
|
if (vp != ovp)
|
||||||
goto unionread;
|
goto unionread;
|
||||||
}
|
}
|
||||||
}
|
#endif /* UNION || LKM */
|
||||||
}
|
|
||||||
#endif /* UNION */
|
|
||||||
|
|
||||||
if (count == auio.uio_resid && (vp->v_flag & VROOT) &&
|
if (count == auio.uio_resid && (vp->v_flag & VROOT) &&
|
||||||
(vp->v_mount->mnt_flag & MNT_UNION)) {
|
(vp->v_mount->mnt_flag & MNT_UNION)) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: vnode.h,v 1.105 2003/03/17 09:06:40 jdolecek Exp $ */
|
/* $NetBSD: vnode.h,v 1.106 2003/03/17 09:11:29 jdolecek Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1989, 1993
|
* Copyright (c) 1989, 1993
|
||||||
|
@ -440,6 +440,11 @@ extern struct vnodeop_desc *vnodeop_descs[];
|
||||||
*/
|
*/
|
||||||
extern struct simplelock mntvnode_slock;
|
extern struct simplelock mntvnode_slock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Union filesystem hook for vn_readdir().
|
||||||
|
*/
|
||||||
|
extern int (*vn_union_readdir_hook) (struct vnode **, struct file *, struct proc *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This macro is very helpful in defining those offsets in the vdesc struct.
|
* This macro is very helpful in defining those offsets in the vdesc struct.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue