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

📄 nfs_vnodeops.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      @(#)nfs_vnodeops.c 1.1 92/07/30 SMI      *//* * Copyright (c) 1986 by Sun Microsystems, Inc. */#include <sys/param.h>#include "boot/systm.h"#include <sys/user.h>#include "boot/vnode.h"#include <sys/vfs.h>#include <sys/file.h>#include <sys/uio.h>#include <sys/buf.h>#include <sys/kernel.h>#include "boot/cmap.h"#include <netinet/in.h>#include <sys/proc.h>#include <rpc/types.h>#include <rpc/auth.h>#include <rpc/clnt.h>#include <rpc/xdr.h>#include "boot/nfs.h"#include <nfs/nfs_clnt.h>#include <nfs/rnode.h>#ifdef	NFSDEBUGstatic int nfsdebug = 10;#endif	/* NFSDEBUG */struct vnode *makenfsnode();char *newname();#define RNOCACHE 0x20		/* don't cache read and write blocks */#define check_stale_fh(errno, vp) if ((errno) == ESTALE) { dnlc_purge_vp(vp); }#define nfsattr_inval(vp)       (vtor(vp)->r_attrtime.tv_sec = 0)#define ISVDEV(t) ((t == VBLK) || (t == VCHR) || (t == VFIFO))#define rlock(rp) { \	while ((rp)->r_flags & RLOCKED) { \		(rp)->r_flags |= RWANT; \		(void) sleep((caddr_t)(rp), PINOD); \	} \	(rp)->r_flags |= RLOCKED; \}#define runlock(rp) { \	(rp)->r_flags &= ~RLOCKED; \	if ((rp)->r_flags&RWANT) { \		(rp)->r_flags &= ~RWANT; \		wakeup((caddr_t)(rp)); \	} \}#undef uextern	struct user u;/* * These are the vnode ops routines which implement the vnode interface to * the networked file system.  These routines just take their parameters, * make them look networkish by putting the right info into interface structs, * and then calling the appropriate remote routine(s) to do the work. * * Note on directory name lookup cacheing:  we desire that all operations * on a given client machine come out the same with or without the cache. * This is the same property we have with the disk buffer cache.  In order * to guarantee this, we serialize all operations on a given directory, * by using rlock and runlock around rfscalls to the server.  This way, * we cannot get into races with ourself that would cause invalid information * in the cache.  Other clients (or the server itself) can cause our * cached information to become invalid, the same as with data buffers. * Also, if we do detect a stale fhandle, we purge the directory cache * relative to that vnode.  This way, the user won't get burned by the * cache repeatedly. */int nfs_open();int nfs_close();int nfs_rdwr();int nfs_ioctl();int nfs_select();int nfs_getattr();int nfs_access();int nfs_lookup();int nfs_readdir();int nfs_readlink();int nfs_inactive();int nfs_bmap();int nfs_strategy();int nfs_badop();int nfs_noop();struct vnodeops nfs_vnodeops = {	nfs_open,	nfs_close,	nfs_rdwr,	nfs_ioctl,	nfs_select,	nfs_getattr,	nfs_badop,	/* nfs_setattr */	nfs_access,	nfs_lookup,	nfs_badop,	/* nfs_create */	nfs_badop,	/* nfs_remove */	nfs_badop,	/* nfs_link */	nfs_badop,	/* nfs_rename */	nfs_badop,	/* nfs_mkdir */	nfs_badop,	/* nfs_rmdir */	nfs_readdir,	nfs_badop,	/* nfs_symlink */	nfs_readlink,	nfs_badop,	/* nfs_fsync */	nfs_inactive,	nfs_bmap,	nfs_strategy,	nfs_badop,	nfs_badop,	nfs_badop,	/* nfs_locktl */	nfs_noop,};/*ARGSUSED*/intnfs_open(vpp, flag, cred)	register struct vnode **vpp;	int flag;	struct ucred *cred;{	struct vattr va;	int error;#ifdef NFSDEBUG	dprint(nfsdebug, 6, "nfs_open %s %x flag %d\n",	    vtomi(*vpp)->mi_hostname, *vpp, flag);#endif	/*	 * validate cached data by getting the attributes from the server	 */	nfsattr_inval(*vpp);	error = nfs_getattr(*vpp, &va, cred);	return (error);}/*ARGSUSED*/intnfs_close(vp, flag, cred)	struct vnode *vp;	int flag;	struct ucred *cred;{#ifdef NFSDEBUG	dprint(nfsdebug, 6, "nfs_close %s %x flag %d\n",	    vtomi(vp)->mi_hostname, vp, flag);#endif	return(EACCES);}intnfs_rdwr(vp, uiop, rw, ioflag, cred)	register struct vnode *vp;	struct uio *uiop;	enum uio_rw rw;	int ioflag;	struct ucred *cred;{	int error = 0;	struct rnode *rp;#ifdef NFSDEBUG1	dprint(nfsdebug, 6, "nfs_rdwr: %s %x rw %s offset %x len %d\n",	    vtomi(vp)->mi_hostname, vp, rw == UIO_READ ? "READ" : "WRITE",	    uiop->uio_offset, uiop->uio_iov->iov_len);#endif	if (vp->v_type != VREG) {		return (EISDIR);	}	if (rw == UIO_WRITE || (rw == UIO_READ && vtor(vp)->r_cred == NULL)) {		crhold(cred);		if (vtor(vp)->r_cred) {			crfree(vtor(vp)->r_cred);		}		vtor(vp)->r_cred = cred;	}	if ((ioflag & IO_APPEND) && rw == UIO_WRITE) {		struct vattr va;		rp = vtor(vp);		rlock(rp);		error = VOP_GETATTR(vp, &va, cred);		if (!error) {			uiop->uio_offset = rp->r_size;		}	}	if (!error) {		error = rwvp(vp, uiop, rw, cred);	}	if ((ioflag & IO_APPEND) && rw == UIO_WRITE) {		runlock(rp);	}#ifdef NFSDEBUG1	dprint(nfsdebug, 6, "nfs_rdwr returning %d\n", error);#endif	/* NFSDEBUG */	return (error);}intrwvp(vp, uio, rw, cred)	register struct vnode *vp;	register struct uio *uio;	enum uio_rw rw;	struct ucred *cred;{	struct buf *bp;	struct rnode *rp;	daddr_t bn;	register int n, on;	int size;	int error = 0;	struct vnode *mapped_vp;	daddr_t mapped_bn;	int eof = 0;#ifdef NFSDEBUG1	dprint(nfsdebug, 6, "rwvp(vp 0x%x uio 0x%x rw 0x%x cred 0x%x)\n",		vp, uio, rw, cred);#endif	/* NFSDEBUG */	if (uio->uio_resid == 0) {		return (0);	}	if (uio->uio_offset < 0 || (uio->uio_offset + uio->uio_resid) < 0) {		return (EINVAL);	}#ifdef notdef	/*	 * Soooo, why wasn't this just removed 	 */	if (rw == UIO_WRITE && vp->v_type == VREG &&	    uio->uio_offset + uio->uio_resid >	      u.u_rlimit[RLIMIT_FSIZE].rlim_cur) {		psignal(u.u_procp, SIGXFSZ);		return (EFBIG);	}#endif notdef	rp = vtor(vp);	/*	 * For now, ensure no cache.	 */	rp->r_flags |= RNOCACHE;	size = vtoblksz(vp);	size &= ~(DEV_BSIZE - 1);	if (size <= 0) {		panic("rwvp: zero size");	}	do {		bn = uio->uio_offset / size;		on = uio->uio_offset % size;		n = MIN((unsigned)(size - on), uio->uio_resid);		VOP_BMAP(vp, bn, &mapped_vp, &mapped_bn);		if (rp->r_flags & RNOCACHE) {			bp = geteblk(size);			if (rw == UIO_READ) {				error = nfsread(vp, bp->b_un.b_addr+on,				    (int)uio->uio_offset, n, (int *)&bp->b_resid,					 cred);				if (error) {					brelse(bp);					goto bad;				}			}		}		if (bp->b_flags & B_ERROR) {			error = geterror(bp);			brelse(bp);			goto bad;		}		u.u_error = uiomove(bp->b_un.b_addr+on, n, rw, uio);		if (rw == UIO_READ) {			brelse(bp);		} else {		}	} while (u.u_error == 0 && uio->uio_resid > 0 && !eof);	if (error == 0)				/* XXX */ 		error = u.u_error;		/* XXX */ bad:	return (error);}/* * Write to file. * Writes to remote server in largest size chunks that the server can * handle.  Write is synchronous. *//*ARGSUSED*/nfswrite(vp, base, offset, count, cred)	struct vnode *vp;	caddr_t base;	int offset;	int count;	struct ucred *cred;{	int error;#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfswrite %s %x offset = %d, count = %d\n",	    vtomi(vp)->mi_hostname, vp, offset, count);#endif	error = EACCES;#ifdef NFSDEBUG	dprint(nfsdebug, 5, "nfswrite: returning %d\n", error);#endif	return (error);}/* * Read from a file. * Reads data in largest chunks our interface can handle */nfsread(vp, base, offset, count, residp, cred)	struct vnode *vp;	caddr_t base;	int offset;	int count;	int *residp;	struct ucred *cred;{	int error;	struct nfsreadargs ra;	struct nfsrdresult rr;	register int tsize;#ifdef NFSDEBUG1	dprint(nfsdebug, 4, "nfsread %s %x offset = %d, totcount = %d\n",	    vtomi(vp)->mi_hostname, vp, offset, count);#endif	/* NFSDEBUG */	do {		tsize = MIN(vtomi(vp)->mi_tsize, count);		rr.rr_data = base;		ra.ra_fhandle = *vtofh(vp);		ra.ra_offset = offset;		ra.ra_totcount = tsize;		ra.ra_count = tsize;		error = rfscall(vtomi(vp), RFS_READ, xdr_readargs, (caddr_t)&ra,			xdr_rdresult, (caddr_t)&rr, cred);		if (!error) {			error = geterrno(rr.rr_status);			check_stale_fh(error, vp);		}		if (!error) {			count -= rr.rr_count;			base += rr.rr_count;			offset += rr.rr_count;		}	} while (!error && count && rr.rr_count == tsize);	*residp = count;	if (!error) {		nfs_attrcache(vp, &rr.rr_attr);	}#ifdef NFSDEBUG1	dprint(nfsdebug, 5, "nfsread: returning %d, resid %d\n",		error, *residp);#endif	return (error);}/*ARGSUSED*/intnfs_ioctl(vp, com, data, flag, cred)	struct vnode *vp;	int com;	caddr_t data;	int flag;	struct ucred *cred;{	return (EOPNOTSUPP);}/*ARGSUSED*/intnfs_select(vp, which, cred)	struct vnode *vp;	int which;	struct ucred *cred;{	return (EOPNOTSUPP);}/* * Timeout values for attributes for * regular files, and for directories. */int nfsac_regtimeo_min = 3;int nfsac_regtimeo_max = 60;int nfsac_dirtimeo_min = 30;int nfsac_dirtimeo_max = 60;/*ARGSUSED*/nfs_attrcache(vp, na)	struct vnode *vp;	struct nfsfattr *na;{#ifdef	NFSDEBUG1	dprint(nfsdebug, 6,		"nfs_attrcache(vp 0x%x na 0x%x)\n",		vp, na);#endif	/* NFSDEBUG */}intnfs_getattr(vp, vap, cred)	struct vnode *vp;	struct vattr *vap;	struct ucred *cred;{	int error;#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_getattr %s %x\n", vtomi(vp)->mi_hostname, vp);#endif	sync_vp(vp);    /* sync blocks so mod time is right */	error = nfsgetattr(vp, vap, cred);#ifdef NFSDEBUG	dprint(nfsdebug, 5, "nfs_getattr: returns %d\n", error);#endif	return (error);}intnfsgetattr(vp, vap, cred)

⌨️ 快捷键说明

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