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

📄 tfs_lookup.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (stat(NSE_TFS_FORWARD_FILE, &statb) == -1) {		return FALSE;	}	if (nse_get_searchlink(".", newpath)) {		return FALSE;	}	newp = expand_slink_to_pnode(newpath, vp->v_environ_id,				     FIRST_SUBL(vp));	if (newp == NULL) {		return FALSE;	}	pp = *parentp;	ptopn(pp, oldpath);	if (newp->p_sub_layer != pp->p_sub_layer) {		nse_log_message("warning: can't forward %s to %s\n",			oldpath, newpath);		free_pnode(newp);		return FALSE;	}	front_pp = get_pnode_at_layer(vp, SUBL_TO_LAYER(vp, newp));	newp->p_refcnt--;	if (change_backlist_name(front_pp, oldpath, newpath) != 0 ||	    update_directory(pp, "", DIR_FORWARD, newp) != 0) {		return FALSE;	}	*parentp = newp;	return TRUE;}/* * Create pnode for a regular file/directory. */struct pnode *create_pnode(parentp, name, type)	struct pnode	*parentp;	char		*name;	unsigned	type;{	struct pnode	*pp;	pp = get_pnode(parentp, name);	pp->p_type = type;	pp->p_refcnt++;	return (pp);}/* * Create pnode for a root vnode. */voidcreate_root_pnode(vp, pn)	struct vnode	*vp;	char		*pn;{	vp->v_pnode = path_to_pnode(pn, MAX_SUB_LAYER - vp->v_writeable);	vp->v_pnode->p_type = PTYPE_DIR;}/* * Expand the variant searchlink in 'path'.  Returns the pnode of the * searchlink, if it evaluates to a valid directory. */static struct pnode *expand_slink_to_pnode(path, environ_id, first_sub_layer)	char		*path;	unsigned	environ_id;	unsigned	first_sub_layer;{	struct pnode	*pp;	char		*cp;	char		*varname;	char		fullname[MAXPATHLEN];	cp = nse_find_substring(path, NSE_TFS_WILDCARD);	if (cp == NULL || !expand_searchlink(path, environ_id, cp, fullname,					     TRUE)) {		varname = environ_var_name(environ_id);		if (varname && nse_find_substring(path, varname)) {			return lookup_dir_pnode(path, first_sub_layer);		} else {			return lookup_dir_pnode(path, MAX_SUB_LAYER);		}	}	pp = lookup_dir_pnode(fullname, first_sub_layer);	if (pp != NULL) {		return pp;	}	if (!expand_searchlink(path, environ_id, cp, fullname, FALSE)) {		strcpy(fullname, path);	}	return lookup_dir_pnode(fullname, MAX_SUB_LAYER);}static struct pnode *lookup_dir_pnode(path, sub_layer)	char		*path;	unsigned	sub_layer;{	struct pnode	*pp;	char		name[MAXPATHLEN];	struct stat	statb;	pp = path_to_pnode(path, sub_layer);	ptoname_or_pn(pp, name);	if ((stat(name, &statb) == 0) && NSE_ISDIR(&statb)) {		pp->p_mtime = statb.st_mtime;		set_expire_time(pp);		return (pp);	} else {		free_pnode(pp);		return (NULL);	}}struct pnode *path_to_pnode(pn, sub_layer)	char		*pn;	unsigned	sub_layer;{	struct pnode	*pp;	char		compname[NFS_MAXNAMLEN + 1];	pp = root_pnode;	pn++;	while (pn[0] != '\0') {		pn = _nse_extract_name(pn, compname);		pp = get_pnode(pp, compname);		pp->p_sub_layer = sub_layer;	}	pp->p_refcnt++;	return (pp);}static struct pnode *get_pnode(parentp, name)	struct pnode	*parentp;	char		*name;{	struct tnode	*tp;	tp = ntree_find_child((struct tnode *) parentp, name);	if (tp != NULL) {		return ((struct pnode *) tp);	} else {		return (alloc_pnode(parentp, name));	}}/* * Hash table which maps fhandles into vnodes.  This is needed so that an * fhandle can be quickly resolved into a vnode when an RPC call comes into * the server.  Note that whiteout vnodes are also kept in this hash table, * because after a flush a whiteout vnode may become a regular vnode. * NOTE: HASH_TABLE_SIZE must be a power of 2 for FH_TABLE_HASH() to work! */#define		FHTABLE_HASH(fh)	(fh & (HASH_TABLE_SIZE - 1))static struct vnode *fhtable[HASH_TABLE_SIZE];/* * Routines which operate on fhandle hash table. *//* * Translates the fhandle 'fh' into a vnode with a pnode attached.  If * we don't initially find the vnode in the fhandle hash table, it may * be because the parent vnode has had its contents swapped out of memory. * If this is the case, swap in the parent directory and try the fhandle * lookup again. */struct vnode *fhtovp(fh)	struct tfsfh	*fh;{	struct vnode	*pvp;	struct vnode	*vp;	extern time_t	tfsd_timestamp;	if (fh->fh_timestamp != tfsd_timestamp) {		return (NULL);	}	vp = fhandle_find(fh->fh_id);	if (vp != NULL) {		return (vp);	}	pvp = fhandle_find(fh->fh_parent_id);	if (pvp == NULL || !pvp->v_pnode->p_swapped) {		goto error;	}	swap_in_directory(pvp->v_pnode);	vp = fhandle_find(fh->fh_id);	if (vp != NULL) {		return (vp);	}error:#ifdef TFSDEBUG	dprint(tfsdebug, 3, "fhtovp: can't find file for fhandle [%d %d]\n",		fh->fh_parent_id, fh->fh_id);#endif TFSDEBUG	return (NULL);}/* * Maps the fhandle 'nodeid' into the corresponding vnode, and returns NULL if * there is no vnode for the fhandle.  Performs a search in the fhandle * hash table. */struct vnode *fhandle_find(nodeid)	unsigned long	nodeid;{	struct vnode	*vp;	vp = fhtable[FHTABLE_HASH(nodeid)];	while (vp != NULL) {		if (nodeid == vp->v_fhid) {			if (vp->v_layer == INVALID_LAYER) {				vnode_tree_release(vp);				return (NULL);			}			if (!vp->v_whited_out && recurse_lookup_pnode(vp)) {				return (vp);			} else {				return (NULL);			}		}		vp = vp->v_fnext;	}	return (NULL);}/* * Put a vnode in the fhandle hash table */voidfhandle_insert(vp)	struct vnode	*vp;{	long		index;	index = FHTABLE_HASH(vp->v_fhid);	vp->v_fnext = fhtable[index];	fhtable[index] = vp;}/* * Remove a vnode from the fhandle hash table */voidfhandle_remove(vp)	struct vnode	*vp;{	struct vnode	*vt;	struct vnode	*vtprev = NULL;	long		index;	index = FHTABLE_HASH(vp->v_fhid);	vt = fhtable[index];	while (vt != NULL) {		if (vt == vp) {			if (vtprev == NULL) {				fhtable[index] = vt->v_fnext;			} else {				vtprev->v_fnext = vt->v_fnext;			}			return;		}		vtprev = vt;		vt = vt->v_fnext;	}}/* * Hash table of vnode component names.  This is needed so that we can * quickly determine if a child vnode with a specified name exists under a * given parent vnode. */static struct tnode *comptable[HASH_TABLE_SIZE];/* * Routines which operate on pathname component hash table. */#ifdef TFSDEBUGcomp_print(){	struct tnode   *tp;	int		i;	int		full_buckets = 0;	int		vnode_count = 0;	for (i = 0 ; i < HASH_TABLE_SIZE ; i++) {		tp = comptable[i];		if (tp) {			full_buckets++;			vnode_count++;			while (tp->t_cnext != NULL) {				vnode_count++;				tp = tp->t_cnext;			}		}	}	dprint(0, 0,		"comptable: %d buckets total, %d vnodes, %d buckets full\n",		HASH_TABLE_SIZE, vnode_count, full_buckets);}#endif TFSDEBUG/* * Try to find vnode for file 'name' with pvp vnode 'pvp'. * Performs a search in the pathname component hash table. */struct vnode   *find_vnode(pvp, name)	struct vnode   *pvp;	char           *name;{	struct tnode   *tp;	tp = comp_find((struct tnode *) pvp, name);	if (tp == NULL) {		return (NULL);	} else {		return ((struct vnode *) tp);	}}static struct tnode *comp_find(ptp, name)	struct tnode   *ptp;	char		*name;{	struct tnode   *tp;	tp = comptable[hash_string(name)];	while (tp != NULL) {		if ((ptp == tp->t_parent) && (NSE_STREQ(name, tp->t_name))) {			return (tp);		}		tp = tp->t_cnext;	}	return (NULL);}/* * Put a tnode in the pathname component hash table */voidcomp_insert(tp)	struct tnode   *tp;{	long            index;	index = hash_string(tp->t_name);	tp->t_cnext = comptable[index];	comptable[index] = tp;}/* * Remove a tnode from the pathname component hash table */voidcomp_remove(tp)	struct tnode   *tp;{	struct tnode   *tt;	struct tnode   *ttprev = NULL;	long            index;	index = hash_string(tp->t_name);	tt = comptable[index];	while (tt != NULL) {		if (tt == tp) {			if (ttprev == NULL) {				comptable[index] = tt->t_cnext;			} else {				ttprev->t_cnext = tt->t_cnext;			}			return;		}		ttprev = tt;		tt = tt->t_cnext;	}}

⌨️ 快捷键说明

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