[Devel] [PATCH RHEL7 COMMIT] make proc_ns_operations work with struct ns_common * instead of void *

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jun 11 19:20:02 MSK 2020


The commit is pushed to "branch-rh7-3.10.0-1127.10.1.vz7.162.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1127.10.1.vz7.162.2
------>
commit 16f3745fe2f317ee056e48696720ef652b14e8ad
Author: Al Viro <viro at zeniv.linux.org.uk>
Date:   Thu Jun 11 19:20:02 2020 +0300

    make proc_ns_operations work with struct ns_common * instead of void *
    
    We can do that now.  And kill ->inum(), while we are at it - all instances
    are identical.
    
    Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
    
    (cherry picked from VZ8 commit 64964528b24ea390824f0e5ce9d34b8d39b28cde)
    
    https://jira.sw.ru/browse/PSBM-102357
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
    
    =====================
    Patchset description:
    port nsfs from vz8
    
    We have problems with /proc/pid/ns/name bind-mounts in CRIU
    
    1) Currently (without nsfs) such a bind mount have same superblock with
    /proc mount, but in case of nested pid-namespaces container can have
    multiple different /proc mounts and for ns-bind-mount we need to bind it
    from the right pidns. So we will need to enter proper pid-namespace to
    reopen ns-file fd from proper proc, it looks too complex.
    
    If we port nsfs ns-bind-mounts will be all on the same superblock which
    does not depend from procfs's we opened the ns-file on.
    
    2) Bigger problem will come then we will wan't to migrate ns-bind-mounts
    from non-nsfs to nsfs (vz8) kernel this would bring a lot of crutches,
    we will need to workaround the fact that before migration mounts were
    with same superblock and after migration they can't be.
    
    To overcome those we can port nsfs to vz7 and do ns-bind-mount support in
    a new world of nsfs, looks like it would be easier.
    
    First we need to revert all patches which depend from nsfs:
    
    8782a0069f1b proc: add a proc_show_path method to fix mountinfo
    b823f8df2fcb ms/tun: Add ioctl() TUNGETDEVNETNS cmd to allow obtaining real net ns of tun device
    302889fa2e3d ms/net: add an ioctl to get a socket network namespace
    7cb9e7ae7041 ms/tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of tun device
    ac08c64138ac nsfs: add ioctl to get a parent namespace
    a8e0dd94d5cd nsfs: add ioctl to get an owning user namespace for ns file descriptor
    93dca538d184 kernel: add a helper to get an owning user namespace for a namespace
    edaecdb8adac ms/pidns: expose task pid_ns_for_children to userspace
    2b151c3f8909 ms/ns: allow ns_entries to have custom symlink content
    
    Cherry-pick nsfs from VZ8:
    
    435d5f4bb2cc common object embedded into various struct ....ns
    58be28256d98 make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
    ff24870f46d5 netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
    3c0411846118 switch the rest of proc_ns_operations to working with &...->ns
    64964528b24e make proc_ns_operations work with struct ns_common * instead of void *
    6344c433a452 new helpers: ns_alloc_inum/ns_free_inum
    33c429405a2c copy address of proc_ns_ops into ns_common
    f77c80142e1a bury struct proc_ns in fs/proc
    292662014509 dcache.c: call ->d_prune() regardless of d_unhashed()
    e149ed2b805f take the targets of /proc/*/ns/* symlinks to separate fs
    
    Cherry-pick part of reverted patches back from VZ8:
    
    bcac25a58bfc kernel: add a helper to get an owning user namespace for a namespace
    6786741dbf99 nsfs: add ioctl to get an owning user namespace for ns file descriptor
    a7306ed8d94a nsfs: add ioctl to get a parent namespace
    c62cce2caee5 net: add an ioctl to get a socket network namespace
    25b14e92af1a ns: allow ns_entries to have custom symlink content
    eaa0d190bfe1 pidns: expose task pid_ns_for_children to userspace
    
    Cherry-pick reverted patches back from MS (we also need them to vz8):
    
    75509fd88fbd nsfs: Add a show_path method to fix mountinfo
    24dce0800baa net: Export open_related_ns()
    d8d211a2a0c3 net: Make extern and export get_net_ns()
    f2780d6d7475 tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of tun device
    0c3e0e3bb623 tun: Add ioctl() TUNGETDEVNETNS cmd to allow obtaining real net ns of tun device
    073c516ff735 nsfs: mark dentry with DCACHE_RCUACCESS
    
    On this kernel I've runed zdtm, so the change should not break interfaces.
    
    https://jira.sw.ru/browse/PSBM-102357
    
    Al Viro (10):
      ms: common object embedded into various struct ....ns
      make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
      netns: switch ->get()/->put()/->install()/->inum() to working with
        &net->ns
      switch the rest of proc_ns_operations to working with &...->ns
      make proc_ns_operations work with struct ns_common * instead of void *
      new helpers: ns_alloc_inum/ns_free_inum
      copy address of proc_ns_ops into ns_common
      bury struct proc_ns in fs/proc
      dcache.c: call ->d_prune() regardless of d_unhashed()
      take the targets of /proc/*/ns/* symlinks to separate fs
    
    Andrey Vagin (4):
      kernel: add a helper to get an owning user namespace for a namespace
      nsfs: add ioctl to get an owning user namespace for ns file descriptor
      nsfs: add ioctl to get a parent namespace
      net: add an ioctl to get a socket network namespace
    
    Cong Wang (1):
      nsfs: mark dentry with DCACHE_RCUACCESS
    
    Eric W. Biederman (1):
      nsfs: Add a show_path method to fix mountinfo
    
    Kirill Tkhai (6):
      ns: allow ns_entries to have custom symlink content
      pidns: expose task pid_ns_for_children to userspace
      net: Export open_related_ns()
      net: Make extern and export get_net_ns()
      tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of tun device
      tun: Add ioctl() TUNGETDEVNETNS cmd to allow obtaining real net ns of
        tun device
    
    Pavel Tikhomirov (10):
      Revert "proc: add a proc_show_path method to fix mountinfo"
      Revert "ms/tun: Add ioctl() TUNGETDEVNETNS cmd to allow obtaining real
        net ns of tun device"
      Revert "ms/net: add an ioctl to get a socket network namespace"
      Revert "ms/tun: Add ioctl() SIOCGSKNS cmd to allow obtaining net ns of
        tun device"
      Revert "nsfs: add ioctl to get a parent namespace"
      Revert "nsfs: add ioctl to get an owning user namespace for ns file
        descriptor"
      Revert "kernel: add a helper to get an owning user namespace for a
        namespace"
      Revert "ms/pidns: expose task pid_ns_for_children to userspace"
      Revert "ms/ns: allow ns_entries to have custom symlink content"
      userns: move EXPORT_SYMBOL closer to current_in_userns
---
 fs/namespace.c           | 13 +++----------
 fs/proc/inode.c          |  2 +-
 fs/proc/namespaces.c     |  8 ++++----
 include/linux/proc_ns.h  | 10 +++++-----
 ipc/namespace.c          | 12 +++---------
 kernel/pid_namespace.c   | 12 +++---------
 kernel/user_namespace.c  | 12 +++---------
 kernel/utsname.c         | 12 +++---------
 net/core/net_namespace.c | 12 +++---------
 9 files changed, 28 insertions(+), 65 deletions(-)

diff --git a/fs/namespace.c b/fs/namespace.c
index f137ac232d4e2..bd1bfa481f574 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3853,7 +3853,7 @@ bool mnt_may_suid(struct vfsmount *mnt)
 	       current_in_userns(mnt->mnt_sb->s_user_ns);
 }
 
-static void *mntns_get(struct task_struct *task)
+static struct ns_common *mntns_get(struct task_struct *task)
 {
 	struct ns_common *ns = NULL;
 	struct nsproxy *nsproxy;
@@ -3869,12 +3869,12 @@ static void *mntns_get(struct task_struct *task)
 	return ns;
 }
 
-static void mntns_put(void *ns)
+static void mntns_put(struct ns_common *ns)
 {
 	put_mnt_ns(to_mnt_ns(ns));
 }
 
-static int mntns_install(struct nsproxy *nsproxy, void *ns)
+static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns)
 {
 	struct fs_struct *fs = current->fs;
 	struct mnt_namespace *mnt_ns = to_mnt_ns(ns), *old_mnt_ns;
@@ -3913,17 +3913,10 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns)
 	return 0;
 }
 
-static unsigned int mntns_inum(void *ns)
-{
-	struct ns_common *p = ns;
-	return p->inum;
-}
-
 const struct proc_ns_operations mntns_operations = {
 	.name		= "mnt",
 	.type		= CLONE_NEWNS,
 	.get		= mntns_get,
 	.put		= mntns_put,
 	.install	= mntns_install,
-	.inum		= mntns_inum,
 };
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 4eef2b46b87e8..8b0445574fe78 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -33,7 +33,7 @@ static void proc_evict_inode(struct inode *inode)
 	struct proc_dir_entry *de;
 	struct ctl_table_header *head;
 	const struct proc_ns_operations *ns_ops;
-	void *ns;
+	struct ns_common *ns;
 
 	truncate_inode_pages_final(&inode->i_data);
 	clear_inode(inode);
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c
index 86aff3a43db21..2d53aea1a691f 100644
--- a/fs/proc/namespaces.c
+++ b/fs/proc/namespaces.c
@@ -70,7 +70,7 @@ static struct dentry *proc_ns_get_dentry(struct super_block *sb,
 	struct inode *inode;
 	struct proc_inode *ei;
 	struct qstr qname = { .name = "", };
-	void *ns;
+	struct ns_common *ns;
 
 	ns = ns_ops->get(task);
 	if (!ns)
@@ -82,7 +82,7 @@ static struct dentry *proc_ns_get_dentry(struct super_block *sb,
 		return ERR_PTR(-ENOMEM);
 	}
 
-	inode = iget_locked(sb, ns_ops->inum(ns));
+	inode = iget_locked(sb, ns->inum);
 	if (!inode) {
 		dput(dentry);
 		ns_ops->put(ns);
@@ -150,7 +150,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
 	struct proc_inode *ei = PROC_I(inode);
 	const struct proc_ns_operations *ns_ops = ei->ns.ns_ops;
 	struct task_struct *task;
-	void *ns;
+	struct ns_common *ns;
 	char name[50];
 	int len = -EACCES;
 
@@ -166,7 +166,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
 	if (!ns)
 		goto out_put_task;
 
-	snprintf(name, sizeof(name), "%s:[%u]", ns_ops->name, ns_ops->inum(ns));
+	snprintf(name, sizeof(name), "%s:[%u]", ns_ops->name, ns->inum);
 	len = strlen(name);
 
 	if (len > buflen)
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index 5478e144c50ab..3bd0aab958775 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -7,18 +7,18 @@
 struct super_block;
 struct pid_namespace;
 struct nsproxy;
+struct ns_common;
 
 struct proc_ns_operations {
 	const char *name;
 	int type;
-	void *(*get)(struct task_struct *task);
-	void (*put)(void *ns);
-	int (*install)(struct nsproxy *nsproxy, void *ns);
-	unsigned int (*inum)(void *ns);
+	struct ns_common *(*get)(struct task_struct *task);
+	void (*put)(struct ns_common *ns);
+	int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
 };
 
 struct proc_ns {
-	void *ns;
+	struct ns_common *ns;
 	const struct proc_ns_operations *ns_ops;
 };
 
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 6781d622549ec..84545678707e8 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -156,7 +156,7 @@ static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns)
 	return container_of(ns, struct ipc_namespace, ns);
 }
 
-static void *ipcns_get(struct task_struct *task)
+static struct ns_common *ipcns_get(struct task_struct *task)
 {
 	struct ipc_namespace *ns = NULL;
 	struct nsproxy *nsproxy;
@@ -170,12 +170,12 @@ static void *ipcns_get(struct task_struct *task)
 	return ns ? &ns->ns : NULL;
 }
 
-static void ipcns_put(void *ns)
+static void ipcns_put(struct ns_common *ns)
 {
 	return put_ipc_ns(to_ipc_ns(ns));
 }
 
-static int ipcns_install(struct nsproxy *nsproxy, void *new)
+static int ipcns_install(struct nsproxy *nsproxy, struct ns_common *new)
 {
 	struct ipc_namespace *ns = to_ipc_ns(new);
 	if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
@@ -189,16 +189,10 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new)
 	return 0;
 }
 
-static unsigned int ipcns_inum(void *vp)
-{
-	return ((struct ns_common *)vp)->inum;
-}
-
 const struct proc_ns_operations ipcns_operations = {
 	.name		= "ipc",
 	.type		= CLONE_NEWIPC,
 	.get		= ipcns_get,
 	.put		= ipcns_put,
 	.install	= ipcns_install,
-	.inum		= ipcns_inum,
 };
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index 2c478203cba37..29c9d06cf8fb7 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -347,7 +347,7 @@ static inline struct pid_namespace *to_pid_ns(struct ns_common *ns)
 	return container_of(ns, struct pid_namespace, ns);
 }
 
-static void *pidns_get(struct task_struct *task)
+static struct ns_common *pidns_get(struct task_struct *task)
 {
 	struct pid_namespace *ns;
 
@@ -360,12 +360,12 @@ static void *pidns_get(struct task_struct *task)
 	return ns ? &ns->ns : NULL;
 }
 
-static void pidns_put(void *ns)
+static void pidns_put(struct ns_common *ns)
 {
 	put_pid_ns(to_pid_ns(ns));
 }
 
-static int pidns_install(struct nsproxy *nsproxy, void *ns)
+static int pidns_install(struct nsproxy *nsproxy, struct ns_common *ns)
 {
 	struct pid_namespace *active = task_active_pid_ns(current);
 	struct pid_namespace *ancestor, *new = to_pid_ns(ns);
@@ -396,18 +396,12 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns)
 	return 0;
 }
 
-static unsigned int pidns_inum(void *ns)
-{
-	return ((struct ns_common *)ns)->inum;
-}
-
 const struct proc_ns_operations pidns_operations = {
 	.name		= "pid",
 	.type		= CLONE_NEWPID,
 	.get		= pidns_get,
 	.put		= pidns_put,
 	.install	= pidns_install,
-	.inum		= pidns_inum,
 };
 
 static __init int pid_namespaces_init(void)
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index c39871e61559d..af9ff26c72b49 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -1031,7 +1031,7 @@ static inline struct user_namespace *to_user_ns(struct ns_common *ns)
 	return container_of(ns, struct user_namespace, ns);
 }
 
-static void *userns_get(struct task_struct *task)
+static struct ns_common *userns_get(struct task_struct *task)
 {
 	struct user_namespace *user_ns;
 
@@ -1042,12 +1042,12 @@ static void *userns_get(struct task_struct *task)
 	return user_ns ? &user_ns->ns : NULL;
 }
 
-static void userns_put(void *ns)
+static void userns_put(struct ns_common *ns)
 {
 	put_user_ns(to_user_ns(ns));
 }
 
-static int userns_install(struct nsproxy *nsproxy, void *ns)
+static int userns_install(struct nsproxy *nsproxy, struct ns_common *ns)
 {
 	struct user_namespace *user_ns = to_user_ns(ns);
 	struct cred *cred;
@@ -1078,18 +1078,12 @@ static int userns_install(struct nsproxy *nsproxy, void *ns)
 	return commit_creds(cred);
 }
 
-static unsigned int userns_inum(void *ns)
-{
-	return ((struct ns_common *)ns)->inum;
-}
-
 const struct proc_ns_operations userns_operations = {
 	.name		= "user",
 	.type		= CLONE_NEWUSER,
 	.get		= userns_get,
 	.put		= userns_put,
 	.install	= userns_install,
-	.inum		= userns_inum,
 };
 
 static __init int user_namespaces_init(void)
diff --git a/kernel/utsname.c b/kernel/utsname.c
index d8c062d2ab289..4247306327fa1 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -147,7 +147,7 @@ static inline struct uts_namespace *to_uts_ns(struct ns_common *ns)
 	return container_of(ns, struct uts_namespace, ns);
 }
 
-static void *utsns_get(struct task_struct *task)
+static struct ns_common *utsns_get(struct task_struct *task)
 {
 	struct uts_namespace *ns = NULL;
 	struct nsproxy *nsproxy;
@@ -163,12 +163,12 @@ static void *utsns_get(struct task_struct *task)
 	return ns ? &ns->ns : NULL;
 }
 
-static void utsns_put(void *ns)
+static void utsns_put(struct ns_common *ns)
 {
 	put_uts_ns(to_uts_ns(ns));
 }
 
-static int utsns_install(struct nsproxy *nsproxy, void *new)
+static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new)
 {
 	struct uts_namespace *ns = to_uts_ns(new);
 
@@ -182,16 +182,10 @@ static int utsns_install(struct nsproxy *nsproxy, void *new)
 	return 0;
 }
 
-static unsigned int utsns_inum(void *vp)
-{
-	return ((struct ns_common *)vp)->inum;
-}
-
 const struct proc_ns_operations utsns_operations = {
 	.name		= "uts",
 	.type		= CLONE_NEWUTS,
 	.get		= utsns_get,
 	.put		= utsns_put,
 	.install	= utsns_install,
-	.inum		= utsns_inum,
 };
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 2a1413dd92a08..9564d242f941d 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -1050,7 +1050,7 @@ void unregister_pernet_device(struct pernet_operations *ops)
 EXPORT_SYMBOL_GPL(unregister_pernet_device);
 
 #ifdef CONFIG_NET_NS
-static void *netns_get(struct task_struct *task)
+static struct ns_common *netns_get(struct task_struct *task)
 {
 	struct net *net = NULL;
 	struct nsproxy *nsproxy;
@@ -1069,12 +1069,12 @@ static inline struct net *to_net_ns(struct ns_common *ns)
 	return container_of(ns, struct net, ns);
 }
 
-static void netns_put(void *ns)
+static void netns_put(struct ns_common *ns)
 {
 	put_net(to_net_ns(ns));
 }
 
-static int netns_install(struct nsproxy *nsproxy, void *ns)
+static int netns_install(struct nsproxy *nsproxy, struct ns_common *ns)
 {
 	struct net *net = to_net_ns(ns);
 
@@ -1087,17 +1087,11 @@ static int netns_install(struct nsproxy *nsproxy, void *ns)
 	return 0;
 }
 
-static unsigned int netns_inum(void *ns)
-{
-	return ((struct ns_common *)ns)->inum;
-}
-
 const struct proc_ns_operations netns_operations = {
 	.name		= "net",
 	.type		= CLONE_NEWNET,
 	.get		= netns_get,
 	.put		= netns_put,
 	.install	= netns_install,
-	.inum		= netns_inum,
 };
 #endif


More information about the Devel mailing list