X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..4a3eedf9ecc9bbe3f3a5c6ce5e53ad199d639d32:/bsd/isofs/cd9660/cd9660_node.c diff --git a/bsd/isofs/cd9660/cd9660_node.c b/bsd/isofs/cd9660/cd9660_node.c index 956074d1d..0b9ddcff8 100644 --- a/bsd/isofs/cd9660/cd9660_node.c +++ b/bsd/isofs/cd9660/cd9660_node.c @@ -1,16 +1,19 @@ /* * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* $NetBSD: cd9660_node.c,v 1.13 1994/12/24 15:30:07 cgd Exp $ */ @@ -110,12 +113,19 @@ extern u_char isonullname[]; * Initialize hash links for inodes and dnodes. */ int -cd9660_init() +cd9660_init(__unused struct vfsconf *cp) { + return 0; +} - isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash); +int +cd9660_hashinit(void) +{ + if (!isohashtbl) + isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash); #ifdef ISODEVMAP - idvhashtbl = hashinit(desiredvnodes / 8, M_ISOFSMNT, &idvhash); + if (!idvhashtbl) + idvhashtbl = hashinit(desiredvnodes / 8, M_ISOFSMNT, &idvhash); #endif return 0; } @@ -125,10 +135,7 @@ cd9660_init() * Enter a new node into the device hash list */ struct iso_dnode * -iso_dmap(device, inum, create) - dev_t device; - ino_t inum; - int create; +iso_dmap(dev_t device, ino_t inum, int create) { register struct iso_dnode **dpp, *dp, *dq; @@ -157,8 +164,7 @@ iso_dmap(device, inum, create) } void -iso_dunmap(device) - dev_t device; +iso_dunmap(dev_t device) { struct iso_dnode **dpp, *dp, *dq; @@ -181,48 +187,60 @@ iso_dunmap(device) * to it. If it is in core, but locked, wait for it. */ struct vnode * -cd9660_ihashget(device, inum, p) - dev_t device; - ino_t inum; - struct proc *p; +cd9660_ihashget(dev_t device, ino_t inum, __unused struct proc *p) { register 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) { - /* - * This is my most dangerous change. I am not waiting for - * the inode lock anymore (ufs doesn't, why should we) and - * I'm worried because there is not lock on the hashtable, - * but there wasn't before so I'll let it go for now. - * -- chw -- + uint32_t vid; + +retry: + for (ip = isohashtbl[INOHASH(device, inum)]; ip; ip = ip->i_next) { + if (inum == ip->i_number && device == ip->i_dev) { + + if (ISSET(ip->i_flag, ISO_INALLOC)) { + /* + * inode is being created... wait for it + * to be ready for consumption */ - vp = ITOV(ip); - simple_lock(&vp->v_interlock); - if (!vget(vp, LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY, p)) - return (vp); - break; + SET(ip->i_flag, ISO_INWALLOC); + tsleep((caddr_t)ip, PINOD, "cd9960_ihashget", 0); + goto retry; } + vp = ITOV(ip); + /* + * the vid needs to be grabbed before we drop + * lock protecting the hash + */ + vid = vnode_vid(vp); + + /* + * we currently depend on running under the FS funnel + * when we do proper locking and advertise ourselves + * as thread safe, we'll need a lock to protect the + * hash lookup... this is where we would drop it + */ + if (vnode_getwithvid(vp, vid)) { + /* + * If vnode is being reclaimed, or has + * already changed identity, no need to wait + */ + return (NULL); + } + return (vp); } - /* NOTREACHED */ + } + return (NULL); } /* * Insert the inode into the hash table, and return it locked. */ void -cd9660_ihashins(ip) - struct iso_node *ip; +cd9660_ihashins(struct iso_node *ip) { struct iso_node **ipp, *iq; - struct proc *p = current_proc(); /* lock the inode, then put it on the appropriate hash list */ - lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct slock *)0, p); ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)]; if ((iq = *ipp)) @@ -230,14 +248,13 @@ cd9660_ihashins(ip) ip->i_next = iq; ip->i_prev = ipp; *ipp = ip; - } +} /* * Remove the inode from the hash table. */ void -cd9660_ihashrem(ip) - register struct iso_node *ip; +cd9660_ihashrem(register struct iso_node *ip) { register struct iso_node *iq; @@ -251,73 +268,53 @@ cd9660_ihashrem(ip) } /* - * Last reference to an inode, write the inode out and if necessary, - * truncate and deallocate the file. + * Last reference to an inode... if we're done with + * it, go ahead and recycle it for other use */ int -cd9660_inactive(ap) - struct vop_inactive_args /* { - struct vnode *a_vp; - struct proc *a_p; - } */ *ap; +cd9660_inactive(struct vnop_inactive_args *ap) { - struct vnode *vp = ap->a_vp; - struct proc *p = ap->a_p; - register struct iso_node *ip = VTOI(vp); - int error = 0; + vnode_t vp = ap->a_vp; + struct iso_node *ip = VTOI(vp); - if (prtactive && vp->v_usecount != 0) - vprint("cd9660_inactive: pushing active", vp); - /* - * We need to unlock the inode here. If we don't panics or - * hangs will ensue. Our callers expect us to take care of this. - */ - - 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) + vnode_recycle(vp); - return error; + return 0; } /* * Reclaim an inode so that it can be used for other purposes. */ int -cd9660_reclaim(ap) - struct vop_reclaim_args /* { - struct vnode *a_vp; - } */ *ap; +cd9660_reclaim(struct vnop_reclaim_args *ap) { - register struct vnode *vp = ap->a_vp; - register struct iso_node *ip = VTOI(vp); + vnode_t vp = ap->a_vp; + struct iso_node *ip = VTOI(vp); - if (prtactive && vp->v_usecount != 0) - vprint("cd9660_reclaim: pushing active", vp); + vnode_removefsref(vp); /* * Remove the inode from its hash chain. */ cd9660_ihashrem(ip); - /* - * Purge old data structures associated with the inode. - */ - cache_purge(vp); + if (ip->i_devvp) { - struct vnode *tvp = ip->i_devvp; + vnode_t devvp = ip->i_devvp; ip->i_devvp = NULL; - vrele(tvp); + vnode_rele(devvp); } + vnode_clearfsnode(vp); + if (ip->i_namep != isonullname) FREE(ip->i_namep, M_TEMP); if (ip->i_riff != NULL) FREE(ip->i_riff, M_TEMP); - FREE_ZONE(vp->v_data, sizeof(struct iso_node), M_ISOFSNODE); - vp->v_data = NULL; + FREE_ZONE(ip, sizeof(struct iso_node), M_ISOFSNODE); + return (0); } @@ -325,10 +322,8 @@ cd9660_reclaim(ap) * File attributes */ void -cd9660_defattr(isodir, inop, bp) - struct iso_directory_record *isodir; - struct iso_node *inop; - struct buf *bp; +cd9660_defattr(struct iso_directory_record *isodir, struct iso_node *inop, + struct buf *bp) { struct buf *bp2 = NULL; struct iso_mnt *imp; @@ -349,12 +344,11 @@ cd9660_defattr(isodir, inop, bp) if (!bp && ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT) && (off = isonum_711(isodir->ext_attr_length))) { - VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL, - &bp2); + cd9660_blkatoff(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL, &bp2); bp = bp2; } if (bp) { - ap = (struct iso_extended_attributes *)bp->b_data; + ap = (struct iso_extended_attributes *)((char *)0 + buf_dataptr(bp)); if (isonum_711(ap->version) == 1) { if (!(ap->perm[0]&0x40)) @@ -375,22 +369,20 @@ cd9660_defattr(isodir, inop, bp) ap = NULL; } if (!ap) { - inop->inode.iso_mode |= VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6; - inop->inode.iso_uid = (uid_t)0; - inop->inode.iso_gid = (gid_t)0; + inop->inode.iso_mode |= VREAD|VWRITE|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6; + inop->inode.iso_uid = ISO_UNKNOWNUID; + inop->inode.iso_gid = ISO_UNKNOWNGID; } if (bp2) - brelse(bp2); + buf_brelse(bp2); } /* * Time stamps */ void -cd9660_deftstamp(isodir,inop,bp) - struct iso_directory_record *isodir; - struct iso_node *inop; - struct buf *bp; +cd9660_deftstamp(struct iso_directory_record *isodir, struct iso_node *inop, + struct buf *bp) { struct buf *bp2 = NULL; struct iso_mnt *imp; @@ -401,11 +393,11 @@ cd9660_deftstamp(isodir,inop,bp) && ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT) && (off = isonum_711(isodir->ext_attr_length))) { - VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL, &bp2); + cd9660_blkatoff(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL, &bp2); bp = bp2; } if (bp) { - ap = (struct iso_extended_attributes *)bp->b_data; + ap = (struct iso_extended_attributes *)((char *)0 + buf_dataptr(bp)); if (isonum_711(ap->version) == 1) { if (!cd9660_tstamp_conv17(ap->ftime,&inop->inode.iso_atime)) @@ -423,16 +415,14 @@ cd9660_deftstamp(isodir,inop,bp) inop->inode.iso_mtime = inop->inode.iso_ctime; } if (bp2) - brelse(bp2); + buf_brelse(bp2); } int -cd9660_tstamp_conv7(pi,pu) - u_char *pi; - struct timespec *pu; +cd9660_tstamp_conv7(u_char *pi, struct timespec *pu) { int crtime, days; - int y, m, d, hour, minute, second, tz; + int y, m, d, hour, minute, second, mytz; y = pi[0] + 1900; m = pi[1]; @@ -440,7 +430,7 @@ cd9660_tstamp_conv7(pi,pu) hour = pi[3]; minute = pi[4]; second = pi[5]; - tz = pi[6]; + mytz = pi[6]; if (y < 1970) { pu->tv_sec = 0; @@ -461,8 +451,8 @@ cd9660_tstamp_conv7(pi,pu) crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second; /* timezone offset is unreliable on some disks */ - if (-48 <= tz && tz <= 52) - crtime -= tz * 15 * 60; + if (-48 <= mytz && mytz <= 52) + crtime -= mytz * 15 * 60; } pu->tv_sec = crtime; pu->tv_nsec = 0; @@ -470,9 +460,7 @@ cd9660_tstamp_conv7(pi,pu) } static u_int -cd9660_chars2ui(begin,len) - u_char *begin; - int len; +cd9660_chars2ui(u_char *begin, int len) { u_int rc; @@ -484,9 +472,7 @@ cd9660_chars2ui(begin,len) } int -cd9660_tstamp_conv17(pi,pu) - u_char *pi; - struct timespec *pu; +cd9660_tstamp_conv17(u_char *pi, struct timespec *pu) { u_char buf[7]; @@ -515,9 +501,7 @@ cd9660_tstamp_conv17(pi,pu) } ino_t -isodirino(isodir, imp) - struct iso_directory_record *isodir; - struct iso_mnt *imp; +isodirino(struct iso_directory_record *isodir, struct iso_mnt *imp) { ino_t ino;