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/isofs/cd9660 | |
parent | fec1be888534eb37405f6bf7a195f28670e1392b (diff) |
Updates for VFS Lite 2 + soft update.
Diffstat (limited to 'sys/isofs/cd9660')
-rw-r--r-- | sys/isofs/cd9660/cd9660_lookup.c | 31 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_mount.h | 46 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_node.c | 74 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_node.h | 7 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_vfsops.c | 74 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_vnops.c | 209 | ||||
-rw-r--r-- | sys/isofs/cd9660/iso.h | 6 |
7 files changed, 248 insertions, 199 deletions
diff --git a/sys/isofs/cd9660/cd9660_lookup.c b/sys/isofs/cd9660/cd9660_lookup.c index 46b9d9b4810..2303ba5ade3 100644 --- a/sys/isofs/cd9660/cd9660_lookup.c +++ b/sys/isofs/cd9660/cd9660_lookup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_lookup.c,v 1.4 1997/10/06 20:19:42 deraadt Exp $ */ +/* $OpenBSD: cd9660_lookup.c,v 1.5 1997/11/06 05:58:09 csapuntz Exp $ */ /* $NetBSD: cd9660_lookup.c,v 1.14 1996/02/09 21:31:56 christos Exp $ */ /*- @@ -130,7 +130,8 @@ cd9660_lookup(v) struct ucred *cred = cnp->cn_cred; int flags = cnp->cn_flags; int nameiop = cnp->cn_nameiop; - + struct proc *p = cnp->cn_proc; + bp = NULL; *vpp = NULL; vdp = ap->a_dvp; @@ -146,6 +147,10 @@ cd9660_lookup(v) return (ENOTDIR); if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)) != 0) return (error); + + if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) && + (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) + return (EROFS); /* * We now have a segment name to search for, and a directory to search. @@ -176,14 +181,14 @@ cd9660_lookup(v) VREF(vdp); error = 0; } else if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); - error = vget(vdp, 1); + VOP_UNLOCK(pdp, 0, p); + error = vget(vdp, LK_EXCLUSIVE, p); if (!error && lockparent && (flags & ISLASTCN)) - error = VOP_LOCK(pdp); + error = vn_lock(pdp, LK_EXCLUSIVE, p); } else { - error = vget(vdp, 1); + error = vget(vdp, LK_EXCLUSIVE, p); if (!lockparent || error || !(flags & ISLASTCN)) - VOP_UNLOCK(pdp); + VOP_UNLOCK(pdp, 0, p); } /* * Check that the capability number did not change @@ -194,9 +199,9 @@ cd9660_lookup(v) return (0); vput(vdp); if (lockparent && pdp != vdp && (flags & ISLASTCN)) - VOP_UNLOCK(pdp); + VOP_UNLOCK(pdp, 0, p); } - if ((error = VOP_LOCK(pdp)) != 0) + if ((error = vn_lock(pdp, LK_EXCLUSIVE, p)) != 0) return (error); vdp = pdp; dp = VTOI(pdp); @@ -419,16 +424,16 @@ found: * it's a relocated directory. */ if (flags & ISDOTDOT) { - VOP_UNLOCK(pdp); /* race to get the inode */ + VOP_UNLOCK(pdp, 0, p); /* race to get the inode */ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp, dp->i_ino != ino, ep); brelse(bp); if (error) { - VOP_LOCK(pdp); + vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p); return (error); } if (lockparent && (flags & ISLASTCN) && - (error = VOP_LOCK(pdp))) { + (error = vn_lock(pdp, LK_EXCLUSIVE, p))) { vput(tdp); return (error); } @@ -444,7 +449,7 @@ found: if (error) return (error); if (!lockparent || !(flags & ISLASTCN)) - VOP_UNLOCK(pdp); + VOP_UNLOCK(pdp, 0, p); *vpp = tdp; } diff --git a/sys/isofs/cd9660/cd9660_mount.h b/sys/isofs/cd9660/cd9660_mount.h new file mode 100644 index 00000000000..7c594d3183d --- /dev/null +++ b/sys/isofs/cd9660/cd9660_mount.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1995 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley + * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension + * Support code is derived from software contributed to Berkeley + * by Atsushi Murai (amurai@spec.co.jp). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)cd9660_mount.h 8.1 (Berkeley) 5/24/95 + */ + +/* + * Arguments to mount ISO 9660 filesystems. + */ +#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/ +#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */ +#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */ diff --git a/sys/isofs/cd9660/cd9660_node.c b/sys/isofs/cd9660/cd9660_node.c index e7d318e2022..712ebfaa4a3 100644 --- a/sys/isofs/cd9660/cd9660_node.c +++ b/sys/isofs/cd9660/cd9660_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_node.c,v 1.5 1997/10/06 20:19:43 deraadt Exp $ */ +/* $OpenBSD: cd9660_node.c,v 1.6 1997/11/06 05:58:10 csapuntz Exp $ */ /* $NetBSD: cd9660_node.c,v 1.15 1996/02/09 21:31:58 christos Exp $ */ /*- @@ -63,6 +63,7 @@ struct iso_node **isohashtbl; u_long isohash; #define INOHASH(device, inum) (((device) + ((inum)>>12)) & isohash) +struct simplelock cd9660_ihash_slock; #ifdef ISODEVMAP struct iso_node **idvhashtbl; @@ -73,18 +74,20 @@ u_long idvhash; int prtactive; /* 1 => print out reclaim of active vnodes */ static u_int cd9660_chars2ui __P((u_char *, int)); - /* * Initialize hash links for inodes and dnodes. */ -void -cd9660_init() +int +cd9660_init(vfsp) + struct vfsconf *vfsp; { isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash); + simple_lock_init(&cd9660_ihash_slock); #ifdef ISODEVMAP idvhashtbl = hashinit(desiredvnodes / 8, M_ISOFSMNT, &idvhash); #endif + return (0); } #ifdef ISODEVMAP @@ -105,6 +108,7 @@ iso_dmap(device, inum, create) return (NULL); if (inum == dp->i_number && device == dp->i_dev) return (dp); + } if (!create) return (NULL); @@ -130,7 +134,7 @@ iso_dunmap(device) struct iso_dnode **dpp, *dp, *dq; for (dpp = idvhashtbl; dpp <= idvhashtbl + idvhash; dpp++) { - for (dp = *dpp; dp != NULL; dp = dq) + for (dp = *dpp; dp != NULL; dp = dq) { dq = dp->d_next; if (device == dp->i_dev) { if (dq) @@ -148,30 +152,28 @@ iso_dunmap(device) * to it. If it is in core, but locked, wait for it. */ struct vnode * -cd9660_ihashget(device, inum) - dev_t device; +cd9660_ihashget(dev, inum) + dev_t dev; ino_t inum; { - register struct iso_node *ip; + struct proc *p = curproc; /* XXX */ + struct iso_node *ip; struct vnode *vp; - for (;;) - for (ip = isohashtbl[INOHASH(device, inum)];; ip = ip->i_next) { - if (ip == NULL) - return (NULL); - if (inum == ip->i_number && device == ip->i_dev) { - if (ip->i_flag & IN_LOCKED) { - ip->i_flag |= IN_WANTED; - sleep(ip, PINOD); - break; - } - vp = ITOV(ip); - if (!vget(vp, 1)) - return (vp); - break; - } - } - /* NOTREACHED */ +loop: + simple_lock(&cd9660_ihash_slock); + for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) { + if (inum == ip->i_number && dev == ip->i_dev) { + vp = ITOV(ip); + simple_lock(&vp->v_interlock); + simple_unlock(&cd9660_ihash_slock); + if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) + goto loop; + return (vp); + } + } + simple_unlock(&cd9660_ihash_slock); + return (NULL); } /* @@ -181,21 +183,19 @@ void cd9660_ihashins(ip) struct iso_node *ip; { + struct proc *p = curproc; struct iso_node **ipp, *iq; + simple_lock(&cd9660_ihash_slock); ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)]; if ((iq = *ipp) != NULL) iq->i_prev = &ip->i_next; ip->i_next = iq; ip->i_prev = ipp; *ipp = ip; - if (ip->i_flag & IN_LOCKED) - panic("cd9660_ihashins: already locked"); - if (curproc) - ip->i_lockholder = curproc->p_pid; - else - ip->i_lockholder = -1; - ip->i_flag |= IN_LOCKED; + simple_unlock(&cd9660_ihash_slock); + + lockmgr(&ip->i_lock, LK_EXCLUSIVE, 0, p); } /* @@ -207,6 +207,7 @@ cd9660_ihashrem(ip) { register struct iso_node *iq; + simple_lock(&cd9660_ihash_slock); if ((iq = ip->i_next) != NULL) iq->i_prev = ip->i_prev; *ip->i_prev = iq; @@ -214,6 +215,7 @@ cd9660_ihashrem(ip) ip->i_next = NULL; ip->i_prev = NULL; #endif + simple_unlock(&cd9660_ihash_slock); } /* @@ -226,8 +228,10 @@ cd9660_inactive(v) { struct vop_inactive_args /* { struct vnode *a_vp; + struct proc *a_p; } */ *ap = v; struct vnode *vp = ap->a_vp; + struct proc *p = ap->a_p; register struct iso_node *ip = VTOI(vp); int error = 0; @@ -235,12 +239,14 @@ cd9660_inactive(v) vprint("cd9660_inactive: pushing active", vp); ip->i_flag = 0; + VOP_UNLOCK(vp, 0, p); /* * If we are done with the inode, reclaim it * so that it can be reused immediately. */ - if (vp->v_usecount == 0 && ip->inode.iso_mode == 0) - vgone(vp); + if (ip->inode.iso_mode == 0) + vrecycle(vp, (struct simplelock *)0, p); + return error; } diff --git a/sys/isofs/cd9660/cd9660_node.h b/sys/isofs/cd9660/cd9660_node.h index 25d6734f515..a5e31291e0a 100644 --- a/sys/isofs/cd9660/cd9660_node.h +++ b/sys/isofs/cd9660/cd9660_node.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_node.h,v 1.4 1997/10/06 20:19:44 deraadt Exp $ */ +/* $OpenBSD: cd9660_node.h,v 1.5 1997/11/06 05:58:11 csapuntz Exp $ */ /* $NetBSD: cd9660_node.h,v 1.11 1996/02/09 21:32:00 christos Exp $ */ /*- @@ -87,7 +87,7 @@ struct iso_node { doff_t i_diroff; /* offset in dir, where we found last entry */ doff_t i_offset; /* offset of free space in directory */ ino_t i_ino; /* inode number of found directory */ - pid_t i_lockholder, i_lockwaiter; + struct lock i_lock; /* node lock */ long iso_extent; /* extent of file */ long i_size; @@ -100,8 +100,6 @@ struct iso_node { #define i_back i_chain[1] /* flags */ -#define IN_LOCKED 0x0001 /* inode is locked */ -#define IN_WANTED 0x0002 /* some process waiting on lock */ #define IN_ACCESS 0x0020 /* inode access time to be updated */ #define VTOI(vp) ((struct iso_node *)(vp)->v_data) @@ -116,6 +114,7 @@ int cd9660_open __P((void *)); int cd9660_close __P((void *)); int cd9660_access __P((void *)); int cd9660_getattr __P((void *)); +int cd9660_setattr __P((void *)); int cd9660_read __P((void *)); int cd9660_ioctl __P((void *)); int cd9660_select __P((void *)); diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c index 0a110fadcc2..222a037cfac 100644 --- a/sys/isofs/cd9660/cd9660_vfsops.c +++ b/sys/isofs/cd9660/cd9660_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_vfsops.c,v 1.10 1997/10/06 20:19:45 deraadt Exp $ */ +/* $OpenBSD: cd9660_vfsops.c,v 1.11 1997/11/06 05:58:11 csapuntz Exp $ */ /* $NetBSD: cd9660_vfsops.c,v 1.20 1996/02/09 21:32:08 christos Exp $ */ /*- @@ -64,7 +64,6 @@ #include <isofs/cd9660/cd9660_node.h> struct vfsops cd9660_vfsops = { - MOUNT_CD9660, cd9660_mount, cd9660_start, cd9660_unmount, @@ -76,14 +75,12 @@ struct vfsops cd9660_vfsops = { cd9660_fhtovp, cd9660_vptofh, cd9660_init, + cd9660_sysctl }; /* * Called by vfs_mountroot when iso is going to be mounted as root. - * - * Name is updated by mount(8) after booting. */ -#define ROOTNAME "root_device" static int iso_mountfs __P((struct vnode *devvp, struct mount *mp, struct proc *p, struct iso_args *argp)); @@ -93,48 +90,37 @@ int iso_disklabelspoof __P((dev_t dev, void (*strat) __P((struct buf *)), int cd9660_mountroot() { - register struct mount *mp; + struct mount *mp; extern struct vnode *rootvp; struct proc *p = curproc; /* XXX */ - struct iso_mnt *imp; - size_t size; int error; struct iso_args args; /* * Get vnodes for swapdev and rootdev. */ - if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) - panic("cd9660_mountroot: can't setup bdevvp's"); - - mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); - bzero((char *)mp, (u_long)sizeof(struct mount)); - mp->mnt_op = &cd9660_vfsops; - mp->mnt_flag = MNT_RDONLY; - LIST_INIT(&mp->mnt_vnodelist); + if ((error = bdevvp(swapdev, &swapdev_vp)) || + (error = bdevvp(rootdev, &rootvp))) { + printf("cd9660_mountroot: can't setup bdevvp's"); + return (error); + } + + + if ((error = vfs_rootmountalloc("cd9660", "root_device", &mp)) != 0) + return (error); args.flags = ISOFSMNT_ROOT; if ((error = iso_mountfs(rootvp, mp, p, &args)) != 0) { - free(mp, M_MOUNT); - return (error); - } - if ((error = vfs_lock(mp)) != 0) { - (void)cd9660_unmount(mp, 0, p); - free(mp, M_MOUNT); - return (error); - } - CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); - mp->mnt_vnodecovered = NULLVP; - imp = VFSTOISOFS(mp); - (void) copystr("/", mp->mnt_stat.f_mntonname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); - (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)cd9660_statfs(mp, &mp->mnt_stat, p); - vfs_unlock(mp); - inittodr(0); /* XXX - can we get the cd creation time here?? */ - return (0); + mp->mnt_vfc->vfc_refcount--; + vfs_unbusy(mp, p); + free(mp, M_MOUNT); + return (error); + } + simple_lock(&mountlist_slock); + CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); + simple_unlock(&mountlist_slock); + (void)cd9660_statfs(mp, &mp->mnt_stat, p); + vfs_unbusy(mp, p); + return (0); } /* @@ -207,6 +193,7 @@ cd9660_mount(mp, path, data, ndp, p) (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); + (void) cd9660_statfs(mp, &mp->mnt_stat, p); return 0; } @@ -318,14 +305,14 @@ iso_mountfs(devvp, mp, p, argp) mp->mnt_data = (qaddr_t)isomp; mp->mnt_stat.f_fsid.val[0] = (long)dev; - mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_CD9660); + mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; mp->mnt_maxsymlinklen = 0; mp->mnt_flag |= MNT_LOCAL; isomp->im_mountp = mp; isomp->im_dev = dev; isomp->im_devvp = devvp; - devvp->v_specflags |= SI_MOUNTEDON; + devvp->v_specmountpoint = mp; /* Check the Rock Ridge Extention support */ if (!(argp->flags & ISOFSMNT_NORRIP)) { @@ -504,7 +491,7 @@ cd9660_unmount(mp, mntflags, p) iso_dunmap(isomp->im_dev); #endif - isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON; + isomp->im_devvp->v_specmountpoint = NULL; error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, p); vrele(isomp->im_devvp); free((caddr_t)isomp, M_ISOFSMNT); @@ -579,7 +566,6 @@ cd9660_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); /* Use the first spare for flags: */ sbp->f_spare[0] = isomp->im_flags; return 0; @@ -708,6 +694,7 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, M_WAITOK); bzero((caddr_t)ip, sizeof(struct iso_node)); + lockinit(&ip->i_lock, PINOD, "isoinode", 0, 0); vp->v_data = ip; ip->i_vnode = vp; ip->i_dev = dev; @@ -852,9 +839,8 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir) if ((nvp = checkalias(vp, ip->inode.iso_rdev, mp)) != NULL) { /* * Discard unneeded vnode, but save its iso_node. + * Note that the lock is carried over in the iso_node */ - cd9660_ihashrem(ip); - VOP_UNLOCK(vp); nvp->v_data = vp->v_data; vp->v_data = NULL; vp->v_op = spec_vnodeop_p; @@ -899,7 +885,7 @@ cd9660_vptofh(vp, fhp) { register struct iso_node *ip = VTOI(vp); register struct ifid *ifhp; - + ifhp = (struct ifid *)fhp; ifhp->ifid_len = sizeof(struct ifid); diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c index a875011ca68..c1e533b78fa 100644 --- a/sys/isofs/cd9660/cd9660_vnops.c +++ b/sys/isofs/cd9660/cd9660_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd9660_vnops.c,v 1.7 1997/10/06 20:19:46 deraadt Exp $ */ +/* $OpenBSD: cd9660_vnops.c,v 1.8 1997/11/06 05:58:12 csapuntz Exp $ */ /* $NetBSD: cd9660_vnops.c,v 1.32 1996/03/16 20:25:40 ws Exp $ */ /*- @@ -120,8 +120,7 @@ cd9660_mknod(ndp, vap, cred, p) dp = iso_dmap(ip->i_dev,ip->i_number,1); if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) { /* same as the unmapped one, delete the mapping */ - dp->d_next->d_prev = dp->d_prev; - *dp->d_prev = dp->d_next; + remque(dp); FREE(dp, M_CACHE); } else /* enter new mapping */ @@ -141,6 +140,48 @@ cd9660_mknod(ndp, vap, cred, p) #endif /* + * Setattr call. Only allowed for block and character special devices. + */ +int +cd9660_setattr(v) + void *v; + +{ + struct vop_setattr_args /* { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap = v; + struct vnode *vp = ap->a_vp; + struct vattr *vap = ap->a_vap; + + if (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || + vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || + vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) + return (EROFS); + if (vap->va_size != VNOVAL) { + switch (vp->v_type) { + case VDIR: + return (EISDIR); + case VLNK: + case VREG: + return (EROFS); + case VCHR: + case VBLK: + case VSOCK: + case VFIFO: + return (0); + default: + return (EINVAL); + } + } + + return (EINVAL); +} + +/* * Open called. * * Nothing to do. @@ -245,15 +286,15 @@ cd9660_getattr(v) return (0); } +#if ISO_DEFAULT_BLOCK_SIZE >= NBPG #ifdef DEBUG extern int doclusterread; #else #define doclusterread 1 #endif - -/* XXX until cluster routines can handle block sizes less than one page */ -#define cd9660_doclusterread \ - (doclusterread && (ISO_DEFAULT_BLOCK_SIZE >= NBPG)) +#else +#define doclusterread 0 +#endif /* * Vnode op for reading. @@ -296,7 +337,7 @@ cd9660_read(v) n = diff; size = blksize(imp, ip, lbn); rablock = lbn + 1; - if (cd9660_doclusterread) { + if (doclusterread) { if (lblktosize(imp, rablock) <= ip->i_size) error = cluster_read(vp, (off_t)ip->i_size, lbn, size, NOCRED, &bp); @@ -319,7 +360,11 @@ cd9660_read(v) } error = uiomove(bp->b_data + on, (int)n, uio); - brelse(bp); + + if (n + on == imp->logical_block_size || + uio->uio_offset == (off_t)ip->i_size) + bp->b_flags |= B_AGE; + brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); return (error); } @@ -486,6 +531,8 @@ cd9660_readdir(v) int error = 0; int reclen; u_short namelen; + int ncookies = 0; + u_long *cookies = NULL; dp = VTOI(vdp); imp = dp->i_mnt; @@ -500,9 +547,19 @@ cd9660_readdir(v) idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = DT_UNKNOWN; idp->uio = uio; + if (ap->a_ncookies == NULL) { + idp->cookies = NULL; + } else { + /* + * Guess the number of cookies needed. + */ + ncookies = uio->uio_resid / 16; + MALLOC(cookies, u_long *, ncookies * sizeof(u_long), M_TEMP, + M_WAITOK); + idp->cookies = cookies; + idp->ncookies = ncookies; + } idp->eofflag = 1; - idp->cookies = ap->a_cookies; - idp->ncookies = ap->a_ncookies; idp->curroff = uio->uio_offset; if ((entryoffsetinblock = idp->curroff & bmask) && @@ -614,8 +671,20 @@ cd9660_readdir(v) if (error < 0) error = 0; + if (ap->a_ncookies != NULL) { + if (error) + free(cookies, M_TEMP); + else { + /* + * Work out the number of cookies actually used. + */ + *ap->a_ncookies = ncookies - idp->ncookies; + *ap->a_cookies = cookies; + } + } + if (bp) - brelse (bp); + brelse (bp); uio->uio_offset = idp->uio_off; *ap->a_eofflag = idp->eofflag; @@ -651,7 +720,7 @@ cd9660_readlink(v) u_short symlen; int error; char *symname; - + ip = VTOI(ap->a_vp); imp = ip->i_mnt; uio = ap->a_uio; @@ -780,48 +849,12 @@ cd9660_lock(v) void *v; { struct vop_lock_args /* { - struct vnode *a_vp; + struct vnode *a_vp; } */ *ap = v; - register struct vnode *vp = ap->a_vp; - register struct iso_node *ip; -#ifdef DIAGNOSTIC - struct proc *p = curproc; /* XXX */ -#endif + struct vnode *vp = ap->a_vp; -start: - while (vp->v_flag & VXLOCK) { - vp->v_flag |= VXWANT; - sleep((caddr_t)vp, PINOD); - } - if (vp->v_tag == VT_NON) - return (ENOENT); - ip = VTOI(vp); - if (ip->i_flag & IN_LOCKED) { - ip->i_flag |= IN_WANTED; -#ifdef DIAGNOSTIC - if (p) { - if (p->p_pid == ip->i_lockholder) - panic("locking against myself"); - ip->i_lockwaiter = p->p_pid; - } else - ip->i_lockwaiter = -1; -#endif - (void) sleep((caddr_t)ip, PINOD); - goto start; - } -#ifdef DIAGNOSTIC - ip->i_lockwaiter = 0; - if (ip->i_lockholder != 0) - panic("lockholder (%d) != 0", ip->i_lockholder); - if (p && p->p_pid == 0) - printf("locking by process 0\n"); - if (p) - ip->i_lockholder = p->p_pid; - else - ip->i_lockholder = -1; -#endif - ip->i_flag |= IN_LOCKED; - return (0); + return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock, + ap->a_p)); } /* @@ -834,27 +867,10 @@ cd9660_unlock(v) struct vop_unlock_args /* { struct vnode *a_vp; } */ *ap = v; - register struct iso_node *ip = VTOI(ap->a_vp); - -#ifdef DIAGNOSTIC - struct proc *p = curproc; /* XXX */ + struct vnode *vp = ap->a_vp; - if ((ip->i_flag & IN_LOCKED) == 0) { - vprint("cd9660_unlock: unlocked inode", ap->a_vp); - panic("cd9660_unlock NOT LOCKED"); - } - if (p && p->p_pid != ip->i_lockholder && p->p_pid > -1 && - ip->i_lockholder > -1/* && lockcount++ < 100*/) - panic("unlocker (%d) != lock holder (%d)", - p->p_pid, ip->i_lockholder); - ip->i_lockholder = 0; -#endif - ip->i_flag &= ~IN_LOCKED; - if (ip->i_flag & IN_WANTED) { - ip->i_flag &= ~IN_WANTED; - wakeup((caddr_t)ip); - } - return (0); + return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE, + &vp->v_interlock, ap->a_p)); } /* @@ -920,9 +936,7 @@ cd9660_islocked(v) struct vnode *a_vp; } */ *ap = v; - if (VTOI(ap->a_vp)->i_flag & IN_LOCKED) - return (1); - return (0); + return (lockstatus(&VTOI(ap->a_vp)->i_lock)); } /* @@ -966,24 +980,11 @@ cd9660_pathconf(v) } /* - * Unsupported operation - */ -/*ARGSUSED*/ -int -cd9660_enotsupp(v) - void *v; -{ - - return (EOPNOTSUPP); -} - -/* * Global vfs data structures for isofs */ -#define cd9660_create cd9660_enotsupp -#define cd9660_mknod cd9660_enotsupp -#define cd9660_setattr cd9660_enotsupp -#define cd9660_write cd9660_enotsupp +#define cd9660_create eopnotsupp +#define cd9660_mknod eopnotsupp +#define cd9660_write eopnotsupp #ifdef NFSSERVER int lease_check __P((void *)); #define cd9660_lease_check lease_check @@ -991,16 +992,17 @@ int lease_check __P((void *)); #define cd9660_lease_check nullop #endif #define cd9660_fsync nullop -#define cd9660_remove cd9660_enotsupp -#define cd9660_rename cd9660_enotsupp -#define cd9660_mkdir cd9660_enotsupp -#define cd9660_rmdir cd9660_enotsupp -#define cd9660_advlock cd9660_enotsupp -#define cd9660_valloc cd9660_enotsupp -#define cd9660_vfree cd9660_enotsupp -#define cd9660_truncate cd9660_enotsupp -#define cd9660_update cd9660_enotsupp -#define cd9660_bwrite cd9660_enotsupp +#define cd9660_remove eopnotsupp +#define cd9660_rename eopnotsupp +#define cd9660_mkdir eopnotsupp +#define cd9660_rmdir eopnotsupp +#define cd9660_advlock eopnotsupp +#define cd9660_valloc eopnotsupp +#define cd9660_vfree eopnotsupp +#define cd9660_truncate eopnotsupp +#define cd9660_update eopnotsupp +#define cd9660_bwrite eopnotsupp +#define cd9660_revoke vop_revoke /* * Global vfs data structures for cd9660 @@ -1021,6 +1023,7 @@ struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { { &vop_lease_desc, cd9660_lease_check },/* lease */ { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */ { &vop_select_desc, cd9660_select }, /* select */ + { &vop_revoke_desc, cd9660_revoke }, /* revoke */ { &vop_mmap_desc, cd9660_mmap }, /* mmap */ { &vop_fsync_desc, cd9660_fsync }, /* fsync */ { &vop_seek_desc, cd9660_seek }, /* seek */ @@ -1073,6 +1076,7 @@ struct vnodeopv_entry_desc cd9660_specop_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 */ @@ -1123,6 +1127,7 @@ struct vnodeopv_entry_desc cd9660_fifoop_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 */ diff --git a/sys/isofs/cd9660/iso.h b/sys/isofs/cd9660/iso.h index 9621bdfa0b3..793cff746e0 100644 --- a/sys/isofs/cd9660/iso.h +++ b/sys/isofs/cd9660/iso.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iso.h,v 1.5 1997/10/06 20:19:47 deraadt Exp $ */ +/* $OpenBSD: iso.h,v 1.6 1997/11/06 05:58:13 csapuntz Exp $ */ /* $NetBSD: iso.h,v 1.11 1996/03/16 20:25:42 ws Exp $ */ /*- @@ -179,7 +179,9 @@ int cd9660_vget __P((struct mount *, ino_t, struct vnode **)); int cd9660_fhtovp __P((struct mount *, struct fid *, struct mbuf *, struct vnode **, int *, struct ucred **)); int cd9660_vptofh __P((struct vnode *, struct fid *)); -void cd9660_init __P((void)); +int cd9660_init __P((struct vfsconf *)); +#define cd9660_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \ + size_t, struct proc *)))eopnotsupp) int cd9660_mountroot __P((void)); |