📄 cd9660_node.c
字号:
/*- * Copyright (c) 1982, 1986, 1989, 1994 * 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_node.c 8.2 (Berkeley) 1/23/94 */#include <sys/param.h>#include <sys/systm.h>#include <sys/mount.h>#include <sys/proc.h>#include <sys/file.h>#include <sys/buf.h>#include <sys/vnode.h>#include <sys/kernel.h>#include <sys/malloc.h>#include <sys/stat.h>#include <isofs/cd9660/iso.h>#include <isofs/cd9660/cd9660_node.h>#include <isofs/cd9660/iso_rrip.h>#define INOHSZ 512#if ((INOHSZ&(INOHSZ-1)) == 0)#define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1))#else#define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ)#endifunion iso_ihead { union iso_ihead *ih_head[2]; struct iso_node *ih_chain[2];} iso_ihead[INOHSZ];#ifdef ISODEVMAP#define DNOHSZ 64#if ((DNOHSZ&(DNOHSZ-1)) == 0)#define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1))#else#define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ)#endifunion iso_dhead { union iso_dhead *dh_head[2]; struct iso_dnode *dh_chain[2];} iso_dhead[DNOHSZ];#endifint prtactive; /* 1 => print out reclaim of active vnodes *//* * Initialize hash links for inodes and dnodes. */cd9660_init(){ register int i; register union iso_ihead *ih = iso_ihead;#ifdef ISODEVMAP register union iso_dhead *dh = iso_dhead;#endif for (i = INOHSZ; --i >= 0; ih++) { ih->ih_head[0] = ih; ih->ih_head[1] = ih; }#ifdef ISODEVMAP for (i = DNOHSZ; --i >= 0; dh++) { dh->dh_head[0] = dh; dh->dh_head[1] = dh; }#endif}#ifdef ISODEVMAP/* * Enter a new node into the device hash list */struct iso_dnode *iso_dmap(dev,ino,create) dev_t dev; ino_t ino; int create;{ struct iso_dnode *dp; union iso_dhead *dh; dh = &iso_dhead[DNOHASH(dev, ino)]; for (dp = dh->dh_chain[0]; dp != (struct iso_dnode *)dh; dp = dp->d_forw) if (ino == dp->i_number && dev == dp->i_dev) return dp; if (!create) return (struct iso_dnode *)0; MALLOC(dp,struct iso_dnode *,sizeof(struct iso_dnode),M_CACHE,M_WAITOK); dp->i_dev = dev; dp->i_number = ino; insque(dp,dh); return dp;}voidiso_dunmap(dev) dev_t dev;{ struct iso_dnode *dp, *dq; union iso_dhead *dh; for (dh = iso_dhead; dh < iso_dhead + DNOHSZ; dh++) { for (dp = dh->dh_chain[0]; dp != (struct iso_dnode *)dh; dp = dq) { dq = dp->d_forw; if (dev == dp->i_dev) { remque(dp); FREE(dp,M_CACHE); } } }}#endif/* * Look up a ISOFS dinode number to find its incore vnode. * If it is not in core, read it in from the specified device. * If it is in core, wait for the lock bit to clear, then * return the inode locked. Detection and handling of mount * points must be done by the calling routine. */iso_iget(xp, ino, relocated, ipp, isodir) struct iso_node *xp; ino_t ino; struct iso_node **ipp; struct iso_directory_record *isodir;{ dev_t dev = xp->i_dev; struct mount *mntp = ITOV(xp)->v_mount; register struct iso_node *ip, *iq; register struct vnode *vp; register struct iso_dnode *dp; struct vnode *nvp; struct buf *bp = NULL, *bp2 = NULL; union iso_ihead *ih; union iso_dhead *dh; int i, error, result; struct iso_mnt *imp; ino_t defino; ih = &iso_ihead[INOHASH(dev, ino)];loop: for (ip = ih->ih_chain[0]; ip != (struct iso_node *)ih; ip = ip->i_forw) { if (ino != ip->i_number || dev != ip->i_dev) continue; if ((ip->i_flag&ILOCKED) != 0) { ip->i_flag |= IWANT; sleep((caddr_t)ip, PINOD); goto loop; } if (vget(ITOV(ip), 1)) goto loop; *ipp = ip; return 0; } /* * Allocate a new vnode/iso_node. */ if (error = getnewvnode(VT_ISOFS, mntp, cd9660_vnodeop_p, &nvp)) { *ipp = 0; return error; } MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, M_WAITOK); bzero((caddr_t)ip, sizeof(struct iso_node)); nvp->v_data = ip; ip->i_vnode = nvp; ip->i_flag = 0; ip->i_devvp = 0; ip->i_diroff = 0; ip->i_lockf = 0; /* * Put it onto its hash chain and lock it so that other requests for * this inode will block if they arrive while we are sleeping waiting * for old data structures to be purged or for the contents of the * disk portion of this inode to be read. */ ip->i_dev = dev; ip->i_number = ino; insque(ip, ih); ISO_ILOCK(ip); imp = VFSTOISOFS (mntp); ip->i_mnt = imp; ip->i_devvp = imp->im_devvp; VREF(ip->i_devvp); if (relocated) { /* * On relocated directories we must * read the `.' entry out of a dir. */ ip->iso_start = ino >> imp->im_bshift; if (error = iso_blkatoff(ip,0,&bp)) { vrele(ip->i_devvp); remque(ip); ip->i_forw = ip; ip->i_back = ip; iso_iput(ip); *ipp = 0; return error; } isodir = (struct iso_directory_record *)bp->b_un.b_addr; } ip->iso_extent = isonum_733(isodir->extent); ip->i_size = isonum_733(isodir->size); ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent; vp = ITOV(ip); /* * Setup time stamp, attribute */ vp->v_type = VNON; switch (imp->iso_ftype) { default: /* ISO_FTYPE_9660 */ if ((imp->im_flags&ISOFSMNT_EXTATT) && isonum_711(isodir->ext_attr_length)) iso_blkatoff(ip,-isonum_711(isodir->ext_attr_length), &bp2); cd9660_defattr(isodir,ip,bp2 ); cd9660_deftstamp(isodir,ip,bp2 ); break; case ISO_FTYPE_RRIP: result = cd9660_rrip_analyze(isodir,ip,imp); break; } if (bp2) brelse(bp2); if (bp) brelse(bp); /* * Initialize the associated vnode */ vp->v_type = IFTOVT(ip->inode.iso_mode); if ( vp->v_type == VFIFO ) {#ifdef FIFO extern int (**cd9660_fifoop_p)(); vp->v_op = cd9660_fifoop_p;#else iso_iput(ip); *ipp = 0; return EOPNOTSUPP;#endif /* FIFO */ } else if ( vp->v_type == VCHR || vp->v_type == VBLK ) { extern int (**cd9660_specop_p)(); /* * if device, look at device number table for translation */#ifdef ISODEVMAP if (dp = iso_dmap(dev,ino,0)) ip->inode.iso_rdev = dp->d_dev;#endif vp->v_op = cd9660_specop_p; if (nvp = checkalias(vp, ip->inode.iso_rdev, mntp)) { /* * Reinitialize aliased inode. */ vp = nvp; iq = VTOI(vp); iq->i_vnode = vp; iq->i_flag = 0; ISO_ILOCK(iq); iq->i_dev = dev; iq->i_number = ino; iq->i_mnt = ip->i_mnt; bcopy(&ip->iso_extent,&iq->iso_extent, (char *)(ip + 1) - (char *)&ip->iso_extent); insque(iq, ih); /* * Discard unneeded vnode * (This introduces the need of INACTIVE modification) */ ip->inode.iso_mode = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -