All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konstantin Khlebnikov <khlebnikov-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org>
To: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: "Roman Gushchin" <klamm-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org>,
	"Serge Hallyn"
	<serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org>,
	"Oleg Nesterov" <oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	"Eric W. Biederman"
	<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
	"Chen Fan"
	<chen.fan.fnst-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>,
	"Andrew Morton"
	<akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
	"Linus Torvalds"
	<torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>,
	"Stéphane Graber"
	<stgraber-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH RFC v3 1/2] nsfs: replace proc_ns_fget() with proc_ns_fdget()
Date: Fri, 25 Sep 2015 16:52:46 +0300	[thread overview]
Message-ID: <20150925135246.27620.97496.stgit@buzz> (raw)

New helper function returns pointer to struct ns_common, can check
namespace type and uses struct fd for returning file reference:
this saves couple atomic operations for single-threaded applications.

Signed-off-by: Konstantin Khlebnikov <khlebnikov-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org>
---
 fs/nsfs.c                |   20 +++++++++++++-------
 include/linux/proc_ns.h  |    4 +++-
 kernel/nsproxy.c         |   15 +++++----------
 net/core/net_namespace.c |   18 ++++++------------
 4 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/fs/nsfs.c b/fs/nsfs.c
index 8f20d6016e20..a2e803c97960 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -119,21 +119,27 @@ int ns_get_name(char *buf, size_t size, struct task_struct *task,
 	return res;
 }
 
-struct file *proc_ns_fget(int fd)
+struct ns_common *proc_ns_fdget(int fd, int nstype, struct fd *fd_ref)
 {
-	struct file *file;
+	struct ns_common *ns;
+	struct fd f;
 
-	file = fget(fd);
-	if (!file)
+	f = fdget(fd);
+	if (!f.file)
 		return ERR_PTR(-EBADF);
 
-	if (file->f_op != &ns_file_operations)
+	if (f.file->f_op != &ns_file_operations)
+		goto out_invalid;
+
+	ns = get_proc_ns(file_inode(f.file));
+	if (nstype && (ns->ops->type != nstype))
 		goto out_invalid;
 
-	return file;
+	*fd_ref = f;
+	return ns;
 
 out_invalid:
-	fput(file);
+	fdput(f);
 	return ERR_PTR(-EINVAL);
 }
 
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 42dfc615dbf8..406ea4617606 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -9,6 +9,7 @@
 struct pid_namespace;
 struct nsproxy;
 struct path;
+struct fd;
 
 struct proc_ns_operations {
 	const char *name;
@@ -65,7 +66,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 struct ns_common *proc_ns_fdget(int fd, int nstype, struct fd *fd_ref);
+
 #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/nsproxy.c b/kernel/nsproxy.c
index 49746c81ad8d..689b929a0fcb 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -222,18 +222,13 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
 {
 	struct task_struct *tsk = current;
 	struct nsproxy *new_nsproxy;
-	struct file *file;
+	struct fd fd_ref;
 	struct ns_common *ns;
 	int err;
 
-	file = proc_ns_fget(fd);
-	if (IS_ERR(file))
-		return PTR_ERR(file);
-
-	err = -EINVAL;
-	ns = get_proc_ns(file_inode(file));
-	if (nstype && (ns->ops->type != nstype))
-		goto out;
+	ns = proc_ns_fdget(fd, nstype, &fd_ref);
+	if (IS_ERR(ns))
+		return PTR_ERR(ns);
 
 	new_nsproxy = create_new_namespaces(0, tsk, current_user_ns(), tsk->fs);
 	if (IS_ERR(new_nsproxy)) {
@@ -248,7 +243,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
 	}
 	switch_task_namespaces(tsk, new_nsproxy);
 out:
-	fput(file);
+	fdput(fd_ref);
 	return err;
 }
 
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 2c2eb1b629b1..ffc5e6df86dc 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -465,21 +465,15 @@ EXPORT_SYMBOL_GPL(__put_net);
 
 struct net *get_net_ns_by_fd(int fd)
 {
-	struct file *file;
 	struct ns_common *ns;
+	struct fd fd_ref;
 	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);
+	ns = proc_ns_fdget(fd, CLONE_NEWNET, &fd_ref);
+	if (IS_ERR(ns))
+		return ERR_CAST(ns);
+	net = get_net(container_of(ns, struct net, ns));
+	fdput(fd_ref);
 	return net;
 }
 

WARNING: multiple messages have this Message-ID (diff)
From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
To: linux-api@vger.kernel.org, containers@lists.linux-foundation.org,
	linux-kernel@vger.kernel.org
Cc: "Roman Gushchin" <klamm@yandex-team.ru>,
	"Serge Hallyn" <serge.hallyn@ubuntu.com>,
	"Oleg Nesterov" <oleg@redhat.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>,
	"Chen Fan" <chen.fan.fnst@cn.fujitsu.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Linus Torvalds" <torvalds@linux-foundation.org>,
	"Stéphane Graber" <stgraber@ubuntu.com>
Subject: [PATCH RFC v3 1/2] nsfs: replace proc_ns_fget() with proc_ns_fdget()
Date: Fri, 25 Sep 2015 16:52:46 +0300	[thread overview]
Message-ID: <20150925135246.27620.97496.stgit@buzz> (raw)

New helper function returns pointer to struct ns_common, can check
namespace type and uses struct fd for returning file reference:
this saves couple atomic operations for single-threaded applications.

Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
---
 fs/nsfs.c                |   20 +++++++++++++-------
 include/linux/proc_ns.h  |    4 +++-
 kernel/nsproxy.c         |   15 +++++----------
 net/core/net_namespace.c |   18 ++++++------------
 4 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/fs/nsfs.c b/fs/nsfs.c
index 8f20d6016e20..a2e803c97960 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -119,21 +119,27 @@ int ns_get_name(char *buf, size_t size, struct task_struct *task,
 	return res;
 }
 
-struct file *proc_ns_fget(int fd)
+struct ns_common *proc_ns_fdget(int fd, int nstype, struct fd *fd_ref)
 {
-	struct file *file;
+	struct ns_common *ns;
+	struct fd f;
 
-	file = fget(fd);
-	if (!file)
+	f = fdget(fd);
+	if (!f.file)
 		return ERR_PTR(-EBADF);
 
-	if (file->f_op != &ns_file_operations)
+	if (f.file->f_op != &ns_file_operations)
+		goto out_invalid;
+
+	ns = get_proc_ns(file_inode(f.file));
+	if (nstype && (ns->ops->type != nstype))
 		goto out_invalid;
 
-	return file;
+	*fd_ref = f;
+	return ns;
 
 out_invalid:
-	fput(file);
+	fdput(f);
 	return ERR_PTR(-EINVAL);
 }
 
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 42dfc615dbf8..406ea4617606 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -9,6 +9,7 @@
 struct pid_namespace;
 struct nsproxy;
 struct path;
+struct fd;
 
 struct proc_ns_operations {
 	const char *name;
@@ -65,7 +66,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 struct ns_common *proc_ns_fdget(int fd, int nstype, struct fd *fd_ref);
+
 #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/nsproxy.c b/kernel/nsproxy.c
index 49746c81ad8d..689b929a0fcb 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -222,18 +222,13 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
 {
 	struct task_struct *tsk = current;
 	struct nsproxy *new_nsproxy;
-	struct file *file;
+	struct fd fd_ref;
 	struct ns_common *ns;
 	int err;
 
-	file = proc_ns_fget(fd);
-	if (IS_ERR(file))
-		return PTR_ERR(file);
-
-	err = -EINVAL;
-	ns = get_proc_ns(file_inode(file));
-	if (nstype && (ns->ops->type != nstype))
-		goto out;
+	ns = proc_ns_fdget(fd, nstype, &fd_ref);
+	if (IS_ERR(ns))
+		return PTR_ERR(ns);
 
 	new_nsproxy = create_new_namespaces(0, tsk, current_user_ns(), tsk->fs);
 	if (IS_ERR(new_nsproxy)) {
@@ -248,7 +243,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype)
 	}
 	switch_task_namespaces(tsk, new_nsproxy);
 out:
-	fput(file);
+	fdput(fd_ref);
 	return err;
 }
 
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 2c2eb1b629b1..ffc5e6df86dc 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -465,21 +465,15 @@ EXPORT_SYMBOL_GPL(__put_net);
 
 struct net *get_net_ns_by_fd(int fd)
 {
-	struct file *file;
 	struct ns_common *ns;
+	struct fd fd_ref;
 	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);
