X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmount_image.c;h=1578353fe9ea21c560568b2e146dda78861b8767;hb=067245fb775d108fd06b0628935ece5dd94b58ce;hp=9dcfe9ee894864b397c605e43702a786e1791e95;hpb=0f69ba2b3fe6fe7ddd579215b5a57b03321510ba;p=wimlib diff --git a/src/mount_image.c b/src/mount_image.c index 9dcfe9ee..1578353f 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -8,7 +8,7 @@ */ /* - * Copyright (C) 2012, 2013 Eric Biggers + * Copyright (C) 2012, 2013, 2014 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -370,32 +370,21 @@ wim_pathname_to_inode(WIMStruct *wim, const tchar *path) return NULL; } -/* Remove a dentry from a mounted WIM image; i.e. remove an alias for the - * corresponding inode. - * - * If there are no remaining references to the inode either through dentries or - * open file descriptors, the inode is freed. Otherwise, the inode is not - * removed, but the dentry is unlinked and freed. - * - * Either way, all lookup table entries referenced by the inode have their - * reference count decremented. If a lookup table entry has no open file - * descriptors and no references remaining, it is freed, and the corresponding - * staging file is unlinked. +/* + * Remove a dentry from a mounted WIM image; i.e. remove an alias for an inode. */ static void remove_dentry(struct wim_dentry *dentry, struct wim_lookup_table *lookup_table) { - struct wim_inode *inode = dentry->d_inode; - struct wim_lookup_table_entry *lte; - unsigned i; + /* Put a reference to each stream the inode contains. */ + inode_unref_streams(dentry->d_inode, lookup_table); - for (i = 0; i <= inode->i_num_ads; i++) { - lte = inode_stream_lte(inode, i, lookup_table); - if (lte) - lte_decrement_refcnt(lte, lookup_table); - } + /* Unlink the dentry from the image's dentry tree. */ unlink_dentry(dentry); + + /* Delete the dentry. This will also decrement the link count of the + * corresponding inode. */ free_dentry(dentry); } @@ -1193,9 +1182,11 @@ release_extra_refcnts(struct wimfs_context *ctx) struct wim_lookup_table *lookup_table = ctx->wim->lookup_table; struct wim_lookup_table_entry *lte, *tmp; - list_for_each_entry_safe(lte, tmp, list, orig_stream_list) - while (lte->out_refcnt--) + list_for_each_entry_safe(lte, tmp, list, orig_stream_list) { + u32 n = lte->out_refcnt; + while (n--) lte_decrement_refcnt(lte, lookup_table); + } } /* Moves the currently selected image, which may have been modified, to a new @@ -2045,32 +2036,6 @@ wimfs_read(const char *path, char *buf, size_t size, return ret; } -struct fill_params { - void *buf; - fuse_fill_dir_t filler; -}; - -static int -dentry_fuse_fill(struct wim_dentry *dentry, void *arg) -{ - struct fill_params *fill_params = arg; - - char *file_name_mbs; - size_t file_name_mbs_nbytes; - int ret; - - ret = utf16le_to_tstr(dentry->file_name, - dentry->file_name_nbytes, - &file_name_mbs, - &file_name_mbs_nbytes); - if (ret) - return -errno; - - ret = fill_params->filler(fill_params->buf, file_name_mbs, NULL, 0); - FREE(file_name_mbs); - return ret; -} - /* Fills in the entries of the directory specified by @path using the * FUSE-provided function @filler. */ static int @@ -2079,22 +2044,38 @@ wimfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, { struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; struct wim_inode *inode; + struct wim_dentry *child; + int ret; if (!fd) return -EBADF; inode = fd->f_inode; - struct fill_params fill_params = { - .buf = buf, - .filler = filler, - }; + ret = filler(buf, ".", NULL, 0); + if (ret) + return ret; + ret = filler(buf, "..", NULL, 0); + if (ret) + return ret; + + for_inode_child(child, inode) { + char *file_name_mbs; + size_t file_name_mbs_nbytes; - filler(buf, ".", NULL, 0); - filler(buf, "..", NULL, 0); + ret = utf16le_to_tstr(child->file_name, + child->file_name_nbytes, + &file_name_mbs, + &file_name_mbs_nbytes); + if (ret) + return -errno; - return for_dentry_in_rbtree(inode->i_children.rb_node, - dentry_fuse_fill, &fill_params); + ret = filler(buf, file_name_mbs, NULL, 0); + FREE(file_name_mbs); + if (ret) + return ret; + } + return 0; } @@ -2171,7 +2152,7 @@ static int wimfs_rename(const char *from, const char *to) { return rename_wim_path(wimfs_get_WIMStruct(), from, to, - WIMLIB_CASE_SENSITIVE); + WIMLIB_CASE_SENSITIVE, NULL); } /* Remove a directory */