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

📄 nfs_vnops.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
 * - make nfs_bmap() essentially a no-op that does no translation * - do nfs_strategy() by faking physical I/O with nfs_readrpc/nfs_writerpc *   after mapping the physical addresses into Kernel Virtual space in the *   nfsiobuf area. *   (Maybe I could use the process's page mapping, but I was concerned that *    Kernel Write might not be enabled and also figured copyout() would do *    a lot more work than bcopy() and also it currently happens in the *    context of the swapper process (2). */intnfs_bmap(ap)	struct vop_bmap_args /* {		struct vnode *a_vp;		daddr_t  a_bn;		struct vnode **a_vpp;		daddr_t *a_bnp;		int *a_runp;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	if (ap->a_vpp != NULL)		*ap->a_vpp = vp;	if (ap->a_bnp != NULL)		*ap->a_bnp = ap->a_bn * btodb(vp->v_mount->mnt_stat.f_iosize);	return (0);}/* * Strategy routine. * For async requests when nfsiod(s) are running, queue the request by * calling nfs_asyncio(), otherwise just all nfs_doio() to do the * request. */intnfs_strategy(ap)	struct vop_strategy_args *ap;{	register struct buf *bp = ap->a_bp;	struct ucred *cr;	struct proc *p;	int error = 0;	if (bp->b_flags & B_PHYS)		panic("nfs physio");	if (bp->b_flags & B_ASYNC)		p = (struct proc *)0;	else		p = curproc;	/* XXX */	if (bp->b_flags & B_READ)		cr = bp->b_rcred;	else		cr = bp->b_wcred;	/*	 * If the op is asynchronous and an i/o daemon is waiting	 * queue the request, wake it up and wait for completion	 * otherwise just do it ourselves.	 */	if ((bp->b_flags & B_ASYNC) == 0 ||		nfs_asyncio(bp, NOCRED))		error = nfs_doio(bp, cr, p);	return (error);}/* * Mmap a file * * NB Currently unsupported. *//* ARGSUSED */intnfs_mmap(ap)	struct vop_mmap_args /* {		struct vnode *a_vp;		int  a_fflags;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	return (EINVAL);}/* * Flush all the blocks associated with a vnode. * 	Walk through the buffer pool and push any dirty pages *	associated with the vnode. *//* ARGSUSED */intnfs_fsync(ap)	struct vop_fsync_args /* {		struct vnodeop_desc *a_desc;		struct vnode * a_vp;		struct ucred * a_cred;		int  a_waitfor;		struct proc * a_p;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	register struct nfsnode *np = VTONFS(vp);	register struct buf *bp;	struct buf *nbp;	struct nfsmount *nmp;	int s, error = 0, slptimeo = 0, slpflag = 0;	nmp = VFSTONFS(vp->v_mount);	if (nmp->nm_flag & NFSMNT_INT)		slpflag = PCATCH;loop:	s = splbio();	for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {		nbp = bp->b_vnbufs.le_next;		if (bp->b_flags & B_BUSY) {			if (ap->a_waitfor != MNT_WAIT)				continue;			bp->b_flags |= B_WANTED;			error = tsleep((caddr_t)bp, slpflag | (PRIBIO + 1),				"nfsfsync", slptimeo);			splx(s);			if (error) {			    if (nfs_sigintr(nmp, (struct nfsreq *)0, ap->a_p))				return (EINTR);			    if (slpflag == PCATCH) {				slpflag = 0;				slptimeo = 2 * hz;			    }			}			goto loop;		}		if ((bp->b_flags & B_DELWRI) == 0)			panic("nfs_fsync: not dirty");		bremfree(bp);		bp->b_flags |= B_BUSY;		splx(s);		bp->b_flags |= B_ASYNC;		VOP_BWRITE(bp);		goto loop;	}	splx(s);	if (ap->a_waitfor == MNT_WAIT) {		while (vp->v_numoutput) {			vp->v_flag |= VBWAIT;			error = tsleep((caddr_t)&vp->v_numoutput,				slpflag | (PRIBIO + 1), "nfsfsync", slptimeo);			if (error) {			    if (nfs_sigintr(nmp, (struct nfsreq *)0, ap->a_p))				return (EINTR);			    if (slpflag == PCATCH) {				slpflag = 0;				slptimeo = 2 * hz;			    }			}		}		if (vp->v_dirtyblkhd.lh_first) {#ifdef DIAGNOSTIC			vprint("nfs_fsync: dirty", vp);#endif			goto loop;		}	}	if (np->n_flag & NWRITEERR) {		error = np->n_error;		np->n_flag &= ~NWRITEERR;	}	return (error);}/* * Return POSIX pathconf information applicable to nfs. * * Currently the NFS protocol does not support getting such * information from the remote server. *//* ARGSUSED */nfs_pathconf(ap)	struct vop_pathconf_args /* {		struct vnode *a_vp;		int a_name;		int *a_retval;	} */ *ap;{	return (EINVAL);}/* * NFS advisory byte-level locks. * Currently unsupported. */intnfs_advlock(ap)	struct vop_advlock_args /* {		struct vnode *a_vp;		caddr_t  a_id;		int  a_op;		struct flock *a_fl;		int  a_flags;	} */ *ap;{	return (EOPNOTSUPP);}/* * Print out the contents of an nfsnode. */intnfs_print(ap)	struct vop_print_args /* {		struct vnode *a_vp;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	register struct nfsnode *np = VTONFS(vp);	printf("tag VT_NFS, fileid %d fsid 0x%x",		np->n_vattr.va_fileid, np->n_vattr.va_fsid);#ifdef FIFO	if (vp->v_type == VFIFO)		fifo_printinfo(vp);#endif /* FIFO */	printf("\n");}/* * NFS directory offset lookup. * Currently unsupported. */intnfs_blkatoff(ap)	struct vop_blkatoff_args /* {		struct vnode *a_vp;		off_t a_offset;		char **a_res;		struct buf **a_bpp;	} */ *ap;{	return (EOPNOTSUPP);}/* * NFS flat namespace allocation. * Currently unsupported. */intnfs_valloc(ap)	struct vop_valloc_args /* {		struct vnode *a_pvp;		int a_mode;		struct ucred *a_cred;		struct vnode **a_vpp;	} */ *ap;{	return (EOPNOTSUPP);}/* * NFS flat namespace free. * Currently unsupported. */intnfs_vfree(ap)	struct vop_vfree_args /* {		struct vnode *a_pvp;		ino_t a_ino;		int a_mode;	} */ *ap;{	return (EOPNOTSUPP);}/* * NFS file truncation. */intnfs_truncate(ap)	struct vop_truncate_args /* {		struct vnode *a_vp;		off_t a_length;		int a_flags;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	/* Use nfs_setattr */	printf("nfs_truncate: need to implement!!");	return (EOPNOTSUPP);}/* * NFS update. */intnfs_update(ap)	struct vop_update_args /* {		struct vnode *a_vp;		struct timeval *a_ta;		struct timeval *a_tm;		int a_waitfor;	} */ *ap;{	/* Use nfs_setattr */	printf("nfs_update: need to implement!!");	return (EOPNOTSUPP);}/* * nfs special file access vnode op. * Essentially just get vattr and then imitate iaccess() since the device is * local to the client. */intnfsspec_access(ap)	struct vop_access_args /* {		struct vnode *a_vp;		int  a_mode;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	register struct vattr *vap;	register gid_t *gp;	register struct ucred *cred = ap->a_cred;	mode_t mode = ap->a_mode;	struct vattr vattr;	register int i;	int error;	/*	 * If you're the super-user,	 * you always get access.	 */	if (cred->cr_uid == 0)		return (0);	vap = &vattr;	if (error = VOP_GETATTR(ap->a_vp, vap, cred, ap->a_p))		return (error);	/*	 * 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 != vap->va_uid) {		mode >>= 3;		gp = cred->cr_groups;		for (i = 0; i < cred->cr_ngroups; i++, gp++)			if (vap->va_gid == *gp)				goto found;		mode >>= 3;found:		;	}	return ((vap->va_mode & mode) == mode ? 0 : EACCES);}/* * Read wrapper for special devices. */intnfsspec_read(ap)	struct vop_read_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap;{	register struct nfsnode *np = VTONFS(ap->a_vp);	/*	 * Set access flag.	 */	np->n_flag |= NACC;	np->n_atim = time;	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap));}/* * Write wrapper for special devices. */intnfsspec_write(ap)	struct vop_write_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap;{	register struct nfsnode *np = VTONFS(ap->a_vp);	/*	 * Set update flag.	 */	np->n_flag |= NUPD;	np->n_mtim = time;	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap));}/* * Close wrapper for special devices. * * Update the times on the nfsnode then do device close. */intnfsspec_close(ap)	struct vop_close_args /* {		struct vnode *a_vp;		int  a_fflag;		struct ucred *a_cred;		struct proc *a_p;	} */ *ap;{	register struct vnode *vp = ap->a_vp;	register struct nfsnode *np = VTONFS(vp);	struct vattr vattr;	if (np->n_flag & (NACC | NUPD)) {		np->n_flag |= NCHG;		if (vp->v_usecount == 1 &&		    (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {			VATTR_NULL(&vattr);			if (np->n_flag & NACC) {				vattr.va_atime.ts_sec = np->n_atim.tv_sec;				vattr.va_atime.ts_nsec =				    np->n_atim.tv_usec * 1000;			}			if (np->n_flag & NUPD) {				vattr.va_mtime.ts_sec = np->n_mtim.tv_sec;				vattr.va_mtime.ts_nsec =				    np->n_mtim.tv_usec * 1000;			}			(void)VOP_SETATTR(vp, &vattr, ap->a_cred, ap->a_p);		}	}	return (VOCALL(spec_vnodeop_p, VOFFSET(vop_close), ap));}#ifdef FIFO/* * Read wrapper for fifos. */intnfsfifo_read(ap)	struct vop_read_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap;{	extern int (**fifo_vnodeop_p)();	register struct nfsnode *np = VTONFS(ap->a_vp);	/*	 * Set access flag.	 */	np->n_flag |= NACC;	np->n_atim = time;	return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap));}/* * Write wrapper for fifos. */intnfsfifo_write(ap)	struct vop_write_args /* {		struct vnode *a_vp;		struct uio *a_uio;		int  a_ioflag;		struct ucred *a_cred;	} */ *ap;{	extern int (**fifo_vnodeop_p)();	register struct nfsnode *np = VTONFS(ap->a_vp);	/*	 * Set update flag.	 */	np->n_flag |= NUPD;	np->n_mtim = time;	return (VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap));}/* * Close wrapper for fifos. * * Update the times on the nfsnode then do fifo close. */intnfsfifo_close(ap)	struct vop_close_args /* {		struct vnode *a_vp;		int  a_fflag;

⌨️ 快捷键说明

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