X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fupdate_image.c;h=9453f2e02cf9d23bee7ae83861c18089e9974131;hp=650dfbbd07fdf0726d3ce737085cdbf214eb9ae5;hb=7b36eb8076864060c623f1e39bdf26b363eaa2e5;hpb=22c0e369cb60b73a9ec209c878173001bfb43db8 diff --git a/src/update_image.c b/src/update_image.c index 650dfbbd..9453f2e0 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -28,6 +28,10 @@ #include "xml.h" #include +#ifdef __WIN32__ +# include "win32.h" +#endif + /* Overlays @branch onto @target, both of which must be directories. */ static int do_overlay(struct wim_dentry *target, struct wim_dentry *branch) @@ -44,6 +48,7 @@ do_overlay(struct wim_dentry *target, struct wim_dentry *branch) } rb_root = &branch->d_inode->i_children; + LIST_HEAD(moved_children); while (rb_root->rb_node) { /* While @branch has children... */ struct wim_dentry *child = rbnode_dentry(rb_root->rb_node); struct wim_dentry *existing; @@ -57,12 +62,17 @@ do_overlay(struct wim_dentry *target, struct wim_dentry *branch) int ret; ret = do_overlay(existing, child); if (ret) { - /* Overlay failed. Revert the change to avoid - * leaking the directory tree rooted at @child. - * */ + /* Overlay failed. Revert the changes. */ dentry_add_child(branch, child); + list_for_each_entry(child, &moved_children, tmp_list) + { + unlink_dentry(child); + dentry_add_child(branch, child); + } return ret; } + } else { + list_add(&child->tmp_list, &moved_children); } } free_dentry(branch); @@ -295,6 +305,8 @@ execute_delete_command(WIMStruct *wim, flags = delete_cmd->delete.delete_flags; wim_path = delete_cmd->delete.wim_path; + DEBUG("Deleting WIM path \"%"TS"\" (flags=%#x)", wim_path, flags); + tree = get_dentry(wim, wim_path); if (!tree) { /* Path to delete does not exist in the WIM. */ @@ -322,7 +334,15 @@ execute_delete_command(WIMStruct *wim, return 0; } -/* +static int +free_dentry_full_path(struct wim_dentry *dentry, void *_ignore) +{ + FREE(dentry->_full_path); + dentry->_full_path = NULL; + return 0; +} + +/* * Rename a file or directory in the WIM. * * This is also called from wimfs_rename() in the FUSE mount code. @@ -382,6 +402,8 @@ rename_wim_path(WIMStruct *wim, const tchar *from, const tchar *to) } unlink_dentry(src); dentry_add_child(parent_of_dst, src); + if (src->_full_path) + for_dentry_in_tree(src, free_dentry_full_path, NULL); return 0; } @@ -397,20 +419,25 @@ execute_rename_command(WIMStruct *wim, ret = rename_wim_path(wim, rename_cmd->rename.wim_source_path, rename_cmd->rename.wim_target_path); if (ret) { + ret = -ret; + errno = ret; + ERROR_WITH_ERRNO("Can't rename \"%"TS"\" to \"%"TS"\"", + rename_cmd->rename.wim_source_path, + rename_cmd->rename.wim_target_path); switch (ret) { - case -ENOMEM: + case ENOMEM: ret = WIMLIB_ERR_NOMEM; break; - case -ENOTDIR: + case ENOTDIR: ret = WIMLIB_ERR_NOTDIR; break; - case -ENOTEMPTY: + case ENOTEMPTY: ret = WIMLIB_ERR_NOTEMPTY; break; - case -EISDIR: + case EISDIR: ret = WIMLIB_ERR_IS_DIRECTORY; break; - case -ENOENT: + case ENOENT: default: ret = WIMLIB_ERR_PATH_DOES_NOT_EXIST; break; @@ -430,7 +457,7 @@ update_op_to_str(int op) case WIMLIB_UPDATE_OP_RENAME: return T("rename"); default: - return T("???"); + wimlib_assert(0); } } @@ -450,15 +477,12 @@ execute_update_commands(WIMStruct *wim, break; case WIMLIB_UPDATE_OP_DELETE: ret = execute_delete_command(wim, &cmds[i]); - if (ret == 0) - wim->deletion_occurred = 1; break; case WIMLIB_UPDATE_OP_RENAME: ret = execute_rename_command(wim, &cmds[i]); break; default: wimlib_assert(0); - break; } if (ret) break; @@ -574,7 +598,7 @@ free_update_commands(struct wimlib_update_command *cmds, size_t num_cmds) { if (cmds) { for (size_t i = 0; i < num_cmds; i++) { - switch (cmds->op) { + switch (cmds[i].op) { case WIMLIB_UPDATE_OP_ADD: FREE(cmds[i].add.fs_source_path); FREE(cmds[i].add.wim_target_path);