⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cd9660_node.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * 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 + -