diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1997-11-06 05:59:40 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 1997-11-06 05:59:40 +0000 |
commit | 4e165724f1631d1deee6fd89b941fabdbcc855d4 (patch) | |
tree | 3aca36af68e90377984b00e9f0050674b0763db5 /sys/miscfs | |
parent | fec1be888534eb37405f6bf7a195f28670e1392b (diff) |
Updates for VFS Lite 2 + soft update.
Diffstat (limited to 'sys/miscfs')
29 files changed, 899 insertions, 953 deletions
diff --git a/sys/miscfs/deadfs/dead_vnops.c b/sys/miscfs/deadfs/dead_vnops.c index 8004672c5fb..76b3dd78b91 100644 --- a/sys/miscfs/deadfs/dead_vnops.c +++ b/sys/miscfs/deadfs/dead_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dead_vnops.c,v 1.4 1997/10/06 20:20:20 deraadt Exp $ */ +/* $OpenBSD: dead_vnops.c,v 1.5 1997/11/06 05:58:31 csapuntz Exp $ */ /* $NetBSD: dead_vnops.c,v 1.16 1996/02/13 13:12:48 mycroft Exp $ */ /* @@ -78,11 +78,11 @@ int dead_select __P((void *)); #define dead_inactive nullop #define dead_reclaim nullop int dead_lock __P((void *)); -#define dead_unlock nullop +#define dead_unlock vop_nounlock int dead_bmap __P((void *)); int dead_strategy __P((void *)); int dead_print __P((void *)); -#define dead_islocked nullop +#define dead_islocked vop_noislocked #define dead_pathconf dead_ebadf #define dead_advlock dead_ebadf #define dead_blkatoff dead_badop @@ -279,11 +279,23 @@ dead_lock(v) { struct vop_lock_args /* { struct vnode *a_vp; + int a_flags; + struct proc *a_p; } */ *ap = v; + struct vnode *vp = ap->a_vp; - if (!chkvnlock(ap->a_vp)) - return (0); - return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap)); + /* + * Since we are not using the lock manager, we must clear + * the interlock here. + */ + if (ap->a_flags & LK_INTERLOCK) { + simple_unlock(&vp->v_interlock); + ap->a_flags &= ~LK_INTERLOCK; + } + if (!chkvnlock(vp)) + return (0); + + return (VCALL(vp, VOFFSET(vop_lock), ap)); } /* diff --git a/sys/miscfs/fdesc/fdesc.h b/sys/miscfs/fdesc/fdesc.h index 35b28bfb755..11c60d9b6ee 100644 --- a/sys/miscfs/fdesc/fdesc.h +++ b/sys/miscfs/fdesc/fdesc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fdesc.h,v 1.4 1997/10/06 21:04:42 deraadt Exp $ */ +/* $OpenBSD: fdesc.h,v 1.5 1997/11/06 05:58:32 csapuntz 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 void fdesc_init __P((void)); +extern int fdesc_init __P((struct vfsconf *)); 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 f6493dd5c4f..34801f8edb6 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.4 1997/10/06 21:04:42 deraadt Exp $ */ +/* $OpenBSD: fdesc_vfsops.c,v 1.5 1997/11/06 05:58:32 csapuntz 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; - getnewfsid(mp, makefstype(MOUNT_FDESC)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -131,15 +131,10 @@ fdesc_unmount(mp, mntflags, p) { int error; int flags = 0; - extern int doforce; struct vnode *rootvp = VFSTOFDESC(mp)->f_root; - if (mntflags & MNT_FORCE) { - /* fdesc can never be rootfs so don't check for it */ - if (!doforce) - return (EINVAL); + if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - } /* * Clear out buffer cache. I don't think we @@ -174,30 +169,18 @@ 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); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); *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; @@ -243,11 +226,12 @@ 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_op->vfs_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } @@ -263,46 +247,17 @@ fdesc_sync(mp, waitfor, uc, p) return (0); } -/* - * 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); -} - +#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) + struct vfsops fdesc_vfsops = { - MOUNT_FDESC, fdesc_mount, fdesc_start, fdesc_unmount, @@ -314,4 +269,6 @@ 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 c9d702f0e43..0522be7820e 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.9 1997/10/06 21:04:43 deraadt Exp $ */ +/* $OpenBSD: fdesc_vnops.c,v 1.10 1997/11/06 05:58:33 csapuntz Exp $ */ /* $NetBSD: fdesc_vnops.c,v 1.32 1996/04/11 11:24:29 mrg Exp $ */ /* @@ -91,11 +91,10 @@ 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 fdesc_enotsupp -#define fdesc_mknod fdesc_enotsupp +#define fdesc_create eopnotsupp +#define fdesc_mknod eopnotsupp int fdesc_open __P((void *)); #define fdesc_close nullop #define fdesc_access nullop @@ -105,34 +104,35 @@ int fdesc_read __P((void *)); int fdesc_write __P((void *)); int fdesc_ioctl __P((void *)); int fdesc_select __P((void *)); -#define fdesc_mmap fdesc_enotsupp +#define fdesc_mmap eopnotsupp #define fdesc_fsync nullop #define fdesc_seek nullop -#define fdesc_remove fdesc_enotsupp +#define fdesc_remove eopnotsupp +#define fdesc_revoke vop_revoke int fdesc_link __P((void *)); -#define fdesc_rename fdesc_enotsupp -#define fdesc_mkdir fdesc_enotsupp -#define fdesc_rmdir fdesc_enotsupp +#define fdesc_rename eopnotsupp +#define fdesc_mkdir eopnotsupp +#define fdesc_rmdir eopnotsupp 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 nullop -#define fdesc_unlock nullop +#define fdesc_lock vop_nolock +#define fdesc_unlock vop_nounlock #define fdesc_bmap fdesc_badop #define fdesc_strategy fdesc_badop int fdesc_print __P((void *)); int fdesc_pathconf __P((void *)); -#define fdesc_islocked nullop -#define fdesc_advlock fdesc_enotsupp -#define fdesc_blkatoff fdesc_enotsupp -#define fdesc_valloc fdesc_enotsupp +#define fdesc_islocked vop_noislocked +#define fdesc_advlock eopnotsupp +#define fdesc_blkatoff eopnotsupp +#define fdesc_valloc eopnotsupp int fdesc_vfree __P((void *)); -#define fdesc_truncate fdesc_enotsupp -#define fdesc_update fdesc_enotsupp -#define fdesc_bwrite fdesc_enotsupp +#define fdesc_truncate eopnotsupp +#define fdesc_update eopnotsupp +#define fdesc_bwrite eopnotsupp static int fdesc_attr __P((int, struct vattr *, struct ucred *, struct proc *)); @@ -150,6 +150,7 @@ 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 */ @@ -188,8 +189,9 @@ struct vnodeopv_desc fdesc_vnodeop_opv_desc = /* * Initialise cache headers */ -void -fdesc_init() +int +fdesc_init(vfsp) + struct vfsconf *vfsp; { int cttymajor; @@ -199,6 +201,7 @@ fdesc_init() break; devctty = makedev(cttymajor, 0); fdhashtbl = hashinit(NFDCACHE, M_CACHE, &fdhash); + return (0); } int @@ -208,6 +211,7 @@ 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; @@ -216,7 +220,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)) + if (vget(fd->fd_vnode, 0, p)) goto loop; *vpp = fd->fd_vnode; return (error); @@ -272,25 +276,23 @@ fdesc_lookup(v) } */ *ap = v; struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; - char *pname; - struct proc *p; - int nfiles; + struct componentname *cnp = ap->a_cnp; + char *pname = cnp->cn_nameptr; + struct proc *p = cnp->cn_proc; + int nfiles = p->p_fd->fd_nfiles; unsigned fd = 0; int error; struct vnode *fvp; char *ln; - pname = ap->a_cnp->cn_nameptr; - if (ap->a_cnp->cn_namelen == 1 && *pname == '.') { + VOP_UNLOCK(dvp, 0, p); + if (cnp->cn_namelen == 1 && *pname == '.') { *vpp = dvp; - VREF(dvp); - VOP_LOCK(dvp); + VREF(dvp); + vn_lock(dvp, LK_SHARED | LK_RETRY, p); return (0); } - p = ap->a_cnp->cn_proc; - nfiles = p->p_fd->fd_nfiles; - switch (VTOFDESC(dvp)->fd_type) { default: case Flink: @@ -300,17 +302,17 @@ fdesc_lookup(v) goto bad; case Froot: - if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) { + if (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; - VOP_LOCK(fvp); + vn_lock(fvp, LK_SHARED | LK_RETRY, p); return (0); } - if (ap->a_cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) { + if (cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) { struct vnode *ttyvp = cttyvp(p); if (ttyvp == NULL) { error = ENXIO; @@ -321,12 +323,12 @@ fdesc_lookup(v) goto bad; *vpp = fvp; fvp->v_type = VCHR; - VOP_LOCK(fvp); + vn_lock(fvp, LK_SHARED | LK_RETRY, p); return (0); } ln = 0; - switch (ap->a_cnp->cn_namelen) { + switch (cnp->cn_namelen) { case 5: if (bcmp(pname, "stdin", 5) == 0) { ln = "fd/0"; @@ -352,7 +354,7 @@ fdesc_lookup(v) VTOFDESC(fvp)->fd_link = ln; *vpp = fvp; fvp->v_type = VLNK; - VOP_LOCK(fvp); + vn_lock(fvp, LK_SHARED | LK_RETRY, p); return (0); } else { error = ENOENT; @@ -362,9 +364,11 @@ fdesc_lookup(v) /* FALL THROUGH */ case Fdevfd: - if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) { - error = fdesc_root(dvp->v_mount, vpp); - return (error); + if (cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) { + if ((error = fdesc_root(dvp->v_mount, vpp))) + goto bad; + + return (0); } fd = 0; @@ -388,11 +392,13 @@ 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); } @@ -683,16 +689,14 @@ fdesc_readdir(v) struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - u_long *a_cookies; - int a_ncookies; + int *a_ncookies; + u_long **a_cookies; } */ *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: @@ -745,8 +749,6 @@ 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; @@ -772,8 +774,6 @@ fdesc_readdir(v) if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) break; - if (ncookies-- > 0) - *cookies++ = i + 1; } } @@ -916,6 +916,7 @@ fdesc_inactive(v) { struct vop_inactive_args /* { struct vnode *a_vp; + struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; @@ -923,6 +924,7 @@ 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); } @@ -1048,18 +1050,6 @@ 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/fifofs/fifo.h b/sys/miscfs/fifofs/fifo.h index a8c3b7f4091..8a1f5ed33ba 100644 --- a/sys/miscfs/fifofs/fifo.h +++ b/sys/miscfs/fifofs/fifo.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fifo.h,v 1.4 1997/10/06 20:20:22 deraadt Exp $ */ +/* $OpenBSD: fifo.h,v 1.5 1997/11/06 05:58:33 csapuntz Exp $ */ /* $NetBSD: fifo.h,v 1.10 1996/02/09 22:40:15 christos Exp $ */ /* @@ -60,6 +60,7 @@ int fifo_select __P((void *)); #define fifo_fsync nullop #define fifo_seek fifo_badop #define fifo_remove fifo_badop +#define fifo_revoke vop_revoke #define fifo_link fifo_badop #define fifo_rename fifo_badop #define fifo_mkdir fifo_badop @@ -68,14 +69,14 @@ int fifo_select __P((void *)); #define fifo_readdir fifo_badop #define fifo_readlink fifo_badop #define fifo_abortop fifo_badop -#define fifo_inactive nullop +int fifo_inactive __P((void *)); #define fifo_reclaim nullop -int fifo_lock __P((void *)); -int fifo_unlock __P((void *)); +#define fifo_lock vop_nolock +#define fifo_unlock vop_nounlock int fifo_bmap __P((void *)); #define fifo_strategy fifo_badop int fifo_print __P((void *)); -#define fifo_islocked nullop +#define fifo_islocked vop_noislocked int fifo_pathconf __P((void *)); int fifo_advlock __P((void *)); #define fifo_blkatoff fifo_badop diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index 9b74f82384c..412f0bd6dc2 100644 --- a/sys/miscfs/fifofs/fifo_vnops.c +++ b/sys/miscfs/fifofs/fifo_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fifo_vnops.c,v 1.6 1997/10/06 20:20:23 deraadt Exp $ */ +/* $OpenBSD: fifo_vnops.c,v 1.7 1997/11/06 05:58:34 csapuntz Exp $ */ /* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */ /* @@ -38,13 +38,13 @@ #include <sys/param.h> #include <sys/proc.h> +#include <sys/systm.h> #include <sys/time.h> #include <sys/namei.h> #include <sys/vnode.h> #include <sys/socket.h> #include <sys/socketvar.h> #include <sys/stat.h> -#include <sys/systm.h> #include <sys/ioctl.h> #include <sys/file.h> #include <sys/errno.h> @@ -79,6 +79,7 @@ struct vnodeopv_entry_desc fifo_vnodeop_entries[] = { { &vop_lease_desc, fifo_lease_check }, /* lease */ { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ { &vop_select_desc, fifo_select }, /* select */ + { &vop_revoke_desc, fifo_revoke }, /* revoke */ { &vop_mmap_desc, fifo_mmap }, /* mmap */ { &vop_fsync_desc, fifo_fsync }, /* fsync */ { &vop_seek_desc, fifo_seek }, /* seek */ @@ -147,6 +148,7 @@ fifo_open(v) } */ *ap = v; register struct vnode *vp = ap->a_vp; register struct fifoinfo *fip; + struct proc *p = ap->a_p; struct socket *rso, *wso; int error; static char openstr[] = "fifo"; @@ -196,10 +198,10 @@ fifo_open(v) if (ap->a_mode & O_NONBLOCK) { } else { while (fip->fi_writers == 0) { - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); error = tsleep((caddr_t)&fip->fi_readers, PCATCH | PSOCK, openstr, 0); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); if (error) goto bad; } @@ -213,10 +215,10 @@ fifo_open(v) } } else { while (fip->fi_readers == 0) { - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); error = tsleep((caddr_t)&fip->fi_writers, PCATCH | PSOCK, openstr, 0); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); if (error) goto bad; } @@ -244,6 +246,7 @@ fifo_read(v) } */ *ap = v; register struct uio *uio = ap->a_uio; register struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock; + struct proc *p = uio->uio_procp; int error, startresid; #ifdef DIAGNOSTIC @@ -255,10 +258,10 @@ fifo_read(v) if (ap->a_ioflag & IO_NDELAY) rso->so_state |= SS_NBIO; startresid = uio->uio_resid; - VOP_UNLOCK(ap->a_vp); + VOP_UNLOCK(ap->a_vp, 0, p); error = soreceive(rso, (struct mbuf **)0, uio, (struct mbuf **)0, (struct mbuf **)0, (int *)0); - VOP_LOCK(ap->a_vp); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p); /* * Clear EOF indication after first such return. */ @@ -287,6 +290,7 @@ fifo_write(v) struct ucred *a_cred; } */ *ap = v; struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock; + struct proc *p = ap->a_uio->uio_procp; int error; #ifdef DIAGNOSTIC @@ -295,9 +299,9 @@ fifo_write(v) #endif if (ap->a_ioflag & IO_NDELAY) wso->so_state |= SS_NBIO; - VOP_UNLOCK(ap->a_vp); + VOP_UNLOCK(ap->a_vp, 0, p); error = sosend(wso, (struct mbuf *)0, ap->a_uio, 0, (struct mbuf *)0, 0); - VOP_LOCK(ap->a_vp); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p); if (ap->a_ioflag & IO_NDELAY) wso->so_state &= ~SS_NBIO; return (error); @@ -369,6 +373,19 @@ fifo_select(v) return (0); } +int +fifo_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); +} + /* * This is a noop, simply returning what one has been given. */ @@ -381,6 +398,7 @@ fifo_bmap(v) daddr_t a_bn; struct vnode **a_vpp; daddr_t *a_bnp; + int *a_runp; } */ *ap = v; if (ap->a_vpp != NULL) @@ -391,26 +409,6 @@ fifo_bmap(v) } /* - * At the moment we do not do any locking. - */ -/* ARGSUSED */ -int -fifo_lock(v) - void *v; -{ - return (0); -} - -/* ARGSUSED */ -int -fifo_unlock(v) - void *v; -{ - - return (0); -} - -/* * Device close routine */ /* ARGSUSED */ @@ -540,4 +538,5 @@ fifo_badop(v) panic("fifo_badop called"); /* NOTREACHED */ + return(0); } diff --git a/sys/miscfs/kernfs/kernfs.h b/sys/miscfs/kernfs/kernfs.h index 2db3b949b50..4082a030f78 100644 --- a/sys/miscfs/kernfs/kernfs.h +++ b/sys/miscfs/kernfs/kernfs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kernfs.h,v 1.5 1997/10/06 20:20:24 deraadt Exp $ */ +/* $OpenBSD: kernfs.h,v 1.6 1997/11/06 05:58:35 csapuntz Exp $ */ /* $NetBSD: kernfs.h,v 1.10 1996/02/09 22:40:21 christos Exp $ */ /* @@ -77,6 +77,18 @@ struct kernfs_node { #define VFSTOKERNFS(mp) ((struct kernfs_mount *)((mp)->mnt_data)) #define VTOKERN(vp) ((struct kernfs_node *)(vp)->v_data) +#define kernfs_fhtovp ((int (*) __P((struct mount *, struct fid *, \ + struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) +#define kernfs_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ + struct proc *)))eopnotsupp) +#define kernfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ + size_t, struct proc *)))eopnotsupp) +#define kernfs_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ + eopnotsupp) +#define kernfs_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) +#define kernfs_sync ((int (*) __P((struct mount *, int, struct ucred *, \ + struct proc *)))eopnotsupp) + extern int (**kernfs_vnodeop_p) __P((void *)); extern struct vfsops kernfs_vfsops; extern dev_t rrootdev; diff --git a/sys/miscfs/kernfs/kernfs_vfsops.c b/sys/miscfs/kernfs/kernfs_vfsops.c index bdb169f5fff..62a3225db50 100644 --- a/sys/miscfs/kernfs/kernfs_vfsops.c +++ b/sys/miscfs/kernfs/kernfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kernfs_vfsops.c,v 1.7 1997/10/06 20:20:25 deraadt Exp $ */ +/* $OpenBSD: kernfs_vfsops.c,v 1.8 1997/11/06 05:58:35 csapuntz Exp $ */ /* $NetBSD: kernfs_vfsops.c,v 1.26 1996/04/22 01:42:27 christos Exp $ */ /* @@ -59,7 +59,7 @@ dev_t rrootdev = NODEV; -void kernfs_init __P((void)); +int kernfs_init __P((struct vfsconf *)); void kernfs_get_rrootdev __P((void)); int kernfs_mount __P((struct mount *, char *, caddr_t, struct nameidata *, struct proc *)); @@ -67,18 +67,13 @@ int kernfs_start __P((struct mount *, int, struct proc *)); int kernfs_unmount __P((struct mount *, int, struct proc *)); int kernfs_root __P((struct mount *, struct vnode **)); int kernfs_statfs __P((struct mount *, struct statfs *, struct proc *)); -int kernfs_quotactl __P((struct mount *, int, uid_t, caddr_t, - struct proc *)); -int kernfs_sync __P((struct mount *, int, struct ucred *, struct proc *)); -int kernfs_vget __P((struct mount *, ino_t, struct vnode **)); -int kernfs_fhtovp __P((struct mount *, struct fid *, struct mbuf *, - struct vnode **, int *, struct ucred **)); -int kernfs_vptofh __P((struct vnode *, struct fid *)); /*ARGSUSED*/ -void -kernfs_init() +int +kernfs_init(vfsp) + struct vfsconf *vfsp; { + return (0); } void @@ -144,7 +139,7 @@ kernfs_mount(mp, path, data, ndp, p) fmp->kf_root = rvp; mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t)fmp; - getnewfsid(mp, makefstype(MOUNT_KERNFS)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -176,7 +171,6 @@ kernfs_unmount(mp, mntflags, p) { int error; int flags = 0; - extern int doforce; struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root; #ifdef KERNFS_DIAGNOSTIC @@ -184,9 +178,6 @@ kernfs_unmount(mp, mntflags, p) #endif if (mntflags & MNT_FORCE) { - /* kernfs can never be rootfs so don't check for it */ - if (!doforce) - return (EINVAL); flags |= FORCECLOSE; } @@ -225,6 +216,7 @@ kernfs_root(mp, vpp) struct vnode **vpp; { struct vnode *vp; + struct proc *p = curproc; #ifdef KERNFS_DIAGNOSTIC printf("kernfs_root(mp = %p)\n", mp); @@ -235,24 +227,12 @@ kernfs_root(mp, vpp) */ vp = VFSTOKERNFS(mp)->kf_root; VREF(vp); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); *vpp = vp; return (0); } int -kernfs_quotactl(mp, cmd, uid, arg, p) - struct mount *mp; - int cmd; - uid_t uid; - caddr_t arg; - struct proc *p; -{ - - return (EOPNOTSUPP); -} - -int kernfs_statfs(mp, sbp, p) struct mount *mp; struct statfs *sbp; @@ -266,8 +246,6 @@ kernfs_statfs(mp, sbp, p) #ifdef COMPAT_09 sbp->f_type = 7; -#else - sbp->f_type = 0; #endif sbp->f_bsize = cnt.v_page_size; sbp->f_iosize = cnt.v_page_size; @@ -277,66 +255,16 @@ kernfs_statfs(mp, sbp, p) sbp->f_files = desiredvnodes; sbp->f_ffree = desiredvnodes - numvnodes; 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_op->vfs_name, MFSNAMELEN); - return (0); -} - -/*ARGSUSED*/ -int -kernfs_sync(mp, waitfor, uc, p) - struct mount *mp; - int waitfor; - struct ucred *uc; - struct proc *p; -{ - + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } -/* - * Kernfs flat namespace lookup. - * Currently unsupported. - */ -int -kernfs_vget(mp, ino, vpp) - struct mount *mp; - ino_t ino; - struct vnode **vpp; -{ - - return (EOPNOTSUPP); -} - -/*ARGSUSED*/ -int -kernfs_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); -} - -/*ARGSUSED*/ -int -kernfs_vptofh(vp, fhp) - struct vnode *vp; - struct fid *fhp; -{ - - return (EOPNOTSUPP); -} - struct vfsops kernfs_vfsops = { - MOUNT_KERNFS, kernfs_mount, kernfs_start, kernfs_unmount, @@ -348,4 +276,5 @@ struct vfsops kernfs_vfsops = { kernfs_fhtovp, kernfs_vptofh, kernfs_init, + kernfs_sysctl }; diff --git a/sys/miscfs/kernfs/kernfs_vnops.c b/sys/miscfs/kernfs/kernfs_vnops.c index 5606fa5ebdd..7f4a33eea58 100644 --- a/sys/miscfs/kernfs/kernfs_vnops.c +++ b/sys/miscfs/kernfs/kernfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kernfs_vnops.c,v 1.12 1997/10/06 20:20:26 deraadt Exp $ */ +/* $OpenBSD: kernfs_vnops.c,v 1.13 1997/11/06 05:58:38 csapuntz Exp $ */ /* $NetBSD: kernfs_vnops.c,v 1.43 1996/03/16 23:52:47 christos Exp $ */ /* @@ -118,11 +118,10 @@ struct kern_target kern_targets[] = { static int nkern_targets = sizeof(kern_targets) / sizeof(kern_targets[0]); int kernfs_badop __P((void *)); -int kernfs_enotsupp __P((void *)); int kernfs_lookup __P((void *)); -#define kernfs_create kernfs_enotsupp -#define kernfs_mknod kernfs_enotsupp +#define kernfs_create eopnotsupp +#define kernfs_mknod eopnotsupp int kernfs_open __P((void *)); #define kernfs_close nullop int kernfs_access __P((void *)); @@ -130,36 +129,37 @@ int kernfs_getattr __P((void *)); int kernfs_setattr __P((void *)); int kernfs_read __P((void *)); int kernfs_write __P((void *)); -#define kernfs_ioctl kernfs_enotsupp -#define kernfs_select kernfs_enotsupp -#define kernfs_mmap kernfs_enotsupp +#define kernfs_ioctl eopnotsupp +#define kernfs_select eopnotsupp +#define kernfs_mmap eopnotsupp #define kernfs_fsync nullop #define kernfs_seek nullop -#define kernfs_remove kernfs_enotsupp +#define kernfs_remove eopnotsupp int kernfs_link __P((void *)); -#define kernfs_rename kernfs_enotsupp -#define kernfs_mkdir kernfs_enotsupp -#define kernfs_rmdir kernfs_enotsupp +#define kernfs_rename eopnotsupp +#define kernfs_revoke vop_revoke +#define kernfs_mkdir eopnotsupp +#define kernfs_rmdir eopnotsupp int kernfs_symlink __P((void *)); int kernfs_readdir __P((void *)); -#define kernfs_readlink kernfs_enotsupp +#define kernfs_readlink eopnotsupp int kernfs_abortop __P((void *)); int kernfs_inactive __P((void *)); int kernfs_reclaim __P((void *)); -#define kernfs_lock nullop -#define kernfs_unlock nullop +#define kernfs_lock vop_nolock +#define kernfs_unlock vop_nounlock #define kernfs_bmap kernfs_badop #define kernfs_strategy kernfs_badop int kernfs_print __P((void *)); -#define kernfs_islocked nullop +#define kernfs_islocked vop_noislocked int kernfs_pathconf __P((void *)); -#define kernfs_advlock kernfs_enotsupp -#define kernfs_blkatoff kernfs_enotsupp -#define kernfs_valloc kernfs_enotsupp +#define kernfs_advlock eopnotsupp +#define kernfs_blkatoff eopnotsupp +#define kernfs_valloc eopnotsupp int kernfs_vfree __P((void *)); -#define kernfs_truncate kernfs_enotsupp -#define kernfs_update kernfs_enotsupp -#define kernfs_bwrite kernfs_enotsupp +#define kernfs_truncate eopnotsupp +#define kernfs_update eopnotsupp +#define kernfs_bwrite eopnotsupp int kernfs_xread __P((struct kern_target *, int, char **, int)); int kernfs_xwrite __P((struct kern_target *, char *, int)); @@ -179,6 +179,7 @@ struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = { { &vop_write_desc, kernfs_write }, /* write */ { &vop_ioctl_desc, kernfs_ioctl }, /* ioctl */ { &vop_select_desc, kernfs_select }, /* select */ + { &vop_revoke_desc, kernfs_revoke }, /* revoke */ { &vop_mmap_desc, kernfs_mmap }, /* mmap */ { &vop_fsync_desc, kernfs_fsync }, /* fsync */ { &vop_seek_desc, kernfs_seek }, /* seek */ @@ -355,6 +356,7 @@ kernfs_lookup(v) struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; char *pname = cnp->cn_nameptr; + struct proc *p = cnp->cn_proc; struct kern_target *kt; struct vnode *fvp; int error, i; @@ -373,7 +375,7 @@ kernfs_lookup(v) if (cnp->cn_namelen == 1 && *pname == '.') { *vpp = dvp; VREF(dvp); - /*VOP_LOCK(dvp);*/ + vn_lock(dvp, LK_SHARED | LK_RETRY, p); return (0); } @@ -381,7 +383,7 @@ kernfs_lookup(v) if (cnp->cn_namelen == 4 && bcmp(pname, "root", 4) == 0) { *vpp = rootdir; VREF(rootdir); - VOP_LOCK(rootdir); + vn_lock(rootdir, LK_SHARED | LK_RETRY, p); return (0); } #endif @@ -396,6 +398,7 @@ kernfs_lookup(v) printf("kernfs_lookup: i = %d, failed", i); #endif + vn_lock(dvp, LK_SHARED | LK_RETRY, p); return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); found: @@ -405,7 +408,7 @@ found: if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp)) return (ENOENT); *vpp = fvp; - if (vget(fvp, 1)) + if (vget(fvp, LK_EXCLUSIVE, p)) goto loop; return (0); } @@ -414,13 +417,16 @@ found: printf("kernfs_lookup: allocate new vnode\n"); #endif error = getnewvnode(VT_KERNFS, dvp->v_mount, kernfs_vnodeop_p, &fvp); - if (error) + if (error) { + vn_lock(dvp, LK_SHARED | LK_RETRY, p); return (error); + } MALLOC(fvp->v_data, void *, sizeof(struct kernfs_node), M_TEMP, M_WAITOK); VTOKERN(fvp)->kf_kt = kt; fvp->v_type = kt->kt_vtype; + vn_lock(fvp, LK_SHARED | LK_RETRY, p); *vpp = fvp; #ifdef KERNFS_DIAGNOSTIC @@ -621,13 +627,10 @@ kernfs_readdir(v) u_long *a_cookies; int a_ncookies; } */ *ap = v; + int error, i; struct uio *uio = ap->a_uio; struct dirent d; struct kern_target *kt; - int i; - int error; - u_long *cookies = ap->a_cookies; - int ncookies = ap->a_ncookies; if (ap->a_vp->v_type != VDIR) return (ENOTDIR); @@ -663,8 +666,6 @@ kernfs_readdir(v) if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) break; - if (ncookies-- > 0) - *cookies++ = i + 1; } uio->uio_offset = i; @@ -677,6 +678,7 @@ kernfs_inactive(v) { struct vop_inactive_args /* { struct vnode *a_vp; + struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; @@ -687,6 +689,7 @@ kernfs_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); } @@ -817,18 +820,6 @@ kernfs_abortop(v) } /* - * /dev/fd vnode unsupported operation - */ -/*ARGSUSED*/ -int -kernfs_enotsupp(v) - void *v; -{ - - return (EOPNOTSUPP); -} - -/* * /dev/fd "should never get here" operation */ /*ARGSUSED*/ diff --git a/sys/miscfs/nullfs/null.h b/sys/miscfs/nullfs/null.h index a986184915b..3a777e78e34 100644 --- a/sys/miscfs/nullfs/null.h +++ b/sys/miscfs/nullfs/null.h @@ -1,4 +1,4 @@ -/* $OpenBSD: null.h,v 1.6 1997/10/06 20:20:28 deraadt Exp $ */ +/* $OpenBSD: null.h,v 1.7 1997/11/06 05:58:39 csapuntz Exp $ */ /* $NetBSD: null.h,v 1.7 1996/05/17 20:53:11 gwr Exp $ */ /* @@ -92,6 +92,8 @@ extern struct vnode *null_checkvp __P((struct vnode *vp, char *fil, int lno)); extern int (**null_vnodeop_p) __P((void *)); extern struct vfsops null_vfsops; -void nullfs_init __P((void)); +int nullfs_init __P((struct vfsconf *)); +int null_bypass __P((void *)); + #endif /* _KERNEL */ diff --git a/sys/miscfs/nullfs/null_subr.c b/sys/miscfs/nullfs/null_subr.c index f115d70e449..a2b9e9ec6e0 100644 --- a/sys/miscfs/nullfs/null_subr.c +++ b/sys/miscfs/nullfs/null_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: null_subr.c,v 1.6 1997/10/06 20:20:29 deraadt Exp $ */ +/* $OpenBSD: null_subr.c,v 1.7 1997/11/06 05:58:39 csapuntz Exp $ */ /* $NetBSD: null_subr.c,v 1.6 1996/05/10 22:50:52 jtk Exp $ */ /* @@ -42,6 +42,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/proc.h> #include <sys/time.h> #include <sys/types.h> #include <sys/vnode.h> @@ -67,7 +68,6 @@ LIST_HEAD(null_node_hashhead, null_node) *null_node_hashtbl; u_long null_node_hash; -void nullfs_init __P((void)); static struct vnode * null_node_find __P((struct mount *, struct vnode *)); static int @@ -75,14 +75,17 @@ static int /* * Initialise cache headers */ -void -nullfs_init() +/*ARGSUSED*/ +int +nullfs_init(vfsp) + struct vfsconf *vfsp; { #ifdef NULLFS_DIAGNOSTIC printf("nullfs_init\n"); /* printed during system boot */ #endif null_node_hashtbl = hashinit(NNULLNODECACHE, M_CACHE, &null_node_hash); + return (0); } /* @@ -96,6 +99,7 @@ null_node_find(mp, lowervp) struct null_node_hashhead *hd; struct null_node *a; struct vnode *vp; + struct proc *p = curproc; /* * Find hash base, and then search the (two-way) linked @@ -113,7 +117,7 @@ loop: * stuff, but we don't want to lock * the lower node. */ - if (vget(vp, 0)) { + if (vget(vp, 0, p)) { printf ("null_node_find: vget failed.\n"); goto loop; }; @@ -141,6 +145,7 @@ null_node_alloc(mp, lowervp, vpp) struct vnode *vp, *nvp; int error; extern int (**dead_vnodeop_p) __P((void *)); + struct proc *p = curproc; if ((error = getnewvnode(VT_NULL, mp, null_vnodeop_p, &vp)) != 0) return (error); @@ -206,14 +211,14 @@ loop: vgone(cvp); goto loop; } - if (vget(cvp, 0)) /* can't lock; will die! */ + if (vget(cvp, 0, p)) /* can't lock; will die! */ goto loop; break; } vp->v_hashchain = cvpp; vp->v_specnext = *cvpp; - vp->v_specflags = 0; + vp->v_specmountpoint = NULL; *cvpp = vp; #ifdef DIAGNOSTIC if (cvp == NULLVP) @@ -249,6 +254,7 @@ null_node_create(mp, lowervp, newvpp, takelock) int takelock; { struct vnode *aliasvp; + struct proc *p = curproc; /* XXX */ if ((aliasvp = null_node_find(mp, lowervp)) != NULL) { /* @@ -297,7 +303,7 @@ null_node_create(mp, lowervp, newvpp, takelock) upper layer lock */ VTONULL(aliasvp)->null_flags |= NULL_LLOCK; if (takelock) - VOP_LOCK(aliasvp); + vn_lock(aliasvp, LK_EXCLUSIVE | LK_RETRY, p); *newvpp = aliasvp; return (0); diff --git a/sys/miscfs/nullfs/null_vfsops.c b/sys/miscfs/nullfs/null_vfsops.c index 5e59d14d7c7..9b9c3459cab 100644 --- a/sys/miscfs/nullfs/null_vfsops.c +++ b/sys/miscfs/nullfs/null_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: null_vfsops.c,v 1.6 1997/10/06 20:20:30 deraadt Exp $ */ +/* $OpenBSD: null_vfsops.c,v 1.7 1997/11/06 05:58:40 csapuntz Exp $ */ /* $NetBSD: null_vfsops.c,v 1.11 1996/05/10 22:50:56 jtk Exp $ */ /* @@ -48,6 +48,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/proc.h> #include <sys/time.h> #include <sys/types.h> #include <sys/vnode.h> @@ -138,7 +139,7 @@ nullfs_mount(mp, path, data, ndp, p) /* * Unlock the node (either the lower or the alias) */ - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); /* * Make sure the node alias worked */ @@ -158,7 +159,7 @@ nullfs_mount(mp, path, data, ndp, p) if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t) xmp; - getnewfsid(mp, makefstype(MOUNT_LOFS)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -200,16 +201,12 @@ nullfs_unmount(mp, mntflags, p) struct vnode *nullm_rootvp = MOUNTTONULLMOUNT(mp)->nullm_rootvp; int error; int flags = 0; - extern int doforce; #ifdef NULLFS_DIAGNOSTIC printf("nullfs_unmount(mp = %p)\n", mp); #endif if (mntflags & MNT_FORCE) { - /* lofs can never be rootfs so don't check for it */ - if (!doforce) - return (EINVAL); flags |= FORCECLOSE; } @@ -253,6 +250,7 @@ nullfs_root(mp, vpp) struct vnode **vpp; { struct vnode *vp; + struct proc *p = curproc; #ifdef NULLFS_DIAGNOSTIC printf("nullfs_root(mp = %p, vp = %p->%p)\n", mp, @@ -266,7 +264,7 @@ nullfs_root(mp, vpp) */ vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp; VREF(vp); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); *vpp = vp; return 0; } @@ -320,7 +318,7 @@ nullfs_statfs(mp, sbp, p) 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_op->vfs_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } @@ -370,8 +368,10 @@ nullfs_vptofh(vp, fhp) return (EOPNOTSUPP); } +#define nullfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ + size_t, struct proc *)))eopnotsupp) + struct vfsops null_vfsops = { - MOUNT_NULL, nullfs_mount, nullfs_start, nullfs_unmount, @@ -383,4 +383,5 @@ struct vfsops null_vfsops = { nullfs_fhtovp, nullfs_vptofh, nullfs_init, + nullfs_sysctl }; diff --git a/sys/miscfs/nullfs/null_vnops.c b/sys/miscfs/nullfs/null_vnops.c index b5d2775bba1..f12f7389d25 100644 --- a/sys/miscfs/nullfs/null_vnops.c +++ b/sys/miscfs/nullfs/null_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: null_vnops.c,v 1.7 1997/10/06 20:20:31 deraadt Exp $ */ +/* $OpenBSD: null_vnops.c,v 1.8 1997/11/06 05:58:40 csapuntz Exp $ */ /* $NetBSD: null_vnops.c,v 1.7 1996/05/10 22:51:01 jtk Exp $ */ /* @@ -98,10 +98,18 @@ * Although bypass handles most operations, * vop_getattr, _inactive, _reclaim, and _print are not bypassed. * Vop_getattr must change the fsid being returned. + * Vop_lock and vop_unlock must handle any locking for the + * current vnode as well as pass the lock request down. * Vop_inactive and vop_reclaim are not bypassed so that - * they can handle freeing null-layer specific data. - * Vop_print is not bypassed to avoid excessive debugging - * information. + * the can handle freeing null-layer specific data. Vop_print + * is not bypassed to avoid excessive debugging information. + * Also, certain vnod eoperations change the locking state within + * the operation (create, mknod, remove, link, rename, mkdir, rmdir, + * and symlink). Ideally, these operations should not change the + * lock state, but should be changed to let the caller of the + * function unlock them.Otherwise all intermediate vnode layers + * (such as union, umapfs, etc) must catch these functions + * to the necessary locking at their layer * * * INSTANTIATING VNODE STACKS @@ -182,7 +190,6 @@ int null_bug_bypass = 0; /* for debugging: enables bypass printf'ing */ -int null_bypass __P((void *)); int null_getattr __P((void *)); int null_inactive __P((void *)); int null_reclaim __P((void *)); @@ -510,6 +517,7 @@ null_lock(v) struct vop_lock_args *ap = v; struct vnode *vp = ap->a_vp; struct null_node *nn; + struct proc *p = ap->a_p; #ifdef NULLFS_DIAGNOSTIC vprint("null_lock_e", ap->a_vp); @@ -533,7 +541,7 @@ start: * is zero, we are probably being reclaimed so we need to * keep our hands off the lower node. */ - VOP_LOCK(nn->null_lowervp); + vn_lock(nn->null_lowervp, LK_EXCLUSIVE | LK_RETRY, p); nn->null_flags |= NULL_LLOCK; } @@ -568,6 +576,7 @@ null_unlock(v) void *v; { struct vop_lock_args *ap = v; + struct proc *p = ap->a_p; struct null_node *nn = VTONULL(ap->a_vp); #ifdef NULLFS_DIAGNOSTIC @@ -587,7 +596,7 @@ null_unlock(v) nn->null_flags &= ~NULL_LOCKED; if ((nn->null_flags & NULL_LLOCK) != 0) - VOP_UNLOCK(nn->null_lowervp); + VOP_UNLOCK(nn->null_lowervp, 0, p); nn->null_flags &= ~NULL_LLOCK; @@ -623,20 +632,21 @@ null_lookup(v) register int error; register struct vnode *dvp; int flags = ap->a_cnp->cn_flags; - + struct componentname *cnp = ap->a_cnp; + struct proc *p = cnp->cn_proc; #ifdef NULLFS_DIAGNOSTIC - printf("null_lookup: dvp=%p, name='%s'\n", - ap->a_dvp, ap->a_cnp->cn_nameptr); + printf("null_lookup: dvp=%lx, name='%s'\n", + ap->a_dvp, cnp->cn_nameptr); #endif /* * the starting dir (ap->a_dvp) comes in locked. */ /* set LOCKPARENT to hold on to it until done below */ - ap->a_cnp->cn_flags |= LOCKPARENT; + cnp->cn_flags |= LOCKPARENT; error = null_bypass(ap); if (!(flags & LOCKPARENT)) - ap->a_cnp->cn_flags &= ~LOCKPARENT; + cnp->cn_flags &= ~LOCKPARENT; if (error) /* @@ -697,20 +707,20 @@ null_lookup(v) * lock. No need for vget() since we hold a * refcount to the starting directory */ - VOP_UNLOCK(dvp); - VOP_LOCK(*ap->a_vpp); + VOP_UNLOCK(dvp, 0, p); + vn_lock(*ap->a_vpp, LK_EXCLUSIVE | LK_RETRY, p); /* * we should return our directory locked if * (flags & LOCKPARENT) and (flags & ISLASTCN) */ if ((flags & LOCKPARENT) && (flags & ISLASTCN)) - VOP_LOCK(dvp); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); } else { /* * Normal directory locking order: we hold the starting * directory locked; now lock our layer of the target. */ - VOP_LOCK(*ap->a_vpp); + vn_lock(*ap->a_vpp, LK_RETRY | LK_EXCLUSIVE, p); /* * underlying starting dir comes back locked * if lockparent (we set it) and no error @@ -740,7 +750,7 @@ null_lookup(v) * end yet, !(flags & ISLASTCN) */ if (!(flags & LOCKPARENT) || !(flags & ISLASTCN)) - VOP_UNLOCK(dvp); + VOP_UNLOCK(dvp, 0, p); } } return error; diff --git a/sys/miscfs/portal/portal_vfsops.c b/sys/miscfs/portal/portal_vfsops.c index f3ee6b53733..b883d8dc06d 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.4 1997/10/06 21:04:46 deraadt Exp $ */ +/* $OpenBSD: portal_vfsops.c,v 1.5 1997/11/06 05:58:41 csapuntz Exp $ */ /* $NetBSD: portal_vfsops.c,v 1.14 1996/02/09 22:40:41 christos Exp $ */ /* @@ -63,25 +63,15 @@ #include <sys/un.h> #include <miscfs/portal/portal.h> -void portal_init __P((void)); +#define portal_init ((int (*) __P((struct vfsconf *)))nullop) + 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) @@ -136,7 +126,7 @@ portal_mount(mp, path, data, ndp, p) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t)fmp; - getnewfsid(mp, makefstype(MOUNT_PORTAL)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -162,14 +152,10 @@ 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; } @@ -221,30 +207,19 @@ 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); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); *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; @@ -264,60 +239,30 @@ 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_op->vfs_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } -/*ARGSUSED*/ -int -portal_sync(mp, waitfor, uc, p) - struct mount *mp; - int waitfor; - struct ucred *uc; - struct proc *p; -{ - return (0); -} +#define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \ + struct proc *)))nullop) -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); -} +#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) struct vfsops portal_vfsops = { - MOUNT_PORTAL, portal_mount, portal_start, portal_unmount, @@ -329,4 +274,5 @@ 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 c2eb92c4aa1..4a36a0bce39 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.4 1997/10/06 21:04:47 deraadt Exp $ */ +/* $OpenBSD: portal_vnops.c,v 1.5 1997/11/06 05:58:41 csapuntz Exp $ */ /* $NetBSD: portal_vnops.c,v 1.17 1996/02/13 13:12:57 mycroft Exp $ */ /* @@ -70,49 +70,50 @@ 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_enotsupp __P((void *)); + +int portal_badop __P((void *)); int portal_lookup __P((void *)); -#define portal_create portal_enotsupp -#define portal_mknod portal_enotsupp +#define portal_create eopnotsupp +#define portal_mknod eopnotsupp 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 portal_enotsupp -#define portal_write portal_enotsupp -#define portal_ioctl portal_enotsupp -#define portal_select portal_enotsupp -#define portal_mmap portal_enotsupp +#define portal_read eopnotsupp +#define portal_write eopnotsupp +#define portal_ioctl eopnotsupp +#define portal_select eopnotsupp +#define portal_mmap eopnotsupp #define portal_fsync nullop #define portal_seek nullop -#define portal_remove portal_enotsupp +#define portal_remove eopnotsupp int portal_link __P((void *)); -#define portal_rename portal_enotsupp -#define portal_mkdir portal_enotsupp -#define portal_rmdir portal_enotsupp +#define portal_rename eopnotsupp +#define portal_mkdir eopnotsupp +#define portal_rmdir eopnotsupp int portal_symlink __P((void *)); int portal_readdir __P((void *)); -#define portal_readlink portal_enotsupp +#define portal_revoke vop_revoke +#define portal_readlink eopnotsupp int portal_abortop __P((void *)); int portal_inactive __P((void *)); int portal_reclaim __P((void *)); -#define portal_lock nullop -#define portal_unlock nullop +#define portal_lock vop_nolock +#define portal_unlock vop_nounlock #define portal_bmap portal_badop #define portal_strategy portal_badop int portal_print __P((void *)); -#define portal_islocked nullop +#define portal_islocked vop_noislocked int portal_pathconf __P((void *)); -#define portal_advlock portal_enotsupp -#define portal_blkatoff portal_enotsupp -#define portal_valloc portal_enotsupp +#define portal_advlock eopnotsupp +#define portal_blkatoff eopnotsupp +#define portal_valloc eopnotsupp int portal_vfree __P((void *)); -#define portal_truncate portal_enotsupp -#define portal_update portal_enotsupp -#define portal_bwrite portal_enotsupp +#define portal_truncate eopnotsupp +#define portal_update eopnotsupp +#define portal_bwrite eopnotsupp int (**portal_vnodeop_p) __P((void *)); struct vnodeopv_entry_desc portal_vnodeop_entries[] = { @@ -129,6 +130,7 @@ 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 */ @@ -596,7 +598,7 @@ int portal_readdir(v) void *v; { - return (0); + return (0); } /*ARGSUSED*/ @@ -604,7 +606,12 @@ 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); } @@ -732,27 +739,10 @@ 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"); - /* NOTREACHED */ + panic ("portal: bad op"); + return (0); } diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index 413c6509b4f..5741a9349df 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs.h,v 1.7 1997/10/06 20:20:33 deraadt Exp $ */ +/* $OpenBSD: procfs.h,v 1.8 1997/11/06 05:58:42 csapuntz Exp $ */ /* $NetBSD: procfs.h,v 1.17 1996/02/12 15:01:41 christos Exp $ */ /* @@ -128,7 +128,9 @@ int procfs_rw __P((void *)); extern int (**procfs_vnodeop_p) __P((void *)); extern struct vfsops procfs_vfsops; -void procfs_init __P((void)); +struct vfsconf; + +int procfs_init __P((struct vfsconf *)); int procfs_root __P((struct mount *, struct vnode **)); #endif /* _KERNEL */ diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c index 24cae7cb845..46642a7c980 100644 --- a/sys/miscfs/procfs/procfs_subr.c +++ b/sys/miscfs/procfs/procfs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs_subr.c,v 1.10 1997/10/06 20:20:33 deraadt Exp $ */ +/* $OpenBSD: procfs_subr.c,v 1.11 1997/11/06 05:58:43 csapuntz Exp $ */ /* $NetBSD: procfs_subr.c,v 1.15 1996/02/12 15:01:42 christos Exp $ */ /* @@ -54,10 +54,14 @@ static TAILQ_HEAD(, pfsnode) pfshead; static int pfsvplock; -void -procfs_init(void) +/*ARGSUSED*/ +int +procfs_init(vfsp) + struct vfsconf *vfsp; + { TAILQ_INIT(&pfshead); + return (0); } /* @@ -93,6 +97,7 @@ procfs_allocvp(mp, vpp, pid, pfs_type) long pid; pfstype pfs_type; { + struct proc *p = curproc; struct pfsnode *pfs; struct vnode *vp; int error; @@ -103,7 +108,7 @@ loop: if (pfs->pfs_pid == pid && pfs->pfs_type == pfs_type && vp->v_mount == mp) { - if (vget(vp, 0)) + if (vget(vp, 0, p)) goto loop; *vpp = vp; return (0); diff --git a/sys/miscfs/procfs/procfs_vfsops.c b/sys/miscfs/procfs/procfs_vfsops.c index c2c31b37595..297323b8d94 100644 --- a/sys/miscfs/procfs/procfs_vfsops.c +++ b/sys/miscfs/procfs/procfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs_vfsops.c,v 1.6 1997/10/06 20:20:34 deraadt Exp $ */ +/* $OpenBSD: procfs_vfsops.c,v 1.7 1997/11/06 05:58:43 csapuntz Exp $ */ /* $NetBSD: procfs_vfsops.c,v 1.25 1996/02/09 22:40:53 christos Exp $ */ /* @@ -61,14 +61,7 @@ int procfs_mount __P((struct mount *, char *, caddr_t, struct nameidata *, struct proc *)); int procfs_start __P((struct mount *, int, struct proc *)); int procfs_unmount __P((struct mount *, int, struct proc *)); -int procfs_quotactl __P((struct mount *, int, uid_t, caddr_t, - struct proc *)); int procfs_statfs __P((struct mount *, struct statfs *, struct proc *)); -int procfs_sync __P((struct mount *, int, struct ucred *, struct proc *)); -int procfs_vget __P((struct mount *, ino_t, struct vnode **)); -int procfs_fhtovp __P((struct mount *, struct fid *, struct mbuf *, - struct vnode **, int *, struct ucred **)); -int procfs_vptofh __P((struct vnode *, struct fid *)); /* * VFS Operations. * @@ -95,7 +88,7 @@ procfs_mount(mp, path, data, ndp, p) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = 0; - getnewfsid(mp, makefstype(MOUNT_PROCFS)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -179,72 +172,25 @@ procfs_statfs(mp, sbp, p) 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_op->vfs_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } -/*ARGSUSED*/ -int -procfs_quotactl(mp, cmds, uid, arg, p) - struct mount *mp; - int cmds; - uid_t uid; - caddr_t arg; - struct proc *p; -{ - - return (EOPNOTSUPP); -} - -/*ARGSUSED*/ -int -procfs_sync(mp, waitfor, uc, p) - struct mount *mp; - int waitfor; - struct ucred *uc; - struct proc *p; -{ - return (0); -} +#define procfs_sync ((int (*) __P((struct mount *, int, struct ucred *, \ + struct proc *)))nullop) -/*ARGSUSED*/ -int -procfs_vget(mp, ino, vpp) - struct mount *mp; - ino_t ino; - struct vnode **vpp; -{ - - return (EOPNOTSUPP); -} - -/*ARGSUSED*/ -int -procfs_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 (EINVAL); -} - -/*ARGSUSED*/ -int -procfs_vptofh(vp, fhp) - struct vnode *vp; - struct fid *fhp; -{ - - return (EINVAL); -} +#define procfs_fhtovp ((int (*) __P((struct mount *, struct fid *, \ + struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp) +#define procfs_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \ + struct proc *)))eopnotsupp) +#define procfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ + size_t, struct proc *)))eopnotsupp) +#define procfs_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \ + eopnotsupp) +#define procfs_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp) struct vfsops procfs_vfsops = { - MOUNT_PROCFS, procfs_mount, procfs_start, procfs_unmount, @@ -256,4 +202,5 @@ struct vfsops procfs_vfsops = { procfs_fhtovp, procfs_vptofh, procfs_init, + procfs_sysctl }; diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 3a7556f819a..11a74d5bd5b 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procfs_vnops.c,v 1.8 1997/10/06 20:20:35 deraadt Exp $ */ +/* $OpenBSD: procfs_vnops.c,v 1.9 1997/11/06 05:58:43 csapuntz Exp $ */ /* $NetBSD: procfs_vnops.c,v 1.40 1996/03/16 23:52:55 christos Exp $ */ /* @@ -728,6 +728,7 @@ procfs_lookup(v) struct vnode **vpp = ap->a_vpp; struct vnode *dvp = ap->a_dvp; char *pname = cnp->cn_nameptr; + struct proc *curp = curproc; struct proc_target *pt; struct vnode *fvp; pid_t pid; @@ -787,7 +788,7 @@ procfs_lookup(v) fvp = procfs_findtextvp(p); /* We already checked that it exists. */ VREF(fvp); - VOP_LOCK(fvp); + vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp); *vpp = fvp; return (0); } @@ -839,8 +840,6 @@ procfs_readdir(v) struct pfsnode *pfs; int i; int error; - u_long *cookies = ap->a_cookies; - int ncookies = ap->a_ncookies; pfs = VTOPFS(ap->a_vp); @@ -880,8 +879,6 @@ procfs_readdir(v) if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) break; - if (ncookies-- > 0) - *cookies++ = i + 1; } break; @@ -943,8 +940,6 @@ procfs_readdir(v) if ((error = uiomove((caddr_t)&d, UIO_MX, uio)) != 0) break; - if (ncookies-- > 0) - *cookies++ = i + 1; } done: diff --git a/sys/miscfs/specfs/spec_vnops.c b/sys/miscfs/specfs/spec_vnops.c index 995870d11d0..b2fcc0aa692 100644 --- a/sys/miscfs/specfs/spec_vnops.c +++ b/sys/miscfs/specfs/spec_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spec_vnops.c,v 1.11 1997/10/06 20:20:37 deraadt Exp $ */ +/* $OpenBSD: spec_vnops.c,v 1.12 1997/11/06 05:58:44 csapuntz Exp $ */ /* $NetBSD: spec_vnops.c,v 1.29 1996/04/22 01:42:38 christos Exp $ */ /* @@ -79,6 +79,7 @@ struct vnodeopv_entry_desc spec_vnodeop_entries[] = { { &vop_lease_desc, spec_lease_check }, /* lease */ { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ { &vop_select_desc, spec_select }, /* select */ + { &vop_revoke_desc, spec_revoke }, /* revoke */ { &vop_mmap_desc, spec_mmap }, /* mmap */ { &vop_fsync_desc, spec_fsync }, /* fsync */ { &vop_seek_desc, spec_seek }, /* seek */ @@ -143,8 +144,13 @@ spec_open(v) struct ucred *a_cred; struct proc *a_p; } */ *ap = v; - struct vnode *bvp, *vp = ap->a_vp; - dev_t bdev, dev = (dev_t)vp->v_rdev; + struct proc *p = ap->a_p; + struct vnode *vp = ap->a_vp; +#if 0 + struct vnode *bvp; + dev_t bdev; +#endif + dev_t dev = (dev_t)vp->v_rdev; register int maj = major(dev); int error; @@ -172,6 +178,7 @@ spec_open(v) * devices whose corresponding block devices are * currently mounted. */ +#if 0 if (securelevel >= 1) { if ((bdev = chrtoblk(dev)) != NODEV && vfinddev(bdev, VBLK, &bvp) && @@ -181,12 +188,13 @@ spec_open(v) if (iskmemdev(dev)) return (EPERM); } +#endif } if (cdevsw[maj].d_type == D_TTY) vp->v_flag |= VISTTY; - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); error = (*cdevsw[maj].d_open)(dev, ap->a_mode, S_IFCHR, ap->a_p); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); return (error); case VBLK: @@ -255,10 +263,10 @@ spec_read(v) switch (vp->v_type) { case VCHR: - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); error = (*cdevsw[major(vp->v_rdev)].d_read) (vp->v_rdev, uio, ap->a_ioflag); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); return (error); case VBLK: @@ -306,6 +314,19 @@ spec_read(v) /* NOTREACHED */ } +int +spec_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); +} + /* * Vnode op for write */ @@ -341,10 +362,10 @@ spec_write(v) switch (vp->v_type) { case VCHR: - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); error = (*cdevsw[major(vp->v_rdev)].d_write) (vp->v_rdev, uio, ap->a_ioflag); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); return (error); case VBLK: @@ -514,6 +535,74 @@ loop: /* * Just call the device strategy routine */ +int fs_read[16], fs_write[16]; + +int cur_found[10]; + +int fs_bwrite[64][10]; +int fs_bwrite_cnt[64]; +int num_found; + +int num_levels = 4; +#include <machine/cpu.h> +#include <machine/pcb.h> + +int find_stack(int); + +int find_stack(int levels) + +{ + struct pcb stack; + int *eip, *ebp; + + savectx(&stack); + ebp = (int *)stack.pcb_ebp; + eip = (int *) *(ebp + 1); + + while ((int)ebp > 0xf0000000 && levels--) { + eip = (int *) *(ebp + 1); + + ebp = (int *) *ebp; + } + + return ((int)eip); +} + +void track_write __P((void)); + +void track_write(void) + +{ + int idx, cnt; + + for (idx = 0; idx < 10; idx++) { + cur_found[idx] = find_stack(idx + num_levels); + } + + for (cnt = 0; cnt < num_found; cnt++) { + for (idx = 0; idx < 10; idx++) { + if (fs_bwrite[cnt][idx] != cur_found[idx]) + goto next_iter; + } + + fs_bwrite_cnt[cnt]++; + break; + next_iter: + } + + if ((cnt == num_found) && + (num_found != 64)) { + for (idx = 0; idx < 10; idx++) { + fs_bwrite[num_found][idx] = cur_found[idx]; + } + + fs_bwrite_cnt[num_found] = 1; + num_found++; + } + + return; +} + int spec_strategy(v) void *v; @@ -521,8 +610,31 @@ spec_strategy(v) struct vop_strategy_args /* { struct buf *a_bp; } */ *ap = v; + struct buf *bp; + + int maj = major(ap->a_bp->b_dev); + + if ((maj >= 0) && (maj < 16)) { + if (ap->a_bp->b_flags & B_READ) + fs_read[maj]++; + else { + fs_write[maj]++; + if (maj == 4) + track_write(); + + } + } + +#if 0 + assert (!(flags & (B_DELWRI | B_DONE))); +#endif - (*bdevsw[major(ap->a_bp->b_dev)].d_strategy)(ap->a_bp); + bp = ap->a_bp; + + if (LIST_FIRST(&bp->b_dep) != NULL && bioops.io_start) + (*bioops.io_start)(bp); + + (*bdevsw[maj].d_strategy)(ap->a_bp); return (0); } @@ -538,33 +650,16 @@ spec_bmap(v) daddr_t a_bn; struct vnode **a_vpp; daddr_t *a_bnp; + int *a_runp; } */ *ap = v; if (ap->a_vpp != NULL) *ap->a_vpp = ap->a_vp; if (ap->a_bnp != NULL) *ap->a_bnp = ap->a_bn; - return (0); -} - -/* - * At the moment we do not do any locking. - */ -/* ARGSUSED */ -int -spec_lock(v) - void *v; -{ - - return (0); -} - -/* ARGSUSED */ -int -spec_unlock(v) - void *v; -{ - + if (ap->a_runp != NULL) + *ap->a_runp = 0; + return (0); } @@ -621,7 +716,9 @@ spec_close(v) * we must invalidate any in core blocks, so that * we can, for instance, change floppy disks. */ + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, ap->a_p); error = vinvalbuf(vp, V_SAVE, ap->a_cred, ap->a_p, 0, 0); + VOP_UNLOCK(vp, 0, ap->a_p); if (error) return (error); /* diff --git a/sys/miscfs/specfs/specdev.h b/sys/miscfs/specfs/specdev.h index 23d90b7c891..cf8193edee2 100644 --- a/sys/miscfs/specfs/specdev.h +++ b/sys/miscfs/specfs/specdev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: specdev.h,v 1.5 1997/10/06 20:20:39 deraadt Exp $ */ +/* $OpenBSD: specdev.h,v 1.6 1997/11/06 05:58:45 csapuntz Exp $ */ /* $NetBSD: specdev.h,v 1.12 1996/02/13 13:13:01 mycroft Exp $ */ /* @@ -44,7 +44,7 @@ struct specinfo { struct vnode **si_hashchain; struct vnode *si_specnext; - long si_flags; + struct mount *si_mountpoint; dev_t si_rdev; struct lockf *si_lockf; }; @@ -54,15 +54,10 @@ struct specinfo { #define v_rdev v_specinfo->si_rdev #define v_hashchain v_specinfo->si_hashchain #define v_specnext v_specinfo->si_specnext -#define v_specflags v_specinfo->si_flags +#define v_specmountpoint v_specinfo->si_mountpoint #define v_speclockf v_specinfo->si_lockf /* - * Flags for specinfo - */ -#define SI_MOUNTEDON 0x0001 /* block special device is mounted on */ - -/* * Special device management */ #define SPECHSZ 64 @@ -113,14 +108,14 @@ int spec_fsync __P((void *)); #define spec_readdir spec_badop #define spec_readlink spec_badop #define spec_abortop spec_badop -#define spec_inactive nullop +int spec_inactive __P((void *)); #define spec_reclaim nullop -int spec_lock __P((void *)); -int spec_unlock __P((void *)); +#define spec_lock vop_nolock +#define spec_unlock vop_nounlock +#define spec_islocked vop_noislocked int spec_bmap __P((void *)); int spec_strategy __P((void *)); int spec_print __P((void *)); -#define spec_islocked nullop int spec_pathconf __P((void *)); int spec_advlock __P((void *)); #define spec_blkatoff spec_badop @@ -130,3 +125,4 @@ int spec_advlock __P((void *)); #define spec_truncate nullop #define spec_update nullop #define spec_bwrite vn_bwrite +#define spec_revoke vop_revoke diff --git a/sys/miscfs/umapfs/umap.h b/sys/miscfs/umapfs/umap.h index 2b8d97ae56d..4b9e9971884 100644 --- a/sys/miscfs/umapfs/umap.h +++ b/sys/miscfs/umapfs/umap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: umap.h,v 1.7 1997/10/06 20:20:40 deraadt Exp $ */ +/* $OpenBSD: umap.h,v 1.8 1997/11/06 05:58:46 csapuntz Exp $ */ /* $NetBSD: umap.h,v 1.6 1996/02/09 22:41:00 christos Exp $ */ /* @@ -94,6 +94,6 @@ extern struct vnode *umap_checkvp __P((struct vnode *vp, char *fil, int lno)); extern int (**umap_vnodeop_p) __P((void *)); extern struct vfsops umap_vfsops; -void umapfs_init __P((void)); +int umapfs_init __P((struct vfsconf *)); #endif /* _KERNEL */ diff --git a/sys/miscfs/umapfs/umap_subr.c b/sys/miscfs/umapfs/umap_subr.c index fd234f356c9..d3f8d9d801b 100644 --- a/sys/miscfs/umapfs/umap_subr.c +++ b/sys/miscfs/umapfs/umap_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umap_subr.c,v 1.10 1997/10/06 20:20:41 deraadt Exp $ */ +/* $OpenBSD: umap_subr.c,v 1.11 1997/11/06 05:58:47 csapuntz Exp $ */ /* $NetBSD: umap_subr.c,v 1.8 1996/03/05 02:35:39 thorpej Exp $ */ /* @@ -42,6 +42,7 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/proc.h> #include <sys/time.h> #include <sys/types.h> #include <sys/vnode.h> @@ -75,14 +76,15 @@ static int umap_node_alloc __P((struct mount *, struct vnode *, /* * Initialise cache headers */ -void -umapfs_init() +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, &umap_node_hash); + return (0); } /* @@ -141,6 +143,7 @@ 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; @@ -166,7 +169,7 @@ loop: * stuff, but we don't want to lock * the lower node. */ - if (vget(vp, 0)) { + if (vget(vp, 0, p)) { #ifdef UMAPFS_DIAGNOSTIC printf ("umap_node_find: vget failed.\n"); #endif @@ -198,6 +201,7 @@ umap_node_alloc(mp, lowervp, vpp) struct umap_node *xp; struct vnode *vp, *nvp; int error; + struct proc *p = curproc; extern int (**dead_vnodeop_p) __P((void *)); if ((error = getnewvnode(VT_UMAP, mp, umap_vnodeop_p, &vp)) != 0) @@ -259,14 +263,14 @@ loop: vgone(cvp); goto loop; } - if (vget(cvp, 0)) /* can't lock; will die! */ + if (vget(cvp, 0, p)) /* can't lock; will die! */ goto loop; break; } vp->v_hashchain = cvpp; vp->v_specnext = *cvpp; - vp->v_specflags = 0; + vp->v_specmountpoint = NULL; *cvpp = vp; #ifdef DIAGNOSTIC if (cvp == NULLVP) diff --git a/sys/miscfs/umapfs/umap_vfsops.c b/sys/miscfs/umapfs/umap_vfsops.c index e8dd5a9044d..67cf09a0a70 100644 --- a/sys/miscfs/umapfs/umap_vfsops.c +++ b/sys/miscfs/umapfs/umap_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umap_vfsops.c,v 1.10 1997/10/06 20:20:41 deraadt Exp $ */ +/* $OpenBSD: umap_vfsops.c,v 1.11 1997/11/06 05:58:48 csapuntz Exp $ */ /* $NetBSD: umap_vfsops.c,v 1.9 1996/02/09 22:41:05 christos Exp $ */ /* @@ -48,6 +48,7 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/time.h> +#include <sys/proc.h> #include <sys/types.h> #include <sys/vnode.h> #include <sys/mount.h> @@ -181,7 +182,7 @@ umapfs_mount(mp, path, data, ndp, p) /* * Unlock the node (either the lower or the alias) */ - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); /* * Make sure the node alias worked */ @@ -201,7 +202,7 @@ umapfs_mount(mp, path, data, ndp, p) if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL) mp->mnt_flag |= MNT_LOCAL; mp->mnt_data = (qaddr_t) amp; - getnewfsid(mp, makefstype(MOUNT_UMAP)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -242,16 +243,12 @@ umapfs_unmount(mp, mntflags, p) struct vnode *umapm_rootvp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp; int error; int flags = 0; - extern int doforce; #ifdef UMAPFS_DIAGNOSTIC printf("umapfs_unmount(mp = %p)\n", mp); #endif if (mntflags & MNT_FORCE) { - /* lofs can never be rootfs so don't check for it */ - if (!doforce) - return (EINVAL); flags |= FORCECLOSE; } @@ -294,6 +291,7 @@ umapfs_root(mp, vpp) struct mount *mp; struct vnode **vpp; { + struct proc *p = curproc; struct vnode *vp; #ifdef UMAPFS_DIAGNOSTIC @@ -308,7 +306,7 @@ umapfs_root(mp, vpp) */ vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp; VREF(vp); - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); *vpp = vp; return (0); } @@ -361,7 +359,7 @@ umapfs_statfs(mp, sbp, p) 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_op->vfs_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } @@ -407,8 +405,11 @@ umapfs_vptofh(vp, fhp) return VFS_VPTOFH(UMAPVPTOLOWERVP(vp), fhp); } +#define umapfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ + size_t, struct proc *)))eopnotsupp) + + struct vfsops umap_vfsops = { - MOUNT_UMAP, umapfs_mount, umapfs_start, umapfs_unmount, @@ -420,4 +421,5 @@ struct vfsops umap_vfsops = { umapfs_fhtovp, umapfs_vptofh, umapfs_init, + umapfs_sysctl }; diff --git a/sys/miscfs/umapfs/umap_vnops.c b/sys/miscfs/umapfs/umap_vnops.c index 18995119006..14a23102aed 100644 --- a/sys/miscfs/umapfs/umap_vnops.c +++ b/sys/miscfs/umapfs/umap_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umap_vnops.c,v 1.8 1997/10/06 20:20:42 deraadt Exp $ */ +/* $OpenBSD: umap_vnops.c,v 1.9 1997/11/06 05:58:49 csapuntz Exp $ */ /* $NetBSD: umap_vnops.c,v 1.5.4.1 1996/05/25 22:13:35 jtc Exp $ */ /* @@ -52,6 +52,7 @@ #include <sys/namei.h> #include <sys/malloc.h> #include <sys/buf.h> +#include <miscfs/nullfs/null.h> #include <miscfs/umapfs/umap.h> @@ -65,6 +66,8 @@ int umap_print __P((void *)); int umap_rename __P((void *)); int umap_strategy __P((void *)); int umap_bwrite __P((void *)); +int umap_unlock __P((void *)); +int umap_lock __P((void *)); /* * Global vfs data structures @@ -83,7 +86,8 @@ struct vnodeopv_entry_desc umap_vnodeop_entries[] = { { &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 }, @@ -378,10 +382,54 @@ umap_inactive(v) * cache and reusable. * */ - VOP_UNLOCK(ap->a_vp); + 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; + + vop_nolock(ap); + if ((ap->a_flags & LK_TYPE_MASK) == LK_DRAIN) + return (0); + ap->a_flags &= ~LK_INTERLOCK; + return (null_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; + + vop_nounlock(ap); + ap->a_flags &= ~LK_INTERLOCK; + return (null_bypass(ap)); +} + + + int umap_reclaim(v) void *v; diff --git a/sys/miscfs/union/union.h b/sys/miscfs/union/union.h index 5d71a6ad984..98cebc433c1 100644 --- a/sys/miscfs/union/union.h +++ b/sys/miscfs/union/union.h @@ -1,4 +1,4 @@ -/* $OpenBSD: union.h,v 1.5 1997/10/06 21:04:48 deraadt Exp $ */ +/* $OpenBSD: union.h,v 1.6 1997/11/06 05:58:51 csapuntz Exp $ */ /* $NetBSD: union.h,v 1.9 1996/02/09 22:41:08 christos Exp $ */ /* @@ -40,6 +40,8 @@ * @(#)union.h 8.9 (Berkeley) 12/10/94 */ +struct vfsconf; + struct union_args { char *target; /* Target of loopback */ int mntflags; /* Options on the mount */ @@ -129,7 +131,7 @@ extern void union_newsize __P((struct vnode *, off_t, off_t)); extern int (**union_vnodeop_p) __P((void *)); extern struct vfsops union_vfsops; -void union_init __P((void)); +int union_init __P((struct vfsconf *)); 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 689dd69b114..70dc63b427b 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.6 1997/10/06 21:04:49 deraadt Exp $ */ +/* $OpenBSD: union_subr.c,v 1.7 1997/11/06 05:58:51 csapuntz 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 vnode *union_dircache __P((struct vnode *, struct proc *)); /* * 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); + lvp = union_dircache(*vpp, p); 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); + VOP_UNLOCK(lvp, 0, p); if (*error) { vrele(lvp); @@ -140,8 +140,9 @@ int union_check(p, vpp, fp, auio, error) return (0); }; -void -union_init() +int +union_init(vfsp) + struct vfsconf *vfsp; { int i; @@ -149,6 +150,7 @@ union_init() LIST_INIT(&unhead[i]); bzero((caddr_t) unvplock, sizeof(unvplock)); union_check_p = union_check; + return (0); } static int @@ -408,7 +410,8 @@ loop: (un->un_uppervp == uppervp || un->un_uppervp == NULLVP) && (UNIONTOV(un)->v_mount == mp)) { - if (vget(UNIONTOV(un), 0)) { + if (vget(UNIONTOV(un), 0, + cnp ? cnp->cn_proc : NULL)) { union_list_unlock(hash); goto loop; } @@ -646,12 +649,12 @@ union_copyfile(fvp, tvp, cred, p) uio.uio_segflg = UIO_SYSSPACE; uio.uio_offset = 0; - VOP_UNLOCK(fvp); /* XXX */ + VOP_UNLOCK(fvp, 0, p); /* XXX */ VOP_LEASE(fvp, p, cred, LEASE_READ); - VOP_LOCK(fvp); /* XXX */ - VOP_UNLOCK(tvp); /* XXX */ + vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, p); + VOP_UNLOCK(tvp, 0, p); /* XXX */ VOP_LEASE(tvp, p, cred, LEASE_WRITE); - VOP_LOCK(tvp); /* XXX */ + vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, p); buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK); @@ -719,11 +722,11 @@ union_copyup(un, docopy, cred, p) * XX - should not ignore errors * from VOP_CLOSE */ - VOP_LOCK(lvp); + vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY, p); error = VOP_OPEN(lvp, FREAD, cred, p); if (error == 0) { error = union_copyfile(lvp, uvp, cred, p); - VOP_UNLOCK(lvp); + VOP_UNLOCK(lvp, 0, p); (void) VOP_CLOSE(lvp, FREAD, cred, p); } #ifdef UNION_DIAGNOSTIC @@ -733,166 +736,166 @@ union_copyup(un, docopy, cred, p) } un->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(uvp); + VOP_UNLOCK(uvp, 0, p); union_vn_close(uvp, FWRITE, cred, p); - 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); + 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); } if (wvp) { @@ -1018,6 +1021,7 @@ void union_removed_upper(un) struct union_node *un; { + struct proc *p = curproc; /* * We do not set the uppervp to NULLVP here, because lowervp @@ -1037,7 +1041,7 @@ union_removed_upper(un) if (un->un_flags & UN_ULOCK) { un->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(un->un_uppervp); + VOP_UNLOCK(un->un_uppervp, 0, p); } } @@ -1109,8 +1113,9 @@ union_dircache_r(vp, vppp, cntp) } struct vnode * -union_dircache(vp) +union_dircache(vp, p) struct vnode *vp; + struct proc *p; { int cnt; struct vnode *nvp = NULLVP; @@ -1118,8 +1123,7 @@ union_dircache(vp) struct vnode **dircache; int error; - VOP_LOCK(vp); - + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); dircache = VTOUNION(vp)->un_dircache; if (dircache == 0) { cnt = 0; @@ -1144,7 +1148,7 @@ union_dircache(vp) if (*vpp == NULLVP) goto out; - VOP_LOCK(*vpp); + vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, p); VREF(*vpp); error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0); if (!error) { @@ -1153,7 +1157,7 @@ union_dircache(vp) } out: - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (nvp); } diff --git a/sys/miscfs/union/union_vfsops.c b/sys/miscfs/union/union_vfsops.c index 5c2a188ad85..c92d96be7cd 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.6 1997/10/06 21:04:50 deraadt Exp $ */ +/* $OpenBSD: union_vfsops.c,v 1.7 1997/11/06 05:58:52 csapuntz Exp $ */ /* $NetBSD: union_vfsops.c,v 1.10 1995/06/18 14:47:47 cgd Exp $ */ /* @@ -64,13 +64,7 @@ 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 @@ -214,7 +208,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; - getnewfsid(mp, makefstype(MOUNT_UNION)); + vfs_getnewfsid(mp); (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); @@ -293,16 +287,12 @@ 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; } @@ -373,6 +363,7 @@ union_root(mp, vpp) struct mount *mp; struct vnode **vpp; { + struct proc *p = curproc; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); int error; int loselock; @@ -385,7 +376,7 @@ union_root(mp, vpp) VOP_ISLOCKED(um->um_uppervp)) { loselock = 1; } else { - VOP_LOCK(um->um_uppervp); + vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p); loselock = 0; } if (um->um_lowervp) @@ -399,9 +390,10 @@ union_root(mp, vpp) 1); if (error) { - if (!loselock) - VOP_UNLOCK(um->um_uppervp); - vrele(um->um_uppervp); + if (loselock) + vrele(um->um_uppervp); + else + vput(um->um_uppervp); if (um->um_lowervp) vrele(um->um_lowervp); } else { @@ -412,19 +404,6 @@ 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; @@ -491,66 +470,29 @@ 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_op->vfs_name, MFSNAMELEN); + strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); return (0); } -/*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_sync ((int (*) __P((struct mount *, int, struct ucred *, \ + struct proc *)))nullop) -/*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); -} +#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) struct vfsops union_vfsops = { - MOUNT_UNION, union_mount, union_start, union_unmount, @@ -562,4 +504,5 @@ 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 36da3175e05..835da8d8518 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.8 1997/10/06 21:04:51 deraadt Exp $ */ +/* $OpenBSD: union_vnops.c,v 1.9 1997/11/06 05:58:54 csapuntz Exp $ */ /* $NetBSD: union_vnops.c,v 1.30.4.1 1996/05/25 22:10:14 jtc Exp $ */ /* @@ -81,6 +81,7 @@ 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 *)); @@ -124,6 +125,7 @@ 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 */ @@ -148,22 +150,22 @@ struct vnodeopv_entry_desc union_vnodeop_entries[] = { struct vnodeopv_desc union_vnodeop_opv_desc = { &union_vnodeop_p, union_vnodeop_entries }; -#define FIXUP(un) { \ +#define FIXUP(un, p) { \ if (((un)->un_flags & UN_ULOCK) == 0) { \ - union_fixup(un); \ + union_fixup(un, p); \ } \ } -static void union_fixup __P((struct union_node *)); +static void union_fixup __P((struct union_node *, struct proc *)); static int union_lookup1 __P((struct vnode *, struct vnode **, struct vnode **, struct componentname *)); static void -union_fixup(un) +union_fixup(un, p) struct union_node *un; + struct proc *p; { - - VOP_LOCK(un->un_uppervp); + vn_lock(un->un_uppervp, LK_EXCLUSIVE | LK_RETRY, p); un->un_flags |= UN_ULOCK; } @@ -174,6 +176,7 @@ 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; @@ -199,7 +202,7 @@ union_lookup1(udvp, dvpp, vpp, cnp) *dvpp = dvp = dvp->v_mount->mnt_vnodecovered; vput(tdvp); VREF(dvp); - VOP_LOCK(dvp); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); } } @@ -213,7 +216,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)) - VOP_LOCK(dvp); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); dvp = tdvp; @@ -225,18 +228,18 @@ union_lookup1(udvp, dvpp, vpp, cnp) while (dvp != udvp && (dvp->v_type == VDIR) && (mp = dvp->v_mountedhere)) { - if (mp->mnt_flag & MNT_MLOCK) { - mp->mnt_flag |= MNT_MWAIT; - sleep((caddr_t) mp, PVFS); + if (vfs_busy(mp, 0, 0, p)) continue; - } + + error = VFS_ROOT(mp, &tdvp); + vfs_unbusy(mp, p); + + vput(dvp); - if ((error = VFS_ROOT(mp, &tdvp)) != 0) { - vput(dvp); + if (error) { return (error); } - vput(dvp); dvp = tdvp; } @@ -260,6 +263,7 @@ 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); @@ -276,9 +280,9 @@ union_lookup(v) if (dvp == NULLVP) return (ENOENT); VREF(dvp); - VOP_LOCK(dvp); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); if (!lockparent || !(cnp->cn_flags & ISLASTCN)) - VOP_UNLOCK(ap->a_dvp); + VOP_UNLOCK(ap->a_dvp, 0, p, 0, p); return (0); } #endif @@ -298,7 +302,7 @@ union_lookup(v) * on and just return that vnode. */ if (upperdvp != NULLVP) { - FIXUP(dun); + FIXUP(dun, p); /* * If we're doing `..' in the underlying filesystem, * we must drop our lock on the union node before @@ -310,7 +314,7 @@ union_lookup(v) if (cnp->cn_flags & ISDOTDOT) { /* retain lock on underlying VP: */ dun->un_flags |= UN_KLOCK; - VOP_UNLOCK(dvp); + VOP_UNLOCK(dvp, 0, p); } uerror = union_lookup1(um->um_uppervp, &upperdvp, &uppervp, cnp); @@ -330,7 +334,7 @@ union_lookup(v) * dun->un_uppervp locked currently--so we get it * locked here (don't set the UN_ULOCK flag). */ - VOP_LOCK(dvp); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); } /*if (uppervp == upperdvp) @@ -367,7 +371,7 @@ union_lookup(v) if (lowerdvp != NULLVP && !iswhiteout) { int nameiop; - VOP_LOCK(lowerdvp); + vn_lock(lowerdvp, LK_EXCLUSIVE | LK_RETRY, p); /* * Only do a LOOKUP on the bottom node, since @@ -392,7 +396,7 @@ union_lookup(v) cnp->cn_nameiop = nameiop; if (lowervp != lowerdvp) - VOP_UNLOCK(lowerdvp); + VOP_UNLOCK(lowerdvp, 0, p); if (cnp->cn_consume != 0) { if (uppervp != NULLVP) { @@ -413,7 +417,7 @@ union_lookup(v) lowervp = LOWERVP(dun->un_pvp); if (lowervp != NULLVP) { VREF(lowervp); - VOP_LOCK(lowervp); + vn_lock(lowervp, LK_EXCLUSIVE | LK_RETRY, p); lerror = 0; } } @@ -462,9 +466,9 @@ union_lookup(v) * locks/etc! */ dun->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(upperdvp); + VOP_UNLOCK(upperdvp, 0, p); uerror = union_mkshadow(um, upperdvp, cnp, &uppervp); - VOP_LOCK(upperdvp); + vn_lock(upperdvp, LK_EXCLUSIVE | LK_RETRY, p); dun->un_flags |= UN_ULOCK; if (uerror) { @@ -478,7 +482,7 @@ union_lookup(v) } if (lowervp != NULLVP) - VOP_UNLOCK(lowervp); + VOP_UNLOCK(lowervp, 0, p); error = union_allocvp(ap->a_vpp, dvp->v_mount, dvp, upperdvp, cnp, uppervp, lowervp, 1); @@ -491,7 +495,7 @@ union_lookup(v) } else { if (*ap->a_vpp != dvp) if (!lockparent || !(cnp->cn_flags & ISLASTCN)) - VOP_UNLOCK(dvp); + VOP_UNLOCK(dvp, 0, p); if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.' && *ap->a_vpp != dvp) { @@ -516,19 +520,21 @@ 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); + FIXUP(un, p); VREF(dvp); un->un_flags |= UN_KLOCK; mp = ap->a_dvp->v_mount; vput(ap->a_dvp); - error = VOP_CREATE(dvp, &vp, ap->a_cnp, ap->a_vap); + error = VOP_CREATE(dvp, &vp, cnp, ap->a_vap); if (error) return (error); @@ -537,7 +543,7 @@ union_create(v) mp, NULLVP, NULLVP, - ap->a_cnp, + cnp, vp, NULLVP, 1); @@ -560,11 +566,12 @@ 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); + FIXUP(un, p); return (VOP_WHITEOUT(un->un_uppervp, ap->a_cnp, ap->a_flags)); } @@ -580,13 +587,14 @@ 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); + FIXUP(un, p); VREF(dvp); un->un_flags |= UN_KLOCK; @@ -656,14 +664,14 @@ union_open(v) * Just open the lower vnode */ un->un_openl++; - VOP_LOCK(tvp); + vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, p); error = VOP_OPEN(tvp, mode, cred, p); - VOP_UNLOCK(tvp); + VOP_UNLOCK(tvp, 0, p); return (error); } - FIXUP(un); + FIXUP(un, p); error = VOP_OPEN(tvp, mode, cred, p); @@ -728,14 +736,15 @@ 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); + FIXUP(un, p); return (VOP_ACCESS(vp, ap->a_mode, ap->a_cred, ap->a_p)); } if ((vp = un->un_lowervp) != NULLVP) { - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 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); @@ -744,7 +753,7 @@ union_access(v) error = VOP_ACCESS(vp, ap->a_mode, um->um_cred, ap->a_p); } - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); if (error) return (error); } @@ -771,7 +780,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 @@ -794,7 +803,7 @@ union_getattr(v) * the union_node's lock flag. */ if (un->un_flags & UN_LOCKED) - FIXUP(un); + FIXUP(un, p); error = VOP_GETATTR(vp, vap, ap->a_cred, ap->a_p); if (error) @@ -836,6 +845,7 @@ 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; /* @@ -857,7 +867,7 @@ union_setattr(v) * otherwise return read-only filesystem error. */ if (un->un_uppervp != NULLVP) { - FIXUP(un); + FIXUP(un, p); error = VOP_SETATTR(un->un_uppervp, ap->a_vap, ap->a_cred, ap->a_p); if ((error == 0) && (ap->a_vap->va_size != VNOVAL)) @@ -882,14 +892,15 @@ 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) - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); else - FIXUP(VTOUNION(ap->a_vp)); + FIXUP(VTOUNION(ap->a_vp), p); error = VOP_READ(vp, ap->a_uio, ap->a_ioflag, ap->a_cred); if (dolock) - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); /* * XXX @@ -926,12 +937,13 @@ 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); + FIXUP(un, p); error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag, ap->a_cred); /* @@ -1027,18 +1039,19 @@ 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) - VOP_LOCK(targetvp); + vn_lock(targetvp, LK_EXCLUSIVE | LK_RETRY, p); else - FIXUP(VTOUNION(ap->a_vp)); + FIXUP(VTOUNION(ap->a_vp), p); error = VOP_FSYNC(targetvp, ap->a_cred, ap->a_waitfor, ap->a_p); if (dolock) - VOP_UNLOCK(targetvp); + VOP_UNLOCK(targetvp, 0, p); } return (error); @@ -1076,6 +1089,7 @@ 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"); @@ -1085,11 +1099,11 @@ union_remove(v) struct vnode *vp = un->un_uppervp; struct componentname *cnp = ap->a_cnp; - FIXUP(dun); + FIXUP(dun, p); VREF(dvp); dun->un_flags |= UN_KLOCK; vput(ap->a_dvp); - FIXUP(un); + FIXUP(un, p); VREF(vp); un->un_flags |= UN_KLOCK; vput(ap->a_vp); @@ -1100,7 +1114,7 @@ union_remove(v) if (!error) union_removed_upper(un); } else { - FIXUP(dun); + FIXUP(dun, p); error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount), dun->un_uppervp, ap->a_cnp, un->un_path); @@ -1128,6 +1142,7 @@ 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); @@ -1146,9 +1161,9 @@ union_link(v) /* * needs to be copied up before we can link it. */ - VOP_LOCK(ap->a_vp); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p); if (dun->un_uppervp == un->un_dirvp) { - VOP_UNLOCK(ap->a_dvp); + VOP_UNLOCK(ap->a_dvp, 0, p); } error = union_copyup(un, 1, ap->a_cnp->cn_cred, ap->a_cnp->cn_proc); @@ -1172,18 +1187,18 @@ union_link(v) (error = relookup(ap->a_dvp, &dvp, ap->a_cnp))) { vrele(ap->a_dvp); - VOP_UNLOCK(ap->a_vp); + VOP_UNLOCK(ap->a_vp, 0, p); return EROFS; } if (dvp != NULLVP) { /* The name we want to create has mysteriously appeared (a race?) */ error = EEXIST; - VOP_UNLOCK(ap->a_vp); + VOP_UNLOCK(ap->a_vp, 0, p); goto croak; } } - VOP_UNLOCK(ap->a_vp); + VOP_UNLOCK(ap->a_vp, 0, p); } vp = un->un_uppervp; } @@ -1198,7 +1213,7 @@ croak: return (error); } - FIXUP(dun); + FIXUP(dun, p); VREF(dvp); dun->un_flags |= UN_KLOCK; vput(ap->a_dvp); @@ -1327,15 +1342,16 @@ 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); + FIXUP(un, p); VREF(dvp); un->un_flags |= UN_KLOCK; - VOP_UNLOCK(ap->a_dvp); + VOP_UNLOCK(ap->a_dvp, 0, p); error = VOP_MKDIR(dvp, &vp, ap->a_cnp, ap->a_vap); if (error) { vrele(ap->a_dvp); @@ -1373,6 +1389,7 @@ 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"); @@ -1382,11 +1399,11 @@ union_rmdir(v) struct vnode *vp = un->un_uppervp; struct componentname *cnp = ap->a_cnp; - FIXUP(dun); + FIXUP(dun, p); VREF(dvp); dun->un_flags |= UN_KLOCK; vput(ap->a_dvp); - FIXUP(un); + FIXUP(un, p); VREF(vp); un->un_flags |= UN_KLOCK; vput(ap->a_vp); @@ -1397,7 +1414,7 @@ union_rmdir(v) if (!error) union_removed_upper(un); } else { - FIXUP(dun); + FIXUP(dun, p); error = union_mkwhiteout( MOUNTTOUNIONMOUNT(UNIONTOV(dun)->v_mount), dun->un_uppervp, ap->a_cnp, un->un_path); @@ -1421,12 +1438,13 @@ 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); + FIXUP(un, p); VREF(dvp); un->un_flags |= UN_KLOCK; vput(ap->a_dvp); @@ -1457,16 +1475,17 @@ union_readdir(v) struct uio *a_uio; struct ucred *a_cred; int *a_eofflag; - u_long *a_cookies; - int a_ncookies; + int *a_ncookies; + u_long **a_cookies; + } */ *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); + FIXUP(un, p); ap->a_vp = vp; return (VCALL(vp, VOFFSET(vop_readdir), ap)); } @@ -1482,16 +1501,18 @@ 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) - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); else - FIXUP(VTOUNION(ap->a_vp)); + FIXUP(VTOUNION(ap->a_vp), p); ap->a_vp = vp; error = VCALL(vp, VOFFSET(vop_readlink), ap); if (dolock) - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (error); } @@ -1500,7 +1521,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() and comes here. union_unlock() + * vput() which calls VOP_UNLOCK(, 0, p) 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. @@ -1519,19 +1540,21 @@ 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) - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); else - FIXUP(VTOUNION(ap->a_dvp)); + FIXUP(VTOUNION(ap->a_dvp), p); } ap->a_dvp = vp; error = VCALL(vp, VOFFSET(vop_abortop), ap); if (islocked && dolock) - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (error); } @@ -1542,6 +1565,7 @@ 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); @@ -1593,34 +1617,40 @@ 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; -start: - while (vp->v_flag & VXLOCK) { - vp->v_flag |= VXWANT; - sleep((caddr_t)vp, PINOD); - } + 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; - un = VTOUNION(vp); +start: + un = VTOUNION(vp); if (un->un_uppervp != NULLVP) { if (((un->un_flags & UN_ULOCK) == 0) && (vp->v_usecount != 0)) { - /* - * 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; + error = vn_lock(un->un_uppervp, flags, p); + if (error) + return (error); + un->un_flags |= UN_ULOCK; } #ifdef DIAGNOSTIC if (un->un_flags & UN_KLOCK) { - vprint("dangling upper lock", vp); - panic("union: dangling upper lock"); + vprint("union: dangling klock", vp); + panic("union: dangling upper lock (%lx)", vp); } -#endif - } + #endif + } if (un->un_flags & UN_LOCKED) { #ifdef DIAGNOSTIC @@ -1648,7 +1678,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() and comes here. union_unlock() + * vput() which calls VOP_UNLOCK(, 0, p) 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. @@ -1662,6 +1692,7 @@ 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) @@ -1674,7 +1705,7 @@ union_unlock(v) un->un_flags &= ~UN_LOCKED; if ((un->un_flags & (UN_ULOCK|UN_KLOCK)) == UN_ULOCK) - VOP_UNLOCK(un->un_uppervp); + VOP_UNLOCK(un->un_uppervp, 0, p); un->un_flags &= ~(UN_ULOCK|UN_KLOCK); @@ -1687,6 +1718,8 @@ union_unlock(v) un->un_pid = 0; #endif + vop_nounlock(v); + return (0); } @@ -1702,17 +1735,18 @@ 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) - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); else - FIXUP(VTOUNION(ap->a_vp)); + FIXUP(VTOUNION(ap->a_vp), p); ap->a_vp = vp; error = VCALL(vp, VOFFSET(vop_bmap), ap); if (dolock) - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (error); } @@ -1763,21 +1797,42 @@ 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) - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); else - FIXUP(VTOUNION(ap->a_vp)); + FIXUP(VTOUNION(ap->a_vp), p); ap->a_vp = vp; error = VCALL(vp, VOFFSET(vop_pathconf), ap); if (dolock) - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); 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; { |