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

📄 nfs_vnodeops.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct vnode *vp;	struct vattr *vap;	struct ucred *cred;{	int error = 0;	struct nfsattrstat *ns;	struct rnode *rp;#ifdef	NFSDEBUG	dprint(nfsdebug, 6,		"nfsgetattr(vp 0x%x vap 0x%x cred 0x%x)\n",		vp, vap, cred);#endif	/* NFSDEBUG */	rp = vtor(vp);	if (timercmp(&time, &rp->r_attrtime, <)) {		/*		 * Use cached attributes.		 */		rp = vtor(vp);		nattr_to_vattr(&rp->r_attr, vap);		vap->va_fsid = 0xff00 | vtomi(vp)->mi_mntno;		if (rp->r_size < vap->va_size || ((rp->r_flags & RDIRTY) == 0)){			rp->r_size = vap->va_size;		} else if (vap->va_size < rp->r_size && (rp->r_flags & RDIRTY)){			vap->va_size = rp->r_size;		}	} else {		ns = (struct nfsattrstat *)kmem_alloc((u_int)sizeof(*ns));		error = rfscall(vtomi(vp), RFS_GETATTR, xdr_fhandle,		    (caddr_t)vtofh(vp), xdr_attrstat, (caddr_t)ns, cred);		if (!error) {			error = geterrno(ns->ns_status);			if (!error) {				nattr_to_vattr(&ns->ns_attr, vap);				/*				 * this is a kludge to make programs that use				 * dev from stat to tell file systems apart				 * happy.  we kludge up a dev from the mount				 * number and an arbitrary major number 255.				 */				vap->va_fsid = 0xff00 | vtomi(vp)->mi_mntno;				if (rp->r_size < vap->va_size ||				    ((rp->r_flags & RDIRTY) == 0)){					rp->r_size = vap->va_size;				} else if ((vap->va_size < rp->r_size) &&				    (rp->r_flags & RDIRTY)) {					vap->va_size = rp->r_size;				}				nfs_attrcache(vp, &ns->ns_attr);			} else {				check_stale_fh(error, vp);			}		}		kmem_free((caddr_t)ns, (u_int)sizeof(*ns));	}#ifdef	NFSDEBUG	dprint(nfsdebug, 6,		"nfsgetattr: returning 0x%x\n", error);#endif	/* NFSDEBUG */	return (error);}/*ARGSUSED*/intnfs_access(vp, mode, cred)	struct vnode *vp;	int mode;	struct ucred *cred;{	struct vattr va;#ifdef NEVER	int *gp;#endif NEVER#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_access %s %x mode %d uid %d\n",	    vtomi(vp)->mi_hostname, vp, mode, cred->cr_uid);#endif	u.u_error = nfsgetattr(vp, &va, cred);	if (u.u_error) {		return (u.u_error);	}	/*	 * If you're the super-user,	 * you always get access.	 */	if (cred->cr_uid == 0)		return (0);#ifdef	NEVER	/*	 * Access check is based on only	 * one of owner, group, public.	 * If not owner, then check group.	 * If not a member of the group, then	 * check public access.	 */	if (cred->cr_uid != va.va_uid) {		mode >>= 3;		if (cred->cr_gid == va.va_gid)			goto found;		gp = cred->cr_groups;		for (; gp < &cred->cr_groups[NGROUPS] && *gp != NOGROUP; gp++)			if (va.va_gid == *gp)				goto found;		mode >>= 3;	}found:#endif  /* NEVER */	if ((va.va_mode & mode) == mode) {#ifdef NFSDEBUG	dprint(nfsdebug, 5, "nfs_access: OK\n");#endif	/* NFSDEBUG */		return (0);	}#ifdef NFSDEBUG	dprint(nfsdebug, 5, "nfs_access: returning %d\n", u.u_error);#endif /* NFSDEBUG */	u.u_error = EACCES;	return (EACCES);}intnfs_readlink(vp, uiop, cred)	struct vnode *vp;	struct uio *uiop;	struct ucred *cred;{	int error;	struct nfsrdlnres rl;#ifdef NFSDEBUG	dprint(nfsdebug, 6,		"nfs_readlink %s %x\n", vtomi(vp)->mi_hostname, vp);#endif	if(vp->v_type != VLNK)		return (ENXIO);	rl.rl_data = (char *)kmem_alloc((u_int)NFS_MAXPATHLEN);	error =	    rfscall(vtomi(vp), RFS_READLINK, xdr_fhandle, (caddr_t)vtofh(vp),	      xdr_rdlnres, (caddr_t)&rl, cred);	if (!error) {		error = geterrno(rl.rl_status);		if (!error) {			error = uiomove(rl.rl_data, (int)rl.rl_count,			    UIO_READ, uiop);		} else {			check_stale_fh(error, vp);		}	}	kmem_free((caddr_t)rl.rl_data, (u_int)NFS_MAXPATHLEN);#ifdef NFSDEBUG	dprint(nfsdebug, 6,		"nfs_readlink: returning %d\n", error);#endif	return (error);}/*ARGSUSED*/staticsync_vp(vp)	struct vnode *vp;{}/* * Weirdness: if the file was removed while it was open it got * renamed (by nfs_remove) instead.  Here we remove the renamed * file. *//*ARGSUSED*/intnfs_inactive(vp, cred)	struct vnode *vp;	struct ucred *cred;{	int error;	struct nfsdiropargs da;	enum nfsstat status;	register struct rnode *rp;#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_inactive '%s' 0x%x\n",	     vtomi(vp)->mi_hostname,  vp);#endif	rp = vtor(vp);	/*	 * Pull rnode off of the hash list so it won't be found	 */	runsave(rp); 	if (rp->r_unldvp != NULL) {		rlock(vtor(rp->r_unldvp));		setdiropargs(&da, rp->r_unlname, rp->r_unldvp);		error = rfscall( vtomi(rp->r_unldvp), RFS_REMOVE,		    xdr_diropargs, (caddr_t)&da,		    xdr_enum, (caddr_t)&status, rp->r_unlcred); 		if (!error) {			error = geterrno(status); 		}		runlock(vtor(rp->r_unldvp));		VN_RELE(rp->r_unldvp);		rp->r_unldvp = NULL;		kmem_free((caddr_t)rp->r_unlname, (u_int)NFS_MAXNAMLEN);		rp->r_unlname = NULL;		crfree(rp->r_unlcred);		rp->r_unlcred = NULL;	}	((struct mntinfo *)vp->v_vfsp->vfs_data)->mi_refct--;	if (rp->r_cred) {		crfree(rp->r_cred);		rp->r_cred = NULL;	}	rfree(rp);#ifdef NFSDEBUG	dprint(nfsdebug, 5, "nfs_inactive done\n");#endif	return (0);}int nfs_dnlc = 1;	/* use dnlc *//* * Remote file system operations having to do with directory manipulation. */nfs_lookup(dvp, nm, vpp, cred)	struct vnode *dvp;	char *nm;	struct vnode **vpp;	struct ucred *cred;{	int error;	struct nfsdiropargs da;	struct  nfsdiropres *dr;	struct vattr va;#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_lookup %s %x '%s'\n",	    vtomi(dvp)->mi_hostname, dvp, nm);#endif 	/*	 * Before checking dnlc, call getattr to be	 * sure directory hasn't changed.  getattr	 * will purge dnlc if a change has occurred.	 */	if (error = nfs_getattr(dvp, &va, cred)) {		return (error);	}	rlock(vtor(dvp));	*vpp = (struct vnode *)0;	if (*vpp) {		VN_HOLD(*vpp);	} else {		dr = (struct  nfsdiropres *)kmem_alloc((u_int)sizeof(*dr));		setdiropargs(&da, nm, dvp); 		error = rfscall(vtomi(dvp), RFS_LOOKUP, xdr_diropargs,		    (caddr_t)&da, xdr_diropres, (caddr_t)dr, cred);		if (!error) {			error = geterrno(dr->dr_status);			check_stale_fh(error, dvp);		}		if (!error) {			*vpp = makenfsnode(&dr->dr_fhandle,			    &dr->dr_attr, dvp->v_vfsp);		} else {			*vpp = (struct vnode *)0;		} 		kmem_free((caddr_t)dr, (u_int)sizeof(*dr));	}	runlock(vtor(dvp));#ifdef NFSDEBUG	dprint(nfsdebug, 5, "nfs_lookup returning %d vp = %x\n", error, *vpp);#endif	return (error);}/* * Read directory entries. * There are some weird things to look out for here.  The uio_offset * field is either 0 or it is the offset returned from a previous * readdir.  It is an opaque value used by the server to find the * correct directory block to read.  The byte count must be at least * vtoblksz(vp) bytes.  The count field is the number of blocks to * read on the server.  This is advisory only, the server may return * only one block's worth of entries.  Entries may be compressed on * the server. */nfs_readdir(vp, uiop, cred)	struct vnode *vp;	register struct uio *uiop;	struct ucred *cred;{	int error = 0;	struct iovec *iovp;	unsigned count;	struct nfsrddirargs rda;	struct nfsrddirres  rd;	struct rnode *rp;#ifdef NFSDEBUG	dprint(nfsdebug, 6, "nfs_readdir(vp 0x%x uiop 0x%x cred 0x%x)\n",	    vp, uiop, cred);#endif	rp = vtor(vp);	if ((rp->r_flags & REOF) && (rp->r_size == (u_long)uiop->uio_offset)) {		return (0);	}	iovp = uiop->uio_iov;	count = iovp->iov_len;#ifdef NFSDEBUG	dprint(nfsdebug, 6, "nfs_readdir %s %x count %d offset %d\n",	    vtomi(vp)->mi_hostname, vp, count, uiop->uio_offset);#endif	/*	 * XXX We should do some kind of test for count >= DEV_BSIZE	 */	if (uiop->uio_iovcnt != 1) {		return (EINVAL);	}	count = MIN(count, vtomi(vp)->mi_tsize);	rda.rda_count = count;	rda.rda_offset = uiop->uio_offset;	rda.rda_fh = *vtofh(vp);	rd.rd_size = count;	rd.rd_entries = (struct direct *)kmem_alloc((u_int)count);	error = rfscall(vtomi(vp), RFS_READDIR, xdr_rddirargs, (caddr_t)&rda,	    xdr_getrddirres, (caddr_t)&rd, cred);	if (!error) {		error = geterrno(rd.rd_status);		check_stale_fh(error, vp);	}	if (!error) {		/*		 * move dir entries to user land		 */		if (rd.rd_size) {			error = uiomove((caddr_t)rd.rd_entries,			    (int)rd.rd_size, UIO_READ, uiop);			rda.rda_offset = rd.rd_offset;			uiop->uio_offset = rd.rd_offset;		}		if (rd.rd_eof) {			rp->r_flags |= REOF;			rp->r_size = uiop->uio_offset;		}	}	kmem_free((caddr_t)rd.rd_entries, (u_int)count);#ifdef NFSDEBUG	dprint(nfsdebug, 6, "nfs_readdir: returning %d resid %d, offset %d\n",	    error, uiop->uio_resid, uiop->uio_offset);#endif	return (error);}/* * Convert from file system blocks to device blocks */intnfs_bmap(vp, bn, vpp, bnp)	struct vnode *vp;	/* file's vnode */	daddr_t bn;		/* fs block number */	struct vnode **vpp;	/* RETURN vp of device */	daddr_t *bnp;		/* RETURN device block number */{	int bsize;		/* server's block size in bytes */#ifdef NFSDEBUG1	dprint(nfsdebug, 4, "nfs_bmap %s %x blk %d vpp 0x%x\n",	    vtomi(vp)->mi_hostname, vp, bn, vpp);#endif	/* NFSDEBUG */	if (vpp)		*vpp = vp;	if (bnp) {		bsize = vtoblksz(vp);		*bnp = bn * (bsize / DEV_BSIZE);	}	return (0);}struct buf *async_bufhead;int async_daemon_count;intnfs_strategy(bp)	register struct buf *bp;{#ifdef NFSDEBUG	dprint(nfsdebug, 4, "nfs_strategy bp %x\n", bp);#endif}async_daemon(){}do_bio(bp)	register struct buf *bp;{#ifdef NFSDEBUG	dprint(nfsdebug, 4,	    "do_bio: addr %x, blk %d, offset %d, size %d, B_READ %d\n",	    bp->b_un.b_addr, bp->b_blkno, bp->b_blkno * DEV_BSIZE,	    bp->b_bcount, bp->b_flags & B_READ);#endif}intnfs_badop(){#ifdef notdef	panic("nfs_badop");#endif	return (0);}intnfs_noop(){	return (EREMOTE);}dnlc_purge_vp(vp)	register struct vnode *vp;{#ifdef	NFSDEBUG        dprint(nfsdebug, 6, "dnlc_purge_vp(vp 0x%x)\n", vp);#endif	/* NFSDEBUG */}

⌨️ 快捷键说明

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