static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, struct cr_img *img) { char path[PATH_MAX]; int ret, root_len; char *msg; root_len = ret = rst_get_mnt_root(gf->remap.rmnt_id, path, sizeof(path)); if (ret < 0) { pr_err("The %d mount is not found for ghost\n", gf->remap.rmnt_id); goto err; } snprintf(path + ret, sizeof(path) - ret, "/%s", gf->remap.rpath); ret = -1; again: if (S_ISFIFO(gfe->mode)) { if ((ret = mknod(path, gfe->mode, 0)) < 0) msg = "Can't create node for ghost file"; } else if (S_ISCHR(gfe->mode) || S_ISBLK(gfe->mode)) { if (!gfe->has_rdev) { pr_err("No rdev for ghost device\n"); goto err; } if ((ret = mknod(path, gfe->mode, gfe->rdev)) < 0) msg = "Can't create node for ghost dev"; } else if (S_ISDIR(gfe->mode)) { if ((ret = mkdir(path, gfe->mode)) < 0) { pr_perror("Can't make ghost dir"); goto err; } } else { if ((ret = mkreg_ghost(path, gfe->mode, gf, img)) < 0) msg = "Can't create ghost regfile\n"; } if (ret < 0) { /* Use grand parent, if parent directory does not exist */ if (errno == ENOENT) { if (trim_last_parent(path) < 0) { pr_err("trim failed: @%s@\n", path); goto err; } goto again; } pr_perror("%s", msg); goto err; } strcpy(gf->remap.rpath, path + root_len + 1); pr_debug("Remap rpath is %s\n", gf->remap.rpath); ret = -1; if (ghost_apply_metadata(path, gfe)) goto err; ret = 0; err: return ret; }
static int create_ghost(struct ghost_file *gf, GhostFileEntry *gfe, struct cr_img *img) { int gfd, ghost_flags, ret; char path[PATH_MAX]; ret = rst_get_mnt_root(gf->remap.rmnt_id, path, sizeof(path)); if (ret < 0) { pr_err("The %d mount is not found for ghost\n", gf->remap.rmnt_id); goto err; } snprintf(path + ret, sizeof(path) - ret, "/%s", gf->remap.rpath); ret = -1; if (S_ISFIFO(gfe->mode)) { if (mknod(path, gfe->mode, 0)) { pr_perror("Can't create node for ghost file"); goto err; } ghost_flags = O_RDWR; /* To not block */ } else if (S_ISCHR(gfe->mode) || S_ISBLK(gfe->mode)) { if (!gfe->has_rdev) { pr_err("No rdev for ghost device\n"); goto err; } if (mknod(path, gfe->mode, gfe->rdev)) { pr_perror("Can't create node for ghost dev"); goto err; } ghost_flags = O_WRONLY; } else if (S_ISDIR(gfe->mode)) { if (mkdir(path, gfe->mode)) { pr_perror("Can't make ghost dir"); goto err; } ghost_flags = O_DIRECTORY; } else ghost_flags = O_WRONLY | O_CREAT | O_EXCL; gfd = open(path, ghost_flags, gfe->mode); if (gfd < 0) { pr_perror("Can't open ghost file %s", path); goto err; } if (fchown(gfd, gfe->uid, gfe->gid) < 0) { pr_perror("Can't reset user/group on ghost %s", path); goto err_c; } if (S_ISREG(gfe->mode)) { if (copy_file(img_raw_fd(img), gfd, 0) < 0) goto err_c; } ret = 0; err_c: close(gfd); err: return ret; }