📄 tfs_lookup.c
字号:
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 + -