Commit aab7e72f authored by Pavel Emelyanov's avatar Pavel Emelyanov

rst file: Introduce the file_remap abstraction

For linked remaps we'll use similar technique as for ghost
files, but lighter. For that sake make reg_file_info remap
to file_remap, not to the whole host_file.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 7cdfc8b3
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
#include "files-reg.h" #include "files-reg.h"
struct file_remap {
char *path;
unsigned int users;
};
/* /*
* Ghost files are those not visible from the FS. Dumping them is * Ghost files are those not visible from the FS. Dumping them is
* nasty and the only way we have -- just carry its contents with * nasty and the only way we have -- just carry its contents with
...@@ -33,11 +38,9 @@ struct ghost_file { ...@@ -33,11 +38,9 @@ struct ghost_file {
u32 dev; u32 dev;
u32 ino; u32 ino;
}; };
struct /* for restoring */ {
char *path; struct file_remap remap; /* for restoring */
};
}; };
unsigned int users;
}; };
static u32 ghost_file_ids = 1; static u32 ghost_file_ids = 1;
...@@ -74,8 +77,8 @@ static int open_remap_ghost(struct reg_file_info *rfi, ...@@ -74,8 +77,8 @@ static int open_remap_ghost(struct reg_file_info *rfi,
gf = shmalloc(sizeof(*gf)); gf = shmalloc(sizeof(*gf));
if (!gf) if (!gf)
return -1; return -1;
gf->path = xmalloc(PATH_MAX); gf->remap.path = xmalloc(PATH_MAX);
if (!gf->path) if (!gf->remap.path)
goto err; goto err;
ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id); ifd = open_image_ro(CR_FD_GHOST_FILE, rfe->remap_id);
...@@ -85,10 +88,10 @@ static int open_remap_ghost(struct reg_file_info *rfi, ...@@ -85,10 +88,10 @@ static int open_remap_ghost(struct reg_file_info *rfi,
if (pb_read_one(ifd, &gfe, PB_GHOST_FILE) < 0) if (pb_read_one(ifd, &gfe, PB_GHOST_FILE) < 0)
goto err; goto err;
snprintf(gf->path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id); snprintf(gf->remap.path, PATH_MAX, "%s.cr.%x.ghost", rfi->path, rfe->remap_id);
if (S_ISFIFO(gfe->mode)) { if (S_ISFIFO(gfe->mode)) {
if (mknod(gf->path, gfe->mode, 0)) { if (mknod(gf->remap.path, gfe->mode, 0)) {
pr_perror("Can't create node for ghost file\n"); pr_perror("Can't create node for ghost file\n");
goto err; goto err;
} }
...@@ -96,7 +99,7 @@ static int open_remap_ghost(struct reg_file_info *rfi, ...@@ -96,7 +99,7 @@ static int open_remap_ghost(struct reg_file_info *rfi,
} else } else
ghost_flags = O_WRONLY | O_CREAT | O_EXCL; ghost_flags = O_WRONLY | O_CREAT | O_EXCL;
gfd = open(gf->path, ghost_flags, gfe->mode); gfd = open(gf->remap.path, ghost_flags, gfe->mode);
if (gfd < 0) { if (gfd < 0) {
pr_perror("Can't open ghost file"); pr_perror("Can't open ghost file");
goto err; goto err;
...@@ -117,17 +120,17 @@ static int open_remap_ghost(struct reg_file_info *rfi, ...@@ -117,17 +120,17 @@ static int open_remap_ghost(struct reg_file_info *rfi,
close(gfd); close(gfd);
gf->id = rfe->remap_id; gf->id = rfe->remap_id;
gf->users = 0; gf->remap.users = 0;
list_add_tail(&gf->list, &ghost_files); list_add_tail(&gf->list, &ghost_files);
gf_found: gf_found:
gf->users++; gf->remap.users++;
rfi->ghost = gf; rfi->remap = &gf->remap;
return 0; return 0;
err: err:
if (gfe) if (gfe)
ghost_file_entry__free_unpacked(gfe, NULL); ghost_file_entry__free_unpacked(gfe, NULL);
xfree(gf->path); xfree(gf->remap.path);
shfree_last(gf); shfree_last(gf);
return -1; return -1;
} }
...@@ -353,11 +356,11 @@ static int open_path(struct file_desc *d, ...@@ -353,11 +356,11 @@ static int open_path(struct file_desc *d,
rfi = container_of(d, struct reg_file_info, d); rfi = container_of(d, struct reg_file_info, d);
if (rfi->ghost) { if (rfi->remap) {
mutex_lock(ghost_file_mutex); mutex_lock(ghost_file_mutex);
if (link(rfi->ghost->path, rfi->path) < 0) { if (link(rfi->remap->path, rfi->path) < 0) {
pr_perror("Can't link %s -> %s\n", pr_perror("Can't link %s -> %s\n",
rfi->ghost->path, rfi->path); rfi->remap->path, rfi->path);
return -1; return -1;
} }
} }
...@@ -368,12 +371,12 @@ static int open_path(struct file_desc *d, ...@@ -368,12 +371,12 @@ static int open_path(struct file_desc *d,
return -1; return -1;
} }
if (rfi->ghost) { if (rfi->remap) {
unlink(rfi->path); unlink(rfi->path);
BUG_ON(!rfi->ghost->users); BUG_ON(!rfi->remap->users);
if (--rfi->ghost->users == 0) { if (--rfi->remap->users == 0) {
pr_info("Unlink the ghost %s\n", rfi->ghost->path); pr_info("Unlink the ghost %s\n", rfi->remap->path);
unlink(rfi->ghost->path); unlink(rfi->remap->path);
} }
mutex_unlock(ghost_file_mutex); mutex_unlock(ghost_file_mutex);
} }
...@@ -436,7 +439,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base) ...@@ -436,7 +439,7 @@ static int collect_one_regfile(void *o, ProtobufCMessage *base)
rfi->rfe = pb_msg(base, RegFileEntry); rfi->rfe = pb_msg(base, RegFileEntry);
rfi->path = rfi->rfe->name; rfi->path = rfi->rfe->name;
rfi->ghost = NULL; rfi->remap = NULL;
pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id); pr_info("Collected [%s] ID %#x\n", rfi->path, rfi->rfe->id);
file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops); file_desc_add(&rfi->d, rfi->rfe->id, &reg_desc_ops);
......
...@@ -11,11 +11,11 @@ ...@@ -11,11 +11,11 @@
struct cr_fdset; struct cr_fdset;
struct fd_parms; struct fd_parms;
struct ghost_file; struct file_remap;
struct reg_file_info { struct reg_file_info {
struct file_desc d; struct file_desc d;
RegFileEntry *rfe; RegFileEntry *rfe;
struct ghost_file *ghost; struct file_remap *remap;
char *path; char *path;
}; };
......
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