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

📄 nfs_vfsops.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* sockargs() call must be after above copyin() calls */	if (error = sockargs(&nam, (caddr_t)args.addr,		args.addrlen, MT_SONAME))		return (error);	args.fh = &nfh;	error = mountnfs(&args, mp, nam, pth, hst, &vp);	return (error);}/* * Common code for mount and mountroot */intmountnfs(argp, mp, nam, pth, hst, vpp)	register struct nfs_args *argp;	register struct mount *mp;	struct mbuf *nam;	char *pth, *hst;	struct vnode **vpp;{	register struct nfsmount *nmp;	struct nfsnode *np;	int error;	if (mp->mnt_flag & MNT_UPDATE) {		nmp = VFSTONFS(mp);		/* update paths, file handles, etc, here	XXX */		m_freem(nam);		return (0);	} else {		MALLOC(nmp, struct nfsmount *, sizeof (struct nfsmount),		    M_NFSMNT, M_WAITOK);		bzero((caddr_t)nmp, sizeof (struct nfsmount));		mp->mnt_data = (qaddr_t)nmp;	}	getnewfsid(mp, MOUNT_NFS);	nmp->nm_mountp = mp;	nmp->nm_flag = argp->flags;	if ((nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_MYWRITE)) ==		(NFSMNT_NQNFS | NFSMNT_MYWRITE)) {		error = EPERM;		goto bad;	}	if (nmp->nm_flag & NFSMNT_NQNFS)		/*		 * We have to set mnt_maxsymlink to a non-zero value so		 * that COMPAT_43 routines will know that we are setting		 * the d_type field in directories (and can zero it for		 * unsuspecting binaries).		 */		mp->mnt_maxsymlinklen = 1;	nmp->nm_timeo = NFS_TIMEO;	nmp->nm_retry = NFS_RETRANS;	nmp->nm_wsize = NFS_WSIZE;	nmp->nm_rsize = NFS_RSIZE;	nmp->nm_numgrps = NFS_MAXGRPS;	nmp->nm_readahead = NFS_DEFRAHEAD;	nmp->nm_leaseterm = NQ_DEFLEASE;	nmp->nm_deadthresh = NQ_DEADTHRESH;	nmp->nm_tnext = (struct nfsnode *)nmp;	nmp->nm_tprev = (struct nfsnode *)nmp;	nmp->nm_inprog = NULLVP;	bcopy((caddr_t)argp->fh, (caddr_t)&nmp->nm_fh, sizeof(nfsv2fh_t));	mp->mnt_stat.f_type = MOUNT_NFS;	bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);	bcopy(pth, mp->mnt_stat.f_mntonname, MNAMELEN);	nmp->nm_nam = nam;	if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {		nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;		if (nmp->nm_timeo < NFS_MINTIMEO)			nmp->nm_timeo = NFS_MINTIMEO;		else if (nmp->nm_timeo > NFS_MAXTIMEO)			nmp->nm_timeo = NFS_MAXTIMEO;	}	if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {		nmp->nm_retry = argp->retrans;		if (nmp->nm_retry > NFS_MAXREXMIT)			nmp->nm_retry = NFS_MAXREXMIT;	}	if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {		nmp->nm_wsize = argp->wsize;		/* Round down to multiple of blocksize */		nmp->nm_wsize &= ~0x1ff;		if (nmp->nm_wsize <= 0)			nmp->nm_wsize = 512;		else if (nmp->nm_wsize > NFS_MAXDATA)			nmp->nm_wsize = NFS_MAXDATA;	}	if (nmp->nm_wsize > MAXBSIZE)		nmp->nm_wsize = MAXBSIZE;	if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {		nmp->nm_rsize = argp->rsize;		/* Round down to multiple of blocksize */		nmp->nm_rsize &= ~0x1ff;		if (nmp->nm_rsize <= 0)			nmp->nm_rsize = 512;		else if (nmp->nm_rsize > NFS_MAXDATA)			nmp->nm_rsize = NFS_MAXDATA;	}	if (nmp->nm_rsize > MAXBSIZE)		nmp->nm_rsize = MAXBSIZE;	if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0 &&		argp->maxgrouplist <= NFS_MAXGRPS)		nmp->nm_numgrps = argp->maxgrouplist;	if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0 &&		argp->readahead <= NFS_MAXRAHEAD)		nmp->nm_readahead = argp->readahead;	if ((argp->flags & NFSMNT_LEASETERM) && argp->leaseterm >= 2 &&		argp->leaseterm <= NQ_MAXLEASE)		nmp->nm_leaseterm = argp->leaseterm;	if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 1 &&		argp->deadthresh <= NQ_NEVERDEAD)		nmp->nm_deadthresh = argp->deadthresh;	/* Set up the sockets and per-host congestion */	nmp->nm_sotype = argp->sotype;	nmp->nm_soproto = argp->proto;	/*	 * For Connection based sockets (TCP,...) defer the connect until	 * the first request, in case the server is not responding.	 */	if (nmp->nm_sotype == SOCK_DGRAM &&		(error = nfs_connect(nmp, (struct nfsreq *)0)))		goto bad;	/*	 * This is silly, but it has to be set so that vinifod() works.	 * We do not want to do an nfs_statfs() here since we can get	 * stuck on a dead server and we are holding a lock on the mount	 * point.	 */	mp->mnt_stat.f_iosize = NFS_MAXDGRAMDATA;	/*	 * A reference count is needed on the nfsnode representing the	 * remote root.  If this object is not persistent, then backward	 * traversals of the mount point (i.e. "..") will not work if	 * the nfsnode gets flushed out of the cache. Ufs does not have	 * this problem, because one can identify root inodes by their	 * number == ROOTINO (2).	 */	if (error = nfs_nget(mp, &nmp->nm_fh, &np))		goto bad;	*vpp = NFSTOV(np);	return (0);bad:	nfs_disconnect(nmp);	free((caddr_t)nmp, M_NFSMNT);	m_freem(nam);	return (error);}/* * unmount system call */intnfs_unmount(mp, mntflags, p)	struct mount *mp;	int mntflags;	struct proc *p;{	register struct nfsmount *nmp;	struct nfsnode *np;	struct vnode *vp;	int error, flags = 0;	extern int doforce;	if (mntflags & MNT_FORCE) {		if (!doforce || (mp->mnt_flag & MNT_ROOTFS))			return (EINVAL);		flags |= FORCECLOSE;	}	nmp = VFSTONFS(mp);	/*	 * Goes something like this..	 * - Check for activity on the root vnode (other than ourselves).	 * - Call vflush() to clear out vnodes for this file system,	 *   except for the root vnode.	 * - Decrement reference on the vnode representing remote root.	 * - Close the socket	 * - Free up the data structures	 */	/*	 * We need to decrement the ref. count on the nfsnode representing	 * the remote root.  See comment in mountnfs().  The VFS unmount()	 * has done vput on this vnode, otherwise we would get deadlock!	 */	if (error = nfs_nget(mp, &nmp->nm_fh, &np))		return(error);	vp = NFSTOV(np);	if (vp->v_usecount > 2) {		vput(vp);		return (EBUSY);	}	/*	 * Must handshake with nqnfs_clientd() if it is active.	 */	nmp->nm_flag |= NFSMNT_DISMINPROG;	while (nmp->nm_inprog != NULLVP)		(void) tsleep((caddr_t)&lbolt, PSOCK, "nfsdism", 0);	if (error = vflush(mp, vp, flags)) {		vput(vp);		nmp->nm_flag &= ~NFSMNT_DISMINPROG;		return (error);	}	/*	 * We are now committed to the unmount.	 * For NQNFS, let the server daemon free the nfsmount structure.	 */	if (nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_KERB))		nmp->nm_flag |= NFSMNT_DISMNT;	/*	 * There are two reference counts to get rid of here.	 */	vrele(vp);	vrele(vp);	vgone(vp);	nfs_disconnect(nmp);	m_freem(nmp->nm_nam);	if ((nmp->nm_flag & (NFSMNT_NQNFS | NFSMNT_KERB)) == 0)		free((caddr_t)nmp, M_NFSMNT);	return (0);}/* * Return root of a filesystem */intnfs_root(mp, vpp)	struct mount *mp;	struct vnode **vpp;{	register struct vnode *vp;	struct nfsmount *nmp;	struct nfsnode *np;	int error;	nmp = VFSTONFS(mp);	if (error = nfs_nget(mp, &nmp->nm_fh, &np))		return (error);	vp = NFSTOV(np);	vp->v_type = VDIR;	vp->v_flag = VROOT;	*vpp = vp;	return (0);}extern int syncprt;/* * Flush out the buffer cache *//* ARGSUSED */intnfs_sync(mp, waitfor, cred, p)	struct mount *mp;	int waitfor;	struct ucred *cred;	struct proc *p;{	register struct vnode *vp;	int error, allerror = 0;	/*	 * Force stale buffer cache information to be flushed.	 */loop:	for (vp = mp->mnt_vnodelist.lh_first;	     vp != NULL;	     vp = vp->v_mntvnodes.le_next) {		/*		 * If the vnode that we are about to sync is no longer		 * associated with this mount point, start over.		 */		if (vp->v_mount != mp)			goto loop;		if (VOP_ISLOCKED(vp) || vp->v_dirtyblkhd.lh_first == NULL)			continue;		if (vget(vp, 1))			goto loop;		if (error = VOP_FSYNC(vp, cred, waitfor, p))			allerror = error;		vput(vp);	}	return (allerror);}/* * NFS flat namespace lookup. * Currently unsupported. *//* ARGSUSED */intnfs_vget(mp, ino, vpp)	struct mount *mp;	ino_t ino;	struct vnode **vpp;{	return (EOPNOTSUPP);}/* * At this point, this should never happen *//* ARGSUSED */intnfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)	register struct mount *mp;	struct fid *fhp;	struct mbuf *nam;	struct vnode **vpp;	int *exflagsp;	struct ucred **credanonp;{	return (EINVAL);}/* * Vnode pointer to File handle, should never happen either *//* ARGSUSED */intnfs_vptofh(vp, fhp)	struct vnode *vp;	struct fid *fhp;{	return (EINVAL);}/* * Vfs start routine, a no-op. *//* ARGSUSED */intnfs_start(mp, flags, p)	struct mount *mp;	int flags;	struct proc *p;{	return (0);}/* * Do operations associated with quotas, not supported *//* ARGSUSED */intnfs_quotactl(mp, cmd, uid, arg, p)	struct mount *mp;	int cmd;	uid_t uid;	caddr_t arg;	struct proc *p;{	return (EOPNOTSUPP);}

⌨️ 快捷键说明

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