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

📄 vfs_dnlc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (tvp != (struct vnode *) 0) {		VN_RELE(tvp);	}}/* * Look up a name in the directory name cache. *//* * This routine has been changed to handle locking of  * the directory name lookup cache and to bump the ref count * the vnode found during the lookup before it is returned to the * caller.  This lets us keep all the dnlc smp locking in this file. */struct vnode *dnlc_lookup(dp, name, cred)	struct vnode *dp;	register char *name;	struct ucred *cred;{	register int namlen;	register int hash;	register struct ncache *ncp;	register struct tvp;	struct vnode *tvp;	if (!dnlc_cache) {		return ((struct vnode *) 0);	}	namlen = strlen(name);	if (namlen > NC_NAMLEN) {		/* SMP lock name cache statistics during access */		smp_lock(&lk_nfsdnlc, LK_RETRY);		ncstats.long_look++;		smp_unlock(&lk_nfsdnlc);		return ((struct vnode *) 0);	}	hash = NC_HASH1(name, namlen, dp);	/* SMP lock directory name cache during access	*/	smp_lock(&lk_nfsdnlc, LK_RETRY);	ncp = dnlc_search(dp, name, namlen, hash, cred);	if (ncp == (struct ncache *) 0) {		ncstats.misses++;		smp_unlock(&lk_nfsdnlc);		return ((struct vnode *) 0);	}	ncstats.hits++;	/*	 * Move this slot to the end of LRU	 * chain.	 */	RM_LRU(ncp);	INS_LRU(ncp, nc_lru.lru_prev);	/*	 * If not at the head of the hash chain,	 * move forward so will be found	 * earlier if looked up again.	 */	if (ncp->hash1_prev != (struct ncache *) &nc_hash1[hash]) {		RM_HASH1(ncp);		INS_HASH1(ncp, ncp->hash1_prev->hash1_prev);	}	tvp = ncp->vp;	VN_HOLD(tvp);	smp_unlock(&lk_nfsdnlc);	return (tvp);}/* * Remove an entry in the directory name cache. */dnlc_remove(dp, name)	struct vnode *dp;	register char *name;{	register int namlen;	register struct ncache *ncp;	int hash;	namlen = strlen(name);	if (namlen > NC_NAMLEN) {		return;	}	hash = NC_HASH1(name, namlen, dp);	/* SMP lock access to directory name lookup cache */	smp_lock(&lk_nfsdnlc, LK_RETRY);	while (ncp = dnlc_search(dp, name, namlen, hash, ANYCRED)) {		dnlc_rm(ncp);	}	smp_unlock(&lk_nfsdnlc);}/* * Purge the entire cache. */dnlc_purge(){	register struct nc_hash *nch;	register struct ncache *ncp;	/* SMP lock access to directory name lookup cache */	smp_lock(&lk_nfsdnlc, LK_RETRY);	ncstats.purges++;start:	for (nch = nc_hash1; nch < &nc_hash1[nchashsize]; nch++) {		ncp = nch->hash1_next;		while (ncp != (struct ncache *) nch) {			if (ncp->dp == 0 || ncp->vp == 0) {				panic("dnlc_purge: zero vp");			}			dnlc_rm(ncp);			goto start;		}	}	smp_unlock(&lk_nfsdnlc);}/* * Purge any cache entries referencing a vnode. */dnlc_purge_vp(vp)	register struct vnode *vp;{	register int moretodo, hash;	register struct nc_hash *nhp;	register struct ncache *ncp;	register int hitcnt = 0;	/* SMP lock access to directory name lookup cache */	smp_lock(&lk_nfsdnlc, LK_RETRY);	ncstats.purgevp++;	do {		moretodo = 0;		hash = NC_HASH2(vp);		(struct nc_hash *) ncp = nhp = &nc_hash2[hash];		while ((ncp = ncp->hash2_next) != (struct ncache *) nhp) {			if (ncp->dp == vp) {				dnlc_rm(ncp);				moretodo = 1;				hitcnt++;				break;			}		}		hash = NC_HASH3(vp);		(struct nc_hash *) ncp = nhp = &nc_hash3[hash];		while ((ncp = ncp->hash3_next) != (struct ncache *) nhp) {			if (ncp->vp == vp) {				dnlc_rm(ncp);				moretodo = 1;				hitcnt++;				break;			}		}	} while (moretodo);	if (hitcnt)		ncstats.purgevpworked++;	smp_unlock(&lk_nfsdnlc);}/* * Purge any cache entry. * Called by iget when inode freelist is empty. */dnlc_purge1(){	register struct ncache *ncp;	smp_lock(&lk_nfsdnlc, LK_RETRY);	for (ncp = nc_lru.lru_next; ncp != (struct ncache *) &nc_lru;	     ncp = ncp->lru_next) {		if (ncp->dp &&		    (((struct gnode *)ncp->vp)->g_count == 1 ||		    (ncp->vp && ((struct gnode *)ncp->dp)->g_count == 1))) {			dnlc_rm(ncp);			ncstats.purge1yes++;			smp_unlock(&lk_nfsdnlc);			return (1);		}	}	ncstats.purge1no++;	smp_unlock(&lk_nfsdnlc);	return (0);}/* * Obliterate a cache entry. *//* * Now assumes lk_nfsdnlc is held.  This is unlocked long enough * to grele the gnodes associated with the cache entry. */staticdnlc_rm(ncp)	register struct ncache *ncp;{	register struct vnode *tdp;	register struct vnode *tvp;	/*	 * Remove from LRU, hash chains.	 */	RM_LRU(ncp);	if (NOT_NULL1(ncp)) {		ncstats.hashedentries--;		RM_HASH1(ncp);		RM_HASH2(ncp);		RM_HASH3(ncp);	}	/*	 * Release ref on vnodes.	 *//*	VN_RELE(ncp->dp); */	tdp = ncp->dp;	ncp->dp = (struct vnode *) 0;/*	VN_RELE(ncp->vp); */	tvp = ncp->vp;	ncp->vp = (struct vnode *) 0;	if (ncp->cred != NOCRED) {		crfree(ncp->cred);		ncp->cred = NOCRED;	}	/*	 * Insert at head of LRU list (first to grab).	 */	INS_LRU(ncp, &nc_lru);	/*	 * And make a dummy hash chain.	 */	NULL_HASH1(ncp);	NULL_HASH2(ncp);	NULL_HASH3(ncp);	smp_unlock(&lk_nfsdnlc);	VN_RELE(tdp);	VN_RELE(tvp);	smp_lock(&lk_nfsdnlc, LK_RETRY);}/* * Utility routine to search for a cache entry. */static struct ncache *dnlc_search(dp, name, namlen, hash, cred)	register struct vnode *dp;	register char *name;	register int namlen;	int hash;	struct ucred *cred;{	register struct nc_hash *nhp;	register struct ncache *ncp;	nhp = &nc_hash1[hash];	for (ncp = nhp->hash1_next; ncp != (struct ncache *) nhp;	    ncp = ncp->hash1_next) {		if (ncp->dp == dp && ncp->namlen == namlen &&		    *ncp->name == *name &&	/* fast chk 1st chr */		    bcmp(ncp->name, name, namlen) == 0 &&		    (cred == ANYCRED || ncp->cred == cred ||		     (cred->cr_uid == ncp->cred->cr_uid &&		      cred->cr_gid == ncp->cred->cr_gid &&		      bcmp((caddr_t)cred->cr_groups, 			   (caddr_t)ncp->cred->cr_groups,			   NGROUPS * sizeof(cred->cr_groups[0])) == 0))) {			return (ncp);		}	}	return ((struct ncache *) 0);}/* * Insert into queue, where the queue pointers are * not in the first two longwords. * Should be in assembler like insque. */staticinsque2(ncp2, ncp1)	register struct ncache *ncp2, *ncp1;{	register struct ncache *ncp3;	ncp3 = ncp1->hash2_next;	ncp1->hash2_next = ncp2;	ncp2->hash2_next = ncp3;	ncp3->hash2_prev = ncp2;	ncp2->hash2_prev = ncp1;}staticinsque3(ncp2, ncp1)	register struct ncache *ncp2, *ncp1;{	register struct ncache *ncp3;	ncp3 = ncp1->hash3_next;	ncp1->hash3_next = ncp2;	ncp2->hash3_next = ncp3;	ncp3->hash3_prev = ncp2;	ncp2->hash3_prev = ncp1;}staticinsque4(ncp2, ncp1)	register struct ncache *ncp2, *ncp1;{	register struct ncache *ncp3;	ncp3 = ncp1->lru_next;	ncp1->lru_next = ncp2;	ncp2->lru_next = ncp3;	ncp3->lru_prev = ncp2;	ncp2->lru_prev = ncp1;}/* * Remove from queue, like insque2, insque3, insque4. */staticremque2(ncp)	register struct ncache *ncp;{	ncp->hash2_prev->hash2_next = ncp->hash2_next;	ncp->hash2_next->hash2_prev = ncp->hash2_prev;}staticremque3(ncp)	register struct ncache *ncp;{	ncp->hash3_prev->hash3_next = ncp->hash3_next;	ncp->hash3_next->hash3_prev = ncp->hash3_prev;}staticremque4(ncp)	register struct ncache *ncp;{	ncp->lru_prev->lru_next = ncp->lru_next;	ncp->lru_next->lru_prev = ncp->lru_prev;}

⌨️ 快捷键说明

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