Commit d0097b2d authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Support ghost directories restore

If we have opened and rmdir-ed directory, the dump works OK
creating the ghost file and remap, but restore creates _file_
instead of directory.

Fix this.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent c06727c2
...@@ -90,6 +90,12 @@ static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, char *root, ...@@ -90,6 +90,12 @@ static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, char *root,
goto err; goto err;
} }
ghost_flags = O_WRONLY; ghost_flags = O_WRONLY;
} else if (S_ISDIR(gfe->mode)) {
if (mkdir(gf->remap.path, gfe->mode)) {
pr_perror("Can't make ghost dir");
goto err;
}
ghost_flags = O_DIRECTORY;
} else } else
ghost_flags = O_WRONLY | O_CREAT | O_EXCL; ghost_flags = O_WRONLY | O_CREAT | O_EXCL;
...@@ -176,6 +182,7 @@ static int open_remap_ghost(struct reg_file_info *rfi, ...@@ -176,6 +182,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
gf->id = rfe->remap_id; gf->id = rfe->remap_id;
gf->remap.users = 0; gf->remap.users = 0;
gf->remap.is_dir = S_ISDIR(gfe->mode);
list_add_tail(&gf->list, &ghost_files); list_add_tail(&gf->list, &ghost_files);
gf_found: gf_found:
rfi->remap = &gf->remap; rfi->remap = &gf->remap;
...@@ -676,7 +683,14 @@ int open_path(struct file_desc *d, ...@@ -676,7 +683,14 @@ int open_path(struct file_desc *d,
if (rfi->remap) { if (rfi->remap) {
mutex_lock(ghost_file_mutex); mutex_lock(ghost_file_mutex);
if (rfi_remap(rfi) < 0) { if (rfi->remap->is_dir) {
/*
* FIXME Can't make directory under new name.
* Will have to open it under the ghost one :(
*/
orig_path = rfi->path;
rfi->path = rfi->remap->path;
} else if (rfi_remap(rfi) < 0) {
static char tmp_path[PATH_MAX]; static char tmp_path[PATH_MAX];
if (errno != EEXIST) { if (errno != EEXIST) {
...@@ -747,7 +761,10 @@ int open_path(struct file_desc *d, ...@@ -747,7 +761,10 @@ int open_path(struct file_desc *d,
BUG_ON(!rfi->remap->users); BUG_ON(!rfi->remap->users);
if (--rfi->remap->users == 0) { if (--rfi->remap->users == 0) {
pr_info("Unlink the ghost %s\n", rfi->remap->path); pr_info("Unlink the ghost %s\n", rfi->remap->path);
unlink(rfi->remap->path); if (rfi->remap->is_dir)
rmdir(rfi->remap->path);
else
unlink(rfi->remap->path);
} }
if (orig_path) if (orig_path)
......
...@@ -13,6 +13,7 @@ struct fd_parms; ...@@ -13,6 +13,7 @@ struct fd_parms;
struct file_remap { struct file_remap {
char *path; char *path;
bool is_dir;
unsigned int users; unsigned int users;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment