summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2003-05-12 21:02:11 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2003-05-12 21:02:11 +0000
commit5aabec7aaeb472ceb236b7d6afd3ec732db1cdef (patch)
treea56e94c7de277a39c06f611e35fd7862484ddf36
parent104c9cee2b7581512ef5cf06fb24402ea5fa56c5 (diff)
umapfs uses the new layer stuff now too.
-rw-r--r--sys/miscfs/umapfs/umap.h73
-rw-r--r--sys/miscfs/umapfs/umap_subr.c368
-rw-r--r--sys/miscfs/umapfs/umap_vfsops.c321
-rw-r--r--sys/miscfs/umapfs/umap_vnops.c477
4 files changed, 434 insertions, 805 deletions
diff --git a/sys/miscfs/umapfs/umap.h b/sys/miscfs/umapfs/umap.h
index 7b879f8f162..89184907c29 100644
--- a/sys/miscfs/umapfs/umap.h
+++ b/sys/miscfs/umapfs/umap.h
@@ -1,5 +1,5 @@
-/* $OpenBSD: umap.h,v 1.9 2002/03/14 01:27:08 millert Exp $ */
-/* $NetBSD: umap.h,v 1.6 1996/02/09 22:41:00 christos Exp $ */
+/* $OpenBSD: umap.h,v 1.10 2003/05/12 21:02:10 tedu Exp $ */
+/* $NetBSD: umap.h,v 1.9 1999/07/08 01:19:06 wrstuden Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -37,63 +37,80 @@
* SUCH DAMAGE.
*
* from: @(#)null_vnops.c 1.5 (Berkeley) 7/10/92
- * @(#)umap.h 8.3 (Berkeley) 1/21/94
+ * @(#)umap.h 8.4 (Berkeley) 8/20/94
*/
+#include <miscfs/genfs/layer.h>
+
#define UMAPFILEENTRIES 64
#define GMAPFILEENTRIES 16
#define NOBODY 32767
#define NULLGROUP 65534
-typedef u_int32_t id_t;
-typedef id_t (*id_map_t)[2];
-
struct umap_args {
- char *target; /* Target of loopback */
- int unentries; /* # of entries in user map array */
- int gnentries; /* # of entries in group map array */
- id_map_t umapdata; /* pointer to array of user mappings */
- id_map_t gmapdata; /* pointer to array of group mappings */
+ struct layer_args la; /* generic layerfs args. Includes
+ * target and export info */
+#define umap_target la.target
+#define umap_export la.export
+ int unentries; /* # of entries in user map array */
+ int gnentries; /* # of entries in group map array */
+ u_long (*mapdata)[2]; /* pointer to array of user mappings */
+ u_long (*gmapdata)[2]; /* pointer to array of group mappings */
};
+#ifdef _KERNEL
+
struct umap_mount {
- struct mount *umapm_vfs;
- struct vnode *umapm_rootvp; /* Reference to root umap_node */
- int info_unentries; /* number of uid mappings */
+ struct layer_mount lm;
+ int info_unentries; /* number of uid mappings */
int info_gnentries; /* number of gid mappings */
- id_t info_umapdata[UMAPFILEENTRIES][2]; /* mapping data for
+ u_long info_umapdata[UMAPFILEENTRIES][2]; /* mapping data for
user mapping in ficus */
- id_t info_gmapdata[GMAPFILEENTRIES][2]; /*mapping data for
+ u_long info_gmapdata[GMAPFILEENTRIES][2]; /*mapping data for
group mapping in ficus */
};
+#define umapm_vfs lm.layerm_vfs
+#define umapm_rootvp lm.layerm_rootvp
+#define umapm_export lm.layerm_export
+#define umapm_flags lm.layerm_flags
+#define umapm_size lm.layerm_size
+#define umapm_tag lm.layerm_tag
+#define umapm_bypass lm.layerm_bypass
+#define umapm_alloc lm.layerm_alloc
+#define umapm_vnodeop_p lm.layerm_vnodeop_p
+#define umapm_node_hashtbl lm.layerm_node_hashtbl
+#define umapm_node_hash lm.layerm_node_hash
+#define umapm_hashlock lm.layerm_hashlock
-#ifdef _KERNEL
/*
* A cache of vnode references
*/
struct umap_node {
- LIST_ENTRY(umap_node) umap_hash; /* Hash list */
- struct vnode *umap_lowervp; /* Aliased vnode - VREFed once */
- struct vnode *umap_vnode; /* Back pointer to vnode/umap_node */
+ struct layer_node ln;
};
-extern int umap_node_create(struct mount *mp, struct vnode *target, struct vnode **vpp);
-extern id_t umap_reverse_findid(id_t id, id_map_t, int nentries);
-extern void umap_mapids(struct mount *v_mount, struct ucred *credp);
+u_long umap_reverse_findid(u_long id, u_long map[][2], int nentries);
+void umap_mapids(struct mount *v_mount, struct ucred *credp);
+
+#define umap_hash ln.layer_hash
+#define umap_lowervp ln.layer_lowervp
+#define umap_vnode ln.layer_vnode
+#define umap_flags ln.layer_flags
#define MOUNTTOUMAPMOUNT(mp) ((struct umap_mount *)((mp)->mnt_data))
#define VTOUMAP(vp) ((struct umap_node *)(vp)->v_data)
#define UMAPTOV(xp) ((xp)->umap_vnode)
#ifdef UMAPFS_DIAGNOSTIC
-extern struct vnode *umap_checkvp(struct vnode *vp, char *fil, int lno);
-#define UMAPVPTOLOWERVP(vp) umap_checkvp((vp), __FILE__, __LINE__)
+#define UMAPVPTOLOWERVP(vp) layer_checkvp((vp), __FILE__, __LINE__)
#else
#define UMAPVPTOLOWERVP(vp) (VTOUMAP(vp)->umap_lowervp)
#endif
-extern int (**umap_vnodeop_p)(void *);
-extern struct vfsops umap_vfsops;
+extern int (**umapfs_vnodeop_p)(void *);
+extern struct vfsops umapfs_vfsops;
+
+int umap_bypass(void *);
-int umapfs_init(struct vfsconf *);
+#define NUMAPNODECACHE 16
#endif /* _KERNEL */
diff --git a/sys/miscfs/umapfs/umap_subr.c b/sys/miscfs/umapfs/umap_subr.c
index 7c5d9fffa68..4f4cfb7c846 100644
--- a/sys/miscfs/umapfs/umap_subr.c
+++ b/sys/miscfs/umapfs/umap_subr.c
@@ -1,8 +1,40 @@
-/* $OpenBSD: umap_subr.c,v 1.14 2002/06/14 21:35:00 todd Exp $ */
-/* $NetBSD: umap_subr.c,v 1.8 1996/03/05 02:35:39 thorpej Exp $ */
+/* $OpenBSD: umap_subr.c,v 1.15 2003/05/12 21:02:10 tedu Exp $ */
+/* $NetBSD: umap_subr.c,v 1.19 2001/11/15 09:48:23 lukem Exp $ */
/*
- * Copyright (c) 1992, 1993
+ * Copyright (c) 1999 National Aeronautics & Space Administration
+ * All rights reserved.
+ *
+ * This software was written by William Studenmund of the
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the National Aeronautics & Space Administration
+ * nor the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NATIONAL AERONAUTICS & SPACE ADMINISTRATION
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ADMINISTRATION OR CONTRIB-
+ * UTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
@@ -37,14 +69,14 @@
* SUCH DAMAGE.
*
* from: Id: lofs_subr.c, v 1.11 1992/05/30 10:05:43 jsp Exp
- * @(#)umap_subr.c 8.6 (Berkeley) 1/26/94
+ * @(#)umap_subr.c 8.9 (Berkeley) 5/14/95
*/
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/time.h>
-#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/namei.h>
@@ -52,54 +84,22 @@
#include <miscfs/specfs/specdev.h>
#include <miscfs/umapfs/umap.h>
-#define LOG2_SIZEVNODE 7 /* log2(sizeof struct vnode) */
-#define NUMAPNODECACHE 16
-
-/*
- * Null layer cache:
- * Each cache entry holds a reference to the target vnode
- * along with a pointer to the alias vnode. When an
- * entry is added the target vnode is VREF'd. When the
- * alias is removed the target vnode is vrele'd.
- */
-
-#define UMAP_NHASH(vp) \
- (&umap_node_hashtbl[(((u_long)vp)>>LOG2_SIZEVNODE) & umap_node_hash])
-LIST_HEAD(umap_node_hashhead, umap_node) *umap_node_hashtbl;
-u_long umap_node_hash;
-
-static id_t umap_findid(id_t, id_map_t, int);
-static struct vnode *umap_node_find(struct mount *, struct vnode *);
-static int umap_node_alloc(struct mount *, struct vnode *,
- struct vnode **);
-
-/*
- * Initialise cache headers
- */
-int
-umapfs_init(struct vfsconf *vfsp)
-{
-
-#ifdef UMAPFS_DIAGNOSTIC
- printf("umapfs_init\n"); /* printed during system boot */
-#endif
- umap_node_hashtbl = hashinit(NUMAPNODECACHE, M_CACHE, M_WAITOK, &umap_node_hash);
- return (0);
-}
+u_long umap_findid(u_long, u_long [][2], int);
+int umap_node_alloc(struct mount *, struct vnode *, struct vnode **);
/*
* umap_findid is called by various routines in umap_vnodeops.c to
* find a user or group id in a map.
*/
-static id_t
+u_long
umap_findid(id, map, nentries)
- id_t id;
- id_map_t map;
- int nentries;
+ u_long id;
+ u_long map[][2];
+ int nentries;
{
int i;
- /* Find {g,u}id entry in map */
+ /* Find uid entry in map */
i = 0;
while ((i<nentries) && ((map[i][0]) != id))
i++;
@@ -115,11 +115,11 @@ umap_findid(id, map, nentries)
* umap_reverse_findid is called by umap_getattr() in umap_vnodeops.c to
* find a user or group id in a map, in reverse.
*/
-id_t
+u_long
umap_reverse_findid(id, map, nentries)
- id_t id;
- id_map_t map;
- int nentries;
+ u_long id;
+ u_long map[][2];
+ int nentries;
{
int i;
@@ -135,264 +135,6 @@ umap_reverse_findid(id, map, nentries)
}
-/*
- * Return alias for target vnode if already exists, else 0.
- */
-static struct vnode *
-umap_node_find(mp, targetvp)
- struct mount *mp;
- struct vnode *targetvp;
-{
- struct proc *p = curproc;
- struct umap_node_hashhead *hd;
- struct umap_node *a;
- struct vnode *vp;
-
-#ifdef UMAPFS_DIAGNOSTIC
- printf("umap_node_find(mp = %p, target = %p)\n", mp, targetvp);
-#endif
-
- /*
- * Find hash base, and then search the (two-way) linked
- * list looking for a umap_node structure which is referencing
- * the target vnode. If found, the increment the umap_node
- * reference count (but NOT the target vnode's VREF counter).
- */
- hd = UMAP_NHASH(targetvp);
-loop:
- for (a = hd->lh_first; a != 0; a = a->umap_hash.le_next) {
- if (a->umap_lowervp == targetvp &&
- a->umap_vnode->v_mount == mp) {
- vp = UMAPTOV(a);
- /*
- * We need vget for the VXLOCK
- * stuff, but we don't want to lock
- * the lower node.
- */
- if (vget(vp, 0, p)) {
-#ifdef UMAPFS_DIAGNOSTIC
- printf ("umap_node_find: vget failed.\n");
-#endif
- goto loop;
- }
- return (vp);
- }
- }
-
-#ifdef UMAPFS_DIAGNOSTIC
- printf("umap_node_find(%p, %p): NOT found\n", mp, targetvp);
-#endif
-
- return (0);
-}
-
-/*
- * Make a new umap_node node.
- * Vp is the alias vnode, lowervp is the target vnode.
- * Maintain a reference to lowervp.
- */
-static int
-umap_node_alloc(mp, lowervp, vpp)
- struct mount *mp;
- struct vnode *lowervp;
- struct vnode **vpp;
-{
- struct umap_node_hashhead *hd;
- struct umap_node *xp;
- struct vnode *vp, *nvp;
- int error;
- struct proc *p = curproc;
- extern int (**dead_vnodeop_p)(void *);
-
- if ((error = getnewvnode(VT_UMAP, mp, umap_vnodeop_p, &vp)) != 0)
- return (error);
- vp->v_type = lowervp->v_type;
-
- MALLOC(xp, struct umap_node *, sizeof(struct umap_node), M_TEMP,
- M_WAITOK);
- if (vp->v_type == VBLK || vp->v_type == VCHR) {
- MALLOC(vp->v_specinfo, struct specinfo *,
- sizeof(struct specinfo), M_VNODE, M_WAITOK);
- vp->v_rdev = lowervp->v_rdev;
- }
-
- vp->v_data = xp;
- xp->umap_vnode = vp;
- xp->umap_lowervp = lowervp;
- /*
- * Before we insert our new node onto the hash chains,
- * check to see if someone else has beaten us to it.
- * (We could have slept in MALLOC.)
- */
- if ((nvp = umap_node_find(mp, lowervp)) != NULL) {
- *vpp = nvp;
-
- /* free the substructures we've allocated. */
- FREE(xp, M_TEMP);
- if (vp->v_type == VBLK || vp->v_type == VCHR)
- FREE(vp->v_specinfo, M_VNODE);
-
- vp->v_type = VBAD; /* node is discarded */
- vp->v_op = dead_vnodeop_p; /* so ops will still work */
- vrele(vp); /* get rid of it. */
- return (0);
- }
-
- /*
- * XXX if it's a device node, it needs to be checkalias()ed.
- * however, for locking reasons, that's just not possible.
- * so we have to do most of the dirty work inline. Note that
- * this is a limited case; we know that there's going to be
- * an alias, and we know that that alias will be a "real"
- * device node, i.e. not tagged VT_NON.
- */
- if (vp->v_type == VBLK || vp->v_type == VCHR) {
- struct vnode *cvp, **cvpp;
-
- cvpp = &speclisth[SPECHASH(vp->v_rdev)];
-loop:
- for (cvp = *cvpp; cvp; cvp = cvp->v_specnext) {
- if (vp->v_rdev != cvp->v_rdev ||
- vp->v_type != cvp->v_type)
- continue;
-
- /*
- * Alias, but not in use, so flush it out.
- */
- if (cvp->v_usecount == 0) {
- vgone(cvp);
- goto loop;
- }
- if (vget(cvp, 0, p)) /* can't lock; will die! */
- goto loop;
- break;
- }
-
- vp->v_hashchain = cvpp;
- vp->v_specnext = *cvpp;
- vp->v_specmountpoint = NULL;
- *cvpp = vp;
-#ifdef DIAGNOSTIC
- if (cvp == NULLVP)
- panic("umap_node_alloc: no alias for device");
-#endif
- vp->v_flag |= VALIASED;
- cvp->v_flag |= VALIASED;
- vrele(cvp);
- }
- /* XXX end of transmogrified checkalias() */
-
- *vpp = vp;
- VREF(lowervp); /* Extra VREF will be vrele'd in umap_node_create */
- hd = UMAP_NHASH(lowervp);
- LIST_INSERT_HEAD(hd, xp, umap_hash);
- return (0);
-}
-
-
-/*
- * Try to find an existing umap_node vnode referring
- * to it, otherwise make a new umap_node vnode which
- * contains a reference to the target vnode.
- */
-int
-umap_node_create(mp, targetvp, newvpp)
- struct mount *mp;
- struct vnode *targetvp;
- struct vnode **newvpp;
-{
- struct vnode *aliasvp;
-
- if ((aliasvp = umap_node_find(mp, targetvp)) != NULL) {
- /*
- * Take another reference to the alias vnode
- */
-#ifdef UMAPFS_DIAGNOSTIC
- vprint("umap_node_create: exists", aliasvp);
-#endif
- /* VREF(aliasvp); */
- } else {
- int error;
-
- /*
- * Get new vnode.
- */
-#ifdef UMAPFS_DIAGNOSTIC
- printf("umap_node_create: create new alias vnode\n");
-#endif
- /*
- * Make new vnode reference the umap_node.
- */
- if ((error = umap_node_alloc(mp, targetvp, &aliasvp)) != 0)
- return (error);
-
- /*
- * aliasvp is already VREF'd by getnewvnode()
- */
- }
-
- vrele(targetvp);
-
-#ifdef UMAPFS_DIAGNOSTIC
- vprint("umap_node_create: alias", aliasvp);
- vprint("umap_node_create: target", targetvp);
-#endif
-
- *newvpp = aliasvp;
- return (0);
-}
-
-#ifdef UMAPFS_DIAGNOSTIC
-int umap_checkvp_barrier = 1;
-struct vnode *
-umap_checkvp(vp, fil, lno)
- struct vnode *vp;
- char *fil;
- int lno;
-{
- struct umap_node *a = VTOUMAP(vp);
-#ifdef notyet
- /*
- * Can't do this check because vop_reclaim runs
- * with funny vop vector.
- */
- if (vp->v_op != umap_vnodeop_p) {
- printf ("umap_checkvp: on non-umap-node\n");
- while (umap_checkvp_barrier) /*WAIT*/ ;
- panic("umap_checkvp");
- }
-#endif
- if (a->umap_lowervp == NULL) {
- /* Should never happen */
- int i; u_long *p;
- printf("vp = %p, ZERO ptr\n", vp);
- for (p = (u_long *) a, i = 0; i < 8; i++)
- printf(" %lx", p[i]);
- printf("\n");
- /* wait for debugger */
- while (umap_checkvp_barrier) /*WAIT*/ ;
- panic("umap_checkvp");
- }
- if (a->umap_lowervp->v_usecount < 1) {
- int i; u_long *p;
- printf("vp = %p, unref'ed lowervp\n", vp);
- for (p = (u_long *) a, i = 0; i < 8; i++)
- printf(" %lx", p[i]);
- printf("\n");
- /* wait for debugger */
- while (umap_checkvp_barrier) /*WAIT*/ ;
- panic ("umap with unref'ed lowervp");
- }
-#ifdef notyet
- printf("umap %p/%d -> %p/%d [%s, %d]\n",
- a->umap_vnode, a->umap_vnode->v_usecount,
- a->umap_lowervp, a->umap_lowervp->v_usecount,
- fil, lno);
-#endif
- return (a->umap_lowervp);
-}
-#endif
-
/* umap_mapids maps all of the ids in a credential, both user and group. */
void
@@ -400,18 +142,18 @@ umap_mapids(v_mount, credp)
struct mount *v_mount;
struct ucred *credp;
{
- int i, unentries, gnentries;
- uid_t uid;
- gid_t gid;
- id_map_t usermap, groupmap;
+ int i, unentries, gnentries;
+ uid_t uid;
+ gid_t gid;
+ u_long (*usermap)[2], (*groupmap)[2];
if (credp == NOCRED)
return;
unentries = MOUNTTOUMAPMOUNT(v_mount)->info_unentries;
- usermap = MOUNTTOUMAPMOUNT(v_mount)->info_umapdata;
+ usermap = MOUNTTOUMAPMOUNT(v_mount)->info_umapdata;
gnentries = MOUNTTOUMAPMOUNT(v_mount)->info_gnentries;
- groupmap = MOUNTTOUMAPMOUNT(v_mount)->info_gmapdata;
+ groupmap = MOUNTTOUMAPMOUNT(v_mount)->info_gmapdata;
/* Find uid entry in map */
@@ -438,7 +180,7 @@ umap_mapids(v_mount, credp)
/* Now we must map each of the set of groups in the cr_groups
structure. */
- for ( i = 0 ; credp->cr_groups[i] != 0 ; i++ ) {
+ for(i=0; i < credp->cr_ngroups; i++) {
gid = (gid_t) umap_findid(credp->cr_groups[i],
groupmap, gnentries);
diff --git a/sys/miscfs/umapfs/umap_vfsops.c b/sys/miscfs/umapfs/umap_vfsops.c
index 1b289d5b8eb..0e2a482d1e1 100644
--- a/sys/miscfs/umapfs/umap_vfsops.c
+++ b/sys/miscfs/umapfs/umap_vfsops.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: umap_vfsops.c,v 1.19 2003/02/24 22:32:46 tedu Exp $ */
-/* $NetBSD: umap_vfsops.c,v 1.9 1996/02/09 22:41:05 christos Exp $ */
+/* $OpenBSD: umap_vfsops.c,v 1.20 2003/05/12 21:02:10 tedu Exp $ */
+/* $NetBSD: umap_vfsops.c,v 1.35 2002/09/21 18:09:31 christos Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* from: @(#)null_vfsops.c 1.5 (Berkeley) 7/10/92
- * @(#)umap_vfsops.c 8.3 (Berkeley) 1/21/94
+ * @(#)umap_vfsops.c 8.8 (Berkeley) 5/14/95
*/
/*
@@ -45,29 +45,21 @@
* (See mount_umap(8) for a description of this layer.)
*/
+
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/time.h>
#include <sys/proc.h>
-#include <sys/types.h>
+#include <sys/time.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/malloc.h>
#include <miscfs/umapfs/umap.h>
+#include <miscfs/genfs/layer_extern.h>
int umapfs_mount(struct mount *, const char *, void *,
- struct nameidata *, struct proc *);
-int umapfs_start(struct mount *, int, struct proc *);
+ struct nameidata *, struct proc *);
int umapfs_unmount(struct mount *, int, struct proc *);
-int umapfs_root(struct mount *, struct vnode **);
-int umapfs_quotactl(struct mount *, int, uid_t, caddr_t,
- struct proc *);
-int umapfs_statfs(struct mount *, struct statfs *, struct proc *);
-int umapfs_sync(struct mount *, int, struct ucred *, struct proc *);
-int umapfs_vget(struct mount *, ino_t, struct vnode **);
-int umapfs_fhtovp(struct mount *, struct fid *, struct vnode **);
-int umapfs_vptofh(struct vnode *, struct fid *);
/*
* Mount umap layer
@@ -82,42 +74,57 @@ umapfs_mount(mp, path, data, ndp, p)
{
struct umap_args args;
struct vnode *lowerrootvp, *vp;
- struct vnode *umapm_rootvp;
struct umap_mount *amp;
size_t size;
int error;
#ifdef UMAPFS_DIAGNOSTIC
int i;
+#endif
+#if 0
+ if (mp->mnt_flag & MNT_GETARGS) {
+ amp = MOUNTTOUMAPMOUNT(mp);
+ if (amp == NULL)
+ return EIO;
+ args.la.target = NULL;
+ vfs_showexport(mp, &args.la.export, &amp->umapm_export);
+ args.nentries = amp->info_nentries;
+ args.gnentries = amp->info_gnentries;
+ return copyout(&args, data, sizeof(args));
+ }
+#endif
+
+ /* only for root */
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
+ return error;
+#ifdef UMAPFS_DIAGNOSTIC
printf("umapfs_mount(mp = %p)\n", mp);
#endif
/*
- * Don't allow users to play with umapfs (when usermount is true).
+ * Get argument
*/
- if (p->p_ucred->cr_uid != 0)
- return EPERM;
+ error = copyin(data, (caddr_t)&args, sizeof(struct umap_args));
+ if (error)
+ return (error);
/*
- * Update is a no-op
+ * Update only does export updating.
*/
if (mp->mnt_flag & MNT_UPDATE) {
- return (EOPNOTSUPP);
- /* return (VFS_MOUNT(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, path, data, ndp, p));*/
+ amp = MOUNTTOUMAPMOUNT(mp);
+ if (args.umap_target == 0)
+ return (vfs_export(mp, &amp->umapm_export,
+ &args.umap_export));
+ else
+ return (EOPNOTSUPP);
}
/*
- * Get argument
- */
- error = copyin(data, &args, sizeof(struct umap_args));
- if (error)
- return (error);
-
- /*
* Find lower node
*/
- NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT|LOCKLEAF,
- UIO_USERSPACE, args.target, p);
+ NDINIT(ndp, LOOKUP, FOLLOW|LOCKLEAF,
+ UIO_USERSPACE, args.umap_target, p);
if ((error = namei(ndp)) != 0)
return (error);
@@ -128,8 +135,6 @@ umapfs_mount(mp, path, data, ndp, p)
#ifdef UMAPFS_DIAGNOSTIC
printf("vp = %p, check for VDIR...\n", lowerrootvp);
#endif
- vrele(ndp->ni_dvp);
- ndp->ni_dvp = 0;
if (lowerrootvp->v_type != VDIR) {
vput(lowerrootvp);
@@ -142,83 +147,96 @@ umapfs_mount(mp, path, data, ndp, p)
amp = (struct umap_mount *) malloc(sizeof(struct umap_mount),
M_MISCFSMNT, M_WAITOK);
+ memset((caddr_t)amp, 0, sizeof(struct umap_mount));
- /*
- * Save reference to underlying FS
- */
+ mp->mnt_data = (qaddr_t)amp;
amp->umapm_vfs = lowerrootvp->v_mount;
+ if (amp->umapm_vfs->mnt_flag & MNT_LOCAL)
+ mp->mnt_flag |= MNT_LOCAL;
/*
* Now copy in the number of entries and maps for umap mapping.
*/
- if (args.unentries < 0 || args.unentries > UMAPFILEENTRIES ||
- args.gnentries < 0 || args.gnentries > GMAPFILEENTRIES) {
+ if (args.unentries > UMAPFILEENTRIES || args.gnentries > GMAPFILEENTRIES) {
vput(lowerrootvp);
return (error);
}
+
amp->info_unentries = args.unentries;
amp->info_gnentries = args.gnentries;
- error = copyin(args.umapdata, (caddr_t)amp->info_umapdata,
- 2*sizeof(**amp->info_umapdata)*args.unentries);
- if (error)
+ error = copyin(args.mapdata, (caddr_t)amp->info_umapdata,
+ 2*sizeof(u_long)*args.unentries);
+ if (error) {
+ vput(lowerrootvp);
return (error);
+ }
#ifdef UMAPFS_DIAGNOSTIC
printf("umap_mount:unentries %d\n",args.unentries);
for (i = 0; i < args.unentries; i++)
- printf(" %d maps to %d\n", amp->info_umapdata[i][0],
+ printf(" %ld maps to %ld\n", amp->info_umapdata[i][0],
amp->info_umapdata[i][1]);
#endif
error = copyin(args.gmapdata, (caddr_t)amp->info_gmapdata,
- 2*sizeof(**amp->info_gmapdata)*args.gnentries);
- if (error)
+ 2*sizeof(u_long)*args.gnentries);
+ if (error) {
+ vput(lowerrootvp);
return (error);
+ }
#ifdef UMAPFS_DIAGNOSTIC
printf("umap_mount:gnentries %d\n",args.gnentries);
for (i = 0; i < args.gnentries; i++)
- printf(" group %d maps to %d\n",
+ printf("\tgroup %ld maps to %ld\n",
amp->info_gmapdata[i][0],
amp->info_gmapdata[i][1]);
#endif
-
/*
- * Save reference. Each mount also holds
- * a reference on the root vnode.
+ * Make sure the mount point's sufficiently initialized
+ * that the node create call will work.
*/
- error = umap_node_create(mp, lowerrootvp, &vp);
+ vfs_getnewfsid(mp);
+ amp->umapm_size = sizeof(struct umap_node);
+ amp->umapm_tag = VT_UMAP;
+ amp->umapm_bypass = umap_bypass;
+ amp->umapm_alloc = layer_node_alloc; /* the default alloc is fine */
+ amp->umapm_vnodeop_p = umapfs_vnodeop_p;
+ simple_lock_init(&amp->umapm_hashlock);
+ amp->umapm_node_hashtbl = hashinit(NUMAPNODECACHE, M_CACHE,
+ M_WAITOK, &amp->umapm_node_hash);
+
+
/*
- * Unlock the node (either the lower or the alias)
+ * fix up umap node for root vnode.
*/
- VOP_UNLOCK(vp, 0, p);
+ error = layer_node_create(mp, lowerrootvp, &vp);
/*
* Make sure the node alias worked
*/
if (error) {
- vrele(lowerrootvp);
+ vput(lowerrootvp);
free(amp, M_MISCFSMNT);
return (error);
}
+ /*
+ * Unlock the node (either the lower or the alias)
+ */
+ VOP_UNLOCK(vp, 0, p);
/*
* Keep a held reference to the root vnode.
* It is vrele'd in umapfs_unmount.
*/
- umapm_rootvp = vp;
- umapm_rootvp->v_flag |= VROOT;
- amp->umapm_rootvp = umapm_rootvp;
- if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
- mp->mnt_flag |= MNT_LOCAL;
- mp->mnt_data = (qaddr_t) amp;
- vfs_getnewfsid(mp);
+ vp->v_flag |= VROOT;
+ amp->umapm_rootvp = vp;
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
- bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
- (void) copyinstr(args.target, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
+ memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
+ (void) copyinstr(args.umap_target, mp->mnt_stat.f_mntfromname,
+ MNAMELEN - 1, &size);
+ memset(mp->mnt_stat.f_mntfromname + size, 0, MNAMELEN - size);
#ifdef UMAPFS_DIAGNOSTIC
printf("umapfs_mount: lower %s, alias at %s\n",
mp->mnt_stat.f_mntfromname, mp->mnt_stat.f_mntonname);
@@ -227,21 +245,6 @@ umapfs_mount(mp, path, data, ndp, p)
}
/*
- * VFS start. Nothing needed here - the start routine
- * on the underlying filesystem will have been called
- * when that filesystem was mounted.
- */
-int
-umapfs_start(mp, flags, p)
- struct mount *mp;
- int flags;
- struct proc *p;
-{
-
- return (0);
-}
-
-/*
* Free reference to umap layer
*/
int
@@ -250,7 +253,7 @@ umapfs_unmount(mp, mntflags, p)
int mntflags;
struct proc *p;
{
- struct vnode *umapm_rootvp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
+ struct vnode *rootvp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
int error;
int flags = 0;
@@ -258,9 +261,8 @@ umapfs_unmount(mp, mntflags, p)
printf("umapfs_unmount(mp = %p)\n", mp);
#endif
- if (mntflags & MNT_FORCE) {
+ if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- }
/*
* Clear out buffer cache. I don't think we
@@ -272,22 +274,22 @@ umapfs_unmount(mp, mntflags, p)
if (mntinvalbuf(mp, 1))
return (EBUSY);
#endif
- if (umapm_rootvp->v_usecount > 1 && !(flags & FORCECLOSE))
+ if (rootvp->v_usecount > 1)
return (EBUSY);
- if ((error = vflush(mp, umapm_rootvp, flags)) != 0)
+ if ((error = vflush(mp, rootvp, flags)) != 0)
return (error);
#ifdef UMAPFS_DIAGNOSTIC
- vprint("alias root of lower", umapm_rootvp);
+ vprint("alias root of lower", rootvp);
#endif
/*
* Release reference on underlying root vnode
*/
- vrele(umapm_rootvp);
+ vrele(rootvp);
/*
* And blow it away for future re-use
*/
- vgone(umapm_rootvp);
+ vgone(rootvp);
/*
* Finally, throw away the umap_mount structure
*/
@@ -296,138 +298,25 @@ umapfs_unmount(mp, mntflags, p)
return (0);
}
-int
-umapfs_root(mp, vpp)
- struct mount *mp;
- struct vnode **vpp;
-{
- struct proc *p = curproc;
- struct vnode *vp;
+extern const struct vnodeopv_desc umapfs_vnodeop_opv_desc;
-#ifdef UMAPFS_DIAGNOSTIC
- printf("umapfs_root(mp = %p, vp = %p->%p)\n", mp,
- MOUNTTOUMAPMOUNT(mp)->umapm_rootvp,
- UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp)
- );
-#endif
-
- /*
- * Return locked reference to root.
- */
- vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
- VREF(vp);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
- *vpp = vp;
- return (0);
-}
-
-int
-umapfs_quotactl(mp, cmd, uid, arg, p)
- struct mount *mp;
- int cmd;
- uid_t uid;
- caddr_t arg;
- struct proc *p;
-{
- return VFS_QUOTACTL(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, cmd, uid, arg, p);
-}
-
-int
-umapfs_statfs(mp, sbp, p)
- struct mount *mp;
- struct statfs *sbp;
- struct proc *p;
-{
- int error;
- struct statfs mstat;
-
-#ifdef UMAPFS_DIAGNOSTIC
- printf("umapfs_statfs(mp = %p, vp = %p->%p)\n", mp,
- MOUNTTOUMAPMOUNT(mp)->umapm_rootvp,
- UMAPVPTOLOWERVP(MOUNTTOUMAPMOUNT(mp)->umapm_rootvp)
- );
-#endif
-
- bzero(&mstat, sizeof(mstat));
-
- error = VFS_STATFS(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, &mstat, p);
- if (error)
- return (error);
-
- /* now copy across the "interesting" information and fake the rest */
- sbp->f_flags = mstat.f_flags;
- sbp->f_bsize = mstat.f_bsize;
- sbp->f_iosize = mstat.f_iosize;
- sbp->f_blocks = mstat.f_blocks;
- sbp->f_bfree = mstat.f_bfree;
- sbp->f_bavail = mstat.f_bavail;
- sbp->f_files = mstat.f_files;
- sbp->f_ffree = mstat.f_ffree;
- if (sbp != &mp->mnt_stat) {
- bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
- bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
- bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
- }
- strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
- return (0);
-}
-
-int
-umapfs_sync(mp, waitfor, cred, p)
- struct mount *mp;
- int waitfor;
- struct ucred *cred;
- struct proc *p;
-{
- /*
- * XXX - Assumes no data cached at umap layer.
- */
- return (0);
-}
-
-int
-umapfs_vget(mp, ino, vpp)
- struct mount *mp;
- ino_t ino;
- struct vnode **vpp;
-{
- return VFS_VGET(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, ino, vpp);
-}
-
-int
-umapfs_fhtovp(mp, fidp, vpp)
- struct mount *mp;
- struct fid *fidp;
- struct vnode **vpp;
-{
- return VFS_FHTOVP(MOUNTTOUMAPMOUNT(mp)->umapm_vfs, fidp, vpp);
-}
-
-int
-umapfs_vptofh(vp, fhp)
- struct vnode *vp;
- struct fid *fhp;
-{
- return VFS_VPTOFH(UMAPVPTOLOWERVP(vp), fhp);
-}
-
-#define umapfs_sysctl ((int (*)(int *, u_int, void *, size_t *, void *, \
- size_t, struct proc *))eopnotsupp)
-#define umapfs_checkexp ((int (*)(struct mount *, struct mbuf *, \
- int *, struct ucred **))eopnotsupp)
+const struct vnodeopv_desc * const umapfs_vnodeopv_descs[] = {
+ &umapfs_vnodeop_opv_desc,
+ NULL,
+};
-struct vfsops umap_vfsops = {
+struct vfsops umapfs_vfsops = {
umapfs_mount,
- umapfs_start,
+ layerfs_start,
umapfs_unmount,
- umapfs_root,
- umapfs_quotactl,
- umapfs_statfs,
- umapfs_sync,
- umapfs_vget,
- umapfs_fhtovp,
- umapfs_vptofh,
- umapfs_init,
- umapfs_sysctl,
- umapfs_checkexp
+ layerfs_root,
+ layerfs_quotactl,
+ layerfs_statfs,
+ layerfs_sync,
+ layerfs_vget,
+ layerfs_fhtovp,
+ layerfs_vptofh,
+ layerfs_init,
+ layerfs_sysctl,
+ layerfs_checkexp,
};
diff --git a/sys/miscfs/umapfs/umap_vnops.c b/sys/miscfs/umapfs/umap_vnops.c
index c6334821e56..ef8585c0654 100644
--- a/sys/miscfs/umapfs/umap_vnops.c
+++ b/sys/miscfs/umapfs/umap_vnops.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: umap_vnops.c,v 1.15 2002/06/23 03:07:22 deraadt Exp $ */
-/* $NetBSD: umap_vnops.c,v 1.5.4.1 1996/05/25 22:13:35 jtc Exp $ */
+/* $OpenBSD: umap_vnops.c,v 1.16 2003/05/12 21:02:10 tedu Exp $ */
+/* $NetBSD: umap_vnops.c,v 1.22 2002/01/04 07:19:34 chs Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -36,38 +36,29 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)umap_vnops.c 8.3 (Berkeley) 1/5/94
+ * @(#)umap_vnops.c 8.6 (Berkeley) 5/22/95
*/
/*
* Umap Layer
*/
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
-#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/malloc.h>
#include <sys/buf.h>
-#include <miscfs/nullfs/null.h>
#include <miscfs/umapfs/umap.h>
+#include <miscfs/genfs/layer_extern.h>
-
-int umap_bug_bypass = 0; /* for debugging: enables bypass printf'ing */
-
-int umap_bypass(void *);
+int umap_lookup(void *);
int umap_getattr(void *);
-int umap_inactive(void *);
-int umap_reclaim(void *);
int umap_print(void *);
int umap_rename(void *);
-int umap_strategy(void *);
-int umap_bwrite(void *);
-int umap_unlock(void *);
-int umap_lock(void *);
/*
* Global vfs data structures
@@ -77,28 +68,36 @@ int umap_lock(void *);
* go away with a merged buffer/block cache.
*
*/
-int (**umap_vnodeop_p)(void *);
-struct vnodeopv_entry_desc umap_vnodeop_entries[] = {
- { &vop_default_desc, umap_bypass },
-
- { &vop_getattr_desc, umap_getattr },
- { &vop_inactive_desc, umap_inactive },
- { &vop_reclaim_desc, umap_reclaim },
- { &vop_print_desc, umap_print },
- { &vop_rename_desc, umap_rename },
- { &vop_lock_desc, umap_lock },
- { &vop_unlock_desc, umap_unlock },
- { &vop_strategy_desc, umap_strategy },
- { &vop_bwrite_desc, umap_bwrite },
-
+int (**umapfs_vnodeop_p)(void *);
+struct vnodeopv_entry_desc umapfs_vnodeop_entries[] = {
+ { &vop_default_desc, umap_bypass },
+
+ { &vop_lookup_desc, umap_lookup },
+ { &vop_getattr_desc, umap_getattr },
+ { &vop_print_desc, umap_print },
+ { &vop_rename_desc, umap_rename },
+
+ { &vop_lock_desc, layer_lock },
+ { &vop_unlock_desc, layer_unlock },
+ { &vop_islocked_desc, layer_islocked },
+ { &vop_fsync_desc, layer_fsync },
+ { &vop_inactive_desc, layer_inactive },
+ { &vop_reclaim_desc, layer_reclaim },
+ { &vop_open_desc, layer_open },
+ { &vop_setattr_desc, layer_setattr },
+ { &vop_access_desc, layer_access },
+
+ { &vop_strategy_desc, layer_strategy },
+ { &vop_bwrite_desc, layer_bwrite },
+ { &vop_bmap_desc, layer_bmap },
{ NULL, NULL }
};
-struct vnodeopv_desc umap_vnodeop_opv_desc =
- { &umap_vnodeop_p, umap_vnodeop_entries };
+const struct vnodeopv_desc umapfs_vnodeop_opv_desc =
+ { &umapfs_vnodeop_p, umapfs_vnodeop_entries };
/*
- * This is the 10-Apr-92 bypass routine.
- * See null_vnops.c:null_bypass for more details.
+ * This is the 08-June-1999 bypass routine.
+ * See layer_vnops.c:layer_bypass for more details.
*/
int
umap_bypass(v)
@@ -112,26 +111,31 @@ umap_bypass(v)
struct ucred *savecredp = 0, *savecompcredp = 0;
struct ucred *compcredp = 0;
struct vnode **this_vp_p;
- int error = 0;
- struct vnode *old_vps[VDESC_MAX_VPS];
- struct vnode *vp1 = 0;
+ int error, error1;
+ int (**our_vnodeop_p)(void *);
+ struct vnode *old_vps[VDESC_MAX_VPS], *vp0;
struct vnode **vps_p[VDESC_MAX_VPS];
struct vnode ***vppp;
struct vnodeop_desc *descp = ap->a_desc;
- int reles, i;
+ int reles, i, flags;
struct componentname **compnamepp = 0;
- if (umap_bug_bypass)
- printf ("umap_bypass: %s\n", descp->vdesc_name);
-
#ifdef SAFETY
/*
* We require at least one vp.
*/
if (descp->vdesc_vp_offsets == NULL ||
descp->vdesc_vp_offsets[0] == VDESC_NO_OFFSET)
- panic ("umap_bypass: no vp's in map.");
+ panic ("umap_bypass: no vp's in map.\n");
#endif
+ vps_p[0] = VOPARG_OFFSETTO(struct vnode**,descp->vdesc_vp_offsets[0],
+ ap);
+ vp0 = *vps_p[0];
+ flags = MOUNTTOUMAPMOUNT(vp0->v_mount)->umapm_flags;
+ our_vnodeop_p = vp0->v_op;
+
+ if (flags & LAYERFS_MBYPASSDEBUG)
+ printf("umap_bypass: %s\n", descp->vdesc_name);
/*
* Map the vnodes going in.
@@ -145,18 +149,14 @@ umap_bypass(v)
vps_p[i] = this_vp_p =
VOPARG_OFFSETTO(struct vnode**, descp->vdesc_vp_offsets[i], ap);
- if (i == 0) {
- vp1 = *vps_p[0];
- }
-
/*
* We're not guaranteed that any but the first vnode
* are of our type. Check for and don't map any
* that aren't. (Must map first vp or vclean fails.)
*/
- if (i && (*this_vp_p == NULLVP ||
- (*this_vp_p)->v_op != umap_vnodeop_p)) {
+ if (i && ((*this_vp_p)==NULL ||
+ (*this_vp_p)->v_op != our_vnodeop_p)) {
old_vps[i] = NULL;
} else {
old_vps[i] = *this_vp_p;
@@ -171,26 +171,28 @@ umap_bypass(v)
* Fix the credentials. (That's the purpose of this layer.)
*/
- if (descp->vdesc_cred_offset != VDESC_NO_OFFSET
- && *(credpp = VOPARG_OFFSETTO(struct ucred**,
- descp->vdesc_cred_offset, ap)) != NOCRED ) {
+ if (descp->vdesc_cred_offset != VDESC_NO_OFFSET) {
+
+ credpp = VOPARG_OFFSETTO(struct ucred**,
+ descp->vdesc_cred_offset, ap);
/* Save old values */
savecredp = *credpp;
- *credpp = crdup(savecredp);
+ if (savecredp != NOCRED)
+ *credpp = crdup(savecredp);
credp = *credpp;
- if (umap_bug_bypass && credp->cr_uid != 0)
- printf("umap_bypass: user was %u, group %u\n",
+ if ((flags & LAYERFS_MBYPASSDEBUG) && credp->cr_uid != 0)
+ printf("umap_bypass: user was %d, group %d\n",
credp->cr_uid, credp->cr_gid);
/* Map all ids in the credential structure. */
- umap_mapids(vp1->v_mount, credp);
+ umap_mapids(vp0->v_mount, credp);
- if (umap_bug_bypass && credp->cr_uid != 0)
- printf("umap_bypass: user now %u, group %u\n",
+ if ((flags & LAYERFS_MBYPASSDEBUG) && credp->cr_uid != 0)
+ printf("umap_bypass: user now %d, group %d\n",
credp->cr_uid, credp->cr_gid);
}
@@ -198,24 +200,26 @@ umap_bypass(v)
* for speed. If there is one, it better get mapped, too.
*/
- if (descp->vdesc_componentname_offset != VDESC_NO_OFFSET
- && (*(compnamepp = VOPARG_OFFSETTO(struct componentname**,
- descp->vdesc_componentname_offset, ap)))->cn_cred != NOCRED ) {
+ if (descp->vdesc_componentname_offset != VDESC_NO_OFFSET) {
+
+ compnamepp = VOPARG_OFFSETTO(struct componentname**,
+ descp->vdesc_componentname_offset, ap);
savecompcredp = (*compnamepp)->cn_cred;
- (*compnamepp)->cn_cred = crdup(savecompcredp);
+ if (savecompcredp != NOCRED)
+ (*compnamepp)->cn_cred = crdup(savecompcredp);
compcredp = (*compnamepp)->cn_cred;
- if (umap_bug_bypass && compcredp->cr_uid != 0)
- printf("umap_bypass: component credit user was %u, group %u\n",
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp->cr_uid != 0)
+ printf("umap_bypass: component credit user was %d, group %d\n",
compcredp->cr_uid, compcredp->cr_gid);
/* Map all ids in the credential structure. */
- umap_mapids(vp1->v_mount, compcredp);
+ umap_mapids(vp0->v_mount, compcredp);
- if (umap_bug_bypass && compcredp->cr_uid != 0)
- printf("umap_bypass: component credit user now %u, group %u\n",
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp->cr_uid != 0)
+ printf("umap_bypass: component credit user now %d, group %d\n",
compcredp->cr_uid, compcredp->cr_gid);
}
@@ -234,12 +238,14 @@ umap_bypass(v)
for (i = 0; i < VDESC_MAX_VPS; reles >>= 1, i++) {
if (descp->vdesc_vp_offsets[i] == VDESC_NO_OFFSET)
break; /* bail out at end of list */
- if (old_vps[i] != NULLVP) {
+ if (old_vps[i]) {
*(vps_p[i]) = old_vps[i];
- if (reles & 1)
+ if (reles & VDESC_VP0_WILLUNLOCK)
+ LAYERFS_UPPERUNLOCK(*(vps_p[i]), 0, error1);
+ if (reles & VDESC_VP0_WILLRELE)
vrele(*(vps_p[i]));
- };
- };
+ }
+ }
/*
* Map the possible out-going vpp
@@ -249,47 +255,151 @@ umap_bypass(v)
if (descp->vdesc_vpp_offset != VDESC_NO_OFFSET &&
!(descp->vdesc_flags & VDESC_NOMAP_VPP) &&
!error) {
- if (!(descp->vdesc_flags & VDESC_VPP_WILLRELE)) {
- vppp = VOPARG_OFFSETTO(struct vnode***,
- descp->vdesc_vpp_offset, ap);
- error = umap_node_create(old_vps[0]->v_mount,
- **vppp, *vppp);
- }
+ if (descp->vdesc_flags & VDESC_VPP_WILLRELE)
+ goto out;
+ vppp = VOPARG_OFFSETTO(struct vnode***,
+ descp->vdesc_vpp_offset, ap);
+ error = layer_node_create(old_vps[0]->v_mount, **vppp, *vppp);
}
+ out:
/*
* Free duplicate cred structure and restore old one.
*/
- if (descp->vdesc_cred_offset != VDESC_NO_OFFSET
- && *credpp != NOCRED) {
- if (umap_bug_bypass && credp && credp->cr_uid != 0)
- printf("umap_bypass: returning-user was %u\n",
- credp->cr_uid);
-
- crfree(credp);
- *credpp = savecredp;
- if (umap_bug_bypass && credpp && (*credpp)->cr_uid != 0)
- printf("umap_bypass: returning-user now %u\n\n",
- savecredp->cr_uid);
+ if (descp->vdesc_cred_offset != VDESC_NO_OFFSET) {
+ if ((flags & LAYERFS_MBYPASSDEBUG) && credp &&
+ credp->cr_uid != 0)
+ printf("umap_bypass: returning-user was %d\n",
+ credp->cr_uid);
+
+ if (savecredp != NOCRED) {
+ crfree(credp);
+ *credpp = savecredp;
+ if ((flags & LAYERFS_MBYPASSDEBUG) && credpp &&
+ (*credpp)->cr_uid != 0)
+ printf("umap_bypass: returning-user now %d\n\n",
+ savecredp->cr_uid);
+ }
+ }
+
+ if (descp->vdesc_componentname_offset != VDESC_NO_OFFSET) {
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp &&
+ compcredp->cr_uid != 0)
+ printf("umap_bypass: returning-component-user was %d\n",
+ compcredp->cr_uid);
+
+ if (savecompcredp != NOCRED) {
+ crfree(compcredp);
+ (*compnamepp)->cn_cred = savecompcredp;
+ if ((flags & LAYERFS_MBYPASSDEBUG) && savecompcredp &&
+ savecompcredp->cr_uid != 0)
+ printf("umap_bypass: returning-component-user now %d\n",
+ savecompcredp->cr_uid);
+ }
+ }
+
+ return (error);
+}
+
+/*
+ * This is based on the 08-June-1999 bypass routine.
+ * See layer_vnops.c:layer_bypass for more details.
+ */
+int
+umap_lookup(v)
+ void *v;
+{
+ struct vop_lookup_args /* {
+ struct vnodeop_desc *a_desc;
+ struct vnode * a_dvp;
+ struct vnode ** a_vpp;
+ struct componentname * a_cnp;
+ } */ *ap = v;
+ struct componentname *cnp = ap->a_cnp;
+ struct ucred *savecompcredp = NULL;
+ struct ucred *compcredp = NULL;
+ struct vnode *dvp, *vp, *ldvp;
+ struct mount *mp;
+ int error;
+ int i, flags, cnf = cnp->cn_flags;
+
+ dvp = ap->a_dvp;
+ mp = dvp->v_mount;
+
+ if ((cnf & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+ return (EROFS);
+
+ flags = MOUNTTOUMAPMOUNT(mp)->umapm_flags;
+ ldvp = UMAPVPTOLOWERVP(dvp);
+
+ if (flags & LAYERFS_MBYPASSDEBUG)
+ printf("umap_lookup\n");
+
+ /*
+ * Fix the credentials. (That's the purpose of this layer.)
+ *
+ * BSD often keeps a credential in the componentname structure
+ * for speed. If there is one, it better get mapped, too.
+ */
+
+ if ((savecompcredp = cnp->cn_cred)) {
+ compcredp = crdup(savecompcredp);
+ cnp->cn_cred = compcredp;
+
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp->cr_uid != 0)
+ printf("umap_lookup: component credit user was %d, group %d\n",
+ compcredp->cr_uid, compcredp->cr_gid);
+
+ /* Map all ids in the credential structure. */
+ umap_mapids(mp, compcredp);
}
- if (descp->vdesc_componentname_offset != VDESC_NO_OFFSET
- && savecompcredp != NOCRED ) {
- if (umap_bug_bypass && compcredp && compcredp->cr_uid != 0)
- printf("umap_bypass: returning-component-user was %u\n",
- compcredp->cr_uid);
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp->cr_uid != 0)
+ printf("umap_lookup: component credit user now %d, group %d\n",
+ compcredp->cr_uid, compcredp->cr_gid);
+
+ ap->a_dvp = ldvp;
+ error = VCALL(ldvp, ap->a_desc->vdesc_offset, ap);
+ vp = *ap->a_vpp;
+ if (error == EJUSTRETURN && (cnf & ISLASTCN) &&
+ (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
+ (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME))
+ error = EROFS;
+
+ /* Do locking fixup as appropriate. See layer_lookup() for info */
+ if ((cnp->cn_flags & PDIRUNLOCK)) {
+ LAYERFS_UPPERUNLOCK(dvp, 0, i);
+ }
+ if (ldvp == vp) {
+ *ap->a_vpp = dvp;
+ VREF(dvp);
+ vrele(vp);
+ } else if (vp != NULL) {
+ error = layer_node_create(mp, vp, ap->a_vpp);
+ }
+
+ /*
+ * Free duplicate cred structure and restore old one.
+ */
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp &&
+ compcredp->cr_uid != 0)
+ printf("umap_lookup: returning-component-user was %d\n",
+ compcredp->cr_uid);
+
+ if (savecompcredp != NOCRED) {
crfree(compcredp);
- (*compnamepp)->cn_cred = savecompcredp;
- if (umap_bug_bypass && credpp && (*credpp)->cr_uid != 0)
- printf("umap_bypass: returning-component-user now %u\n",
+ cnp->cn_cred = savecompcredp;
+ if ((flags & LAYERFS_MBYPASSDEBUG) && savecompcredp &&
+ savecompcredp->cr_uid != 0)
+ printf("umap_lookup: returning-component-user now %d\n",
savecompcredp->cr_uid);
}
return (error);
}
-
/*
* We handle getattr to change the fsid.
*/
@@ -303,18 +413,20 @@ umap_getattr(v)
struct ucred *a_cred;
struct proc *a_p;
} */ *ap = v;
- uid_t uid;
- gid_t gid;
- int error, tmpid, unentries, gnentries;
- id_map_t umapdata, gmapdata;
- struct vnode **vp1p;
- struct vnodeop_desc *descp = ap->a_desc;
+ uid_t uid;
+ gid_t gid;
+ int error, tmpid, unentries, gnentries, flags;
+ u_long (*mapdata)[2];
+ u_long (*gmapdata)[2];
+ struct vnode **vp1p;
+ const struct vnodeop_desc *descp = ap->a_desc;
if ((error = umap_bypass(ap)) != 0)
return (error);
/* Requires that arguments be restored. */
ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
+ flags = MOUNTTOUMAPMOUNT(ap->a_vp->v_mount)->umapm_flags;
/*
* Umap needs to map the uid and gid returned by a stat
* into the proper values for this site. This involves
@@ -330,25 +442,25 @@ umap_getattr(v)
uid = ap->a_vap->va_uid;
gid = ap->a_vap->va_gid;
- if (umap_bug_bypass)
- printf("umap_getattr: mapped uid = %u, mapped gid = %u\n", uid,
+ if ((flags & LAYERFS_MBYPASSDEBUG))
+ printf("umap_getattr: mapped uid = %d, mapped gid = %d\n", uid,
gid);
vp1p = VOPARG_OFFSETTO(struct vnode**, descp->vdesc_vp_offsets[0], ap);
unentries = MOUNTTOUMAPMOUNT((*vp1p)->v_mount)->info_unentries;
- umapdata = (MOUNTTOUMAPMOUNT((*vp1p)->v_mount)->info_umapdata);
+ mapdata = (MOUNTTOUMAPMOUNT((*vp1p)->v_mount)->info_umapdata);
gnentries = MOUNTTOUMAPMOUNT((*vp1p)->v_mount)->info_gnentries;
- gmapdata = (MOUNTTOUMAPMOUNT((*vp1p)->v_mount)->info_gmapdata);
+ gmapdata = (MOUNTTOUMAPMOUNT((*vp1p)->v_mount)->info_gmapdata);
/* Reverse map the uid for the vnode. Since it's a reverse
map, we can't use umap_mapids() to do it. */
- tmpid = umap_reverse_findid(uid, umapdata, unentries);
+ tmpid = umap_reverse_findid(uid, mapdata, unentries);
if (tmpid != -1) {
ap->a_vap->va_uid = (uid_t) tmpid;
- if (umap_bug_bypass)
- printf("umap_getattr: original uid = %u\n", uid);
+ if ((flags & LAYERFS_MBYPASSDEBUG))
+ printf("umap_getattr: original uid = %d\n", uid);
} else
ap->a_vap->va_uid = (uid_t) NOBODY;
@@ -358,145 +470,14 @@ umap_getattr(v)
if (tmpid != -1) {
ap->a_vap->va_gid = (gid_t) tmpid;
- if (umap_bug_bypass)
- printf("umap_getattr: original gid = %u\n", gid);
+ if ((flags & LAYERFS_MBYPASSDEBUG))
+ printf("umap_getattr: original gid = %d\n", gid);
} else
ap->a_vap->va_gid = (gid_t) NULLGROUP;
return (0);
}
-/*ARGSUSED*/
-int
-umap_inactive(v)
- void *v;
-{
- struct vop_inactive_args /* {
- struct vnode *a_vp;
- struct proc *a_p;
- } */ *ap = v;
- /*
- * Do nothing (and _don't_ bypass).
- * Wait to vrele lowervp until reclaim,
- * so that until then our umap_node is in the
- * cache and reusable.
- *
- */
- VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
- return (0);
-}
-
-/*
- * We need to process our own vnode lock and then clear the
- * interlock flag as it applies only to our vnode, not the
- * vnodes below us on the stack.
- */
-int
-umap_lock(v)
- void *v;
-{
- struct vop_lock_args /* {
- struct vnode *a_vp;
- int a_flags;
- struct proc *a_p;
- } */ *ap = v;
-
-#if 0
- vop_generic_lock(ap);
-#endif
- if ((ap->a_flags & LK_TYPE_MASK) == LK_DRAIN)
- return (0);
- ap->a_flags &= ~LK_INTERLOCK;
- return (umap_bypass(ap));
-}
-
-/*
- * We need to process our own vnode unlock and then clear the
- * interlock flag as it applies only to our vnode, not the
- * vnodes below us on the stack.
- */
-int
-umap_unlock(v)
- void *v;
-{
- struct vop_unlock_args /* {
- struct vnode *a_vp;
- int a_flags;
- struct proc *a_p;
- } */ *ap = v;
-
-#if 0
- vop_generic_unlock(ap);
-#endif
- ap->a_flags &= ~LK_INTERLOCK;
- return (umap_bypass(ap));
-}
-
-
-
-int
-umap_reclaim(v)
- void *v;
-{
- struct vop_reclaim_args /* {
- struct vnode *a_vp;
- } */ *ap = v;
- struct vnode *vp = ap->a_vp;
- struct umap_node *xp = VTOUMAP(vp);
- struct vnode *lowervp = xp->umap_lowervp;
-
- /* After this assignment, this node will not be re-used. */
- xp->umap_lowervp = NULL;
- LIST_REMOVE(xp, umap_hash);
- FREE(vp->v_data, M_TEMP);
- vp->v_data = NULL;
- vrele(lowervp);
- return (0);
-}
-
-int
-umap_strategy(v)
- void *v;
-{
- struct vop_strategy_args /* {
- struct buf *a_bp;
- } */ *ap = v;
- struct buf *bp = ap->a_bp;
- int error;
- struct vnode *savedvp;
-
- savedvp = bp->b_vp;
- bp->b_vp = UMAPVPTOLOWERVP(bp->b_vp);
-
- error = VOP_STRATEGY(ap->a_bp);
-
- bp->b_vp = savedvp;
-
- return (error);
-}
-
-int
-umap_bwrite(v)
- void *v;
-{
- struct vop_bwrite_args /* {
- struct buf *a_bp;
- } */ *ap = v;
- struct buf *bp = ap->a_bp;
- int error;
- struct vnode *savedvp;
-
- savedvp = bp->b_vp;
- bp->b_vp = UMAPVPTOLOWERVP(bp->b_vp);
-
- error = VOP_BWRITE(ap->a_bp);
-
- bp->b_vp = savedvp;
-
- return (error);
-}
-
-
int
umap_print(v)
void *v;
@@ -522,34 +503,35 @@ umap_rename(v)
struct vnode *a_tvp;
struct componentname *a_tcnp;
} */ *ap = v;
- int error;
+ int error, flags;
struct componentname *compnamep;
struct ucred *compcredp, *savecompcredp;
struct vnode *vp;
/*
* Rename is irregular, having two componentname structures.
- * We need to map the cred in the second structure,
+ * We need to map the cre in the second structure,
* and then bypass takes care of the rest.
*/
vp = ap->a_fdvp;
+ flags = MOUNTTOUMAPMOUNT(vp->v_mount)->umapm_flags;
compnamep = ap->a_tcnp;
compcredp = compnamep->cn_cred;
savecompcredp = compcredp;
compcredp = compnamep->cn_cred = crdup(savecompcredp);
- if (umap_bug_bypass && compcredp->cr_uid != 0)
- printf("umap_rename: rename component credit user was %u, group %u\n",
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp->cr_uid != 0)
+ printf("umap_rename: rename component credit user was %d, group %d\n",
compcredp->cr_uid, compcredp->cr_gid);
/* Map all ids in the credential structure. */
umap_mapids(vp->v_mount, compcredp);
- if (umap_bug_bypass && compcredp->cr_uid != 0)
- printf("umap_rename: rename component credit user now %u, group %u\n",
+ if ((flags & LAYERFS_MBYPASSDEBUG) && compcredp->cr_uid != 0)
+ printf("umap_rename: rename component credit user now %d, group %d\n",
compcredp->cr_uid, compcredp->cr_gid);
error = umap_bypass(ap);
@@ -561,4 +543,3 @@ umap_rename(v)
return error;
}
-