📄 tfs_swap.c
字号:
vl->nodeids[index] = vp->v_fhid; } else { vl = NSE_NEW(Vnodelist); vl->name = NSE_STRDUP(vp->v_name); vl->nodeids[index] = vp->v_fhid; vl->layer = vp->v_layer; vl->back_layer = vp->v_back_layer; vl->whited_out = vp->v_whited_out; vl->back_whited_out = vp->v_back_whited_out; vl->mtime = vp->v_mtime; (void) nse_list_add_new_data(list, (Nse_opaque) vl); } }}static voidrelease_child_vnodes(pvp) struct vnode *pvp;{ struct vnode *vp; struct vnode *next_vp; for (vp = CHILD_VNODE(pvp); vp != NULL; vp = next_vp) { next_vp = NEXT_VNODE(vp); if (CHILD_VNODE(vp) != NULL || (vp->v_pnode != NULL && vp->v_pnode->p_swapped)) { continue; } free_vnode(vp); }}static voidrestore_child_vnodes(pvp, list, index) struct vnode *pvp; Nse_list list; int index;{ nse_list_iterate(list, restore_vnode, pvp, index);}static voidrestore_vnode(vl, pvp, index) Vnodelist vl; struct vnode *pvp; int index;{ struct vnode *vp; if (vl->nodeids[index] == 0) { return; } vp = create_vnode(pvp, vl->name, vl->nodeids[index]); vp->v_layer = vl->layer; vp->v_back_layer = vl->back_layer; vp->v_whited_out = vl->whited_out; vp->v_back_whited_out = vl->back_whited_out; vp->v_mtime = vl->mtime;}/* * Note that we don't write a version number into .tfs_swap as we do with * other .tfs_ files because .tfs_swap is only read by the same instance * of the TFS. */static Tfs_swapread_swapfile(pp) struct pnode *pp;{ char path[MAXPATHLEN]; FILE *file; Tfs_swap swap = NULL; int pid; long timestamp; int ch; Filelist fl; Vnodelist vl; int count; Nse_err err; ptoname_or_pn(pp, path); nse_pathcat(path, NSE_TFS_SWAP_FILE); file = open_tfs_file(path, "r", (Nse_err *) NULL); if (file == NULL) { return NULL; } err = nse_fscanf(path, &count, file, "%d %ld\n", &pid, ×tamp); if (err || count != 2 || pid != my_pid || timestamp != my_timestamp) { goto error; } swap = swap_rec_create(); err = nse_fscanf(path, &count, file, "%ld %ld\n", &swap->dir_nodeids[0], &swap->dir_nodeids[1]); if (err || count != 2) { goto error; } do { err = nse_fgetc(path, file, &ch); if (err) { goto error; } ungetc(ch, file); if (ch != '/' || ch == EOF) { break; } if (err = read_dirpnode_entry(file, path, &fl)) { goto error; } if (fl) { (void) nse_list_add_new_data(swap->directories, (Nse_opaque) fl); } } while (1); do { if (err = read_vnode_entry(file, path, &vl)) { goto error; } if (vl == NULL) { break; } (void) nse_list_add_new_data(swap->children, (Nse_opaque) vl); } while (1); if (err = nse_fclose(path, file)) { goto error; } (void) unlink(path); return swap;error: if (err) { nse_log_err_print(err); fclose(file); } if (swap) { swap_rec_destroy(swap); } fclose(file); return NULL;}static bool_twrite_swapfile(path, file, swap) char *path; FILE *file; Tfs_swap swap;{ Nse_err err; if ((err = nse_fprintf(path, file, "%d %ld\n", my_pid, my_timestamp)) || (err = nse_fprintf(path, file, "%ld %ld\n", swap->dir_nodeids[0], swap->dir_nodeids[1])) || (err = (Nse_err) nse_list_iterate_or(swap->directories, write_dirpnode_entry, file, path)) || (err = (Nse_err) nse_list_iterate_or(swap->children, write_vnode_entry, file, path))) { fclose(file); } else { err = nse_fclose(path, file); } if (err) { nse_log_err_print(err); (void) unlink(path); } return (err == NULL);}#define DIR_PNODE_FORMAT "%s %d\n"static Nse_errread_dirpnode_entry(file, path, entryp) FILE *file; char *path; Filelist *entryp;{ Filelist fl; char name[MAXPATHLEN]; int sub_layer; int count; Nse_err err; err = nse_fscanf(path, &count, file, DIR_PNODE_FORMAT, name, &sub_layer); if (err || count != 2) { *entryp = NULL; return err; } fl = NSE_NEW(Filelist); fl->fname = NSE_STRDUP(name); fl->layer = sub_layer; *entryp = fl; return NULL;}static Nse_errwrite_dirpnode_entry(fl, file, path) Filelist fl; FILE *file; char *path;{ return nse_fprintf(path, file, DIR_PNODE_FORMAT, fl->fname, fl->layer);}#define VNODE_FORMAT "%s %ld %ld %d %d %d %d %ld\n"#define VNODE_SHORT_FORMAT "%s %ld %ld %d %d\n"static Nse_errread_vnode_entry(file, path, entryp) FILE *file; char *path; Vnodelist *entryp;{ Vnodelist vl; char line[MAXPATHLEN]; char name[MAXPATHLEN]; int nitems; bool_t eof; Nse_err err; err = nse_fgets(path, line, MAXPATHLEN, file, &eof); if (eof) { *entryp = NULL; return err; } vl = NSE_NEW(Vnodelist); nitems = sscanf(line, VNODE_FORMAT, name, &vl->nodeids[0], &vl->nodeids[1], &vl->layer, &vl->whited_out, &vl->back_layer, &vl->back_whited_out, &vl->mtime); if (nitems == 5) { vl->back_layer = INVALID_LAYER; } else if (nitems != 8) { free((char *) vl); *entryp = NULL; return NULL; } vl->name = NSE_STRDUP(name); *entryp = vl; return NULL;}static Nse_errwrite_vnode_entry(vl, file, path) Vnodelist vl; FILE *file; char *path;{ if (vl->back_layer != INVALID_LAYER || vl->mtime != 0) { return nse_fprintf(path, file, VNODE_FORMAT, vl->name, vl->nodeids[0], vl->nodeids[1], vl->layer, vl->whited_out, vl->back_layer, vl->back_whited_out, vl->mtime); } else { return nse_fprintf(path, file, VNODE_SHORT_FORMAT, vl->name, vl->nodeids[0], vl->nodeids[1], vl->layer, vl->whited_out); }}static Tfs_swapswap_rec_create(){ Tfs_swap swap; swap = NSE_NEW(Tfs_swap); swap->directories = filelist_create(); swap->children = vnodelist_create(); return swap;}static voidswap_rec_destroy(swap) Tfs_swap swap;{ nse_list_destroy(swap->directories); nse_list_destroy(swap->children); free((char *) swap);}static bool_tvnodelist_name_eq(vl, name) Vnodelist vl; char *name;{ return NSE_STREQ(vl->name, name);}/* * Routines to implement the LRU pnode queue. */voidswqueue_use_pnode(pp) struct pnode *pp;{ if (pp == tail_pnode) { return; } swqueue_dequeue(pp); swqueue_enqueue(pp);}voidswqueue_add_pnode(pp) struct pnode *pp;{ swqueue_enqueue(pp); if (nse_list_nelems(pnode_queue) > MAX_RESIDENT_PNODES) { pp = (struct pnode *) nse_listelem_data( nse_list_first_elem(pnode_queue)); swqueue_dequeue(pp); swap_out_directory(pp); }}static voidswqueue_enqueue(pp) struct pnode *pp;{ (void) nse_list_add_new_data(pnode_queue, (Nse_opaque) pp); pp->p_in_queue = TRUE; tail_pnode = pp;}voidswqueue_dequeue(pp) struct pnode *pp;{ nse_listelem_delete(pnode_queue, nse_list_find_elem(pnode_queue, (Nse_opaque) pp)); pp->p_in_queue = FALSE; if (pp == tail_pnode) { tail_pnode = NULL; }}#ifdef TFSDEBUGvoidswqueue_print(){ dprint(0, 0, "Swap queue: (LRU is first elem)\n"); nse_list_iterate(pnode_queue, print_enqueued_pnode); dprint(0, 0, "%d directories swapped out, %d swapped in, %d swap-out errors\n", nswapout, nswapin, nswapouterr);}static voidprint_enqueued_pnode(pp) struct pnode *pp;{ char pn[MAXPATHLEN]; ptopn(pp, pn); dprint(0, 0, " %s\n", pn);}#endif TFSDEBUGvoidinit_swap(){ struct timeval tv; my_pid = getpid(); gettimeofday(&tv, (struct timezone *) NULL); my_timestamp = tv.tv_sec; pnode_queue = ptrlist_create();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -