📄 tfs_backlink.c
字号:
(result = get_backlinks(shared_pp->p_name, searchlink, &backlinks, shared_pp))) { return result; } result = (int) nse_list_iterate_or(backlinks, bl_whiteout, name, exclude_pp); nse_list_destroy(backlinks); return result;}static intbl_whiteout(bp, name, exclude_pp) Backlink bp; char *name; struct pnode *exclude_pp;{ struct vnode *vnodes[MAX_NAMES]; struct vnode *vp; struct vnode *childvp; int result; if (bp->pnode == exclude_pp) { return 0; } bzero((char *) vnodes, sizeof vnodes); get_vnodes(bp->pnode, vnodes); vp = vnodes[0]; if (vp == NULL) { return tfsd_set_whiteout(bp->path, name, (struct pnode *) NULL); } if (result = validate_directory(vp)) { return result; } childvp = find_vnode(vp, name); if (childvp) { return update_directory(vp->v_pnode, name, DIR_REMOVE_FILE, TRUE, FALSE, NULL); } return 0;}static intget_backlinks(dir_path, searchlink, backlinks, pp) char *dir_path; char *searchlink; Nse_list *backlinks; struct pnode *pp;{ Nse_whiteout first_bl; Nse_whiteout bl; Backlink bp; char *path; int result; struct stat statb; if (result = tfsd_get_tfs_info(dir_path, searchlink, &first_bl, (Nse_whiteout *) NULL, FALSE, pp, TRUE)) { return result; } *backlinks = bklink_list_create(); for (bl = first_bl; bl != NULL; bl = bl->next) { path = index(bl->name, '/'); pp = path_to_pnode(path, MAX_SUB_LAYER - 1); if (pp->p_refcnt == 1 && stat(path, &statb) == -1) { free_pnode(pp); continue; } bp = (Backlink) nse_list_add_new_elem(*backlinks); bp->pnode = pp; bp->path = NSE_STRDUP(path); *path = '\0'; bp->varname = NSE_STRDUP(bl->name); *path = '/'; } nse_dispose_whiteout(first_bl); return 0;}static intbl_rename_dir(bp, shared_path, old_pattern, new_pattern, same_directory) Backlink bp; char *shared_path; char *old_pattern; char *new_pattern; bool_t same_directory;{ char path[MAXPATHLEN]; int result; sprintf(path, "%s2 %s", NSE_TFS_RENAME_STR, shared_path); *rindex(path, '/') = '\0'; if ((result = change_to_dir(PARENT_PNODE(bp->pnode))) || (result = set_rename_record(".", path))) { return result; } strcpy(path, bp->pnode->p_name); if (result = recursive_directory_op(path, rename_searchlink, old_pattern, new_pattern)) { return result; } replace_substring(bp->path, old_pattern, new_pattern, path); if (same_directory) { char *newname; newname = rindex(path, '/') + 1; if (rename(bp->pnode->p_name, newname) < 0) { return errno; } } else { if (rename(bp->pnode->p_name, path) < 0) { if (errno == ENOENT) { char searchlink[MAXPATHLEN]; /* * The destination parent directory doesn't * exist. Since create_parent_dir may change * the current directory, use the full * pathname. */ replace_substring(shared_path, old_pattern, new_pattern, searchlink); if (result = create_parent_dir(path, searchlink, bp->varname)) { return result; } if (rename(bp->path, path) < 0) { return errno; } } else { return errno; } } } return 0;}static intrename_shared_dir(pp, new_path, old_pattern, new_pattern, same_directory) struct pnode *pp; char *new_path; char *old_pattern; char *new_pattern; bool_t same_directory;{ char path[MAXPATHLEN]; int result; if (result = change_to_dir(PARENT_PNODE(pp))) { return result; } strcpy(path, pp->p_name); if (result = recursive_directory_op(path, rename_backlinks, old_pattern, new_pattern)) { return result; } if (same_directory) { char *newname; newname = rindex(new_path, '/') + 1; if (rename(pp->p_name, newname) < 0) { return errno; } } else { if (rename(pp->p_name, new_path) < 0) { return errno; } } return 0;}static intrecursive_directory_op(path, func, arg1, arg2) char *path; int (*func)(); char *arg1; char *arg2;{ DIR *dirp; struct direct *dp; struct stat statb; char curname[MAXNAMLEN]; int result; dirp = opendir(path); if (dirp == NULL) { nse_log_message("warning: can't read directory %s\n", path); return 0; } while (dp = readdir(dirp)) { if (NSE_STREQ(dp->d_name, ".") || NSE_STREQ(dp->d_name, "..") || is_tfs_special_file(dp->d_name)) { continue; } nse_pathcat(path, dp->d_name); if (lstat(path, &statb) < 0) { closedir(dirp); return errno; } if (NSE_ISDIR(&statb)) { strcpy(curname, dp->d_name); closedir(dirp); if (result = recursive_directory_op(path, func, arg1, arg2)) { return result; } *rindex(path, '/') = '\0'; dirp = opendir(path); if (dirp == NULL) { nse_log_message( "warning: can't read directory %s\n", path); return 0; } /* * Pick up where we left off. */ while (dp = readdir(dirp)) { if (NSE_STREQ(curname, dp->d_name)) { break; } } } else { *rindex(path, '/') = '\0'; } } closedir(dirp); return func(path, arg1, arg2);}static intrename_searchlink(path, old_pattern, new_pattern) char *path; char *old_pattern; char *new_pattern;{ char searchlink[MAXPATHLEN]; char new_searchlink[MAXPATHLEN]; Nse_whiteout wo; Nse_whiteout bl; int result; if (result = tfsd_get_tfs_info(path, searchlink, &bl, &wo, TRUE, (struct pnode *) NULL, FALSE)) { return result; } replace_substring(searchlink, old_pattern, new_pattern, new_searchlink); return tfsd_set_tfs_info(path, new_searchlink, bl, wo, (struct pnode *) NULL);}static intrename_backlinks(path, old_pattern, new_pattern) char *path; char *old_pattern; char *new_pattern;{ char searchlink[MAXPATHLEN]; char new_backlink[MAXPATHLEN]; Nse_whiteout wo; Nse_whiteout bl_first; Nse_whiteout bl; int result; if (result = tfsd_get_tfs_info(path, searchlink, &bl_first, &wo, TRUE, (struct pnode *) NULL, FALSE)) { return (result); } for (bl = bl_first; bl != NULL; bl = bl->next) { replace_substring(bl->name, old_pattern, new_pattern, new_backlink); free(bl->name); bl->name = NSE_STRDUP(new_backlink); } return tfsd_set_tfs_info(path, searchlink, bl_first, wo, (struct pnode *) NULL);}/* * Create the parent directory of the directory named 'path'. * 'searchlink' is the value of the searchlink from the directory 'path'. */static intcreate_parent_dir(path, searchlink, varname) char *path; char *searchlink; char *varname;{ char *p; char *s; int result = 0; struct stat statb; p = rindex(path, '/'); *p = '\0'; s = rindex(searchlink, '/'); *s = '\0'; if (stat(path, &statb) == -1) { if (result = create_parent_dir(path, searchlink, varname)) { goto error; } if (mkdir(path, 0777) < 0) { result = errno; goto error; } result = tfsd_set_searchlink(path, searchlink, (struct pnode *) NULL); if (result == 0) { char backlink[MAXPATHLEN]; strcpy(backlink, varname); strcat(backlink, path); result = tfsd_set_backlink(searchlink, backlink); } } else { struct pnode *pp; /* * There may be a invalid directory vnode whose only pnode * will be covered by the directory we are creating here. */ pp = path_to_pnode(path, MAX_SUB_LAYER - 1); result = update_directory(pp, (char *) NULL, DIR_FLUSH); free_pnode(pp); }error: *p = '/'; *s = '/'; return result;}static intclear_all_rename_records(old_parentp, new_parentp, old_pattern, new_pattern, backlinks, recover) struct pnode *old_parentp; struct pnode *new_parentp; char *old_pattern; char *new_pattern; Nse_list backlinks; bool_t recover;{ int result; if (result = (int) nse_list_iterate_or(backlinks, bl_clear_rename_record, old_pattern, new_pattern, recover)) { return result; } if (new_parentp != old_parentp) { if ((result = change_to_dir(new_parentp)) || (result = clear_rename_record("."))) { return result; } } if (result = change_to_dir(old_parentp)) { return result; } return clear_rename_record(".");}static intbl_clear_rename_record(bp, old_pattern, new_pattern, recover) Backlink bp; char *old_pattern; char *new_pattern; bool_t recover;{ if (recover) { char old_backlink[MAXPATHLEN]; /* * In the recovery case, the backlinks contain the new * directory names of the front layers. */ replace_substring(bp->path, new_pattern, old_pattern, old_backlink); *rindex(old_backlink, '/') = '\0'; return clear_rename_record(old_backlink); } else { int result; if (result = change_to_dir(PARENT_PNODE(bp->pnode))) { return result; } return clear_rename_record("."); }}static intset_rename_record(path, entry) char *path; char *entry;{ char searchlink[MAXPATHLEN]; Nse_whiteout wo; Nse_whiteout bl; Nse_whiteout bl_rename; int result; if (result = tfsd_get_tfs_info(path, searchlink, &bl, &wo, TRUE, (struct pnode *) NULL, FALSE)) { return result; } if (bl_rename = bl_list_get_rename_elem(bl)) { free(bl_rename->name); bl_rename->name = NSE_STRDUP(entry); } else { bl_rename = NSE_NEW(Nse_whiteout); bl_rename->name = NSE_STRDUP(entry); bl_rename->next = bl; bl = bl_rename; } return tfsd_set_tfs_info(path, searchlink, bl, wo, (struct pnode *) NULL);}static intclear_rename_record(path) char *path;{ char searchlink[MAXPATHLEN]; Nse_whiteout wo; Nse_whiteout bl; Nse_whiteout bl_rename; int result; if (result = tfsd_get_tfs_info(path, searchlink, &bl, &wo, TRUE, (struct pnode *) NULL, FALSE)) { return result; } if (bl_rename = bl_list_get_rename_elem(bl)) { bl_list_remove_elem(&bl, bl_rename); } return tfsd_set_tfs_info(path, searchlink, bl, wo, (struct pnode *) NULL);}Nse_whiteoutbl_list_get_rename_elem(bl_first) Nse_whiteout bl_first;{ Nse_whiteout bl; int rename_str_len = strlen(NSE_TFS_RENAME_STR); for (bl = bl_first; bl != NULL; bl = bl->next) { if (0 == strncmp(bl->name, NSE_TFS_RENAME_STR, rename_str_len)) { return bl; } } return NULL;}static voidbl_list_remove_elem(bl_first, bl_to_delete) Nse_whiteout *bl_first; Nse_whiteout bl_to_delete;{ Nse_whiteout bl; Nse_whiteout bl_prev = NULL; for (bl = *bl_first; bl != NULL; bl = bl->next) { if (bl == bl_to_delete) { if (bl_prev) { bl_prev->next = bl->next; } else { *bl_first = bl->next; } bl->next = NULL; nse_dispose_whiteout(bl); return; } bl_prev = bl; }}static voidreplace_substring(orig_path, old_pattern, new_pattern, new_path) char *orig_path; char *old_pattern; char *new_pattern; char *new_path;{ char *cp; char c; cp = nse_find_substring(orig_path, old_pattern); if (cp == NULL) { strcpy(new_path, orig_path); return; } c = *cp; *cp = '\0'; strcpy(new_path, orig_path); *cp = c; strcat(new_path, new_pattern); cp += strlen(old_pattern); if (*cp != '/' && *cp != '\0') { /* * Sanity check to ensure that 'old_pattern' exactly * matched a portion of the path 'orig_path'. */ strcpy(new_path, orig_path); } else { strcat(new_path, cp); }}static char *common_suffix(name1, name2) char *name1; char *name2;{ char *cp1 = &name1[strlen(name1) - 1]; char *cp2 = &name2[strlen(name2) - 1]; for ( ; *cp1 == *cp2; cp1--, cp2--) ; return ++cp1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -