void fstree_insert_update_file(const char *path, const char *follow) { struct dir_record *dr; struct vfile_record *vfr; struct file_record *fr, *new_fr; uint16_t key = ~0; char *filename; size_t length; filename = split_basename(path, dirname); if (!(dr = find_dr(dirname))) goto DR; else { length = (size_t) strlen((char *) filename); key = compute_crc32(key, (const unsigned char *) filename, length); if (!(vfr = find(dr->vroot, key, 0))) { PHOENIXFS_DBG("fstree_insert_update_file:: missing vfr: %s", filename); goto VFR; } else { if (vfr->HEAD >= 0) fr = vfr->history[vfr->HEAD]; else fr = NULL; goto FR; } } DR: dr = make_dr(dirname); insert_dr(dr); VFR: vfr = make_vfr(filename); insert_vfr(dr, vfr); FR: if (!(new_fr = make_fr(path, follow))) { PHOENIXFS_DBG("fstree_insert_update_file:: Can't make fr %s", path); return; } /* If content is present in the old fr, don't make a new fr */ if (fr && !memcmp(fr->sha1, new_fr->sha1, 20)) { PHOENIXFS_DBG("fstree_insert_update_file:: unmodified: %s", path); free(new_fr); return; } insert_fr(vfr, new_fr); }
static int phoenixfs_rename(const char *path, const char *newpath) { char xnewpath[PATH_MAX]; struct dir_record *dr; struct vfile_record *vfr, *new_vfr; char *filename, *newfilename; uint16_t key = ~0; size_t length; uint8_t start_rev, rev_nr; PHOENIXFS_DBG("rename:: %s to %s", path, newpath); build_xpath(xpath, path, 0); build_xpath(xnewpath, newpath, 0); if (rename(xpath, xnewpath) < 0) return -errno; /* Update fstree */ filename = split_basename(path, xpath); if (!(dr = find_dr(xpath))) { PHOENIXFS_DBG("rename:: Missing dr for %s", xpath); return 0; } /* Find the old vfr to copy out data from and remove */ length = (size_t) strlen((char *) filename); key = compute_crc32(key, (const unsigned char *) filename, length); if (!(vfr = find(dr->vroot, key, 0))) { PHOENIXFS_DBG("rename:: Missing vfr for %s", path); return 0; } /* Make a new vfr and copy out history from old vfr */ newfilename = split_basename(path, NULL); new_vfr = make_vfr(newfilename); /* Compute start_rev and rev_nr */ if (vfr->HEAD < 0) { start_rev = 0; rev_nr = 0; } else if (vfr->history[(vfr->HEAD + 1) % REV_TRUNCATE]) { /* History is full, and is probably wrapping around */ start_rev = (vfr->HEAD + 1) % REV_TRUNCATE; rev_nr = 20; } else { /* History is not completely filled */ start_rev = 0; rev_nr = vfr->HEAD + 1; } PHOENIXFS_DBG("rename:: copying %d revisions", rev_nr); while (start_rev < rev_nr) { new_vfr->history[start_rev] = vfr->history[start_rev]; start_rev = (start_rev + 1) % REV_TRUNCATE; } new_vfr->HEAD = rev_nr - 1; insert_vfr(dr, new_vfr); /* Remove old vfr */ dr->vroot = remove_entry(dr->vroot, key); return 0; }