and call it from open_related_ns().
Unified · Split
| @@ -17,6 +17,7 @@ struct fs_context; · 16 unmodified lines | ||
| 17 | 17 | struct pipe_inode_info; |
| 18 | 18 | struct iov_iter; |
| 19 | 19 | struct mnt_idmap; |
| 20 | +struct ns_common; | |
| 20 | 21 | |
| 21 | 22 | /* |
| 22 | 23 | * block/bdev.c |
| @@ -321,3 +322,4 @@ struct stashed_operations { · 298 unmodified lines | ||
| 321 | 322 | int path_from_stashed(struct dentry **stashed, struct vfsmount *mnt, void *data, |
| 322 | 323 | struct path *path); |
| 323 | 324 | void stashed_dentry_prune(struct dentry *dentry); |
| 325 | +int open_namespace(struct ns_common *ns); | |
| @@ -82,40 +82,47 @@ int ns_get_path(struct path *path, struct task_struct *task, · 81 unmodified lines | ||
| 82 | 82 | return ns_get_path_cb(path, ns_get_path_task, &args); |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | −int open_related_ns(struct ns_common *ns, | |
| 86 | − struct ns_common *(*get_ns)(struct ns_common *ns)) | |
| 85 | +/** | |
| 86 | + * open_namespace - open a namespace | |
| 87 | + * @ns: the namespace to open | |
| 88 | + * | |
| 89 | + * This will consume a reference to @ns indendent of success or failure. | |
| 90 | + * | |
| 91 | + * Return: A file descriptor on success or a negative error code on failure. | |
| 92 | + */ | |
| 93 | +int open_namespace(struct ns_common *ns) | |
| 87 | 94 | { |
| 88 | − struct path path = {}; | |
| 89 | − struct ns_common *relative; | |
| 95 | + struct path path __free(path_put) = {}; | |
| 90 | 96 | struct file *f; |
| 91 | 97 | int err; |
| 92 | − int fd; | |
| 93 | 98 | |
| 94 | − fd = get_unused_fd_flags(O_CLOEXEC); | |
| 99 | + /* call first to consume reference */ | |
| 100 | + err = path_from_stashed(&ns->stashed, nsfs_mnt, ns, &path); | |
| 101 | + if (err < 0) | |
| 102 | + return err; | |
| 103 | + | |
| 104 | + CLASS(get_unused_fd, fd)(O_CLOEXEC); | |
| 95 | 105 | if (fd < 0) |
| 96 | 106 | return fd; |
| 97 | 107 | |
| 108 | + f = dentry_open(&path, O_RDONLY, current_cred()); | |
| 109 | + if (IS_ERR(f)) | |
| 110 | + return PTR_ERR(f); | |
| 111 | + | |
| 112 | + fd_install(fd, f); | |
| 113 | + return take_fd(fd); | |
| 114 | +} | |
| 115 | + | |
| 116 | +int open_related_ns(struct ns_common *ns, | |
| 117 | + struct ns_common *(*get_ns)(struct ns_common *ns)) | |
| 118 | +{ | |
| 119 | + struct ns_common *relative; | |
| 120 | + | |
| 98 | 121 | relative = get_ns(ns); |
| 99 | − if (IS_ERR(relative)) { | |
| 100 | − put_unused_fd(fd); | |
| 122 | + if (IS_ERR(relative)) | |
| 101 | 123 | return PTR_ERR(relative); |
| 102 | − } | |
| 103 | 124 | |
| 104 | − err = path_from_stashed(&relative->stashed, nsfs_mnt, relative, &path); | |
| 105 | − if (err < 0) { | |
| 106 | − put_unused_fd(fd); | |
| 107 | − return err; | |
| 108 | − } | |
| 109 | − | |
| 110 | − f = dentry_open(&path, O_RDONLY, current_cred()); | |
| 111 | − path_put(&path); | |
| 112 | − if (IS_ERR(f)) { | |
| 113 | − put_unused_fd(fd); | |
| 114 | − fd = PTR_ERR(f); | |
| 115 | − } else | |
| 116 | − fd_install(fd, f); | |
| 117 | − | |
| 118 | − return fd; | |
| 125 | + return open_namespace(relative); | |
| 119 | 126 | } |
| 120 | 127 | EXPORT_SYMBOL_GPL(open_related_ns); |
| 121 | 128 | |