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

📄 ufs_vnodeops.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lintstatic        char sccsid[] = "@(#)ufs_vnodeops.c 1.1 92/07/30 Copyr 1986 Sun Micro";#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. */#include <sys/param.h>#include "boot/systm.h"#include <sys/user.h>#include <sys/buf.h>#include <sys/vfs.h>#include "boot/vnode.h"#include <sys/proc.h>#include <sys/file.h>#include <sys/uio.h>#include <sys/conf.h>#include <sys/kernel.h>#include "boot/cmap.h"#include <ufs/fs.h>#include "boot/inode.h"#include <ufs/mount.h>#include <ufs/fsdir.h>#ifdef QUOTA#include <ufs/quota.h>#endif#include <sys/dirent.h>#ifdef	NFS_BOOT#undef uextern struct user u;static int dump_debug = 20;#else #include <specfs/fifo.h>	/* this defines PIPE_BUF for ufs_getattr() */#include <krpc/lockmgr.h>#endif	 /* NFS_BOOT */#define ISVDEV(t) ((t == VCHR) || (t == VBLK) || (t == VFIFO))extern int ufs_open();extern int ufs_close();extern int ufs_rdwr();extern int ufs_ioctl();extern int ufs_select();extern int ufs_getattr();extern int ufs_access();extern int ufs_lookup();extern int ufs_readdir();extern int ufs_readlink();extern int ufs_fsync();extern int ufs_inactive();extern int ufs_bmap();extern int ufs_strategy();extern int ufs_bread();extern int ufs_brelse();extern int ufs_fid();extern int ufs_badop();struct vnodeops ufs_vnodeops = {	ufs_open,	ufs_close,	ufs_rdwr,	ufs_ioctl,	ufs_select,	ufs_getattr,	ufs_badop,	/* ufs_setattr */	ufs_access,	ufs_lookup,	ufs_badop,	/* ufs_create */	ufs_badop,	/* ufs_remove */	ufs_badop,	/* ufs_link */	ufs_badop,	/* ufs_rename */	ufs_badop,	/* ufs_mkdir */	ufs_badop,	/* ufs_rmdir */	ufs_readdir,	ufs_badop,	/* ufs_symlink */	ufs_readlink,	ufs_fsync,	ufs_inactive,	ufs_bmap,	ufs_strategy,	ufs_bread,	ufs_brelse,	ufs_badop,	/* ufs_lockctl */	ufs_fid,	/* ufs_badop, */};intufs_open(vpp, flag, cred)	struct vnode **vpp;	int flag;	struct ucred *cred;{#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6, "ufs_open(vpp 0x%x flag 0x%x cred 0x%x)\n", 		vpp, flag, cred);#endif	 /* DUMP_DEBUG */	return (0);}/*ARGSUSED*/intufs_close(vp, flag, cred)	struct vnode *vp;	int flag;	struct ucred *cred;{	return (0);}/* * read or write a vnode *//*ARGSUSED*/intufs_rdwr(vp, uiop, rw, ioflag, cred)	struct vnode *vp;	struct uio *uiop;	enum uio_rw rw;	int ioflag;	struct ucred *cred;{	register struct inode *ip;	int error;#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6,		"ufs_rdwr(vp 0x%x uiop 0x%x rw 0x%x ioflag 0x%x cred 0x%x)\n", 		vp, uiop, rw, ioflag, cred);#endif	 /* DUMP_DEBUG */	ip = VTOI(vp);	if ((ip->i_mode&IFMT) == IFREG) {		ILOCK(ip);		if ((ioflag & IO_APPEND) && (rw == UIO_WRITE)) {			/*			 * in append mode start at end of file.			 */			uiop->uio_offset = ip->i_size;		}		error = rwip(ip, uiop, rw, ioflag);		IUNLOCK(ip);	} else {		error = rwip(ip, uiop, rw, ioflag);	}	return (error);}intrwip(ip, uio, rw, ioflag)	register struct inode *ip;	register struct uio *uio;	enum uio_rw rw;	int ioflag;{	struct vnode *devvp;	struct buf *bp;	struct fs *fs;	daddr_t lbn, bn;	register int n, on, type;	int size;	long bsize;	extern int mem_no;	int error = 0;	int iupdat_flag = 0;#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6, "rwip(ip 0x%x uio 0x%x rw 0x%x ioflag 0x%x)\n", 		ip, uio, rw, ioflag);#endif	 /* DUMP_DEBUG */	if (rw != UIO_READ && rw != UIO_WRITE)		panic("rwip");	if (rw == UIO_READ && uio->uio_resid == 0)		return (0);	if ((uio->uio_offset < 0 || (uio->uio_offset + uio->uio_resid) < 0))		return (EINVAL);	if (rw == UIO_READ)		imark(ip, IACC);	if (uio->uio_resid == 0)		return (0);	type = ip->i_mode&IFMT;	if (type == IFCHR || type == IFBLK || type == IFIFO) {		panic("rwip dev inode");	}#ifdef notdef	if (rw == UIO_WRITE && type == IFREG &&	    uio->uio_offset + uio->uio_resid >	      u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {#ifdef	NFS_BOOT		dprint(dump_debug, 6, "rwip(1): no write\n");#else		psignal(u.u_procp, SIGXFSZ);		return (EFBIG);#endif	/* NFS_BOOT */	}#endif notdef	devvp = ip->i_devvp;	fs = ip->i_fs;	bsize = fs->fs_bsize;	u.u_error = 0;	do {		lbn = uio->uio_offset / bsize;		on = uio->uio_offset % bsize;		n = MIN((unsigned)(bsize - on), uio->uio_resid);		if (rw == UIO_READ) {			int diff = ip->i_size - uio->uio_offset;			if (diff <= 0)				return (0);			if (diff < n)				n = diff;		}		bn =		    fsbtodb(fs, bmap(ip, lbn,			 rw == UIO_WRITE ? B_WRITE: B_READ,			 (int)(on+n), (ioflag & IO_SYNC) ? &iupdat_flag : 0));		if (u.u_error || rw == UIO_WRITE && (long)bn<0)			return (u.u_error);		if (rw == UIO_WRITE &&		   (uio->uio_offset + n > ip->i_size) &&		   (type == IFDIR || type == IFREG || type == IFLNK)) {#ifdef	 NFS_BOOT			dprint(dump_debug, 6, "rwip(2): no write\n");#else			ip->i_size = uio->uio_offset + n;			if (ioflag & IO_SYNC) {				iupdat_flag = 1;			}#endif	/* NFS_BOOT */		}		size = blksize(fs, ip, lbn);		if (rw == UIO_READ) {			if ((long)bn<0) {				bp = geteblk(size);				clrbuf(bp);			} else if (ip->i_lastr + 1 == lbn)#ifdef	NFS_BOOT				bp = bread(devvp, bn, size);#else				bp = breada(devvp, bn, size, rablock, rasize);#endif	/* NFS_BOOT */			else				bp = bread(devvp, bn, size);			ip->i_lastr = lbn;		} else {#ifdef	 NFS_BOOT			dprint(dump_debug, 6, "rwip(3): no write\n");#else			int i, count;			extern struct cmap *mfind();			count = howmany(size, DEV_BSIZE);			for (i = 0; i < count; i += CLBYTES/DEV_BSIZE)				if (mfind(devvp, (daddr_t)(bn + i)))					munhash(devvp, (daddr_t)(bn + i));			if (n == bsize) 				bp = getblk(devvp, bn, size);			else				bp = bread(devvp, bn, size);#endif	/* NFS_BOOT */		}		n = MIN(n, bp->b_bcount - bp->b_resid);		if (bp->b_flags & B_ERROR) {			error = EIO;			brelse(bp);			goto bad;		}		u.u_error = uiomove(bp->b_un.b_addr+on, n, rw, uio);		if (rw == UIO_READ) {			if (n + on == bsize || uio->uio_offset == ip->i_size)				bp->b_flags |= B_DONTNEED;			brelse(bp);		} else {#ifdef	 NFS_BOOT			dprint(dump_debug, 6, "rwip(4): no write\n");#else			if ((ioflag & IO_SYNC) || (ip->i_mode&IFMT) == IFDIR)				bwrite(bp);			else if (n + on == bsize) {				bp->b_flags |= B_DONTNEED;				bawrite(bp);			} else				bdwrite(bp);			imark(ip, IUPD|ICHG);			if (u.u_ruid != 0)				ip->i_mode &= ~(ISUID|ISGID);#endif	/* NFS_BOOT */		}	} while (u.u_error == 0 && uio->uio_resid > 0 && n != 0);	if (iupdat_flag) {#ifdef	 NFS_BOOT			dprint(dump_debug, 6, "rwip(5): no write\n");#else		iupdat(ip, 1);#endif	/* NFS_BOOT */	}	if (error == 0)				/* XXX */		error = u.u_error;		/* XXX */bad:#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6, "rwip: error 0x%x\n", error);#endif	 /* DUMP_DEBUG */	return (error);}/*ARGSUSED*/intufs_ioctl(vp, com, data, flag, cred)	struct vnode *vp;	int com;	caddr_t data;	int flag;	struct ucred *cred;{	return (EINVAL);}/*ARGSUSED*/intufs_select(vp, which, cred)	struct vnode *vp;	int which;	struct ucred *cred;{	return (EINVAL);}/*ARGSUSED*/intufs_getattr(vp, vap, cred)	struct vnode *vp;	register struct vattr *vap;	struct ucred *cred;{	register struct inode *ip;	ip = VTOI(vp);	/*	 * Copy from inode table.	 */	vap->va_type = IFTOVT(ip->i_mode);	vap->va_mode = ip->i_mode;	vap->va_uid = ip->i_uid;	vap->va_gid = ip->i_gid;	vap->va_fsid = ip->i_dev;	vap->va_nodeid = ip->i_number;	vap->va_nlink = ip->i_nlink;	vap->va_size = ip->i_size;	vap->va_atime = ip->i_atime;	vap->va_mtime = ip->i_mtime;	vap->va_ctime = ip->i_ctime;	vap->va_rdev = ip->i_rdev;	vap->va_blocks = ip->i_blocks;	switch(ip->i_mode & IFMT) {	case IFBLK:		vap->va_blocksize = BLKDEV_IOSIZE;		break;	case IFCHR:		vap->va_blocksize = MAXBSIZE;		break;	default:		vap->va_blocksize = vp->v_vfsp->vfs_bsize;		break;	}	return (0);}/*ARGSUSED*/intufs_access(vp, mode, cred)	struct vnode *vp;	int mode;	struct ucred *cred;{	register struct inode *ip;	int error;#ifdef	DUMP_DEBUG1	dprint(dump_debug, 6, "ufs_access(vp 0x%x mode 0x%x cred 0x%x)\n", 		vp, mode, cred);#endif	/* DUMP_DEBUG */	ip = VTOI(vp);	ilock(ip);	error = iaccess(ip, mode);	iunlock(ip);#ifdef	DUMP_DEBUG1	dprint(dump_debug, 6, "ufs_access: error 0x%x\n", 		error);#endif	/* DUMP_DEBUG */	return (error);}/*ARGSUSED*/intufs_readlink(vp, uiop, cred)	struct vnode *vp;	struct uio *uiop;	struct ucred *cred;{	register struct inode *ip;	register int error;	if (vp->v_type != VLNK)		return (EINVAL);	ip = VTOI(vp);	ilock(ip);	error = rwip(ip, uiop, UIO_READ, 0);	iunlock(ip);	return (error);}/*ARGSUSED*/intufs_fsync(vp, cred)	struct vnode *vp;	struct ucred *cred;{	return (0);}/*ARGSUSED*/intufs_inactive(vp, cred)	struct vnode *vp;	struct ucred *cred;{	return (0);}/* * Unix file system operations having to do with directory manipulation. *//*ARGSUSED*/ufs_lookup(dvp, nm, vpp, cred)	struct vnode *dvp;	char *nm;	struct vnode **vpp;	struct ucred *cred;{	register int error;	struct inode *ip;#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6,		"ufs_lookup(dvp 0x%x nm %s vpp 0x%x cred 0x%x)\n", 		dvp, nm, vpp, cred);#endif	 /* DUMP_DEBUG */	error = dirlook(VTOI(dvp), nm, &ip);#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6, "ufs_lookup: dirlook error 0x%x\n", error);#endif	 /* DUMP_DEBUG */	if (error == 0) {		*vpp = ITOV(ip);		iunlock(ip);		/*		 * If vnode is a device return special vnode instead		 */		if (ISVDEV((*vpp)->v_type)) {#ifdef NFS_BOOT#else			struct vnode *newvp;#endif NFS_BOOT#ifdef	 NFS_BOOT			/*			 * Boot should not be looking up devices.			 */			dprint(dump_debug, 6,				"ufs_lookup: tried to access device\n");			#else			newvp = specvp(*vpp, (*vpp)->v_rdev);			VN_RELE(*vpp);			*vpp = newvp;#endif	 /* NFS_BOOT */		}	}	return (error);}/*ARGSUSED*/static intufs_readdir(vp, uiop, cred)        struct vnode *vp;        struct uio *uiop;        struct ucred *cred;{        register struct iovec *iovp;        register struct inode *ip;        struct uio tuio;        struct iovec tiov;        register struct direct *idp;        register struct dirent *odp;        off_t offset;        caddr_t inbuf, outbuf;        int bytes_read, bytes_wanted, total_bytes_wanted;        int incount = 0;        int outcount = 0;        int eof;        int error;        ip = VTOI(vp);        iovp = uiop->uio_iov;        total_bytes_wanted = iovp->iov_len;        bytes_wanted = iovp->iov_len & ~(DIRBLKSIZ - 1);        /* Setup temporary space to read directory entries into */        inbuf = (caddr_t) kmem_alloc((u_int)bytes_wanted);        tuio.uio_segflg = UIO_SYSSPACE;        tuio.uio_iov = &tiov;        tuio.uio_iovcnt = 1;        tuio.uio_resid = bytes_wanted;        tuio.uio_offset = offset = uiop->uio_offset & ~(DIRBLKSIZ - 1);        /* Get space to change dir. entries into filesystem independent format */        outbuf = (caddr_t)kmem_alloc((u_int)(total_bytes_wanted + sizeof(struct dirent)));        odp = (struct dirent *) outbuf;nextblk:        tuio.uio_resid = bytes_wanted;        tiov.iov_len = bytes_wanted;        tiov.iov_base = inbuf;        /* Read a chunk */        if (error = rwip(ip, &tuio, UIO_READ, 0))                goto out;        bytes_read = bytes_wanted - tuio.uio_resid;        eof = (bytes_read < bytes_wanted);        incount = 0;        idp = (struct direct *) inbuf;         /* Transform to file-system independent format */        while (incount < bytes_read) {                /* Skip to requested offset, and skip empty entries */                if (idp->d_ino != 0 && offset >= uiop->uio_offset) {                        odp->d_fileno = idp->d_ino;                        odp->d_namlen = idp->d_namlen;                        (void) strcpy(odp->d_name, idp->d_name);                        odp->d_reclen = DIRSIZ(odp);                        odp->d_off = offset + idp->d_reclen;                        outcount += odp->d_reclen;                        /* Got as many bytes as requested, quit */                        if (outcount > total_bytes_wanted) {                                outcount -= odp->d_reclen;                                break;                        }                        odp = (struct dirent *)((int)odp + odp->d_reclen);                }                        incount += idp->d_reclen;                offset += idp->d_reclen;                idp = (struct direct *)((int)idp + idp->d_reclen);        }         /* Read whole block, but got no entries, read another if not eof */        if (!eof && !outcount)                goto nextblk;        /* Copy out the entry data */        if (error = uiomove(outbuf, outcount, UIO_READ, uiop))                goto out;        uiop->uio_offset = offset;out:        ITIMES(ip);        kmem_free(inbuf, (u_int)bytes_wanted);        kmem_free(outbuf, (u_int)(total_bytes_wanted + sizeof(struct dirent)));        return (error);}/*ARGSUSED*/rdwri(rw, ip, base, len, offset, seg, aresid)	enum uio_rw rw;	struct inode *ip;	caddr_t base;	int len;	int offset;	int seg;	int *aresid;{	register int error;	error = EACCES;	return (error);}/*ARGSUSED*/intufs_bmap(vp, lbn, vpp, bnp)	struct vnode *vp;	daddr_t lbn;	struct vnode **vpp;	daddr_t *bnp;{	return (0);}/* * read a logical block and return it in a buffer *//*ARGSUSED*/intufs_bread(vp, lbn, bpp, sizep)	struct vnode *vp;	daddr_t lbn;	struct buf **bpp;	long *sizep;{#ifdef	 NEVER	register struct inode *ip;	register struct buf *bp;	register daddr_t bn;	register int size;#ifdef	 DUMP_DEBUG1	dprint(dump_debug, 6, "ufs_bread(vp 0x%x lbn 0x%x bpp 0x%x sizep 0x%x)\n", 		vp, lbn, bpp, sizep);#endif	 /* DUMP_DEBUG */	ip = VTOI(vp);	size = blksize(ip->i_fs, ip, lbn);	bn = fsbtodb(ip->i_fs, bmap(ip, lbn, B_READ));	if ((long)bn < 0) {		bp = geteblk(size);		clrbuf(bp);	} else if (ip->i_lastr + 1 == lbn) {		bp = breada(ip->i_devvp, bn, size, rablock, rasize);	} else {		bp = bread(ip->i_devvp, bn, size);	}	ip->i_lastr = lbn;	imark(ip, IACC);	if (bp->b_flags & B_ERROR) {		brelse(bp);		return (EIO);	} else {		*bpp = bp;		return (0);	}#endif	 /* NEVER */}/* * release a block returned by ufs_bread *//*ARGSUSED*/ufs_brelse(vp, bp)	struct vnode *vp;	struct buf *bp;{}intufs_badop(){	panic("ufs_badop");}/* * Record-locking requests are passed to the local Lock-Manager daemon. *//*ARGSUSED*/intufs_lockctl(vp, ld, cmd, cred)	struct vnode *vp;	struct flock *ld;	int cmd;	struct ucred *cred;{}/*ARGSUSED*/ufs_fid(vp, fidpp)	struct vnode *vp;	struct fid **fidpp;{	return (0);}/*ARGSUSED*/ufs_strategy(bp)	register struct buf *bp;{}/* * Stubs *//* * Zero out a buffer's data portion. */blkclr(addr, count)	char *addr;	int count;{        bzero(addr, count);}

⌨️ 快捷键说明

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