void add_to_dict(struct dentry *d) { int loc = d->word[0]-'a'; struct dentry *root = dict[loc], *prev; int ret; if (!root) { dict[loc] = d; return; } prev = root; while (root) { ret = strcmp(d->word, root->word); if (ret == 0) { ++root->freq; free_dentry(d); return; } else if (ret < 1) { if (root == dict[loc]) dict[loc] = d; else prev->next = d; d->next = root; return; } prev = root; root = root->next; } prev->next = d; }
/* * Call this only if you hold the parent's mutex _and_ ref count. */ void __put_dentry(struct dentry *dentry) { struct dentry *parent; assert(have_mutex(dentry->ddent_mutex)); if (!--dentry->ref_count) { parent = dentry->parent; free_dentry(dentry); locked_dec(&parent->ref_count, parent->ddent_mutex); assert(parent->ref_count != 0); } }
void put_dentry(struct dentry *dentry) { struct dentry *parent; for (;;) { lock(dentry->ddent_mutex); if (--dentry->ref_count) { unlock(dentry->ddent_mutex); return; } parent = dentry->parent; assert(parent != NULL); assert(&parent->mutex == dentry->ddent_mutex); free_dentry(dentry); unlock(&parent->mutex); dentry = parent; } }
static int do_attach_branch(struct wim_dentry *branch, const utf16lechar *target, struct update_command_journal *j, int add_flags, wimlib_progress_func_t progfunc, void *progctx) { struct wim_dentry *parent; struct wim_dentry *existing; const utf16lechar empty_name[1] = {0}; const utf16lechar *cur_component_name; size_t cur_component_nbytes; const utf16lechar *next_component_name; int ret; /* Attempt to create root directory before proceeding to the "real" * first component */ parent = NULL; existing = *j->root_p; cur_component_name = empty_name; cur_component_nbytes = 0; /* Skip leading slashes */ next_component_name = target; while (*next_component_name == cpu_to_le16(WIM_PATH_SEPARATOR)) next_component_name++; while (*next_component_name) { /* While not the last component ... */ const utf16lechar *end; if (existing) { /* Descend into existing directory */ if (!dentry_is_directory(existing)) { ERROR("\"%"TS"\" in the WIM image " "is not a directory!", dentry_full_path(existing)); return WIMLIB_ERR_NOTDIR; } } else { /* A parent directory of the target didn't exist. Make * the way by creating a filler directory. */ struct wim_dentry *filler; ret = new_filler_directory(&filler); if (ret) return ret; ret = dentry_set_name_utf16le(filler, cur_component_name, cur_component_nbytes); if (ret) { free_dentry(filler); return ret; } ret = journaled_link(j, filler, parent); if (ret) { free_dentry(filler); return ret; } existing = filler; } /* Advance to next component */ cur_component_name = next_component_name; end = cur_component_name + 1; while (*end && *end != cpu_to_le16(WIM_PATH_SEPARATOR)) end++; next_component_name = end; if (*end) { /* There will still be more components after this. */ do { } while (*++next_component_name == cpu_to_le16(WIM_PATH_SEPARATOR)); wimlib_assert(*next_component_name); /* No trailing slashes */ } else { /* This will be the last component */ next_component_name = end; } parent = existing; cur_component_nbytes = (end - cur_component_name) * sizeof(utf16lechar); existing = get_dentry_child_with_utf16le_name( parent, cur_component_name, cur_component_nbytes, WIMLIB_CASE_PLATFORM_DEFAULT); } /* Last component */ if (existing) { return handle_conflict(branch, existing, j, add_flags, progfunc, progctx); } else { return journaled_link(j, branch, parent); } }