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

📄 cd9660_vnops.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 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_vnops.c	8.3 (Berkeley) 1/23/94 */#include <sys/param.h>#include <sys/systm.h>#include <sys/namei.h>#include <sys/resourcevar.h>#include <sys/kernel.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/buf.h>#include <sys/proc.h>#include <sys/conf.h>#include <sys/mount.h>#include <sys/vnode.h>#include <miscfs/specfs/specdev.h>#include <miscfs/fifofs/fifo.h>#include <sys/malloc.h>#include <sys/dir.h>#include <isofs/cd9660/iso.h>#include <isofs/cd9660/cd9660_node.h>#include <isofs/cd9660/iso_rrip.h>#if 0/* * Mknod vnode call *  Actually remap the device number */cd9660_mknod(ndp, vap, cred, p)	struct nameidata *ndp;	struct ucred *cred;	struct vattr *vap;	struct proc *p;{#ifndef	ISODEVMAP	free(ndp->ni_pnbuf, M_NAMEI);	vput(ndp->ni_dvp);	vput(ndp->ni_vp);	return EINVAL;#else	register struct vnode *vp;	struct iso_node *ip;	struct iso_dnode *dp;	int error;		vp = ndp->ni_vp;	ip = VTOI(vp);		if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP	    || vap->va_type != vp->v_type	    || (vap->va_type != VCHR && vap->va_type != VBLK)) {		free(ndp->ni_pnbuf, M_NAMEI);		vput(ndp->ni_dvp);		vput(ndp->ni_vp);		return EINVAL;	}		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 */		remque(dp);		FREE(dp,M_CACHE);	} else		/* enter new mapping */		dp->d_dev = vap->va_rdev;		/*	 * Remove inode so that it will be reloaded by iget and	 * checked to see if it is an alias of an existing entry	 * in the inode cache.	 */	vput(vp);	vp->v_type = VNON;	vgone(vp);	return (0);#endif}#endif/* * Open called. * * Nothing to do. *//* ARGSUSED */intcd9660_open(ap)	struct vop_open_args /* {		struct vnode *a_vp;		int  a_mode;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	return (0);}/* * Close called * * Update the times on the inode on writeable file systems. *//* ARGSUSED */intcd9660_close(ap)	struct vop_close_args /* {		struct vnode *a_vp;		int  a_fflag;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	return (0);}/* * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. * The mode is shifted to select the owner/group/other fields. The * super user is granted all permissions. *//* ARGSUSED */cd9660_access(ap)	struct vop_access_args /* {		struct vnode *a_vp;		int  a_mode;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	return (0);}cd9660_getattr(ap)	struct vop_getattr_args /* {		struct vnode *a_vp;		struct vattr *a_vap;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	struct vnode *vp = ap->a_vp;	register struct vattr *vap = ap->a_vap;	register struct iso_node *ip = VTOI(vp);	int i;	vap->va_fsid	= ip->i_dev;	vap->va_fileid	= ip->i_number;	vap->va_mode	= ip->inode.iso_mode;	vap->va_nlink	= ip->inode.iso_links;	vap->va_uid	= ip->inode.iso_uid;	vap->va_gid	= ip->inode.iso_gid;	vap->va_atime	= ip->inode.iso_atime;	vap->va_mtime	= ip->inode.iso_mtime;	vap->va_ctime	= ip->inode.iso_ctime;	vap->va_rdev	= ip->inode.iso_rdev;	vap->va_size	= (u_quad_t) ip->i_size;	vap->va_flags	= 0;	vap->va_gen = 1;	vap->va_blocksize = ip->i_mnt->logical_block_size;	vap->va_bytes	= (u_quad_t) ip->i_size;	vap->va_type	= vp->v_type;	return (0);}#if ISO_DEFAULT_BLOCK_SIZE >= NBPG#ifdef DEBUGextern int doclusterread;#else#define doclusterread 1#endif#else/* XXX until cluster routines can handle block sizes less than one page */#define doclusterread 0#endif/* * Vnode op for reading. */cd9660_read(ap)	struct vop_read_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int a_ioflag;		struct ucred *a_cred;	} */ *ap;{	struct vnode *vp = ap->a_vp;	register struct uio *uio = ap->a_uio;	register struct iso_node *ip = VTOI(vp);	register struct iso_mnt *imp;	struct buf *bp;	daddr_t lbn, bn, rablock;	off_t diff;	int rasize, error = 0;	long size, n, on;		if (uio->uio_resid == 0)		return (0);	if (uio->uio_offset < 0)		return (EINVAL);	ip->i_flag |= IACC;	imp = ip->i_mnt;	do {		lbn = iso_lblkno(imp, uio->uio_offset);		on = iso_blkoff(imp, uio->uio_offset);		n = min((unsigned)(imp->logical_block_size - on),			uio->uio_resid);		diff = (off_t)ip->i_size - uio->uio_offset;		if (diff <= 0)			return (0);		if (diff < n)			n = diff;		size = iso_blksize(imp, ip, lbn);		rablock = lbn + 1;		if (doclusterread) {			if (iso_lblktosize(imp, rablock) <= ip->i_size)				error = cluster_read(vp, (off_t)ip->i_size,						     lbn, size, NOCRED, &bp);			else 				error = bread(vp, lbn, size, NOCRED, &bp);		} else {			if (vp->v_lastr + 1 == lbn &&			    iso_lblktosize(imp, rablock) < ip->i_size) {				rasize = iso_blksize(imp, ip, rablock);				error = breadn(vp, lbn, size, &rablock,					       &rasize, 1, NOCRED, &bp);			} else				error = bread(vp, lbn, size, NOCRED, &bp);		}		vp->v_lastr = lbn;		n = min(n, size - bp->b_resid);		if (error) {			brelse(bp);			return (error);		}		error = uiomove(bp->b_un.b_addr + on, (int)n, uio);		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);}/* ARGSUSED */intcd9660_ioctl(ap)	struct vop_ioctl_args /* {		struct vnode *a_vp;		int  a_command;		caddr_t  a_data;		int  a_fflag;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	printf("You did ioctl for isofs !!\n");	return (ENOTTY);}/* ARGSUSED */intcd9660_select(ap)	struct vop_select_args /* {		struct vnode *a_vp;		int  a_which;		int  a_fflags;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	/*	 * We should really check to see if I/O is possible.	 */	return (1);}/* * Mmap a file * * NB Currently unsupported. *//* ARGSUSED */intcd9660_mmap(ap)	struct vop_mmap_args /* {		struct vnode *a_vp;		int  a_fflags;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	return (EINVAL);}/* * Seek on a file * * Nothing to do, so just return. *//* ARGSUSED */intcd9660_seek(ap)	struct vop_seek_args /* {		struct vnode *a_vp;		off_t  a_oldoff;		off_t  a_newoff;		struct ucred *a_cred;	} */ *ap;{	return (0);}/* * Structure for reading directories */struct isoreaddir {	struct dirent saveent;	struct dirent assocent;	struct dirent current;	off_t saveoff;	off_t assocoff;	off_t curroff;	struct uio *uio;	off_t uio_off;	u_int *cookiep;	int ncookies;	int eof;};static intiso_uiodir(idp,dp,off)	struct isoreaddir *idp;	struct dirent *dp;	off_t off;{	int error;		dp->d_name[dp->d_namlen] = 0;	dp->d_reclen = DIRSIZ(dp);		if (idp->uio->uio_resid < dp->d_reclen) {		idp->eof = 0;		return -1;	}		if (idp->cookiep) {		if (idp->ncookies <= 0) {			idp->eof = 0;			return -1;		}				*idp->cookiep++ = off;		--idp->ncookies;	}		if (error = uiomove(dp,dp->d_reclen,idp->uio))		return error;	idp->uio_off = off;	return 0;}static intiso_shipdir(idp)	struct isoreaddir *idp;{	struct dirent *dp;	int cl, sl, assoc;	int error;	char *cname, *sname;		cl = idp->current.d_namlen;	cname = idp->current.d_name;	if (assoc = cl > 1 && *cname == ASSOCCHAR) {		cl--;		cname++;	}		dp = &idp->saveent;	sname = dp->d_name;	if (!(sl = dp->d_namlen)) {		dp = &idp->assocent;		sname = dp->d_name + 1;		sl = dp->d_namlen - 1;	}	if (sl > 0) {		if (sl != cl		    || bcmp(sname,cname,sl)) {			if (idp->assocent.d_namlen) {				if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff))					return error;				idp->assocent.d_namlen = 0;			}			if (idp->saveent.d_namlen) {				if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))					return error;				idp->saveent.d_namlen = 0;			}		}	}	idp->current.d_reclen = DIRSIZ(&idp->current);	if (assoc) {		idp->assocoff = idp->curroff;		bcopy(&idp->current,&idp->assocent,idp->current.d_reclen);	} else {		idp->saveoff = idp->curroff;		bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);	}	return 0;}/* * Vnode op for readdir * XXX make sure everything still works now that eofflagp and cookiep * are no longer args. */intcd9660_readdir(ap)	struct vop_readdir_args /* {		struct vnode *a_vp;		struct uio *a_uio;		struct ucred *a_cred;	} */ *ap;{	register struct uio *uio = ap->a_uio;	struct isoreaddir *idp;	int entryoffsetinblock;	int error = 0;	int endsearch;	struct iso_directory_record *ep;	u_short elen;	int reclen;	struct iso_mnt *imp;	struct iso_node *ip;	struct buf *bp = NULL;		ip = VTOI(ap->a_vp);	imp = ip->i_mnt;		MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK);	idp->saveent.d_namlen = 0;	idp->assocent.d_namlen = 0;	idp->uio = uio;#if 0	idp->cookiep = cookies;	idp->ncookies = ncookies;	idp->eof = 1;#else	idp->cookiep = 0;#endif	idp->curroff = uio->uio_offset;		entryoffsetinblock = iso_blkoff(imp, idp->curroff);	if (entryoffsetinblock != 0) {		if (error = iso_blkatoff(ip, idp->curroff, &bp)) {			FREE(idp,M_TEMP);			return (error);		}	}		endsearch = ip->i_size;		while (idp->curroff < endsearch) {		/*		 * If offset is on a block boundary,		 * read the next directory block.		 * Release previous if it exists.		 */				if (iso_blkoff(imp, idp->curroff) == 0) {			if (bp != NULL)				brelse(bp);			if (error = iso_blkatoff(ip, idp->curroff, &bp))				break;			entryoffsetinblock = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -