diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1997-10-06 21:04:52 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1997-10-06 21:04:52 +0000 |
commit | d042ad0a2a321d6b685d1212df8e2c67b693ea38 (patch) | |
tree | 9b948218c6c8713f2b26a74216c652e6d8d2de78 /sys/miscfs | |
parent | 63fbed82d279556a12545b0450cba696bbe74d53 (diff) |
back out vfs lite2 till after 2.2
Diffstat (limited to 'sys/miscfs')
-rw-r--r-- | sys/miscfs/fdesc/fdesc.h | 4 | ||||
-rw-r--r-- | sys/miscfs/fdesc/fdesc_vfsops.c | 81 | ||||
-rw-r--r-- | sys/miscfs/fdesc/fdesc_vnops.c | 110 | ||||
-rw-r--r-- | sys/miscfs/portal/portal_vfsops.c | 94 | ||||
-rw-r--r-- | sys/miscfs/portal/portal_vnops.c | 78 | ||||
-rw-r--r-- | sys/miscfs/union/union.h | 6 | ||||
-rw-r--r-- | sys/miscfs/union/union_subr.c | 360 | ||||
-rw-r--r-- | sys/miscfs/union/union_vfsops.c | 101 | ||||
-rw-r--r-- | sys/miscfs/union/union_vnops.c | 257 |
9 files changed, 602 insertions, 489 deletions
diff --git a/sys/miscfs/fdesc/fdesc.h b/sys/miscfs/fdesc/fdesc.h index 9a2aa369ad3..35b28bfb755 100644 --- a/sys/miscfs/fdesc/fdesc.h +++ b/sys/miscfs/fdesc/fdesc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fdesc.h,v 1.3 1997/10/06 15:19:00 csapuntz Exp $ */ +/* $OpenBSD: fdesc.h,v 1.4 1997/10/06 21:04:42 deraadt Exp $ */ /* $NetBSD: fdesc.h,v 1.9 1996/02/09 22:40:03 christos Exp $ */ /* @@ -76,7 +76,7 @@ struct fdescnode { #define VTOFDESC(vp) ((struct fdescnode *)(vp)->v_data) extern dev_t devctty; -extern int fdesc_init __P((struct vfsconf *)); +extern void fdesc_init __P((void)); extern int fdesc_root __P((struct mount *, struct vnode **)); extern int fdesc_allocvp __P((fdntype, int, struct mount *, struct vnode **)); extern int (**fdesc_vnodeop_p) __P((void *)); diff --git a/sys/miscfs/fdesc/fdesc_vfsops.c b/sys/miscfs/fdesc/fdesc_vfsops.c index 33a6f5589cc..f6493dd5c4f 100644 --- a/sys/miscfs/fdesc/fdesc_vfsops.c +++ b/sys/miscfs/fdesc/fdesc_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdesc_vfsops.c,v 1.3 1997/10/06 15:19:01 csapuntz Exp $ */ +/* $OpenBSD: fdesc_vfsops.c,v 1.4 1997/10/06 21:04:42 deraadt Exp $ */ /* $NetBSD: fdesc_vfsops.c,v 1.21 1996/02/09 22:40:07 christos Exp $ */ /* @@ -105,7 +105,7 @@ fdesc_mount(mp, path, data, ndp, p) fmp->f_root = rvp; mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t)fmp; - vfs_getnewfsid(mp); + getnewfsid(mp, makefstype(MOUNT_FDESC)); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -131,10 +131,15 @@ fdesc_unmount(mp, mntflags, p) { int error; int flags = 0; + extern int doforce; struct vnode *rootvp = VFSTOFDESC(mp)->f_root; - if (mntflags & MNT_FORCE) + if (mntflags & MNT_FORCE) { + /* fdesc can never be rootfs so don't check for it */ + if (!doforce) + return (EINVAL); flags |= FORCECLOSE; + } /* * Clear out buffer cache. I don't think we @@ -169,18 +174,30 @@ fdesc_root(mp, vpp) struct vnode **vpp; { struct vnode *vp; - struct proc *p = curproc; /* XXX */ + /* * Return locked reference to root. */ vp = VFSTOFDESC(mp)->f_root; VREF(vp); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); *vpp = vp; return (0); } int +fdesc_quotactl(mp, cmd, uid, arg, p) + struct mount *mp; + int cmd; + uid_t uid; + caddr_t arg; + struct proc *p; +{ + + return (EOPNOTSUPP); +} + +int fdesc_statfs(mp, sbp, p) struct mount *mp; struct statfs *sbp; @@ -226,12 +243,11 @@ fdesc_statfs(mp, sbp, p) sbp->f_files = lim + 1; /* Allow for "." */ sbp->f_ffree = freefd; /* See comments above */ if (sbp != &mp->mnt_stat) { - sbp->f_type = mp->mnt_vfc->vfc_typenum; 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); + strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); return (0); } @@ -247,17 +263,46 @@ fdesc_sync(mp, waitfor, uc, p) return (0); } -#define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \ - struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) -#define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ - struct proc *)))eopnotsupp) -#define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ - size_t, struct proc *)))eopnotsupp) -#define fdesc_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ - eopnotsupp) -#define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) - +/* + * Fdesc flat namespace lookup. + * Currently unsupported. + */ +int +fdesc_vget(mp, ino, vpp) + struct mount *mp; + ino_t ino; + struct vnode **vpp; +{ + + return (EOPNOTSUPP); +} + + +/*ARGSUSED*/ +int +fdesc_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) + struct mount *mp; + struct fid *fhp; + struct mbuf *nam; + struct vnode **vpp; + int *exflagsp; + struct ucred **credanonp; +{ + + return (EOPNOTSUPP); +} + +/*ARGSUSED*/ +int +fdesc_vptofh(vp, fhp) + struct vnode *vp; + struct fid *fhp; +{ + return (EOPNOTSUPP); +} + struct vfsops fdesc_vfsops = { + MOUNT_FDESC, fdesc_mount, fdesc_start, fdesc_unmount, @@ -269,6 +314,4 @@ struct vfsops fdesc_vfsops = { fdesc_fhtovp, fdesc_vptofh, fdesc_init, - fdesc_sysctl }; - diff --git a/sys/miscfs/fdesc/fdesc_vnops.c b/sys/miscfs/fdesc/fdesc_vnops.c index 7d916ef544a..c9d702f0e43 100644 --- a/sys/miscfs/fdesc/fdesc_vnops.c +++ b/sys/miscfs/fdesc/fdesc_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdesc_vnops.c,v 1.8 1997/10/06 15:19:01 csapuntz Exp $ */ +/* $OpenBSD: fdesc_vnops.c,v 1.9 1997/10/06 21:04:43 deraadt Exp $ */ /* $NetBSD: fdesc_vnops.c,v 1.32 1996/04/11 11:24:29 mrg Exp $ */ /* @@ -91,10 +91,11 @@ LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl; u_long fdhash; int fdesc_badop __P((void *)); +int fdesc_enotsupp __P((void *)); int fdesc_lookup __P((void *)); -#define fdesc_create eopnotsupp -#define fdesc_mknod eopnotsupp +#define fdesc_create fdesc_enotsupp +#define fdesc_mknod fdesc_enotsupp int fdesc_open __P((void *)); #define fdesc_close nullop #define fdesc_access nullop @@ -104,35 +105,34 @@ int fdesc_read __P((void *)); int fdesc_write __P((void *)); int fdesc_ioctl __P((void *)); int fdesc_select __P((void *)); -#define fdesc_mmap eopnotsupp +#define fdesc_mmap fdesc_enotsupp #define fdesc_fsync nullop #define fdesc_seek nullop -#define fdesc_remove eopnotsupp -#define fdesc_revoke vop_revoke +#define fdesc_remove fdesc_enotsupp int fdesc_link __P((void *)); -#define fdesc_rename eopnotsupp -#define fdesc_mkdir eopnotsupp -#define fdesc_rmdir eopnotsupp +#define fdesc_rename fdesc_enotsupp +#define fdesc_mkdir fdesc_enotsupp +#define fdesc_rmdir fdesc_enotsupp int fdesc_symlink __P((void *)); int fdesc_readdir __P((void *)); int fdesc_readlink __P((void *)); int fdesc_abortop __P((void *)); int fdesc_inactive __P((void *)); int fdesc_reclaim __P((void *)); -#define fdesc_lock vop_nolock -#define fdesc_unlock vop_nounlock +#define fdesc_lock nullop +#define fdesc_unlock nullop #define fdesc_bmap fdesc_badop #define fdesc_strategy fdesc_badop int fdesc_print __P((void *)); int fdesc_pathconf __P((void *)); -#define fdesc_islocked vop_noislocked -#define fdesc_advlock eopnotsupp -#define fdesc_blkatoff eopnotsupp -#define fdesc_valloc eopnotsupp +#define fdesc_islocked nullop +#define fdesc_advlock fdesc_enotsupp +#define fdesc_blkatoff fdesc_enotsupp +#define fdesc_valloc fdesc_enotsupp int fdesc_vfree __P((void *)); -#define fdesc_truncate eopnotsupp -#define fdesc_update eopnotsupp -#define fdesc_bwrite eopnotsupp +#define fdesc_truncate fdesc_enotsupp +#define fdesc_update fdesc_enotsupp +#define fdesc_bwrite fdesc_enotsupp static int fdesc_attr __P((int, struct vattr *, struct ucred *, struct proc *)); @@ -150,7 +150,6 @@ struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = { { &vop_read_desc, fdesc_read }, /* read */ { &vop_write_desc, fdesc_write }, /* write */ { &vop_ioctl_desc, fdesc_ioctl }, /* ioctl */ - { &vop_revoke_desc, fdesc_revoke }, /* revoke */ { &vop_select_desc, fdesc_select }, /* select */ { &vop_mmap_desc, fdesc_mmap }, /* mmap */ { &vop_fsync_desc, fdesc_fsync }, /* fsync */ @@ -189,9 +188,8 @@ struct vnodeopv_desc fdesc_vnodeop_opv_desc = /* * Initialise cache headers */ -int -fdesc_init(vfsp) - struct vfsconf *vfsp; +void +fdesc_init() { int cttymajor; @@ -201,7 +199,6 @@ fdesc_init(vfsp) break; devctty = makedev(cttymajor, 0); fdhashtbl = hashinit(NFDCACHE, M_CACHE, &fdhash); - return (0); } int @@ -211,7 +208,6 @@ fdesc_allocvp(ftype, ix, mp, vpp) struct mount *mp; struct vnode **vpp; { - struct proc *p = curproc; /* XXX */ struct fdhashhead *fc; struct fdescnode *fd; int error = 0; @@ -220,7 +216,7 @@ fdesc_allocvp(ftype, ix, mp, vpp) loop: for (fd = fc->lh_first; fd != 0; fd = fd->fd_hash.le_next) { if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) { - if (vget(fd->fd_vnode, 0, p)) + if (vget(fd->fd_vnode, 0)) goto loop; *vpp = fd->fd_vnode; return (error); @@ -276,23 +272,25 @@ fdesc_lookup(v) } */ *ap = v; struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - char *pname = cnp->cn_nameptr; - struct proc *p = cnp->cn_proc; - int nfiles = p->p_fd->fd_nfiles; + char *pname; + struct proc *p; + int nfiles; unsigned fd = 0; int error; struct vnode *fvp; char *ln; - VOP_UNLOCK(dvp, 0, p); - if (cnp->cn_namelen == 1 && *pname == '.') { + pname = ap->a_cnp->cn_nameptr; + if (ap->a_cnp->cn_namelen == 1 && *pname == '.') { *vpp = dvp; - VREF(dvp); - vn_lock(dvp, LK_SHARED | LK_RETRY, p); + VREF(dvp); + VOP_LOCK(dvp); return (0); } + p = ap->a_cnp->cn_proc; + nfiles = p->p_fd->fd_nfiles; + switch (VTOFDESC(dvp)->fd_type) { default: case Flink: @@ -302,17 +300,17 @@ fdesc_lookup(v) goto bad; case Froot: - if (cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) { + if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) { error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp); if (error) goto bad; *vpp = fvp; fvp->v_type = VDIR; - vn_lock(fvp, LK_SHARED | LK_RETRY, p); + VOP_LOCK(fvp); return (0); } - if (cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) { + if (ap->a_cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) { struct vnode *ttyvp = cttyvp(p); if (ttyvp == NULL) { error = ENXIO; @@ -323,12 +321,12 @@ fdesc_lookup(v) goto bad; *vpp = fvp; fvp->v_type = VCHR; - vn_lock(fvp, LK_SHARED | LK_RETRY, p); + VOP_LOCK(fvp); return (0); } ln = 0; - switch (cnp->cn_namelen) { + switch (ap->a_cnp->cn_namelen) { case 5: if (bcmp(pname, "stdin", 5) == 0) { ln = "fd/0"; @@ -354,7 +352,7 @@ fdesc_lookup(v) VTOFDESC(fvp)->fd_link = ln; *vpp = fvp; fvp->v_type = VLNK; - vn_lock(fvp, LK_SHARED | LK_RETRY, p); + VOP_LOCK(fvp); return (0); } else { error = ENOENT; @@ -364,11 +362,9 @@ fdesc_lookup(v) /* FALL THROUGH */ case Fdevfd: - if (cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) { - if ((error = fdesc_root(dvp->v_mount, vpp))) - goto bad; - - return (0); + if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) { + error = fdesc_root(dvp->v_mount, vpp); + return (error); } fd = 0; @@ -392,13 +388,11 @@ fdesc_lookup(v) if (error) goto bad; VTOFDESC(fvp)->fd_fd = fd; - vn_lock(fvp, LK_SHARED | LK_RETRY, p); *vpp = fvp; return (0); } bad:; - vn_lock(dvp, LK_SHARED | LK_RETRY, p); *vpp = NULL; return (error); } @@ -689,14 +683,16 @@ fdesc_readdir(v) struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; + u_long *a_cookies; + int a_ncookies; } */ *ap = v; struct uio *uio = ap->a_uio; struct dirent d; struct filedesc *fdp; int i; int error; + u_long *cookies = ap->a_cookies; + int ncookies = ap->a_ncookies; switch (VTOFDESC(ap->a_vp)->fd_type) { case Fctty: @@ -749,6 +745,8 @@ fdesc_readdir(v) if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) break; + if (ncookies-- > 0) + *cookies++ = i + 1; } } else { for (; i - 2 < fdp->fd_nfiles && uio->uio_resid >= UIO_MX; @@ -774,6 +772,8 @@ fdesc_readdir(v) if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) break; + if (ncookies-- > 0) + *cookies++ = i + 1; } } @@ -916,7 +916,6 @@ fdesc_inactive(v) { struct vop_inactive_args /* { struct vnode *a_vp; - struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; @@ -924,7 +923,6 @@ fdesc_inactive(v) * Clear out the v_type field to avoid * nasty things happening in vgone(). */ - VOP_UNLOCK(vp, 0, ap->a_p); vp->v_type = VNON; return (0); } @@ -1050,6 +1048,18 @@ fdesc_abortop(v) } /* + * /dev/fd vnode unsupported operation + */ +/*ARGSUSED*/ +int +fdesc_enotsupp(v) + void *v; +{ + + return (EOPNOTSUPP); +} + +/* * /dev/fd "should never get here" operation */ /*ARGSUSED*/ diff --git a/sys/miscfs/portal/portal_vfsops.c b/sys/miscfs/portal/portal_vfsops.c index 52cdac6b4f1..f3ee6b53733 100644 --- a/sys/miscfs/portal/portal_vfsops.c +++ b/sys/miscfs/portal/portal_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: portal_vfsops.c,v 1.3 1997/10/06 15:19:08 csapuntz Exp $ */ +/* $OpenBSD: portal_vfsops.c,v 1.4 1997/10/06 21:04:46 deraadt Exp $ */ /* $NetBSD: portal_vfsops.c,v 1.14 1996/02/09 22:40:41 christos Exp $ */ /* @@ -63,15 +63,25 @@ #include <sys/un.h> #include <miscfs/portal/portal.h> -#define portal_init ((int (*) __P((struct vfsconf *)))nullop) - +void portal_init __P((void)); int portal_mount __P((struct mount *, char *, caddr_t, struct nameidata *, struct proc *)); int portal_start __P((struct mount *, int, struct proc *)); int portal_unmount __P((struct mount *, int, struct proc *)); int portal_root __P((struct mount *, struct vnode **)); +int portal_quotactl __P((struct mount *, int, uid_t, caddr_t, + struct proc *)); int portal_statfs __P((struct mount *, struct statfs *, struct proc *)); +int portal_sync __P((struct mount *, int, struct ucred *, struct proc *)); +int portal_vget __P((struct mount *, ino_t, struct vnode **)); +int portal_fhtovp __P((struct mount *, struct fid *, struct mbuf *, + struct vnode **, int *, struct ucred **)); +int portal_vptofh __P((struct vnode *, struct fid *)); +void +portal_init() +{ +} /* * Mount the per-process file descriptors (/dev/fd) @@ -126,7 +136,7 @@ portal_mount(mp, path, data, ndp, p) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t)fmp; - vfs_getnewfsid(mp); + getnewfsid(mp, makefstype(MOUNT_PORTAL)); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -152,10 +162,14 @@ portal_unmount(mp, mntflags, p) int mntflags; struct proc *p; { + extern int doforce; struct vnode *rootvp = VFSTOPORTAL(mp)->pm_root; int error, flags = 0; if (mntflags & MNT_FORCE) { + /* portal can never be rootfs so don't check for it */ + if (!doforce) + return (EINVAL); flags |= FORCECLOSE; } @@ -207,19 +221,30 @@ portal_root(mp, vpp) struct vnode **vpp; { struct vnode *vp; - struct proc *p = curproc; /* * Return locked reference to root. */ vp = VFSTOPORTAL(mp)->pm_root; VREF(vp); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); *vpp = vp; return (0); } int +portal_quotactl(mp, cmd, uid, arg, p) + struct mount *mp; + int cmd; + uid_t uid; + caddr_t arg; + struct proc *p; +{ + + return (EOPNOTSUPP); +} + +int portal_statfs(mp, sbp, p) struct mount *mp; struct statfs *sbp; @@ -239,30 +264,60 @@ portal_statfs(mp, sbp, p) sbp->f_files = 1; /* Allow for "." */ sbp->f_ffree = 0; /* See comments above */ if (sbp != &mp->mnt_stat) { - sbp->f_type = mp->mnt_vfc->vfc_typenum; 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); + strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); return (0); } +/*ARGSUSED*/ +int +portal_sync(mp, waitfor, uc, p) + struct mount *mp; + int waitfor; + struct ucred *uc; + struct proc *p; +{ -#define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \ - struct proc *)))nullop) + return (0); +} -#define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \ - struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) -#define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ - struct proc *)))eopnotsupp) -#define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ - size_t, struct proc *)))eopnotsupp) -#define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ - eopnotsupp) -#define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) +int +portal_vget(mp, ino, vpp) + struct mount *mp; + ino_t ino; + struct vnode **vpp; +{ + + return (EOPNOTSUPP); +} + +int +portal_fhtovp(mp, fhp, mb, vpp, what, anon) + struct mount *mp; + struct fid *fhp; + struct mbuf *mb; + struct vnode **vpp; + int *what; + struct ucred **anon; +{ + + return (EOPNOTSUPP); +} + +int +portal_vptofh(vp, fhp) + struct vnode *vp; + struct fid *fhp; +{ + + return (EOPNOTSUPP); +} struct vfsops portal_vfsops = { + MOUNT_PORTAL, portal_mount, portal_start, portal_unmount, @@ -274,5 +329,4 @@ struct vfsops portal_vfsops = { portal_fhtovp, portal_vptofh, portal_init, - portal_sysctl }; diff --git a/sys/miscfs/portal/portal_vnops.c b/sys/miscfs/portal/portal_vnops.c index b71c8adb103..c2eb92c4aa1 100644 --- a/sys/miscfs/portal/portal_vnops.c +++ b/sys/miscfs/portal/portal_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: portal_vnops.c,v 1.3 1997/10/06 15:19:09 csapuntz Exp $ */ +/* $OpenBSD: portal_vnops.c,v 1.4 1997/10/06 21:04:47 deraadt Exp $ */ /* $NetBSD: portal_vnops.c,v 1.17 1996/02/13 13:12:57 mycroft Exp $ */ /* @@ -70,50 +70,49 @@ static int portal_fileid = PORTAL_ROOTFILEID+1; static void portal_closefd __P((struct proc *, int)); static int portal_connect __P((struct socket *, struct socket *)); - -int portal_badop __P((void *)); +int portal_badop __P((void *)); +int portal_enotsupp __P((void *)); int portal_lookup __P((void *)); -#define portal_create eopnotsupp -#define portal_mknod eopnotsupp +#define portal_create portal_enotsupp +#define portal_mknod portal_enotsupp int portal_open __P((void *)); #define portal_close nullop #define portal_access nullop int portal_getattr __P((void *)); int portal_setattr __P((void *)); -#define portal_read eopnotsupp -#define portal_write eopnotsupp -#define portal_ioctl eopnotsupp -#define portal_select eopnotsupp -#define portal_mmap eopnotsupp +#define portal_read portal_enotsupp +#define portal_write portal_enotsupp +#define portal_ioctl portal_enotsupp +#define portal_select portal_enotsupp +#define portal_mmap portal_enotsupp #define portal_fsync nullop #define portal_seek nullop -#define portal_remove eopnotsupp +#define portal_remove portal_enotsupp int portal_link __P((void *)); -#define portal_rename eopnotsupp -#define portal_mkdir eopnotsupp -#define portal_rmdir eopnotsupp +#define portal_rename portal_enotsupp +#define portal_mkdir portal_enotsupp +#define portal_rmdir portal_enotsupp int portal_symlink __P((void *)); int portal_readdir __P((void *)); -#define portal_revoke vop_revoke -#define portal_readlink eopnotsupp +#define portal_readlink portal_enotsupp int portal_abortop __P((void *)); int portal_inactive __P((void *)); int portal_reclaim __P((void *)); -#define portal_lock vop_nolock -#define portal_unlock vop_nounlock +#define portal_lock nullop +#define portal_unlock nullop #define portal_bmap portal_badop #define portal_strategy portal_badop int portal_print __P((void *)); -#define portal_islocked vop_noislocked +#define portal_islocked nullop int portal_pathconf __P((void *)); -#define portal_advlock eopnotsupp -#define portal_blkatoff eopnotsupp -#define portal_valloc eopnotsupp +#define portal_advlock portal_enotsupp +#define portal_blkatoff portal_enotsupp +#define portal_valloc portal_enotsupp int portal_vfree __P((void *)); -#define portal_truncate eopnotsupp -#define portal_update eopnotsupp -#define portal_bwrite eopnotsupp +#define portal_truncate portal_enotsupp +#define portal_update portal_enotsupp +#define portal_bwrite portal_enotsupp int (**portal_vnodeop_p) __P((void *)); struct vnodeopv_entry_desc portal_vnodeop_entries[] = { @@ -130,7 +129,6 @@ struct vnodeopv_entry_desc portal_vnodeop_entries[] = { { &vop_write_desc, portal_write }, /* write */ { &vop_ioctl_desc, portal_ioctl }, /* ioctl */ { &vop_select_desc, portal_select }, /* select */ - { &vop_revoke_desc, portal_revoke }, /* revoke */ { &vop_mmap_desc, portal_mmap }, /* mmap */ { &vop_fsync_desc, portal_fsync }, /* fsync */ { &vop_seek_desc, portal_seek }, /* seek */ @@ -598,7 +596,7 @@ int portal_readdir(v) void *v; { - return (0); + return (0); } /*ARGSUSED*/ @@ -606,12 +604,7 @@ int portal_inactive(v) void *v; { - struct vop_inactive_args /* { - struct vnode *a_vp; - struct proc *a_p; - } */ *ap = v; - VOP_UNLOCK(ap->a_vp, 0, ap->a_p); return (0); } @@ -739,10 +732,27 @@ portal_abortop(v) return (0); } +/* + * Portal vnode unsupported operation + */ +/*ARGSUSED*/ +int +portal_enotsupp(v) + void *v; +{ + + return (EOPNOTSUPP); +} + +/* + * Portal "should never get here" operation + */ +/*ARGSUSED*/ int portal_badop(v) void *v; { - panic ("portal: bad op"); - return (0); + + panic("portal: bad op"); + /* NOTREACHED */ } diff --git a/sys/miscfs/union/union.h b/sys/miscfs/union/union.h index ee541b44dbc..5d71a6ad984 100644 --- a/sys/miscfs/union/union.h +++ b/sys/miscfs/union/union.h @@ -1,4 +1,4 @@ -/* $OpenBSD: union.h,v 1.4 1997/10/06 15:19:16 csapuntz Exp $ */ +/* $OpenBSD: union.h,v 1.5 1997/10/06 21:04:48 deraadt Exp $ */ /* $NetBSD: union.h,v 1.9 1996/02/09 22:41:08 christos Exp $ */ /* @@ -40,8 +40,6 @@ * @(#)union.h 8.9 (Berkeley) 12/10/94 */ -struct vfsconf; - struct union_args { char *target; /* Target of loopback */ int mntflags; /* Options on the mount */ @@ -131,7 +129,7 @@ extern void union_newsize __P((struct vnode *, off_t, off_t)); extern int (**union_vnodeop_p) __P((void *)); extern struct vfsops union_vfsops; -int union_init __P((struct vfsconf *)); +void union_init __P((void)); int union_freevp __P((struct vnode *)); #endif /* _KERNEL */ diff --git a/sys/miscfs/union/union_subr.c b/sys/miscfs/union/union_subr.c index f9b98c0ad55..689dd69b114 100644 --- a/sys/miscfs/union/union_subr.c +++ b/sys/miscfs/union/union_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: union_subr.c,v 1.5 1997/10/06 15:19:17 csapuntz Exp $ */ +/* $OpenBSD: union_subr.c,v 1.6 1997/10/06 21:04:49 deraadt Exp $ */ /* $NetBSD: union_subr.c,v 1.18 1996/02/09 22:41:10 christos Exp $ */ /* @@ -78,7 +78,7 @@ static int union_relookup __P((struct union_mount *, struct vnode *, struct componentname *, char *, int)); int union_vn_close __P((struct vnode *, int, struct ucred *, struct proc *)); static void union_dircache_r __P((struct vnode *, struct vnode ***, int *)); -struct vnode *union_dircache __P((struct vnode *, struct proc *)); +struct vnode *union_dircache __P((struct vnode *)); /* * This variable is used to hold a pointer to a function @@ -105,7 +105,7 @@ int union_check(p, vpp, fp, auio, error) if ((*vpp)->v_op == union_vnodeop_p) { struct vnode *lvp; - lvp = union_dircache(*vpp, p); + lvp = union_dircache(*vpp); if (lvp != NULLVP) { struct vattr va; @@ -122,7 +122,7 @@ int union_check(p, vpp, fp, auio, error) if (lvp != NULLVP) { *error = VOP_OPEN(lvp, FREAD, fp->f_cred, p); - VOP_UNLOCK(lvp, 0, p); + VOP_UNLOCK(lvp); if (*error) { vrele(lvp); @@ -140,9 +140,8 @@ int union_check(p, vpp, fp, auio, error) return (0); }; -int -union_init(vfsp) - struct vfsconf *vfsp; +void +union_init() { int i; @@ -150,7 +149,6 @@ union_init(vfsp) LIST_INIT(&unhead[i]); bzero((caddr_t) unvplock, sizeof(unvplock)); union_check_p = union_check; - return (0); } static int @@ -410,8 +408,7 @@ loop: (un->un_uppervp == uppervp || un->un_uppervp == NULLVP) && (UNIONTOV(un)->v_mount == mp)) { - if (vget(UNIONTOV(un), 0, - cnp ? cnp->cn_proc : NULL)) { + if (vget(UNIONTOV(un), 0)) { union_list_unlock(hash); goto loop; } @@ -649,12 +646,12 @@ union_copyfile(fvp, tvp, cred, p) uio.uio_segflg = UIO_SYSSPACE; uio.uio_offset = 0; - VOP_UNLOCK(fvp, 0, p); /* XXX */ + VOP_UNLOCK(fvp); /* XXX */ VOP_LEASE(fvp, p, cred, LEASE_READ); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, p); - VOP_UNLOCK(tvp, 0, p); /* XXX */ + VOP_LOCK(fvp); /* XXX */ + VOP_UNLOCK(tvp); /* XXX */ VOP_LEASE(tvp, p, cred, LEASE_WRITE); - vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(tvp); /* XXX */ buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK); @@ -722,11 +719,11 @@ union_copyup(un, docopy, cred, p) * XX - should not ignore errors * from VOP_CLOSE */ - vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(lvp); error = VOP_OPEN(lvp, FREAD, cred, p); if (error == 0) { error = union_copyfile(lvp, uvp, cred, p); - VOP_UNLOCK(lvp, 0, p); + VOP_UNLOCK(lvp); (void) VOP_CLOSE(lvp, FREAD, cred, p); } #ifdef UNION_DIAGNOSTIC @@ -736,166 +733,166 @@ union_copyup(un, docopy, cred, p) } un->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(uvp, 0, p); + VOP_UNLOCK(uvp); union_vn_close(uvp, FWRITE, cred, p); - vn_lock(uvp, LK_EXCLUSIVE | LK_RETRY, p); - un->un_flags |= UN_ULOCK; - - /* - * Subsequent IOs will go to the top layer, so - * call close on the lower vnode and open on the - * upper vnode to ensure that the filesystem keeps - * its references counts right. This doesn't do - * the right thing with (cred) and (FREAD) though. - * Ignoring error returns is not right, either. - */ - if (error == 0) { - int i; - - for (i = 0; i < un->un_openl; i++) { - (void) VOP_CLOSE(lvp, FREAD, cred, p); - (void) VOP_OPEN(uvp, FREAD, cred, p); - } - un->un_openl = 0; - } - - return (error); - - } - - static int - union_relookup(um, dvp, vpp, cnp, cn, path, pathlen) - struct union_mount *um; - struct vnode *dvp; - struct vnode **vpp; - struct componentname *cnp; - struct componentname *cn; - char *path; - int pathlen; - { - int error; - - /* - * A new componentname structure must be faked up because - * there is no way to know where the upper level cnp came - * from or what it is being used for. This must duplicate - * some of the work done by NDINIT, some of the work done - * by namei, some of the work done by lookup and some of - * the work done by VOP_LOOKUP when given a CREATE flag. - * Conclusion: Horrible. - * - * The pathname buffer will be FREEed by VOP_MKDIR. - */ - cn->cn_namelen = pathlen; - cn->cn_pnbuf = malloc(cn->cn_namelen+1, M_NAMEI, M_WAITOK); - bcopy(path, cn->cn_pnbuf, cn->cn_namelen); - cn->cn_pnbuf[cn->cn_namelen] = '\0'; - - cn->cn_nameiop = CREATE; - cn->cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN); - cn->cn_proc = cnp->cn_proc; - if (um->um_op == UNMNT_ABOVE) - cn->cn_cred = cnp->cn_cred; - else - cn->cn_cred = um->um_cred; - cn->cn_nameptr = cn->cn_pnbuf; - cn->cn_hash = cnp->cn_hash; - cn->cn_consume = cnp->cn_consume; - - VREF(dvp); - error = relookup(dvp, vpp, cn); - if (!error) - vrele(dvp); - else { - free(cn->cn_pnbuf, M_NAMEI); - cn->cn_pnbuf = 0; - } - - return (error); - } - - /* - * Create a shadow directory in the upper layer. - * The new vnode is returned locked. - * - * (um) points to the union mount structure for access to the - * the mounting process's credentials. - * (dvp) is the directory in which to create the shadow directory. - * it is unlocked on entry and exit. - * (cnp) is the componentname to be created. - * (vpp) is the returned newly created shadow directory, which - * is returned locked. - */ - int - union_mkshadow(um, dvp, cnp, vpp) - struct union_mount *um; - struct vnode *dvp; - struct componentname *cnp; - struct vnode **vpp; - { - int error; - struct vattr va; - struct proc *p = cnp->cn_proc; - struct componentname cn; - - error = union_relookup(um, dvp, vpp, cnp, &cn, - cnp->cn_nameptr, cnp->cn_namelen); - if (error) - return (error); - - if (*vpp) { - VOP_ABORTOP(dvp, &cn); - VOP_UNLOCK(dvp, 0, p); - vrele(*vpp); - *vpp = NULLVP; - return (EEXIST); - } - - /* - * policy: when creating the shadow directory in the - * upper layer, create it owned by the user who did - * the mount, group from parent directory, and mode - * 777 modified by umask (ie mostly identical to the - * mkdir syscall). (jsp, kb) - */ - - VATTR_NULL(&va); - va.va_type = VDIR; - va.va_mode = um->um_cmode; - - /* VOP_LEASE: dvp is locked */ - VOP_LEASE(dvp, p, cn.cn_cred, LEASE_WRITE); - - error = VOP_MKDIR(dvp, vpp, &cn, &va); - return (error); - } - - /* - * Create a whiteout entry in the upper layer. - * - * (um) points to the union mount structure for access to the - * the mounting process's credentials. - * (dvp) is the directory in which to create the whiteout. - * it is locked on entry and exit. - * (cnp) is the componentname to be created. - */ - int - union_mkwhiteout(um, dvp, cnp, path) - struct union_mount *um; - struct vnode *dvp; - struct componentname *cnp; - char *path; - { - int error; - struct proc *p = cnp->cn_proc; - struct vnode *wvp; - struct componentname cn; - - VOP_UNLOCK(dvp, 0, p); - error = union_relookup(um, dvp, &wvp, cnp, &cn, path, strlen(path)); - if (error) { - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); - return (error); + VOP_LOCK(uvp); + un->un_flags |= UN_ULOCK; + + /* + * Subsequent IOs will go to the top layer, so + * call close on the lower vnode and open on the + * upper vnode to ensure that the filesystem keeps + * its references counts right. This doesn't do + * the right thing with (cred) and (FREAD) though. + * Ignoring error returns is not right, either. + */ + if (error == 0) { + int i; + + for (i = 0; i < un->un_openl; i++) { + (void) VOP_CLOSE(lvp, FREAD, cred, p); + (void) VOP_OPEN(uvp, FREAD, cred, p); + } + un->un_openl = 0; + } + + return (error); + +} + +static int +union_relookup(um, dvp, vpp, cnp, cn, path, pathlen) + struct union_mount *um; + struct vnode *dvp; + struct vnode **vpp; + struct componentname *cnp; + struct componentname *cn; + char *path; + int pathlen; +{ + int error; + + /* + * A new componentname structure must be faked up because + * there is no way to know where the upper level cnp came + * from or what it is being used for. This must duplicate + * some of the work done by NDINIT, some of the work done + * by namei, some of the work done by lookup and some of + * the work done by VOP_LOOKUP when given a CREATE flag. + * Conclusion: Horrible. + * + * The pathname buffer will be FREEed by VOP_MKDIR. + */ + cn->cn_namelen = pathlen; + cn->cn_pnbuf = malloc(cn->cn_namelen+1, M_NAMEI, M_WAITOK); + bcopy(path, cn->cn_pnbuf, cn->cn_namelen); + cn->cn_pnbuf[cn->cn_namelen] = '\0'; + + cn->cn_nameiop = CREATE; + cn->cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN); + cn->cn_proc = cnp->cn_proc; + if (um->um_op == UNMNT_ABOVE) + cn->cn_cred = cnp->cn_cred; + else + cn->cn_cred = um->um_cred; + cn->cn_nameptr = cn->cn_pnbuf; + cn->cn_hash = cnp->cn_hash; + cn->cn_consume = cnp->cn_consume; + + VREF(dvp); + error = relookup(dvp, vpp, cn); + if (!error) + vrele(dvp); + else { + free(cn->cn_pnbuf, M_NAMEI); + cn->cn_pnbuf = 0; + } + + return (error); +} + +/* + * Create a shadow directory in the upper layer. + * The new vnode is returned locked. + * + * (um) points to the union mount structure for access to the + * the mounting process's credentials. + * (dvp) is the directory in which to create the shadow directory. + * it is unlocked on entry and exit. + * (cnp) is the componentname to be created. + * (vpp) is the returned newly created shadow directory, which + * is returned locked. + */ +int +union_mkshadow(um, dvp, cnp, vpp) + struct union_mount *um; + struct vnode *dvp; + struct componentname *cnp; + struct vnode **vpp; +{ + int error; + struct vattr va; + struct proc *p = cnp->cn_proc; + struct componentname cn; + + error = union_relookup(um, dvp, vpp, cnp, &cn, + cnp->cn_nameptr, cnp->cn_namelen); + if (error) + return (error); + + if (*vpp) { + VOP_ABORTOP(dvp, &cn); + VOP_UNLOCK(dvp); + vrele(*vpp); + *vpp = NULLVP; + return (EEXIST); + } + + /* + * policy: when creating the shadow directory in the + * upper layer, create it owned by the user who did + * the mount, group from parent directory, and mode + * 777 modified by umask (ie mostly identical to the + * mkdir syscall). (jsp, kb) + */ + + VATTR_NULL(&va); + va.va_type = VDIR; + va.va_mode = um->um_cmode; + + /* VOP_LEASE: dvp is locked */ + VOP_LEASE(dvp, p, cn.cn_cred, LEASE_WRITE); + + error = VOP_MKDIR(dvp, vpp, &cn, &va); + return (error); +} + +/* + * Create a whiteout entry in the upper layer. + * + * (um) points to the union mount structure for access to the + * the mounting process's credentials. + * (dvp) is the directory in which to create the whiteout. + * it is locked on entry and exit. + * (cnp) is the componentname to be created. + */ +int +union_mkwhiteout(um, dvp, cnp, path) + struct union_mount *um; + struct vnode *dvp; + struct componentname *cnp; + char *path; +{ + int error; + struct proc *p = cnp->cn_proc; + struct vnode *wvp; + struct componentname cn; + + VOP_UNLOCK(dvp); + error = union_relookup(um, dvp, &wvp, cnp, &cn, path, strlen(path)); + if (error) { + VOP_LOCK(dvp); + return (error); } if (wvp) { @@ -1021,7 +1018,6 @@ void union_removed_upper(un) struct union_node *un; { - struct proc *p = curproc; /* * We do not set the uppervp to NULLVP here, because lowervp @@ -1041,7 +1037,7 @@ union_removed_upper(un) if (un->un_flags & UN_ULOCK) { un->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(un->un_uppervp, 0, p); + VOP_UNLOCK(un->un_uppervp); } } @@ -1113,9 +1109,8 @@ union_dircache_r(vp, vppp, cntp) } struct vnode * -union_dircache(vp, p) +union_dircache(vp) struct vnode *vp; - struct proc *p; { int cnt; struct vnode *nvp = NULLVP; @@ -1123,7 +1118,8 @@ union_dircache(vp, p) struct vnode **dircache; int error; - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); + dircache = VTOUNION(vp)->un_dircache; if (dircache == 0) { cnt = 0; @@ -1148,7 +1144,7 @@ union_dircache(vp, p) if (*vpp == NULLVP) goto out; - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(*vpp); VREF(*vpp); error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0); if (!error) { @@ -1157,7 +1153,7 @@ union_dircache(vp, p) } out: - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); return (nvp); } diff --git a/sys/miscfs/union/union_vfsops.c b/sys/miscfs/union/union_vfsops.c index bcdff8cd3bf..5c2a188ad85 100644 --- a/sys/miscfs/union/union_vfsops.c +++ b/sys/miscfs/union/union_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: union_vfsops.c,v 1.5 1997/10/06 15:19:17 csapuntz Exp $ */ +/* $OpenBSD: union_vfsops.c,v 1.6 1997/10/06 21:04:50 deraadt Exp $ */ /* $NetBSD: union_vfsops.c,v 1.10 1995/06/18 14:47:47 cgd Exp $ */ /* @@ -64,7 +64,13 @@ int union_mount __P((struct mount *, char *, caddr_t, struct nameidata *, int union_start __P((struct mount *, int, struct proc *)); int union_unmount __P((struct mount *, int, struct proc *)); int union_root __P((struct mount *, struct vnode **)); +int union_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *)); int union_statfs __P((struct mount *, struct statfs *, struct proc *)); +int union_sync __P((struct mount *, int, struct ucred *, struct proc *)); +int union_vget __P((struct mount *, ino_t, struct vnode **)); +int union_fhtovp __P((struct mount *, struct fid *, struct mbuf *, + struct vnode **, int *, struct ucred **)); +int union_vptofh __P((struct vnode *, struct fid *)); /* * Mount union filesystem @@ -208,7 +214,7 @@ union_mount(mp, path, data, ndp, p) mp->mnt_flag |= (um->um_uppervp->v_mount->mnt_flag & MNT_RDONLY); mp->mnt_data = (qaddr_t)um; - vfs_getnewfsid(mp); + getnewfsid(mp, makefstype(MOUNT_UNION)); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -287,12 +293,16 @@ union_unmount(mp, mntflags, p) int error; int freeing; int flags = 0; + extern int doforce; #ifdef UNION_DIAGNOSTIC printf("union_unmount(mp = %p)\n", mp); #endif if (mntflags & MNT_FORCE) { + /* union can never be rootfs so don't check for it */ + if (!doforce) + return (EINVAL); flags |= FORCECLOSE; } @@ -363,7 +373,6 @@ union_root(mp, vpp) struct mount *mp; struct vnode **vpp; { - struct proc *p = curproc; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); int error; int loselock; @@ -376,7 +385,7 @@ union_root(mp, vpp) VOP_ISLOCKED(um->um_uppervp)) { loselock = 1; } else { - vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(um->um_uppervp); loselock = 0; } if (um->um_lowervp) @@ -390,10 +399,9 @@ union_root(mp, vpp) 1); if (error) { - if (loselock) - vrele(um->um_uppervp); - else - vput(um->um_uppervp); + if (!loselock) + VOP_UNLOCK(um->um_uppervp); + vrele(um->um_uppervp); if (um->um_lowervp) vrele(um->um_lowervp); } else { @@ -404,6 +412,19 @@ union_root(mp, vpp) return (error); } +/*ARGSUSED*/ +int +union_quotactl(mp, cmd, uid, arg, p) + struct mount *mp; + int cmd; + uid_t uid; + caddr_t arg; + struct proc *p; +{ + + return (EOPNOTSUPP); +} + int union_statfs(mp, sbp, p) struct mount *mp; @@ -470,29 +491,66 @@ union_statfs(mp, sbp, p) sbp->f_ffree += mstat.f_ffree; if (sbp != &mp->mnt_stat) { - sbp->f_type = mp->mnt_vfc->vfc_typenum; 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); + strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN); return (0); } -#define union_sync ((int (*) __P((struct mount *, int, struct ucred *, \ - struct proc *)))nullop) +/*ARGSUSED*/ +int +union_sync(mp, waitfor, cred, p) + struct mount *mp; + int waitfor; + struct ucred *cred; + struct proc *p; +{ + + /* + * XXX - Assumes no data cached at union layer. + */ + return (0); +} -#define union_fhtovp ((int (*) __P((struct mount *, struct fid *, \ - struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) -#define union_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ - struct proc *)))eopnotsupp) -#define union_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ - size_t, struct proc *)))eopnotsupp) -#define union_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ - eopnotsupp) -#define union_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) +/*ARGSUSED*/ +int +union_vget(mp, ino, vpp) + struct mount *mp; + ino_t ino; + struct vnode **vpp; +{ + + return (EOPNOTSUPP); +} + +/*ARGSUSED*/ +int +union_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp) + struct mount *mp; + struct fid *fidp; + struct mbuf *nam; + struct vnode **vpp; + int *exflagsp; + struct ucred **credanonp; +{ + + return (EOPNOTSUPP); +} + +/*ARGSUSED*/ +int +union_vptofh(vp, fhp) + struct vnode *vp; + struct fid *fhp; +{ + + return (EOPNOTSUPP); +} struct vfsops union_vfsops = { + MOUNT_UNION, union_mount, union_start, union_unmount, @@ -504,5 +562,4 @@ struct vfsops union_vfsops = { union_fhtovp, union_vptofh, union_init, - union_sysctl }; diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c index 3ebaad3721a..36da3175e05 100644 --- a/sys/miscfs/union/union_vnops.c +++ b/sys/miscfs/union/union_vnops.c @@ -1,4 +1,4 @@ -/* $openbsd: union_vnops.c,v 1.6 1996/12/08 17:40:29 kstailey Exp $ */ +/* $OpenBSD: union_vnops.c,v 1.8 1997/10/06 21:04:51 deraadt Exp $ */ /* $NetBSD: union_vnops.c,v 1.30.4.1 1996/05/25 22:10:14 jtc Exp $ */ /* @@ -81,7 +81,6 @@ int union_link __P((void *)); int union_rename __P((void *)); int union_mkdir __P((void *)); int union_rmdir __P((void *)); -int union_revoke __P((void *)); int union_symlink __P((void *)); int union_readdir __P((void *)); int union_readlink __P((void *)); @@ -125,7 +124,6 @@ struct vnodeopv_entry_desc union_vnodeop_entries[] = { { &vop_symlink_desc, union_symlink }, /* symlink */ { &vop_readdir_desc, union_readdir }, /* readdir */ { &vop_readlink_desc, union_readlink }, /* readlink */ - { &vop_revoke_desc, union_revoke }, /* revoke */ { &vop_abortop_desc, union_abortop }, /* abortop */ { &vop_inactive_desc, union_inactive }, /* inactive */ { &vop_reclaim_desc, union_reclaim }, /* reclaim */ @@ -150,22 +148,22 @@ struct vnodeopv_entry_desc union_vnodeop_entries[] = { struct vnodeopv_desc union_vnodeop_opv_desc = { &union_vnodeop_p, union_vnodeop_entries }; -#define FIXUP(un, p) { \ +#define FIXUP(un) { \ if (((un)->un_flags & UN_ULOCK) == 0) { \ - union_fixup(un, p); \ + union_fixup(un); \ } \ } -static void union_fixup __P((struct union_node *, struct proc *)); +static void union_fixup __P((struct union_node *)); static int union_lookup1 __P((struct vnode *, struct vnode **, struct vnode **, struct componentname *)); static void -union_fixup(un, p) +union_fixup(un) struct union_node *un; - struct proc *p; { - vn_lock(un->un_uppervp, LK_EXCLUSIVE | LK_RETRY, p); + + VOP_LOCK(un->un_uppervp); un->un_flags |= UN_ULOCK; } @@ -176,7 +174,6 @@ union_lookup1(udvp, dvpp, vpp, cnp) struct vnode **vpp; struct componentname *cnp; { - struct proc *p = cnp->cn_proc; int error; struct vnode *tdvp; struct vnode *dvp; @@ -202,7 +199,7 @@ union_lookup1(udvp, dvpp, vpp, cnp) *dvpp = dvp = dvp->v_mount->mnt_vnodecovered; vput(tdvp); VREF(dvp); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(dvp); } } @@ -216,7 +213,7 @@ union_lookup1(udvp, dvpp, vpp, cnp) * here to allow it to be unlocked again (phew) in union_lookup. */ if (dvp != tdvp && !(cnp->cn_flags & ISLASTCN)) - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(dvp); dvp = tdvp; @@ -228,18 +225,18 @@ union_lookup1(udvp, dvpp, vpp, cnp) while (dvp != udvp && (dvp->v_type == VDIR) && (mp = dvp->v_mountedhere)) { - if (vfs_busy(mp, 0, 0, p)) + if (mp->mnt_flag & MNT_MLOCK) { + mp->mnt_flag |= MNT_MWAIT; + sleep((caddr_t) mp, PVFS); continue; - - error = VFS_ROOT(mp, &tdvp); - vfs_unbusy(mp, p); - - vput(dvp); + } - if (error) { + if ((error = VFS_ROOT(mp, &tdvp)) != 0) { + vput(dvp); return (error); } + vput(dvp); dvp = tdvp; } @@ -263,7 +260,6 @@ union_lookup(v) struct vnode *upperdvp, *lowerdvp; struct vnode *dvp = ap->a_dvp; struct union_node *dun = VTOUNION(dvp); - struct proc *p = curproc; struct componentname *cnp = ap->a_cnp; int lockparent = cnp->cn_flags & LOCKPARENT; struct union_mount *um = MOUNTTOUNIONMOUNT(dvp->v_mount); @@ -280,9 +276,9 @@ union_lookup(v) if (dvp == NULLVP) return (ENOENT); VREF(dvp); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(dvp); if (!lockparent || !(cnp->cn_flags & ISLASTCN)) - VOP_UNLOCK(ap->a_dvp, 0, p, 0, p); + VOP_UNLOCK(ap->a_dvp); return (0); } #endif @@ -302,7 +298,7 @@ union_lookup(v) * on and just return that vnode. */ if (upperdvp != NULLVP) { - FIXUP(dun, p); + FIXUP(dun); /* * If we're doing `..' in the underlying filesystem, * we must drop our lock on the union node before @@ -314,7 +310,7 @@ union_lookup(v) if (cnp->cn_flags & ISDOTDOT) { /* retain lock on underlying VP: */ dun->un_flags |= UN_KLOCK; - VOP_UNLOCK(dvp, 0, p); + VOP_UNLOCK(dvp); } uerror = union_lookup1(um->um_uppervp, &upperdvp, &uppervp, cnp); @@ -334,7 +330,7 @@ union_lookup(v) * dun->un_uppervp locked currently--so we get it * locked here (don't set the UN_ULOCK flag). */ - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(dvp); } /*if (uppervp == upperdvp) @@ -371,7 +367,7 @@ union_lookup(v) if (lowerdvp != NULLVP && !iswhiteout) { int nameiop; - vn_lock(lowerdvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(lowerdvp); /* * Only do a LOOKUP on the bottom node, since @@ -396,7 +392,7 @@ union_lookup(v) cnp->cn_nameiop = nameiop; if (lowervp != lowerdvp) - VOP_UNLOCK(lowerdvp, 0, p); + VOP_UNLOCK(lowerdvp); if (cnp->cn_consume != 0) { if (uppervp != NULLVP) { @@ -417,7 +413,7 @@ union_lookup(v) lowervp = LOWERVP(dun->un_pvp); if (lowervp != NULLVP) { VREF(lowervp); - vn_lock(lowervp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(lowervp); lerror = 0; } } @@ -466,9 +462,9 @@ union_lookup(v) * locks/etc! */ dun->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(upperdvp, 0, p); + VOP_UNLOCK(upperdvp); uerror = union_mkshadow(um, upperdvp, cnp, &uppervp); - vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(upperdvp); dun->un_flags |= UN_ULOCK; if (uerror) { @@ -482,7 +478,7 @@ union_lookup(v) } if (lowervp != NULLVP) - VOP_UNLOCK(lowervp, 0, p); + VOP_UNLOCK(lowervp); error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp, uppervp, lowervp, 1); @@ -495,7 +491,7 @@ union_lookup(v) } else { if (*ap->a_vpp != dvp) if (!lockparent || !(cnp->cn_flags & ISLASTCN)) - VOP_UNLOCK(dvp, 0, p); + VOP_UNLOCK(dvp); if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.' && *ap->a_vpp != dvp) { @@ -520,21 +516,19 @@ union_create(v) } */ *ap = v; struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp; - struct componentname *cnp = ap->a_cnp; - struct proc *p = cnp->cn_proc; if ((dvp = un->un_uppervp) != NULLVP) { int error; struct vnode *vp; struct mount *mp; - FIXUP(un, p); + FIXUP(un); VREF(dvp); un->un_flags |= UN_KLOCK; mp = ap->a_dvp->v_mount; vput(ap->a_dvp); - error = VOP_CREATE(dvp, &vp, cnp, ap->a_vap); + error = VOP_CREATE(dvp, &vp, ap->a_cnp, ap->a_vap); if (error) return (error); @@ -543,7 +537,7 @@ union_create(v) mp, NULLVP, NULLVP, - cnp, + ap->a_cnp, vp, NULLVP, 1); @@ -566,12 +560,11 @@ union_whiteout(v) int a_flags; } */ *ap = v; struct union_node *un = VTOUNION(ap->a_dvp); - struct proc *p = curproc; if (un->un_uppervp == NULLVP) return (EOPNOTSUPP); - FIXUP(un, p); + FIXUP(un); return (VOP_WHITEOUT(un->un_uppervp, ap->a_cnp, ap->a_flags)); } @@ -587,14 +580,13 @@ union_mknod(v) } */ *ap = v; struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp; - struct proc *p = ap->a_cnp->cn_proc; if ((dvp = un->un_uppervp) != NULLVP) { int error; struct vnode *vp; struct mount *mp; - FIXUP(un, p); + FIXUP(un); VREF(dvp); un->un_flags |= UN_KLOCK; @@ -664,14 +656,14 @@ union_open(v) * Just open the lower vnode */ un->un_openl++; - vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(tvp); error = VOP_OPEN(tvp, mode, cred, p); - VOP_UNLOCK(tvp, 0, p); + VOP_UNLOCK(tvp); return (error); } - FIXUP(un, p); + FIXUP(un); error = VOP_OPEN(tvp, mode, cred, p); @@ -736,15 +728,14 @@ union_access(v) struct union_node *un = VTOUNION(ap->a_vp); int error = EACCES; struct vnode *vp; - struct proc *p = ap->a_p; if ((vp = un->un_uppervp) != NULLVP) { - FIXUP(un, p); + FIXUP(un); return (VOP_ACCESS(vp, ap->a_mode, ap->a_cred, ap->a_p)); } if ((vp = un->un_lowervp) != NULLVP) { - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); error = VOP_ACCESS(vp, ap->a_mode, ap->a_cred, ap->a_p); if (error == 0) { struct union_mount *um = MOUNTTOUNIONMOUNT(ap->a_vp->v_mount); @@ -753,7 +744,7 @@ union_access(v) error = VOP_ACCESS(vp, ap->a_mode, um->um_cred, ap->a_p); } - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); if (error) return (error); } @@ -780,7 +771,7 @@ union_getattr(v) struct vnode *vp = un->un_uppervp; struct vattr *vap; struct vattr va; - struct proc *p = ap->a_p; + /* * Some programs walk the filesystem hierarchy by counting @@ -803,7 +794,7 @@ union_getattr(v) * the union_node's lock flag. */ if (un->un_flags & UN_LOCKED) - FIXUP(un, p); + FIXUP(un); error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p); if (error) @@ -845,7 +836,6 @@ union_setattr(v) struct proc *a_p; } */ *ap = v; struct union_node *un = VTOUNION(ap->a_vp); - struct proc *p = ap->a_p; int error; /* @@ -867,7 +857,7 @@ union_setattr(v) * otherwise return read-only filesystem error. */ if (un->un_uppervp != NULLVP) { - FIXUP(un, p); + FIXUP(un); error = VOP_SETATTR(un->un_uppervp, ap->a_vap, ap->a_cred, ap->a_p); if ((error == 0) && (ap->a_vap->va_size != VNOVAL)) @@ -892,15 +882,14 @@ union_read(v) int error; struct vnode *vp = OTHERVP(ap->a_vp); int dolock = (vp == LOWERVP(ap->a_vp)); - struct proc *p = curproc; if (dolock) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); else - FIXUP(VTOUNION(ap->a_vp), p); + FIXUP(VTOUNION(ap->a_vp)); error = VOP_READ(vp, ap->a_uio, ap->a_ioflag, ap->a_cred); if (dolock) - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); /* * XXX @@ -937,13 +926,12 @@ union_write(v) int error; struct vnode *vp; struct union_node *un = VTOUNION(ap->a_vp); - struct proc *p = curproc; vp = UPPERVP(ap->a_vp); if (vp == NULLVP) panic("union: missing upper layer in write"); - FIXUP(un, p); + FIXUP(un); error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag, ap->a_cred); /* @@ -1039,19 +1027,18 @@ union_fsync(v) } */ *ap = v; int error = 0; struct vnode *targetvp = OTHERVP(ap->a_vp); - struct proc *p = ap->a_p; if (targetvp != NULLVP) { int dolock = (targetvp == LOWERVP(ap->a_vp)); if (dolock) - vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(targetvp); else - FIXUP(VTOUNION(ap->a_vp), p); + FIXUP(VTOUNION(ap->a_vp)); error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, ap->a_p); if (dolock) - VOP_UNLOCK(targetvp, 0, p); + VOP_UNLOCK(targetvp); } return (error); @@ -1089,7 +1076,6 @@ union_remove(v) int error; struct union_node *dun = VTOUNION(ap->a_dvp); struct union_node *un = VTOUNION(ap->a_vp); - struct proc *p = ap->a_cnp->cn_proc; if (dun->un_uppervp == NULLVP) panic("union remove: null upper vnode"); @@ -1099,11 +1085,11 @@ union_remove(v) struct vnode *vp = un->un_uppervp; struct componentname *cnp = ap->a_cnp; - FIXUP(dun, p); + FIXUP(dun); VREF(dvp); dun->un_flags |= UN_KLOCK; vput(ap->a_dvp); - FIXUP(un, p); + FIXUP(un); VREF(vp); un->un_flags |= UN_KLOCK; vput(ap->a_vp); @@ -1114,7 +1100,7 @@ union_remove(v) if (!error) union_removed_upper(un); } else { - FIXUP(dun, p); + FIXUP(dun); error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount), dun->un_uppervp, ap->a_cnp, un->un_path); @@ -1142,7 +1128,6 @@ union_link(v) struct union_node *dun; struct vnode *dvp; struct vnode *vp; - struct proc *p = ap->a_cnp->cn_proc; dun = VTOUNION(ap->a_dvp); @@ -1161,9 +1146,9 @@ union_link(v) /* * needs to be copied up before we can link it. */ - vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(ap->a_vp); if (dun->un_uppervp == un->un_dirvp) { - VOP_UNLOCK(ap->a_dvp, 0, p); + VOP_UNLOCK(ap->a_dvp); } error = union_copyup(un, 1, ap->a_cnp->cn_cred, ap->a_cnp->cn_proc); @@ -1187,18 +1172,18 @@ union_link(v) (error = relookup(ap->a_dvp, &dvp, ap->a_cnp))) { vrele(ap->a_dvp); - VOP_UNLOCK(ap->a_vp, 0, p); + VOP_UNLOCK(ap->a_vp); return EROFS; } if (dvp != NULLVP) { /* The name we want to create has mysteriously appeared (a race?) */ error = EEXIST; - VOP_UNLOCK(ap->a_vp, 0, p); + VOP_UNLOCK(ap->a_vp); goto croak; } } - VOP_UNLOCK(ap->a_vp, 0, p); + VOP_UNLOCK(ap->a_vp); } vp = un->un_uppervp; } @@ -1213,7 +1198,7 @@ croak: return (error); } - FIXUP(dun, p); + FIXUP(dun); VREF(dvp); dun->un_flags |= UN_KLOCK; vput(ap->a_dvp); @@ -1342,16 +1327,15 @@ union_mkdir(v) } */ *ap = v; struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp = un->un_uppervp; - struct proc *p = ap->a_cnp->cn_proc; if (dvp != NULLVP) { int error; struct vnode *vp; - FIXUP(un, p); + FIXUP(un); VREF(dvp); un->un_flags |= UN_KLOCK; - VOP_UNLOCK(ap->a_dvp, 0, p); + VOP_UNLOCK(ap->a_dvp); error = VOP_MKDIR(dvp, &vp, ap->a_cnp, ap->a_vap); if (error) { vrele(ap->a_dvp); @@ -1389,7 +1373,6 @@ union_rmdir(v) int error; struct union_node *dun = VTOUNION(ap->a_dvp); struct union_node *un = VTOUNION(ap->a_vp); - struct proc *p = ap->a_cnp->cn_proc; if (dun->un_uppervp == NULLVP) panic("union rmdir: null upper vnode"); @@ -1399,11 +1382,11 @@ union_rmdir(v) struct vnode *vp = un->un_uppervp; struct componentname *cnp = ap->a_cnp; - FIXUP(dun, p); + FIXUP(dun); VREF(dvp); dun->un_flags |= UN_KLOCK; vput(ap->a_dvp); - FIXUP(un, p); + FIXUP(un); VREF(vp); un->un_flags |= UN_KLOCK; vput(ap->a_vp); @@ -1414,7 +1397,7 @@ union_rmdir(v) if (!error) union_removed_upper(un); } else { - FIXUP(dun, p); + FIXUP(dun); error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount), dun->un_uppervp, ap->a_cnp, un->un_path); @@ -1438,13 +1421,12 @@ union_symlink(v) } */ *ap = v; struct union_node *un = VTOUNION(ap->a_dvp); struct vnode *dvp = un->un_uppervp; - struct proc *p = ap->a_cnp->cn_proc; if (dvp != NULLVP) { int error; struct vnode *vp; - FIXUP(un, p); + FIXUP(un); VREF(dvp); un->un_flags |= UN_KLOCK; vput(ap->a_dvp); @@ -1475,17 +1457,16 @@ union_readdir(v) struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - int *a_ncookies; - u_long **a_cookies; - + u_long *a_cookies; + int a_ncookies; } */ *ap = v; register struct union_node *un = VTOUNION(ap->a_vp); register struct vnode *vp; - struct proc *p = curproc; + if ((vp = un->un_uppervp) == NULLVP) return (0); - FIXUP(un, p); + FIXUP(un); ap->a_vp = vp; return (VCALL(vp, VOFFSET(vop_readdir), ap)); } @@ -1501,18 +1482,16 @@ union_readlink(v) } */ *ap = v; int error; struct vnode *vp = OTHERVP(ap->a_vp); - struct proc *p = curproc; - int dolock = (vp == LOWERVP(ap->a_vp)); if (dolock) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); else - FIXUP(VTOUNION(ap->a_vp), p); + FIXUP(VTOUNION(ap->a_vp)); ap->a_vp = vp; error = VCALL(vp, VOFFSET(vop_readlink), ap); if (dolock) - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); return (error); } @@ -1521,7 +1500,7 @@ union_readlink(v) * When operations want to vput() a union node yet retain a lock on * the upper VP (say, to do some further operations like link(), * mkdir(), ...), they set UN_KLOCK on the union node, then call - * vput() which calls VOP_UNLOCK(, 0, p) and comes here. union_unlock() + * vput() which calls VOP_UNLOCK() and comes here. union_unlock() * unlocks the union node (leaving the upper VP alone), clears the * KLOCK flag, and then returns to vput(). The caller then does whatever * is left to do with the upper VP, and insures that it gets unlocked. @@ -1540,21 +1519,19 @@ union_abortop(v) int error; struct vnode *vp = OTHERVP(ap->a_dvp); struct union_node *un = VTOUNION(ap->a_dvp); - struct proc *p = ap->a_cnp->cn_proc; - int islocked = un->un_flags & UN_LOCKED; int dolock = (vp == LOWERVP(ap->a_dvp)); if (islocked) { if (dolock) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); else - FIXUP(VTOUNION(ap->a_dvp), p); + FIXUP(VTOUNION(ap->a_dvp)); } ap->a_dvp = vp; error = VCALL(vp, VOFFSET(vop_abortop), ap); if (islocked && dolock) - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); return (error); } @@ -1565,7 +1542,6 @@ union_inactive(v) { struct vop_inactive_args /* { struct vnode *a_vp; - struct proc *a_p; } */ *ap = v; struct union_node *un = VTOUNION(ap->a_vp); @@ -1617,40 +1593,34 @@ union_lock(v) struct vop_lock_args *ap = v; struct vnode *vp = ap->a_vp; struct union_node *un; - struct proc *p = ap->a_p; - int flags = ap->a_flags; - int error = 0; - - vop_nolock(ap); - /* - * Need to do real lockmgr-style locking here. - * in the mean time, draining won't work quite right, - * which could lead to a few race conditions. - * the following test was here, but is not quite right, we - * still need to take the lock: - if ((flags & LK_TYPE_MASK) == LK_DRAIN) - return (0); - */ - flags &= ~LK_INTERLOCK; start: - un = VTOUNION(vp); + while (vp->v_flag & VXLOCK) { + vp->v_flag |= VXWANT; + sleep((caddr_t)vp, PINOD); + } + + un = VTOUNION(vp); if (un->un_uppervp != NULLVP) { if (((un->un_flags & UN_ULOCK) == 0) && (vp->v_usecount != 0)) { - error = vn_lock(un->un_uppervp, flags, p); - if (error) - return (error); - un->un_flags |= UN_ULOCK; + /* + * We MUST always use the order of: take upper + * vp lock, manipulate union node flags, drop + * upper vp lock. This code must not be an + * exception. + */ + VOP_LOCK(un->un_uppervp); + un->un_flags |= UN_ULOCK; } #ifdef DIAGNOSTIC if (un->un_flags & UN_KLOCK) { - vprint("union: dangling klock", vp); - panic("union: dangling upper lock (%lx)", vp); + vprint("dangling upper lock", vp); + panic("union: dangling upper lock"); } - #endif - } +#endif + } if (un->un_flags & UN_LOCKED) { #ifdef DIAGNOSTIC @@ -1678,7 +1648,7 @@ start: * When operations want to vput() a union node yet retain a lock on * the upper VP (say, to do some further operations like link(), * mkdir(), ...), they set UN_KLOCK on the union node, then call - * vput() which calls VOP_UNLOCK(, 0, p) and comes here. union_unlock() + * vput() which calls VOP_UNLOCK() and comes here. union_unlock() * unlocks the union node (leaving the upper VP alone), clears the * KLOCK flag, and then returns to vput(). The caller then does whatever * is left to do with the upper VP, and insures that it gets unlocked. @@ -1692,7 +1662,6 @@ union_unlock(v) { struct vop_lock_args *ap = v; struct union_node *un = VTOUNION(ap->a_vp); - struct proc *p = ap->a_p; #ifdef DIAGNOSTIC if ((un->un_flags & UN_LOCKED) == 0) @@ -1705,7 +1674,7 @@ union_unlock(v) un->un_flags &= ~UN_LOCKED; if ((un->un_flags & (UN_ULOCK|UN_KLOCK)) == UN_ULOCK) - VOP_UNLOCK(un->un_uppervp, 0, p); + VOP_UNLOCK(un->un_uppervp); un->un_flags &= ~(UN_ULOCK|UN_KLOCK); @@ -1718,8 +1687,6 @@ union_unlock(v) un->un_pid = 0; #endif - vop_nounlock(v); - return (0); } @@ -1735,18 +1702,17 @@ union_bmap(v) int *a_runp; } */ *ap = v; int error; - struct proc *p = curproc; struct vnode *vp = OTHERVP(ap->a_vp); int dolock = (vp == LOWERVP(ap->a_vp)); if (dolock) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); else - FIXUP(VTOUNION(ap->a_vp), p); + FIXUP(VTOUNION(ap->a_vp)); ap->a_vp = vp; error = VCALL(vp, VOFFSET(vop_bmap), ap); if (dolock) - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); return (error); } @@ -1797,42 +1763,21 @@ union_pathconf(v) } */ *ap = v; int error; struct vnode *vp = OTHERVP(ap->a_vp); - struct proc *p = curproc; int dolock = (vp == LOWERVP(ap->a_vp)); if (dolock) - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_LOCK(vp); else - FIXUP(VTOUNION(ap->a_vp), p); + FIXUP(VTOUNION(ap->a_vp)); ap->a_vp = vp; error = VCALL(vp, VOFFSET(vop_pathconf), ap); if (dolock) - VOP_UNLOCK(vp, 0, p); + VOP_UNLOCK(vp); return (error); } int -union_revoke(v) - void *v; -{ - struct vop_revoke_args /* { - struct vnode *a_vp; - int a_flags; - struct proc *a_p; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - - if (UPPERVP(vp)) - VOP_REVOKE(UPPERVP(vp), ap->a_flags); - if (LOWERVP(vp)) - VOP_REVOKE(LOWERVP(vp), ap->a_flags); - vgone(vp); - - return (0); -} - -int union_advlock(v) void *v; { |