Commit 8a073493 authored by Pavel Emelyanov's avatar Pavel Emelyanov

files: Fix open_path() to provide mntns root fd to callbacks

This fixes the support for fifo-s in mount namespaces and
makes it easier to control the correct open_path() usage in
the future.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent b9c6cf3d
...@@ -71,7 +71,7 @@ const struct fdtype_ops fifo_dump_ops = { ...@@ -71,7 +71,7 @@ const struct fdtype_ops fifo_dump_ops = {
static struct pipe_data_rst *pd_hash_fifo[PIPE_DATA_HASH_SIZE]; static struct pipe_data_rst *pd_hash_fifo[PIPE_DATA_HASH_SIZE];
static int do_open_fifo(struct reg_file_info *rfi, void *arg) static int do_open_fifo(int ns_root_fd, struct reg_file_info *rfi, void *arg)
{ {
struct fifo_info *info = arg; struct fifo_info *info = arg;
int new_fifo, fake_fifo = -1; int new_fifo, fake_fifo = -1;
...@@ -82,13 +82,13 @@ static int do_open_fifo(struct reg_file_info *rfi, void *arg) ...@@ -82,13 +82,13 @@ static int do_open_fifo(struct reg_file_info *rfi, void *arg)
* proceed the restoration procedure we open a fake * proceed the restoration procedure we open a fake
* fifo here. * fifo here.
*/ */
fake_fifo = open(rfi->path, O_RDWR); fake_fifo = openat(ns_root_fd, rfi->path, O_RDWR);
if (fake_fifo < 0) { if (fake_fifo < 0) {
pr_perror("Can't open fake fifo %#x [%s]", info->fe->id, rfi->path); pr_perror("Can't open fake fifo %#x [%s]", info->fe->id, rfi->path);
return -1; return -1;
} }
new_fifo = open(rfi->path, rfi->rfe->flags); new_fifo = openat(ns_root_fd, rfi->path, rfi->rfe->flags);
if (new_fifo < 0) { if (new_fifo < 0) {
pr_perror("Can't open fifo %#x [%s]", info->fe->id, rfi->path); pr_perror("Can't open fifo %#x [%s]", info->fe->id, rfi->path);
goto out; goto out;
......
...@@ -632,10 +632,11 @@ static inline int rfi_remap(struct reg_file_info *rfi) ...@@ -632,10 +632,11 @@ static inline int rfi_remap(struct reg_file_info *rfi)
} }
int open_path(struct file_desc *d, int open_path(struct file_desc *d,
int(*open_cb)(struct reg_file_info *, void *), void *arg) int(*open_cb)(int mntns_root, struct reg_file_info *, void *), void *arg)
{ {
struct reg_file_info *rfi; struct reg_file_info *rfi;
int tmp; struct ns_id *ns;
int tmp, mntns_root;
char *orig_path = NULL; char *orig_path = NULL;
rfi = container_of(d, struct reg_file_info, d); rfi = container_of(d, struct reg_file_info, d);
...@@ -673,7 +674,13 @@ int open_path(struct file_desc *d, ...@@ -673,7 +674,13 @@ int open_path(struct file_desc *d,
} }
} }
tmp = open_cb(rfi, arg); ns = lookup_nsid_by_mnt_id(rfi->rfe->mnt_id);
if (ns == NULL)
return -1;
mntns_root = mntns_get_root_fd(ns);
tmp = open_cb(mntns_root, rfi, arg);
if (tmp < 0) { if (tmp < 0) {
pr_perror("Can't open file %s", rfi->path); pr_perror("Can't open file %s", rfi->path);
return -1; return -1;
...@@ -698,19 +705,12 @@ int open_path(struct file_desc *d, ...@@ -698,19 +705,12 @@ int open_path(struct file_desc *d,
return tmp; return tmp;
} }
static int do_open_reg_noseek_flags(struct reg_file_info *rfi, void *arg) static int do_open_reg_noseek_flags(int ns_root_fd, struct reg_file_info *rfi, void *arg)
{ {
u32 flags = *(u32 *)arg; u32 flags = *(u32 *)arg;
int fd, mntns_root; int fd;
struct ns_id *nsid;
nsid = lookup_nsid_by_mnt_id(rfi->rfe->mnt_id);
if (nsid == NULL)
return -1;
mntns_root = mntns_get_root_fd(nsid);
fd = openat(mntns_root, rfi->path, flags); fd = openat(ns_root_fd, rfi->path, flags);
if (fd < 0) { if (fd < 0) {
pr_perror("Can't open file %s on restore", rfi->path); pr_perror("Can't open file %s on restore", rfi->path);
return fd; return fd;
...@@ -719,16 +719,16 @@ static int do_open_reg_noseek_flags(struct reg_file_info *rfi, void *arg) ...@@ -719,16 +719,16 @@ static int do_open_reg_noseek_flags(struct reg_file_info *rfi, void *arg)
return fd; return fd;
} }
static int do_open_reg_noseek(struct reg_file_info *rfi, void *arg) static int do_open_reg_noseek(int ns_root_fd, struct reg_file_info *rfi, void *arg)
{ {
return do_open_reg_noseek_flags(rfi, &rfi->rfe->flags); return do_open_reg_noseek_flags(ns_root_fd, rfi, &rfi->rfe->flags);
} }
static int do_open_reg(struct reg_file_info *rfi, void *arg) static int do_open_reg(int ns_root_fd, struct reg_file_info *rfi, void *arg)
{ {
int fd; int fd;
fd = do_open_reg_noseek(rfi, arg); fd = do_open_reg_noseek(ns_root_fd, rfi, arg);
if (fd < 0) if (fd < 0)
return fd; return fd;
......
...@@ -24,7 +24,8 @@ struct reg_file_info { ...@@ -24,7 +24,8 @@ struct reg_file_info {
}; };
extern int open_reg_by_id(u32 id); extern int open_reg_by_id(u32 id);
extern int open_path(struct file_desc *, int (*open_cb)(struct reg_file_info *, void *), void *arg); extern int open_path(struct file_desc *, int (*open_cb)(int ns_root_fd,
struct reg_file_info *, void *), void *arg);
extern void clear_ghost_files(void); extern void clear_ghost_files(void);
extern int prepare_shared_reg_files(void); extern int prepare_shared_reg_files(void);
......
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