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

📄 nfs_nqlease.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	u_quad_t frev;		nfsstats.rpccnt[NQNFSPROC_GETLEASE]++;	mb = mreq = nfsm_reqh(vp, NQNFSPROC_GETLEASE, NFSX_FH+2*NFSX_UNSIGNED,		 &bpos);	nfsm_fhtom(vp);	nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED);	*tl++ = txdr_unsigned(rwflag);	*tl = txdr_unsigned(nmp->nm_leaseterm);	reqtime = time.tv_sec;	nfsm_request(vp, NQNFSPROC_GETLEASE, p, cred);	np = VTONFS(vp);	nfsm_dissect(tl, u_long *, 4*NFSX_UNSIGNED);	cachable = fxdr_unsigned(int, *tl++);	reqtime += fxdr_unsigned(int, *tl++);	if (reqtime > time.tv_sec) {		fxdr_hyper(tl, &frev);		nqnfs_clientlease(nmp, np, rwflag, cachable, reqtime, frev);		nfsm_loadattr(vp, (struct vattr *)0);	} else		error = NQNFS_EXPIRED;	nfsm_reqdone;	return (error);}/* * Client vacated message function. */nqnfs_vacated(vp, cred)	register struct vnode *vp;	struct ucred *cred;{	register caddr_t cp;	register struct mbuf *m;	register int i;	caddr_t bpos;	u_long xid;	int error = 0;	struct mbuf *mreq, *mb, *mb2, *mheadend;	struct nfsmount *nmp;	struct nfsreq myrep;		nmp = VFSTONFS(vp->v_mount);	nfsstats.rpccnt[NQNFSPROC_VACATED]++;	nfsm_reqhead(vp, NQNFSPROC_VACATED, NFSX_FH);	nfsm_fhtom(vp);	m = mreq;	i = 0;	while (m) {		i += m->m_len;		m = m->m_next;	}	m = nfsm_rpchead(cred, TRUE, NQNFSPROC_VACATED,		RPCAUTH_UNIX, 5*NFSX_UNSIGNED, (char *)0,		mreq, i, &mheadend, &xid);	if (nmp->nm_sotype == SOCK_STREAM) {		M_PREPEND(m, NFSX_UNSIGNED, M_WAIT);		*mtod(m, u_long *) = htonl(0x80000000 | (m->m_pkthdr.len -			NFSX_UNSIGNED));	}	myrep.r_flags = 0;	myrep.r_nmp = nmp;	if (nmp->nm_soflags & PR_CONNREQUIRED)		(void) nfs_sndlock(&nmp->nm_flag, (struct nfsreq *)0);	(void) nfs_send(nmp->nm_so, nmp->nm_nam, m, &myrep);	if (nmp->nm_soflags & PR_CONNREQUIRED)		nfs_sndunlock(&nmp->nm_flag);	return (error);}/* * Called for client side callbacks */nqnfs_callback(nmp, mrep, md, dpos)	struct nfsmount *nmp;	struct mbuf *mrep, *md;	caddr_t dpos;{	register struct vnode *vp;	register u_long *tl;	register long t1;	nfsv2fh_t nfh;	fhandle_t *fhp;	struct nfsnode *np;	struct nfsd nd;	int error;	char *cp2;	nd.nd_mrep = mrep;	nd.nd_md = md;	nd.nd_dpos = dpos;	if (error = nfs_getreq(&nd, FALSE))		return (error);	md = nd.nd_md;	dpos = nd.nd_dpos;	if (nd.nd_procnum != NQNFSPROC_EVICTED) {		m_freem(mrep);		return (EPERM);	}	fhp = &nfh.fh_generic;	nfsm_srvmtofh(fhp);	m_freem(mrep);	if (error = nfs_nget(nmp->nm_mountp, fhp, &np))		return (error);	vp = NFSTOV(np);	if (np->n_tnext) {		np->n_expiry = 0;		np->n_flag |= NQNFSEVICTED;		if (np->n_tprev != (struct nfsnode *)nmp) {			if (np->n_tnext == (struct nfsnode *)nmp)				nmp->nm_tprev = np->n_tprev;			else				np->n_tnext->n_tprev = np->n_tprev;			np->n_tprev->n_tnext = np->n_tnext;			np->n_tnext = nmp->nm_tnext;			nmp->nm_tnext = np;			np->n_tprev = (struct nfsnode *)nmp;			if (np->n_tnext == (struct nfsnode *)nmp)				nmp->nm_tprev = np;			else				np->n_tnext->n_tprev = np;		}	}	vrele(vp);	nfsm_srvdone;}/* * Nqnfs client helper daemon. Runs once a second to expire leases. * It also get authorization strings for "kerb" mounts. * It must start at the beginning of the list again after any potential * "sleep" since nfs_reclaim() called from vclean() can pull a node off * the list asynchronously. */nqnfs_clientd(nmp, cred, ncd, flag, argp, p)	register struct nfsmount *nmp;	struct ucred *cred;	struct nfsd_cargs *ncd;	int flag;	caddr_t argp;	struct proc *p;{	register struct nfsnode *np;	struct vnode *vp;	struct nfsreq myrep;	int error, vpid;	/*	 * First initialize some variables	 */	nqnfs_prog = txdr_unsigned(NQNFS_PROG);	nqnfs_vers = txdr_unsigned(NQNFS_VER1);	/*	 * If an authorization string is being passed in, get it.	 */	if ((flag & NFSSVC_GOTAUTH) &&		(nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_DISMNT)) == 0) {		if (nmp->nm_flag & NFSMNT_HASAUTH)			panic("cld kerb");		if ((flag & NFSSVC_AUTHINFAIL) == 0) {			if (ncd->ncd_authlen <= RPCAUTH_MAXSIZ &&				copyin(ncd->ncd_authstr, nmp->nm_authstr,				ncd->ncd_authlen) == 0) {				nmp->nm_authtype = ncd->ncd_authtype;				nmp->nm_authlen = ncd->ncd_authlen;			} else				nmp->nm_flag |= NFSMNT_AUTHERR;		} else			nmp->nm_flag |= NFSMNT_AUTHERR;		nmp->nm_flag |= NFSMNT_HASAUTH;		wakeup((caddr_t)&nmp->nm_authlen);	} else		nmp->nm_flag |= NFSMNT_WAITAUTH;	/*	 * Loop every second updating queue until there is a termination sig.	 */	while ((nmp->nm_flag & NFSMNT_DISMNT) == 0) {	    if (nmp->nm_flag & NFSMNT_NQNFS) {		/*		 * If there are no outstanding requests (and therefore no		 * processes in nfs_reply) and there is data in the receive		 * queue, poke for callbacks.		 */		if (nfsreqh.r_next == &nfsreqh && nmp->nm_so &&		    nmp->nm_so->so_rcv.sb_cc > 0) {		    myrep.r_flags = R_GETONEREP;		    myrep.r_nmp = nmp;		    myrep.r_mrep = (struct mbuf *)0;		    myrep.r_procp = (struct proc *)0;		    (void) nfs_reply(&myrep);		}		/*		 * Loop through the leases, updating as required.		 */		np = nmp->nm_tnext;		while (np != (struct nfsnode *)nmp &&		       (nmp->nm_flag & NFSMNT_DISMINPROG) == 0) {			vp = NFSTOV(np);if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash2");			vpid = vp->v_id;			if (np->n_expiry < time.tv_sec) {			   if (vget(vp, 1) == 0) {			     nmp->nm_inprog = vp;			     if (vpid == vp->v_id) {if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash3");				if (np->n_tnext == (struct nfsnode *)nmp)					nmp->nm_tprev = np->n_tprev;				else					np->n_tnext->n_tprev = np->n_tprev;				if (np->n_tprev == (struct nfsnode *)nmp)					nmp->nm_tnext = np->n_tnext;				else					np->n_tprev->n_tnext = np->n_tnext;				np->n_tnext = (struct nfsnode *)0;				if ((np->n_flag & (NMODIFIED | NQNFSEVICTED))				    && vp->v_type == VREG) {					if (np->n_flag & NQNFSEVICTED) {						(void) nfs_vinvalbuf(vp,						       V_SAVE, cred, p, 0);						np->n_flag &= ~NQNFSEVICTED;						(void) nqnfs_vacated(vp, cred);					} else {						(void) VOP_FSYNC(vp, cred,						    MNT_WAIT, p);						np->n_flag &= ~NMODIFIED;					}				}			      }			      vrele(vp);			      nmp->nm_inprog = NULLVP;			    }			    if (np != nmp->nm_tnext)				np = nmp->nm_tnext;			    else				break;			} else if ((np->n_expiry - NQ_RENEWAL) < time.tv_sec) {			    if ((np->n_flag & (NQNFSWRITE | NQNFSNONCACHE))				 == NQNFSWRITE && vp->v_dirtyblkhd.lh_first &&				 vget(vp, 1) == 0) {				 nmp->nm_inprog = vp;if (vp->v_mount->mnt_stat.f_fsid.val[1] != MOUNT_NFS) panic("trash4");				 if (vpid == vp->v_id &&				     nqnfs_getlease(vp, NQL_WRITE, cred, p)==0)					np->n_brev = np->n_lrev;				 vrele(vp);				 nmp->nm_inprog = NULLVP;			    }			    if (np != nmp->nm_tnext)				np = nmp->nm_tnext;			    else				break;			} else				break;		}	    }	    /*	     * Get an authorization string, if required.	     */	    if ((nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_DISMNT | NFSMNT_HASAUTH)) == 0) {		ncd->ncd_authuid = nmp->nm_authuid;		if (copyout((caddr_t)ncd, argp, sizeof (struct nfsd_cargs)))			nmp->nm_flag |= NFSMNT_WAITAUTH;		else			return (ENEEDAUTH);	    }	    /*	     * Wait a bit (no pun) and do it again.	     */	    if ((nmp->nm_flag & NFSMNT_DISMNT) == 0 &&		(nmp->nm_flag & (NFSMNT_WAITAUTH | NFSMNT_HASAUTH))) {		    error = tsleep((caddr_t)&nmp->nm_authstr, PSOCK | PCATCH,			"nqnfstimr", hz / 3);		    if (error == EINTR || error == ERESTART)			(void) dounmount(nmp->nm_mountp, 0, p);	    }	}	free((caddr_t)nmp, M_NFSMNT);	if (error == EWOULDBLOCK)		error = 0;	return (error);}/* * Adjust all timer queue expiry times when the time of day clock is changed. * Called from the settimeofday() syscall. */voidlease_updatetime(deltat)	register int deltat;{	register struct nqlease *lp;	register struct nfsnode *np;	struct mount *mp;	struct nfsmount *nmp;	int s;	if (nqnfsstarttime != 0)		nqnfsstarttime += deltat;	s = splsoftclock();	lp = nqthead.th_chain[0];	while (lp != (struct nqlease *)&nqthead) {		lp->lc_expiry += deltat;		lp = lp->lc_chain1[0];	}	splx(s);	/*	 * Search the mount list for all nqnfs mounts and do their timer	 * queues.	 */	for (mp = mountlist.tqh_first; mp != NULL; mp = mp->mnt_list.tqe_next) {		if (mp->mnt_stat.f_fsid.val[1] == MOUNT_NFS) {			nmp = VFSTONFS(mp);			if (nmp->nm_flag & NFSMNT_NQNFS) {				np = nmp->nm_tnext;				while (np != (struct nfsnode *)nmp) {					np->n_expiry += deltat;					np = np->n_tnext;				}			}		}	}}/* * Lock a server lease. */voidnqsrv_locklease(lp)	struct nqlease *lp;{	while (lp->lc_flag & LC_LOCKED) {		lp->lc_flag |= LC_WANTED;		(void) tsleep((caddr_t)lp, PSOCK, "nqlc", 0);	}	lp->lc_flag |= LC_LOCKED;	lp->lc_flag &= ~LC_WANTED;}/* * Unlock a server lease. */voidnqsrv_unlocklease(lp)	struct nqlease *lp;{	lp->lc_flag &= ~LC_LOCKED;	if (lp->lc_flag & LC_WANTED)		wakeup((caddr_t)lp);}/* * Update a client lease. */voidnqnfs_clientlease(nmp, np, rwflag, cachable, expiry, frev)	register struct nfsmount *nmp;	register struct nfsnode *np;	int rwflag, cachable;	time_t expiry;	u_quad_t frev;{	register struct nfsnode *tp;	if (np->n_tnext) {		if (np->n_tnext == (struct nfsnode *)nmp)			nmp->nm_tprev = np->n_tprev;		else			np->n_tnext->n_tprev = np->n_tprev;		if (np->n_tprev == (struct nfsnode *)nmp)			nmp->nm_tnext = np->n_tnext;		else			np->n_tprev->n_tnext = np->n_tnext;		if (rwflag == NQL_WRITE)			np->n_flag |= NQNFSWRITE;	} else if (rwflag == NQL_READ)		np->n_flag &= ~NQNFSWRITE;	else		np->n_flag |= NQNFSWRITE;	if (cachable)		np->n_flag &= ~NQNFSNONCACHE;	else		np->n_flag |= NQNFSNONCACHE;	np->n_expiry = expiry;	np->n_lrev = frev;	tp = nmp->nm_tprev;	while (tp != (struct nfsnode *)nmp && tp->n_expiry > np->n_expiry)		tp = tp->n_tprev;	if (tp == (struct nfsnode *)nmp) {		np->n_tnext = nmp->nm_tnext;		nmp->nm_tnext = np;	} else {		np->n_tnext = tp->n_tnext;		tp->n_tnext = np;	}	np->n_tprev = tp;	if (np->n_tnext == (struct nfsnode *)nmp)		nmp->nm_tprev = np;	else		np->n_tnext->n_tprev = np;}

⌨️ 快捷键说明

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