+	ns = proc_ns_fdget(fd, CLONE_NEWNET, &fd_ref);
+	if (IS_ERR(ns))
+		return ERR_CAST(ns);
+	net = get_net(container_of(ns, struct net, ns));
+	fdput(fd_ref);
 	return net;
 }
 


             reply	other threads:[~2015-09-25 13:52 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-25 13:52 Konstantin Khlebnikov [this message]
2015-09-25 13:52 ` [PATCH RFC v3 1/2] nsfs: replace proc_ns_fget() with proc_ns_fdget() Konstantin Khlebnikov
2015-09-25 13:52 ` [PATCH RFC v3 2/2] pidns: introduce syscall getvpid Konstantin Khlebnikov
2015-09-25 13:52   ` Konstantin Khlebnikov
2015-09-28  4:12   ` kbuild test robot
2015-09-28  4:12     ` kbuild test robot
2015-09-28 16:22   ` Eric W. Biederman
2015-09-28 16:22     ` Eric W. Biederman
2015-09-28 16:57   ` Eric W. Biederman
2015-09-28 16:57     ` Eric W. Biederman
     [not found]     ` <87d1x25vng.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
2015-10-20 10:04       ` Konstantin Khlebnikov
2015-10-20 10:04         ` Konstantin Khlebnikov
2015-10-20 10:04       ` Konstantin Khlebnikov
2015-09-25 17:56 ` [PATCH 0/1] ns: introduce proc_get_ns_by_fd() Oleg Nesterov
2015-09-25 17:56   ` Oleg Nesterov
     [not found]   ` <20150925175654.GA12504-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-09-25 17:57     ` [PATCH 1/1] " Oleg Nesterov
2015-09-25 17:57       ` Oleg Nesterov
2015-09-28  8:21     ` [PATCH 0/1] " Konstantin Khlebnikov
2015-09-28  8:21     ` Konstantin Khlebnikov
2015-09-28  8:21       ` Konstantin Khlebnikov
2015-09-28 16:37     ` Eric W. Biederman
2015-09-28 16:37       ` Eric W. Biederman
     [not found]       ` <871tdi8pqj.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
2015-09-29 16:43         ` Oleg Nesterov
2015-09-29 16:43           ` Oleg Nesterov
     [not found]           ` <20150929164315.GA16734-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-09-29 17:30             ` Eric W. Biederman
2015-09-29 17:30             ` Eric W. Biederman
2015-09-29 17:30               ` Eric W. Biederman
     [not found]               ` <874mid16bk.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
2015-09-29 18:38                 ` Oleg Nesterov
2015-09-29 18:38                 ` Oleg Nesterov
2015-09-29 18:38                   ` Oleg Nesterov
     [not found]                   ` <20150929183833.GA21875-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2015-09-29 19:05                     ` Eric W. Biederman
2015-09-29 19:05                       ` Eric W. Biederman
2015-09-29 16:43         ` Oleg Nesterov
2015-09-30  2:54         ` Chen Fan
2015-09-30  2:54         ` Chen Fan
2015-09-30  2:54           ` Chen Fan
2015-09-28 16:37     ` Eric W. Biederman
  -- strict thread matches above, loose matches on Subject: below --
2015-09-25 13:52 [PATCH RFC v3 1/2] nsfs: replace proc_ns_fget() with proc_ns_fdget() Konstantin Khlebnikov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150925135246.27620.97496.stgit@buzz \
    --to=khlebnikov-xojtrxgx1jsebxzfvpsj4g@public.gmane.org \
    --cc=akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
    --cc=chen.fan.fnst-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org \
    --cc=containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    --cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
    --cc=klamm-XoJtRXgx1JseBXzfvpsJ4g@public.gmane.org \
    --cc=linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=oleg-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=serge.hallyn-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org \
    --cc=stgraber-GeWIH/nMZzLQT0dZR+AlfA@public.gmane.org \
    --cc=torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.