lkml.org 
[lkml]   [2015]   [Sep]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 1/1] ns: introduce proc_get_ns_by_fd()
Introduce proc_get_ns_by_fd() so that get_net_ns_by_fd() becomes
one-liner. It will have another CLONE_NEWPID user soon.

TODO: proc_get_ns_by_fd() can share some code with proc_ns_fget().

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
fs/nsfs.c | 24 ++++++++++++++++++++++++
include/linux/proc_ns.h | 3 +++
kernel/pid_namespace.c | 6 ++++++
net/core/net_namespace.c | 23 +++++++----------------
4 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/fs/nsfs.c b/fs/nsfs.c
index 99521e7..72474ca 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -136,6 +136,30 @@ out_invalid:
return ERR_PTR(-EINVAL);
}

+void *proc_get_ns_by_fd(int fd, int type)
+{
+ struct fd f;
+ struct ns_common *ns;
+ void *ret;
+
+ f = fdget(fd);
+ if (!f.file)
+ return ERR_PTR(-EBADF);
+
+ ret = ERR_PTR(-EINVAL);
+ if (f.file->f_op != &ns_file_operations)
+ goto put;
+
+ ns = get_proc_ns(file_inode(f.file));
+ if (ns->ops->type != type || !ns->ops->get_type)
+ goto put;
+
+ ret = ns->ops->get_type(ns);
+put:
+ fdput(f);
+ return ret;
+}
+
static const struct super_operations nsfs_ops = {
.statfs = simple_statfs,
.evict_inode = nsfs_evict,
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 42dfc61..d956f89 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -16,6 +16,7 @@ struct proc_ns_operations {
struct ns_common *(*get)(struct task_struct *task);
void (*put)(struct ns_common *ns);
int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
+ void *(*get_type)(struct ns_common *ns);
};

extern const struct proc_ns_operations netns_operations;
@@ -66,6 +67,8 @@ static inline int ns_alloc_inum(struct ns_common *ns)
#define ns_free_inum(ns) proc_free_inum((ns)->inum)

extern struct file *proc_ns_fget(int fd);
+extern void *proc_get_ns_by_fd(int fd, int type);
+
#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
extern void *ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index a65ba13..0c87393 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -388,12 +388,18 @@ static int pidns_install(struct nsproxy *nsproxy, struct ns_common *ns)
return 0;
}

+static void *pidns_get_type(struct ns_common *ns)
+{
+ return get_pid_ns(to_pid_ns(ns));
+}
+
const struct proc_ns_operations pidns_operations = {
.name = "pid",
.type = CLONE_NEWPID,
.get = pidns_get,
.put = pidns_put,
.install = pidns_install,
+ .get_type = pidns_get_type,
};

static __init int pid_namespaces_init(void)
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 572af00..6465dc0 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -420,22 +420,7 @@ EXPORT_SYMBOL_GPL(__put_net);

struct net *get_net_ns_by_fd(int fd)
{
- struct file *file;
- struct ns_common *ns;
- struct net *net;
-
- file = proc_ns_fget(fd);
- if (IS_ERR(file))
- return ERR_CAST(file);
-
- ns = get_proc_ns(file_inode(file));
- if (ns->ops == &netns_operations)
- net = get_net(container_of(ns, struct net, ns));
- else
- net = ERR_PTR(-EINVAL);
-
- fput(file);
- return net;
+ return proc_get_ns_by_fd(fd, CLONE_NEWNET);
}

#else
@@ -955,11 +940,17 @@ static int netns_install(struct nsproxy *nsproxy, struct ns_common *ns)
return 0;
}

+static void *netns_get_type(struct ns_common *ns)
+{
+ return get_net(to_net_ns(ns));
+}
+
const struct proc_ns_operations netns_operations = {
.name = "net",
.type = CLONE_NEWNET,
.get = netns_get,
.put = netns_put,
.install = netns_install,
+ .get_type = netns_get_type,
};
#endif
--
1.5.5.1



\
 
 \ /
  Last update: 2015-09-25 20:21    [W:0.113 / U:0.448 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site