From 8a07349388c9baaa8f821ee9b8279a22075d51cd Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Fri, 6 Jun 2014 12:20:02 +0400 Subject: [PATCH] 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: Pavel Emelyanov --- fifo.c | 6 +++--- files-reg.c | 34 +++++++++++++++++----------------- include/files-reg.h | 3 ++- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/fifo.c b/fifo.c index 71334ed49..ad7108806 100644 --- a/fifo.c +++ b/fifo.c @@ -71,7 +71,7 @@ const struct fdtype_ops fifo_dump_ops = { 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; int new_fifo, fake_fifo = -1; @@ -82,13 +82,13 @@ static int do_open_fifo(struct reg_file_info *rfi, void *arg) * proceed the restoration procedure we open a fake * fifo here. */ - fake_fifo = open(rfi->path, O_RDWR); + fake_fifo = openat(ns_root_fd, rfi->path, O_RDWR); if (fake_fifo < 0) { pr_perror("Can't open fake fifo %#x [%s]", info->fe->id, rfi->path); 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) { pr_perror("Can't open fifo %#x [%s]", info->fe->id, rfi->path); goto out; diff --git a/files-reg.c b/files-reg.c index 9f225bcd7..1f23f718f 100644 --- a/files-reg.c +++ b/files-reg.c @@ -632,10 +632,11 @@ static inline int rfi_remap(struct reg_file_info *rfi) } 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; - int tmp; + struct ns_id *ns; + int tmp, mntns_root; char *orig_path = NULL; rfi = container_of(d, struct reg_file_info, 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) { pr_perror("Can't open file %s", rfi->path); return -1; @@ -698,19 +705,12 @@ int open_path(struct file_desc *d, 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; - int fd, mntns_root; - struct ns_id *nsid; + int fd; - 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) { pr_perror("Can't open file %s on restore", rfi->path); return fd; @@ -719,16 +719,16 @@ static int do_open_reg_noseek_flags(struct reg_file_info *rfi, void *arg) 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; - fd = do_open_reg_noseek(rfi, arg); + fd = do_open_reg_noseek(ns_root_fd, rfi, arg); if (fd < 0) return fd; diff --git a/include/files-reg.h b/include/files-reg.h index b8ffb04cd..859c661c9 100644 --- a/include/files-reg.h +++ b/include/files-reg.h @@ -24,7 +24,8 @@ struct reg_file_info { }; 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 int prepare_shared_reg_files(void);