Commit 603ba7e41bf5d405aba22294af5d075d8898176d

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs pile #2 from Al Viro:
 "Next pile (and there'll be one or two more).

  The large piece in this one is getting rid of /proc/*/ns/* weirdness;
  among other things, it allows to (finally) make nameidata completely
  opaque outside of fs/namei.c, making for easier further cleanups in
  there"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  coda_venus_readdir(): use file_inode()
  fs/namei.c: fold link_path_walk() call into path_init()
  path_init(): don't bother with LOOKUP_PARENT in argument
  fs/namei.c: new helper (path_cleanup())
  path_init(): store the "base" pointer to file in nameidata itself
  make default ->i_fop have ->open() fail with ENXIO
  make nameidata completely opaque outside of fs/namei.c
  kill proc_ns completely
  take the targets of /proc/*/ns/* symlinks to separate fs
  bury struct proc_ns in fs/proc
  copy address of proc_ns_ops into ns_common
  new helpers: ns_alloc_inum/ns_free_inum
  make proc_ns_operations work with struct ns_common * instead of void *
  switch the rest of proc_ns_operations to working with &...->ns
  netns: switch ->get()/->put()/->install()/->inum() to working with &net->ns
  make mntns ->get()/->put()/->install()/->inum() work with &mnt_ns->ns
  common object embedded into various struct ....ns

Showing 36 changed files Side-by-side Diff

arch/ia64/kernel/perfmon.c
... ... @@ -2145,22 +2145,12 @@
2145 2145 return 0;
2146 2146 }
2147 2147  
2148   -static int
2149   -pfm_no_open(struct inode *irrelevant, struct file *dontcare)
2150   -{
2151   - DPRINT(("pfm_no_open called\n"));
2152   - return -ENXIO;
2153   -}
2154   -
2155   -
2156   -
2157 2148 static const struct file_operations pfm_file_ops = {
2158 2149 .llseek = no_llseek,
2159 2150 .read = pfm_read,
2160 2151 .write = pfm_write,
2161 2152 .poll = pfm_poll,
2162 2153 .unlocked_ioctl = pfm_ioctl,
2163   - .open = pfm_no_open, /* special open code to disallow open via /proc */
2164 2154 .fasync = pfm_fasync,
2165 2155 .release = pfm_close,
2166 2156 .flush = pfm_flush
... ... @@ -11,7 +11,7 @@
11 11 attr.o bad_inode.o file.o filesystems.o namespace.o \
12 12 seq_file.o xattr.o libfs.o fs-writeback.o \
13 13 pnode.o splice.o sync.o utimes.o \
14   - stack.o fs_struct.o statfs.o fs_pin.o
  14 + stack.o fs_struct.o statfs.o fs_pin.o nsfs.o
15 15  
16 16 ifeq ($(CONFIG_BLOCK),y)
17 17 obj-y += buffer.o block_dev.o direct-io.o mpage.o
... ... @@ -426,7 +426,6 @@
426 426 struct coda_file_info *cfi;
427 427 struct coda_inode_info *cii;
428 428 struct file *host_file;
429   - struct dentry *de;
430 429 struct venus_dirent *vdir;
431 430 unsigned long vdir_size = offsetof(struct venus_dirent, d_name);
432 431 unsigned int type;
... ... @@ -438,8 +437,7 @@
438 437 BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
439 438 host_file = cfi->cfi_container;
440 439  
441   - de = coda_file->f_path.dentry;
442   - cii = ITOC(de->d_inode);
  440 + cii = ITOC(file_inode(coda_file));
443 441  
444 442 vdir = kmalloc(sizeof(*vdir), GFP_KERNEL);
445 443 if (!vdir) return -ENOMEM;
... ... @@ -114,6 +114,11 @@
114 114 }
115 115 #endif
116 116  
  117 +static int no_open(struct inode *inode, struct file *file)
  118 +{
  119 + return -ENXIO;
  120 +}
  121 +
117 122 /**
118 123 * inode_init_always - perform inode structure intialisation
119 124 * @sb: superblock inode belongs to
... ... @@ -125,7 +130,7 @@
125 130 int inode_init_always(struct super_block *sb, struct inode *inode)
126 131 {
127 132 static const struct inode_operations empty_iops;
128   - static const struct file_operations empty_fops;
  133 + static const struct file_operations no_open_fops = {.open = no_open};
129 134 struct address_space *const mapping = &inode->i_data;
130 135  
131 136 inode->i_sb = sb;
... ... @@ -133,7 +138,7 @@
133 138 inode->i_flags = 0;
134 139 atomic_set(&inode->i_count, 1);
135 140 inode->i_op = &empty_iops;
136   - inode->i_fop = &empty_fops;
  141 + inode->i_fop = &no_open_fops;
137 142 inode->__i_nlink = 1;
138 143 inode->i_opflags = 0;
139 144 i_uid_write(inode, 0);
... ... @@ -1798,7 +1803,7 @@
1798 1803 } else if (S_ISFIFO(mode))
1799 1804 inode->i_fop = &pipefifo_fops;
1800 1805 else if (S_ISSOCK(mode))
1801   - inode->i_fop = &bad_sock_fops;
  1806 + ; /* leave it no_open_fops */
1802 1807 else
1803 1808 printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for"
1804 1809 " inode %s:%lu\n", mode, inode->i_sb->s_id,
... ... @@ -147,4 +147,9 @@
147 147 */
148 148 extern void sb_pin_kill(struct super_block *sb);
149 149 extern void mnt_pin_kill(struct mount *m);
  150 +
  151 +/*
  152 + * fs/nsfs.c
  153 + */
  154 +extern struct dentry_operations ns_dentry_operations;
1 1 #include <linux/mount.h>
2 2 #include <linux/seq_file.h>
3 3 #include <linux/poll.h>
  4 +#include <linux/ns_common.h>
4 5  
5 6 struct mnt_namespace {
6 7 atomic_t count;
7   - unsigned int proc_inum;
  8 + struct ns_common ns;
8 9 struct mount * root;
9 10 struct list_head list;
10 11 struct user_namespace *user_ns;
... ... @@ -487,6 +487,19 @@
487 487 }
488 488 EXPORT_SYMBOL(path_put);
489 489  
  490 +struct nameidata {
  491 + struct path path;
  492 + struct qstr last;
  493 + struct path root;
  494 + struct inode *inode; /* path.dentry.d_inode */
  495 + unsigned int flags;
  496 + unsigned seq, m_seq;
  497 + int last_type;
  498 + unsigned depth;
  499 + struct file *base;
  500 + char *saved_names[MAX_NESTED_LINKS + 1];
  501 +};
  502 +
490 503 /*
491 504 * Path walking has 2 modes, rcu-walk and ref-walk (see
492 505 * Documentation/filesystems/path-lookup.txt). In situations when we can't
... ... @@ -695,6 +708,18 @@
695 708 nd->flags |= LOOKUP_JUMPED;
696 709 }
697 710  
  711 +void nd_set_link(struct nameidata *nd, char *path)
  712 +{
  713 + nd->saved_names[nd->depth] = path;
  714 +}
  715 +EXPORT_SYMBOL(nd_set_link);
  716 +
  717 +char *nd_get_link(struct nameidata *nd)
  718 +{
  719 + return nd->saved_names[nd->depth];
  720 +}
  721 +EXPORT_SYMBOL(nd_get_link);
  722 +
698 723 static inline void put_link(struct nameidata *nd, struct path *link, void *cookie)
699 724 {
700 725 struct inode *inode = link->dentry->d_inode;
701 726  
702 727  
... ... @@ -1821,13 +1846,14 @@
1821 1846 }
1822 1847  
1823 1848 static int path_init(int dfd, const char *name, unsigned int flags,
1824   - struct nameidata *nd, struct file **fp)
  1849 + struct nameidata *nd)
1825 1850 {
1826 1851 int retval = 0;
1827 1852  
1828 1853 nd->last_type = LAST_ROOT; /* if there are only slashes... */
1829   - nd->flags = flags | LOOKUP_JUMPED;
  1854 + nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT;
1830 1855 nd->depth = 0;
  1856 + nd->base = NULL;
1831 1857 if (flags & LOOKUP_ROOT) {
1832 1858 struct dentry *root = nd->root.dentry;
1833 1859 struct inode *inode = root->d_inode;
... ... @@ -1847,7 +1873,7 @@
1847 1873 } else {
1848 1874 path_get(&nd->path);
1849 1875 }
1850   - return 0;
  1876 + goto done;
1851 1877 }
1852 1878  
1853 1879 nd->root.mnt = NULL;
... ... @@ -1897,7 +1923,7 @@
1897 1923 nd->path = f.file->f_path;
1898 1924 if (flags & LOOKUP_RCU) {
1899 1925 if (f.flags & FDPUT_FPUT)
1900   - *fp = f.file;
  1926 + nd->base = f.file;
1901 1927 nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
1902 1928 rcu_read_lock();
1903 1929 } else {
1904 1930  
1905 1931  
1906 1932  
... ... @@ -1908,15 +1934,28 @@
1908 1934  
1909 1935 nd->inode = nd->path.dentry->d_inode;
1910 1936 if (!(flags & LOOKUP_RCU))
1911   - return 0;
  1937 + goto done;
1912 1938 if (likely(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)))
1913   - return 0;
  1939 + goto done;
1914 1940 if (!(nd->flags & LOOKUP_ROOT))
1915 1941 nd->root.mnt = NULL;
1916 1942 rcu_read_unlock();
1917 1943 return -ECHILD;
  1944 +done:
  1945 + current->total_link_count = 0;
  1946 + return link_path_walk(name, nd);
1918 1947 }
1919 1948  
  1949 +static void path_cleanup(struct nameidata *nd)
  1950 +{
  1951 + if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
  1952 + path_put(&nd->root);
  1953 + nd->root.mnt = NULL;
  1954 + }
  1955 + if (unlikely(nd->base))
  1956 + fput(nd->base);
  1957 +}
  1958 +
1920 1959 static inline int lookup_last(struct nameidata *nd, struct path *path)
1921 1960 {
1922 1961 if (nd->last_type == LAST_NORM && nd->last.name[nd->last.len])
... ... @@ -1930,7 +1969,6 @@
1930 1969 static int path_lookupat(int dfd, const char *name,
1931 1970 unsigned int flags, struct nameidata *nd)
1932 1971 {
1933   - struct file *base = NULL;
1934 1972 struct path path;
1935 1973 int err;
1936 1974  
... ... @@ -1948,14 +1986,7 @@
1948 1986 * be handled by restarting a traditional ref-walk (which will always
1949 1987 * be able to complete).
1950 1988 */
1951   - err = path_init(dfd, name, flags | LOOKUP_PARENT, nd, &base);
1952   -
1953   - if (unlikely(err))
1954   - goto out;
1955   -
1956   - current->total_link_count = 0;
1957   - err = link_path_walk(name, nd);
1958   -
  1989 + err = path_init(dfd, name, flags, nd);
1959 1990 if (!err && !(flags & LOOKUP_PARENT)) {
1960 1991 err = lookup_last(nd, &path);
1961 1992 while (err > 0) {
... ... @@ -1983,14 +2014,7 @@
1983 2014 }
1984 2015 }
1985 2016  
1986   -out:
1987   - if (base)
1988   - fput(base);
1989   -
1990   - if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) {
1991   - path_put(&nd->root);
1992   - nd->root.mnt = NULL;
1993   - }
  2017 + path_cleanup(nd);
1994 2018 return err;
1995 2019 }
1996 2020  
1997 2021  
1998 2022  
... ... @@ -2297,19 +2321,13 @@
2297 2321 static int
2298 2322 path_mountpoint(int dfd, const char *name, struct path *path, unsigned int flags)
2299 2323 {
2300   - struct file *base = NULL;
2301 2324 struct nameidata nd;
2302 2325 int err;
2303 2326  
2304   - err = path_init(dfd, name, flags | LOOKUP_PARENT, &nd, &base);
  2327 + err = path_init(dfd, name, flags, &nd);
2305 2328 if (unlikely(err))
2306 2329 goto out;
2307 2330  
2308   - current->total_link_count = 0;
2309   - err = link_path_walk(name, &nd);
2310   - if (err)
2311   - goto out;
2312   -
2313 2331 err = mountpoint_last(&nd, path);
2314 2332 while (err > 0) {
2315 2333 void *cookie;
... ... @@ -2325,12 +2343,7 @@
2325 2343 put_link(&nd, &link, cookie);
2326 2344 }
2327 2345 out:
2328   - if (base)
2329   - fput(base);
2330   -
2331   - if (nd.root.mnt && !(nd.flags & LOOKUP_ROOT))
2332   - path_put(&nd.root);
2333   -
  2346 + path_cleanup(&nd);
2334 2347 return err;
2335 2348 }
2336 2349  
... ... @@ -3181,7 +3194,6 @@
3181 3194 static struct file *path_openat(int dfd, struct filename *pathname,
3182 3195 struct nameidata *nd, const struct open_flags *op, int flags)
3183 3196 {
3184   - struct file *base = NULL;
3185 3197 struct file *file;
3186 3198 struct path path;
3187 3199 int opened = 0;
3188 3200  
... ... @@ -3198,15 +3210,10 @@
3198 3210 goto out;
3199 3211 }
3200 3212  
3201   - error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base);
  3213 + error = path_init(dfd, pathname->name, flags, nd);
3202 3214 if (unlikely(error))
3203 3215 goto out;
3204 3216  
3205   - current->total_link_count = 0;
3206   - error = link_path_walk(pathname->name, nd);
3207   - if (unlikely(error))
3208   - goto out;
3209   -
3210 3217 error = do_last(nd, &path, file, op, &opened, pathname);
3211 3218 while (unlikely(error > 0)) { /* trailing symlink */
3212 3219 struct path link = path;
... ... @@ -3229,10 +3236,7 @@
3229 3236 put_link(nd, &link, cookie);
3230 3237 }
3231 3238 out:
3232   - if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT))
3233   - path_put(&nd->root);
3234   - if (base)
3235   - fput(base);
  3239 + path_cleanup(nd);
3236 3240 if (!(opened & FILE_OPENED)) {
3237 3241 BUG_ON(!error);
3238 3242 put_filp(file);
... ... @@ -1569,17 +1569,13 @@
1569 1569 static bool is_mnt_ns_file(struct dentry *dentry)
1570 1570 {
1571 1571 /* Is this a proxy for a mount namespace? */
1572   - struct inode *inode = dentry->d_inode;
1573   - struct proc_ns *ei;
  1572 + return dentry->d_op == &ns_dentry_operations &&
  1573 + dentry->d_fsdata == &mntns_operations;
  1574 +}
1574 1575  
1575   - if (!proc_ns_inode(inode))
1576   - return false;
1577   -
1578   - ei = get_proc_ns(inode);
1579   - if (ei->ns_ops != &mntns_operations)
1580   - return false;
1581   -
1582   - return true;
  1576 +struct mnt_namespace *to_mnt_ns(struct ns_common *ns)
  1577 +{
  1578 + return container_of(ns, struct mnt_namespace, ns);
1583 1579 }
1584 1580  
1585 1581 static bool mnt_ns_loop(struct dentry *dentry)
... ... @@ -1591,7 +1587,7 @@
1591 1587 if (!is_mnt_ns_file(dentry))
1592 1588 return false;
1593 1589  
1594   - mnt_ns = get_proc_ns(dentry->d_inode)->ns;
  1590 + mnt_ns = to_mnt_ns(get_proc_ns(dentry->d_inode));
1595 1591 return current->nsproxy->mnt_ns->seq >= mnt_ns->seq;
1596 1592 }
1597 1593  
1598 1594  
... ... @@ -2020,9 +2016,12 @@
2020 2016 if (IS_MNT_UNBINDABLE(old))
2021 2017 goto out2;
2022 2018  
2023   - if (!check_mnt(parent) || !check_mnt(old))
  2019 + if (!check_mnt(parent))
2024 2020 goto out2;
2025 2021  
  2022 + if (!check_mnt(old) && old_path.dentry->d_op != &ns_dentry_operations)
  2023 + goto out2;
  2024 +
2026 2025 if (!recurse && has_locked_children(old, old_path.dentry))
2027 2026 goto out2;
2028 2027  
... ... @@ -2640,7 +2639,7 @@
2640 2639  
2641 2640 static void free_mnt_ns(struct mnt_namespace *ns)
2642 2641 {
2643   - proc_free_inum(ns->proc_inum);
  2642 + ns_free_inum(&ns->ns);
2644 2643 put_user_ns(ns->user_ns);
2645 2644 kfree(ns);
2646 2645 }
2647 2646  
... ... @@ -2662,11 +2661,12 @@
2662 2661 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
2663 2662 if (!new_ns)
2664 2663 return ERR_PTR(-ENOMEM);
2665   - ret = proc_alloc_inum(&new_ns->proc_inum);
  2664 + ret = ns_alloc_inum(&new_ns->ns);
2666 2665 if (ret) {
2667 2666 kfree(new_ns);
2668 2667 return ERR_PTR(ret);
2669 2668 }
  2669 + new_ns->ns.ops = &mntns_operations;
2670 2670 new_ns->seq = atomic64_add_return(1, &mnt_ns_seq);
2671 2671 atomic_set(&new_ns->count, 1);
2672 2672 new_ns->root = NULL;
2673 2673  
2674 2674  
2675 2675  
2676 2676  
2677 2677  
2678 2678  
... ... @@ -3144,31 +3144,31 @@
3144 3144 return visible;
3145 3145 }
3146 3146  
3147   -static void *mntns_get(struct task_struct *task)
  3147 +static struct ns_common *mntns_get(struct task_struct *task)
3148 3148 {
3149   - struct mnt_namespace *ns = NULL;
  3149 + struct ns_common *ns = NULL;
3150 3150 struct nsproxy *nsproxy;
3151 3151  
3152 3152 task_lock(task);
3153 3153 nsproxy = task->nsproxy;
3154 3154 if (nsproxy) {
3155   - ns = nsproxy->mnt_ns;
3156   - get_mnt_ns(ns);
  3155 + ns = &nsproxy->mnt_ns->ns;
  3156 + get_mnt_ns(to_mnt_ns(ns));
3157 3157 }
3158 3158 task_unlock(task);
3159 3159  
3160 3160 return ns;
3161 3161 }
3162 3162  
3163   -static void mntns_put(void *ns)
  3163 +static void mntns_put(struct ns_common *ns)
3164 3164 {
3165   - put_mnt_ns(ns);
  3165 + put_mnt_ns(to_mnt_ns(ns));
3166 3166 }
3167 3167  
3168   -static int mntns_install(struct nsproxy *nsproxy, void *ns)
  3168 +static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns)
3169 3169 {
3170 3170 struct fs_struct *fs = current->fs;
3171   - struct mnt_namespace *mnt_ns = ns;
  3171 + struct mnt_namespace *mnt_ns = to_mnt_ns(ns);
3172 3172 struct path root;
3173 3173  
3174 3174 if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
3175 3175  
... ... @@ -3198,18 +3198,11 @@
3198 3198 return 0;
3199 3199 }
3200 3200  
3201   -static unsigned int mntns_inum(void *ns)
3202   -{
3203   - struct mnt_namespace *mnt_ns = ns;
3204   - return mnt_ns->proc_inum;
3205   -}
3206   -
3207 3201 const struct proc_ns_operations mntns_operations = {
3208 3202 .name = "mnt",
3209 3203 .type = CLONE_NEWNS,
3210 3204 .get = mntns_get,
3211 3205 .put = mntns_put,
3212 3206 .install = mntns_install,
3213   - .inum = mntns_inum,
3214 3207 };
  1 +#include <linux/mount.h>
  2 +#include <linux/file.h>
  3 +#include <linux/fs.h>
  4 +#include <linux/proc_ns.h>
  5 +#include <linux/magic.h>
  6 +#include <linux/ktime.h>
  7 +
  8 +static struct vfsmount *nsfs_mnt;
  9 +
  10 +static const struct file_operations ns_file_operations = {
  11 + .llseek = no_llseek,
  12 +};
  13 +
  14 +static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
  15 +{
  16 + struct inode *inode = dentry->d_inode;
  17 + const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
  18 +
  19 + return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
  20 + ns_ops->name, inode->i_ino);
  21 +}
  22 +
  23 +static void ns_prune_dentry(struct dentry *dentry)
  24 +{
  25 + struct inode *inode = dentry->d_inode;
  26 + if (inode) {
  27 + struct ns_common *ns = inode->i_private;
  28 + atomic_long_set(&ns->stashed, 0);
  29 + }
  30 +}
  31 +
  32 +const struct dentry_operations ns_dentry_operations =
  33 +{
  34 + .d_prune = ns_prune_dentry,
  35 + .d_delete = always_delete_dentry,
  36 + .d_dname = ns_dname,
  37 +};
  38 +
  39 +static void nsfs_evict(struct inode *inode)
  40 +{
  41 + struct ns_common *ns = inode->i_private;
  42 + clear_inode(inode);
  43 + ns->ops->put(ns);
  44 +}
  45 +
  46 +void *ns_get_path(struct path *path, struct task_struct *task,
  47 + const struct proc_ns_operations *ns_ops)
  48 +{
  49 + struct vfsmount *mnt = mntget(nsfs_mnt);
  50 + struct qstr qname = { .name = "", };
  51 + struct dentry *dentry;
  52 + struct inode *inode;
  53 + struct ns_common *ns;
  54 + unsigned long d;
  55 +
  56 +again:
  57 + ns = ns_ops->get(task);
  58 + if (!ns) {
  59 + mntput(mnt);
  60 + return ERR_PTR(-ENOENT);
  61 + }
  62 + rcu_read_lock();
  63 + d = atomic_long_read(&ns->stashed);
  64 + if (!d)
  65 + goto slow;
  66 + dentry = (struct dentry *)d;
  67 + if (!lockref_get_not_dead(&dentry->d_lockref))
  68 + goto slow;
  69 + rcu_read_unlock();
  70 + ns_ops->put(ns);
  71 +got_it:
  72 + path->mnt = mnt;
  73 + path->dentry = dentry;
  74 + return NULL;
  75 +slow:
  76 + rcu_read_unlock();
  77 + inode = new_inode_pseudo(mnt->mnt_sb);
  78 + if (!inode) {
  79 + ns_ops->put(ns);
  80 + mntput(mnt);
  81 + return ERR_PTR(-ENOMEM);
  82 + }
  83 + inode->i_ino = ns->inum;
  84 + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  85 + inode->i_flags |= S_IMMUTABLE;
  86 + inode->i_mode = S_IFREG | S_IRUGO;
  87 + inode->i_fop = &ns_file_operations;
  88 + inode->i_private = ns;
  89 +
  90 + dentry = d_alloc_pseudo(mnt->mnt_sb, &qname);
  91 + if (!dentry) {
  92 + iput(inode);
  93 + mntput(mnt);
  94 + return ERR_PTR(-ENOMEM);
  95 + }
  96 + d_instantiate(dentry, inode);
  97 + dentry->d_fsdata = (void *)ns_ops;
  98 + d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry);
  99 + if (d) {
  100 + d_delete(dentry); /* make sure ->d_prune() does nothing */
  101 + dput(dentry);
  102 + cpu_relax();
  103 + goto again;
  104 + }
  105 + goto got_it;
  106 +}
  107 +
  108 +int ns_get_name(char *buf, size_t size, struct task_struct *task,
  109 + const struct proc_ns_operations *ns_ops)
  110 +{
  111 + struct ns_common *ns;
  112 + int res = -ENOENT;
  113 + ns = ns_ops->get(task);
  114 + if (ns) {
  115 + res = snprintf(buf, size, "%s:[%u]", ns_ops->name, ns->inum);
  116 + ns_ops->put(ns);
  117 + }
  118 + return res;
  119 +}
  120 +
  121 +struct file *proc_ns_fget(int fd)
  122 +{
  123 + struct file *file;
  124 +
  125 + file = fget(fd);
  126 + if (!file)
  127 + return ERR_PTR(-EBADF);
  128 +
  129 + if (file->f_op != &ns_file_operations)
  130 + goto out_invalid;
  131 +
  132 + return file;
  133 +
  134 +out_invalid:
  135 + fput(file);
  136 + return ERR_PTR(-EINVAL);
  137 +}
  138 +
  139 +static const struct super_operations nsfs_ops = {
  140 + .statfs = simple_statfs,
  141 + .evict_inode = nsfs_evict,
  142 +};
  143 +static struct dentry *nsfs_mount(struct file_system_type *fs_type,
  144 + int flags, const char *dev_name, void *data)
  145 +{
  146 + return mount_pseudo(fs_type, "nsfs:", &nsfs_ops,
  147 + &ns_dentry_operations, NSFS_MAGIC);
  148 +}
  149 +static struct file_system_type nsfs = {
  150 + .name = "nsfs",
  151 + .mount = nsfs_mount,
  152 + .kill_sb = kill_anon_super,
  153 +};
  154 +
  155 +void __init nsfs_init(void)
  156 +{
  157 + nsfs_mnt = kern_mount(&nsfs);
  158 + if (IS_ERR(nsfs_mnt))
  159 + panic("can't set nsfs up\n");
  160 + nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
  161 +}
... ... @@ -32,8 +32,6 @@
32 32 {
33 33 struct proc_dir_entry *de;
34 34 struct ctl_table_header *head;
35   - const struct proc_ns_operations *ns_ops;
36   - void *ns;
37 35  
38 36 truncate_inode_pages_final(&inode->i_data);
39 37 clear_inode(inode);
... ... @@ -50,11 +48,6 @@
50 48 RCU_INIT_POINTER(PROC_I(inode)->sysctl, NULL);
51 49 sysctl_head_put(head);
52 50 }
53   - /* Release any associated namespace */
54   - ns_ops = PROC_I(inode)->ns.ns_ops;
55   - ns = PROC_I(inode)->ns.ns;
56   - if (ns_ops && ns)
57   - ns_ops->put(ns);
58 51 }
59 52  
60 53 static struct kmem_cache * proc_inode_cachep;
... ... @@ -73,8 +66,7 @@
73 66 ei->pde = NULL;
74 67 ei->sysctl = NULL;
75 68 ei->sysctl_entry = NULL;
76   - ei->ns.ns = NULL;
77   - ei->ns.ns_ops = NULL;
  69 + ei->ns_ops = NULL;
78 70 inode = &ei->vfs_inode;
79 71 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
80 72 return inode;
... ... @@ -65,7 +65,7 @@
65 65 struct proc_dir_entry *pde;
66 66 struct ctl_table_header *sysctl;
67 67 struct ctl_table *sysctl_entry;
68   - struct proc_ns ns;
  68 + const struct proc_ns_operations *ns_ops;
69 69 struct inode vfs_inode;
70 70 };
71 71  
fs/proc/namespaces.c
1 1 #include <linux/proc_fs.h>
2 2 #include <linux/nsproxy.h>
3   -#include <linux/sched.h>
4 3 #include <linux/ptrace.h>
5   -#include <linux/fs_struct.h>
6   -#include <linux/mount.h>
7   -#include <linux/path.h>
8 4 #include <linux/namei.h>
9 5 #include <linux/file.h>
10 6 #include <linux/utsname.h>
11 7  
12 8  
13 9  
14 10  
15 11  
16 12  
17 13  
18 14  
19 15  
20 16  
... ... @@ -34,138 +30,45 @@
34 30 &mntns_operations,
35 31 };
36 32  
37   -static const struct file_operations ns_file_operations = {
38   - .llseek = no_llseek,
39   -};
40   -
41   -static const struct inode_operations ns_inode_operations = {
42   - .setattr = proc_setattr,
43   -};
44   -
45   -static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
46   -{
47   - struct inode *inode = dentry->d_inode;
48   - const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns.ns_ops;
49   -
50   - return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
51   - ns_ops->name, inode->i_ino);
52   -}
53   -
54   -const struct dentry_operations ns_dentry_operations =
55   -{
56   - .d_delete = always_delete_dentry,
57   - .d_dname = ns_dname,
58   -};
59   -
60   -static struct dentry *proc_ns_get_dentry(struct super_block *sb,
61   - struct task_struct *task, const struct proc_ns_operations *ns_ops)
62   -{
63   - struct dentry *dentry, *result;
64   - struct inode *inode;
65   - struct proc_inode *ei;
66   - struct qstr qname = { .name = "", };
67   - void *ns;
68   -
69   - ns = ns_ops->get(task);
70   - if (!ns)
71   - return ERR_PTR(-ENOENT);
72   -
73   - dentry = d_alloc_pseudo(sb, &qname);
74   - if (!dentry) {
75   - ns_ops->put(ns);
76   - return ERR_PTR(-ENOMEM);
77   - }
78   -
79   - inode = iget_locked(sb, ns_ops->inum(ns));
80   - if (!inode) {
81   - dput(dentry);
82   - ns_ops->put(ns);
83   - return ERR_PTR(-ENOMEM);
84   - }
85   -
86   - ei = PROC_I(inode);
87   - if (inode->i_state & I_NEW) {
88   - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
89   - inode->i_op = &ns_inode_operations;
90   - inode->i_mode = S_IFREG | S_IRUGO;
91   - inode->i_fop = &ns_file_operations;
92   - ei->ns.ns_ops = ns_ops;
93   - ei->ns.ns = ns;
94   - unlock_new_inode(inode);
95   - } else {
96   - ns_ops->put(ns);
97   - }
98   -
99   - d_set_d_op(dentry, &ns_dentry_operations);
100   - result = d_instantiate_unique(dentry, inode);
101   - if (result) {
102   - dput(dentry);
103   - dentry = result;
104   - }
105   -
106   - return dentry;
107   -}
108   -
109 33 static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd)
110 34 {
111 35 struct inode *inode = dentry->d_inode;
112   - struct super_block *sb = inode->i_sb;
113   - struct proc_inode *ei = PROC_I(inode);
  36 + const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
114 37 struct task_struct *task;
115 38 struct path ns_path;
116 39 void *error = ERR_PTR(-EACCES);
117 40  
118 41 task = get_proc_task(inode);
119 42 if (!task)
120   - goto out;
  43 + return error;
121 44  
122   - if (!ptrace_may_access(task, PTRACE_MODE_READ))
123   - goto out_put_task;
124   -
125   - ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns.ns_ops);
126   - if (IS_ERR(ns_path.dentry)) {
127   - error = ERR_CAST(ns_path.dentry);
128   - goto out_put_task;
  45 + if (ptrace_may_access(task, PTRACE_MODE_READ)) {
  46 + error = ns_get_path(&ns_path, task, ns_ops);
  47 + if (!error)
  48 + nd_jump_link(nd, &ns_path);
129 49 }
130   -
131   - ns_path.mnt = mntget(nd->path.mnt);
132   - nd_jump_link(nd, &ns_path);
133   - error = NULL;
134   -
135   -out_put_task:
136 50 put_task_struct(task);
137   -out:
138 51 return error;
139 52 }
140 53  
141 54 static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int buflen)
142 55 {
143 56 struct inode *inode = dentry->d_inode;
144   - struct proc_inode *ei = PROC_I(inode);
145   - const struct proc_ns_operations *ns_ops = ei->ns.ns_ops;
  57 + const struct proc_ns_operations *ns_ops = PROC_I(inode)->ns_ops;
146 58 struct task_struct *task;
147   - void *ns;
148 59 char name[50];
149 60 int res = -EACCES;
150 61  
151 62 task = get_proc_task(inode);
152 63 if (!task)
153   - goto out;
  64 + return res;
154 65  
155   - if (!ptrace_may_access(task, PTRACE_MODE_READ))
156   - goto out_put_task;
157   -
158   - res = -ENOENT;
159   - ns = ns_ops->get(task);
160   - if (!ns)
161   - goto out_put_task;
162   -
163   - snprintf(name, sizeof(name), "%s:[%u]", ns_ops->name, ns_ops->inum(ns));
164   - res = readlink_copy(buffer, buflen, name);
165   - ns_ops->put(ns);
166   -out_put_task:
  66 + if (ptrace_may_access(task, PTRACE_MODE_READ)) {
  67 + res = ns_get_name(name, sizeof(name), task, ns_ops);
  68 + if (res >= 0)
  69 + res = readlink_copy(buffer, buflen, name);
  70 + }
167 71 put_task_struct(task);
168   -out:
169 72 return res;
170 73 }
171 74  
... ... @@ -189,7 +92,7 @@
189 92 ei = PROC_I(inode);
190 93 inode->i_mode = S_IFLNK|S_IRWXUGO;
191 94 inode->i_op = &proc_ns_link_inode_operations;
192   - ei->ns.ns_ops = ns_ops;
  95 + ei->ns_ops = ns_ops;
193 96  
194 97 d_set_d_op(dentry, &pid_dentry_operations);
195 98 d_add(dentry, inode);
... ... @@ -267,32 +170,4 @@
267 170 .getattr = pid_getattr,
268 171 .setattr = proc_setattr,
269 172 };
270   -
271   -struct file *proc_ns_fget(int fd)
272   -{
273   - struct file *file;
274   -
275   - file = fget(fd);
276   - if (!file)
277   - return ERR_PTR(-EBADF);
278   -
279   - if (file->f_op != &ns_file_operations)
280   - goto out_invalid;
281   -
282   - return file;
283   -
284   -out_invalid:
285   - fput(file);
286   - return ERR_PTR(-EINVAL);
287   -}
288   -
289   -struct proc_ns *get_proc_ns(struct inode *inode)
290   -{
291   - return &PROC_I(inode)->ns;
292   -}
293   -
294   -bool proc_ns_inode(struct inode *inode)
295   -{
296   - return inode->i_fop == &ns_file_operations;
297   -}
... ... @@ -2176,7 +2176,6 @@
2176 2176 extern int sync_filesystem(struct super_block *);
2177 2177 extern const struct file_operations def_blk_fops;
2178 2178 extern const struct file_operations def_chr_fops;
2179   -extern const struct file_operations bad_sock_fops;
2180 2179 #ifdef CONFIG_BLOCK
2181 2180 extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long);
2182 2181 extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long);
include/linux/ipc_namespace.h
... ... @@ -6,6 +6,7 @@
6 6 #include <linux/rwsem.h>
7 7 #include <linux/notifier.h>
8 8 #include <linux/nsproxy.h>
  9 +#include <linux/ns_common.h>
9 10  
10 11 struct user_namespace;
11 12  
... ... @@ -58,7 +59,7 @@
58 59 /* user_ns which owns the ipc ns */
59 60 struct user_namespace *user_ns;
60 61  
61   - unsigned int proc_inum;
  62 + struct ns_common ns;
62 63 };
63 64  
64 65 extern struct ipc_namespace init_ipc_ns;
include/linux/namei.h
... ... @@ -7,21 +7,10 @@
7 7 #include <linux/path.h>
8 8  
9 9 struct vfsmount;
  10 +struct nameidata;
10 11  
11 12 enum { MAX_NESTED_LINKS = 8 };
12 13  
13   -struct nameidata {
14   - struct path path;
15   - struct qstr last;
16   - struct path root;
17   - struct inode *inode; /* path.dentry.d_inode */
18   - unsigned int flags;
19   - unsigned seq, m_seq;
20   - int last_type;
21   - unsigned depth;
22   - char *saved_names[MAX_NESTED_LINKS + 1];
23   -};
24   -
25 14 /*
26 15 * Type of the last component on LOOKUP_PARENT
27 16 */
... ... @@ -82,16 +71,8 @@
82 71 extern void unlock_rename(struct dentry *, struct dentry *);
83 72  
84 73 extern void nd_jump_link(struct nameidata *nd, struct path *path);
85   -
86   -static inline void nd_set_link(struct nameidata *nd, char *path)
87   -{
88   - nd->saved_names[nd->depth] = path;
89   -}
90   -
91   -static inline char *nd_get_link(struct nameidata *nd)
92   -{
93   - return nd->saved_names[nd->depth];
94   -}
  74 +extern void nd_set_link(struct nameidata *nd, char *path);
  75 +extern char *nd_get_link(struct nameidata *nd);
95 76  
96 77 static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
97 78 {
include/linux/ns_common.h
  1 +#ifndef _LINUX_NS_COMMON_H
  2 +#define _LINUX_NS_COMMON_H
  3 +
  4 +struct proc_ns_operations;
  5 +
  6 +struct ns_common {
  7 + atomic_long_t stashed;
  8 + const struct proc_ns_operations *ops;
  9 + unsigned int inum;
  10 +};
  11 +
  12 +#endif
include/linux/pid_namespace.h
... ... @@ -8,6 +8,7 @@
8 8 #include <linux/threads.h>
9 9 #include <linux/nsproxy.h>
10 10 #include <linux/kref.h>
  11 +#include <linux/ns_common.h>
11 12  
12 13 struct pidmap {
13 14 atomic_t nr_free;
... ... @@ -43,7 +44,7 @@
43 44 kgid_t pid_gid;
44 45 int hide_pid;
45 46 int reboot; /* group exit code if this pidns was rebooted */
46   - unsigned int proc_inum;
  47 + struct ns_common ns;
47 48 };
48 49  
49 50 extern struct pid_namespace init_pid_ns;
include/linux/proc_ns.h
... ... @@ -4,23 +4,20 @@
4 4 #ifndef _LINUX_PROC_NS_H
5 5 #define _LINUX_PROC_NS_H
6 6  
  7 +#include <linux/ns_common.h>
  8 +
7 9 struct pid_namespace;
8 10 struct nsproxy;
  11 +struct path;
9 12  
10 13 struct proc_ns_operations {
11 14 const char *name;
12 15 int type;
13   - void *(*get)(struct task_struct *task);
14   - void (*put)(void *ns);
15   - int (*install)(struct nsproxy *nsproxy, void *ns);
16   - unsigned int (*inum)(void *ns);
  16 + struct ns_common *(*get)(struct task_struct *task);
  17 + void (*put)(struct ns_common *ns);
  18 + int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
17 19 };
18 20  
19   -struct proc_ns {
20   - void *ns;
21   - const struct proc_ns_operations *ns_ops;
22   -};
23   -
24 21 extern const struct proc_ns_operations netns_operations;
25 22 extern const struct proc_ns_operations utsns_operations;
26 23 extern const struct proc_ns_operations ipcns_operations;
27 24  
28 25  
29 26  
30 27  
... ... @@ -43,33 +40,39 @@
43 40  
44 41 extern int pid_ns_prepare_proc(struct pid_namespace *ns);
45 42 extern void pid_ns_release_proc(struct pid_namespace *ns);
46   -extern struct file *proc_ns_fget(int fd);
47   -extern struct proc_ns *get_proc_ns(struct inode *);
48 43 extern int proc_alloc_inum(unsigned int *pino);
49 44 extern void proc_free_inum(unsigned int inum);
50   -extern bool proc_ns_inode(struct inode *inode);
51 45  
52 46 #else /* CONFIG_PROC_FS */
53 47  
54 48 static inline int pid_ns_prepare_proc(struct pid_namespace *ns) { return 0; }
55 49 static inline void pid_ns_release_proc(struct pid_namespace *ns) {}
56 50  
57   -static inline struct file *proc_ns_fget(int fd)
58   -{
59   - return ERR_PTR(-EINVAL);
60   -}
61   -
62   -static inline struct proc_ns *get_proc_ns(struct inode *inode) { return NULL; }
63   -
64 51 static inline int proc_alloc_inum(unsigned int *inum)
65 52 {
66 53 *inum = 1;
67 54 return 0;
68 55 }
69 56 static inline void proc_free_inum(unsigned int inum) {}
70   -static inline bool proc_ns_inode(struct inode *inode) { return false; }
71 57  
72 58 #endif /* CONFIG_PROC_FS */
  59 +
  60 +static inline int ns_alloc_inum(struct ns_common *ns)
  61 +{
  62 + atomic_long_set(&ns->stashed, 0);
  63 + return proc_alloc_inum(&ns->inum);
  64 +}
  65 +
  66 +#define ns_free_inum(ns) proc_free_inum((ns)->inum)
  67 +
  68 +extern struct file *proc_ns_fget(int fd);
  69 +#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
  70 +extern void *ns_get_path(struct path *path, struct task_struct *task,
  71 + const struct proc_ns_operations *ns_ops);
  72 +
  73 +extern int ns_get_name(char *buf, size_t size, struct task_struct *task,
  74 + const struct proc_ns_operations *ns_ops);
  75 +extern void nsfs_init(void);
73 76  
74 77 #endif /* _LINUX_PROC_NS_H */
include/linux/user_namespace.h
... ... @@ -3,6 +3,7 @@
3 3  
4 4 #include <linux/kref.h>
5 5 #include <linux/nsproxy.h>
  6 +#include <linux/ns_common.h>
6 7 #include <linux/sched.h>
7 8 #include <linux/err.h>
8 9  
... ... @@ -26,7 +27,7 @@
26 27 int level;
27 28 kuid_t owner;
28 29 kgid_t group;
29   - unsigned int proc_inum;
  30 + struct ns_common ns;
30 31  
31 32 /* Register of per-UID persistent keyrings for this namespace */
32 33 #ifdef CONFIG_PERSISTENT_KEYRINGS
include/linux/utsname.h
... ... @@ -5,6 +5,7 @@
5 5 #include <linux/sched.h>
6 6 #include <linux/kref.h>
7 7 #include <linux/nsproxy.h>
  8 +#include <linux/ns_common.h>
8 9 #include <linux/err.h>
9 10 #include <uapi/linux/utsname.h>
10 11  
... ... @@ -23,7 +24,7 @@
23 24 struct kref kref;
24 25 struct new_utsname name;
25 26 struct user_namespace *user_ns;
26   - unsigned int proc_inum;
  27 + struct ns_common ns;
27 28 };
28 29 extern struct uts_namespace init_uts_ns;
29 30  
include/net/net_namespace.h
... ... @@ -26,6 +26,7 @@
26 26 #endif
27 27 #include <net/netns/nftables.h>
28 28 #include <net/netns/xfrm.h>
  29 +#include <linux/ns_common.h>
29 30  
30 31 struct user_namespace;
31 32 struct proc_dir_entry;
... ... @@ -60,7 +61,7 @@
60 61  
61 62 struct user_namespace *user_ns; /* Owning user namespace */
62 63  
63   - unsigned int proc_inum;
  64 + struct ns_common ns;
64 65  
65 66 struct proc_dir_entry *proc_net;
66 67 struct proc_dir_entry *proc_net_stat;
include/uapi/linux/magic.h
... ... @@ -72,6 +72,7 @@
72 72 #define MTD_INODE_FS_MAGIC 0x11307854
73 73 #define ANON_INODE_FS_MAGIC 0x09041934
74 74 #define BTRFS_TEST_MAGIC 0x73727279
  75 +#define NSFS_MAGIC 0x6e736673
75 76  
76 77 #endif /* __LINUX_MAGIC_H__ */
... ... @@ -79,6 +79,7 @@
79 79 #include <linux/random.h>
80 80 #include <linux/list.h>
81 81 #include <linux/integrity.h>
  82 +#include <linux/proc_ns.h>
82 83  
83 84 #include <asm/io.h>
84 85 #include <asm/bugs.h>
... ... @@ -665,6 +666,7 @@
665 666 /* rootfs populating might need page-writeback */
666 667 page_writeback_init();
667 668 proc_root_init();
  669 + nsfs_init();
668 670 cgroup_init();
669 671 cpuset_init();
670 672 taskstats_init_early();
... ... @@ -35,7 +35,10 @@
35 35 .domainname = UTS_DOMAINNAME,
36 36 },
37 37 .user_ns = &init_user_ns,
38   - .proc_inum = PROC_UTS_INIT_INO,
  38 + .ns.inum = PROC_UTS_INIT_INO,
  39 +#ifdef CONFIG_UTS_NS
  40 + .ns.ops = &utsns_operations,
  41 +#endif
39 42 };
40 43 EXPORT_SYMBOL_GPL(init_uts_ns);
41 44  
... ... @@ -31,7 +31,10 @@
31 31 struct ipc_namespace init_ipc_ns = {
32 32 .count = ATOMIC_INIT(1),
33 33 .user_ns = &init_user_ns,
34   - .proc_inum = PROC_IPC_INIT_INO,
  34 + .ns.inum = PROC_IPC_INIT_INO,
  35 +#ifdef CONFIG_IPC_NS
  36 + .ns.ops = &ipcns_operations,
  37 +#endif
35 38 };
36 39  
37 40 atomic_t nr_ipc_ns = ATOMIC_INIT(1);
... ... @@ -26,16 +26,17 @@
26 26 if (ns == NULL)
27 27 return ERR_PTR(-ENOMEM);
28 28  
29   - err = proc_alloc_inum(&ns->proc_inum);
  29 + err = ns_alloc_inum(&ns->ns);
30 30 if (err) {
31 31 kfree(ns);
32 32 return ERR_PTR(err);
33 33 }
  34 + ns->ns.ops = &ipcns_operations;
34 35  
35 36 atomic_set(&ns->count, 1);
36 37 err = mq_init_ns(ns);
37 38 if (err) {
38   - proc_free_inum(ns->proc_inum);
  39 + ns_free_inum(&ns->ns);
39 40 kfree(ns);
40 41 return ERR_PTR(err);
41 42 }
... ... @@ -97,7 +98,7 @@
97 98 atomic_dec(&nr_ipc_ns);
98 99  
99 100 put_user_ns(ns->user_ns);
100   - proc_free_inum(ns->proc_inum);
  101 + ns_free_inum(&ns->ns);
101 102 kfree(ns);
102 103 }
103 104  
104 105  
... ... @@ -127,8 +128,13 @@
127 128 }
128 129 }
129 130  
130   -static void *ipcns_get(struct task_struct *task)
  131 +static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns)
131 132 {
  133 + return container_of(ns, struct ipc_namespace, ns);
  134 +}
  135 +
  136 +static struct ns_common *ipcns_get(struct task_struct *task)
  137 +{
132 138 struct ipc_namespace *ns = NULL;
133 139 struct nsproxy *nsproxy;
134 140  
135 141  
136 142  
137 143  
138 144  
... ... @@ -138,17 +144,17 @@
138 144 ns = get_ipc_ns(nsproxy->ipc_ns);
139 145 task_unlock(task);
140 146  
141   - return ns;
  147 + return ns ? &ns->ns : NULL;
142 148 }
143 149  
144   -static void ipcns_put(void *ns)
  150 +static void ipcns_put(struct ns_common *ns)
145 151 {
146   - return put_ipc_ns(ns);
  152 + return put_ipc_ns(to_ipc_ns(ns));
147 153 }
148 154  
149   -static int ipcns_install(struct nsproxy *nsproxy, void *new)
  155 +static int ipcns_install(struct nsproxy *nsproxy, struct ns_common *new)
150 156 {
151   - struct ipc_namespace *ns = new;
  157 + struct ipc_namespace *ns = to_ipc_ns(new);
152 158 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
153 159 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
154 160 return -EPERM;
155 161  
... ... @@ -160,19 +166,11 @@
160 166 return 0;
161 167 }
162 168  
163   -static unsigned int ipcns_inum(void *vp)
164   -{
165   - struct ipc_namespace *ns = vp;
166   -
167   - return ns->proc_inum;
168   -}
169   -
170 169 const struct proc_ns_operations ipcns_operations = {
171 170 .name = "ipc",
172 171 .type = CLONE_NEWIPC,
173 172 .get = ipcns_get,
174 173 .put = ipcns_put,
175 174 .install = ipcns_install,
176   - .inum = ipcns_inum,
177 175 };
... ... @@ -220,11 +220,10 @@
220 220  
221 221 SYSCALL_DEFINE2(setns, int, fd, int, nstype)
222 222 {
223   - const struct proc_ns_operations *ops;
224 223 struct task_struct *tsk = current;
225 224 struct nsproxy *new_nsproxy;
226   - struct proc_ns *ei;
227 225 struct file *file;
  226 + struct ns_common *ns;
228 227 int err;
229 228  
230 229 file = proc_ns_fget(fd);
... ... @@ -232,9 +231,8 @@
232 231 return PTR_ERR(file);
233 232  
234 233 err = -EINVAL;
235   - ei = get_proc_ns(file_inode(file));
236   - ops = ei->ns_ops;
237   - if (nstype && (ops->type != nstype))
  234 + ns = get_proc_ns(file_inode(file));
  235 + if (nstype && (ns->ops->type != nstype))
238 236 goto out;
239 237  
240 238 new_nsproxy = create_new_namespaces(0, tsk, current_user_ns(), tsk->fs);
... ... @@ -243,7 +241,7 @@
243 241 goto out;
244 242 }
245 243  
246   - err = ops->install(new_nsproxy, ei->ns);
  244 + err = ns->ops->install(new_nsproxy, ns);
247 245 if (err) {
248 246 free_nsproxy(new_nsproxy);
249 247 goto out;
... ... @@ -79,7 +79,10 @@
79 79 .level = 0,
80 80 .child_reaper = &init_task,
81 81 .user_ns = &init_user_ns,
82   - .proc_inum = PROC_PID_INIT_INO,
  82 + .ns.inum = PROC_PID_INIT_INO,
  83 +#ifdef CONFIG_PID_NS
  84 + .ns.ops = &pidns_operations,
  85 +#endif
83 86 };
84 87 EXPORT_SYMBOL_GPL(init_pid_ns);
85 88  
kernel/pid_namespace.c
... ... @@ -105,9 +105,10 @@
105 105 if (ns->pid_cachep == NULL)
106 106 goto out_free_map;
107 107  
108   - err = proc_alloc_inum(&ns->proc_inum);
  108 + err = ns_alloc_inum(&ns->ns);
109 109 if (err)
110 110 goto out_free_map;
  111 + ns->ns.ops = &pidns_operations;
111 112  
112 113 kref_init(&ns->kref);
113 114 ns->level = level;
... ... @@ -142,7 +143,7 @@
142 143 {
143 144 int i;
144 145  
145   - proc_free_inum(ns->proc_inum);
  146 + ns_free_inum(&ns->ns);
146 147 for (i = 0; i < PIDMAP_ENTRIES; i++)
147 148 kfree(ns->pidmap[i].page);
148 149 put_user_ns(ns->user_ns);
149 150  
... ... @@ -333,8 +334,13 @@
333 334 return 0;
334 335 }
335 336  
336   -static void *pidns_get(struct task_struct *task)
  337 +static inline struct pid_namespace *to_pid_ns(struct ns_common *ns)
337 338 {
  339 + return container_of(ns, struct pid_namespace, ns);
  340 +}
  341 +
  342 +static struct ns_common *pidns_get(struct task_struct *task)
  343 +{
338 344 struct pid_namespace *ns;
339 345  
340 346 rcu_read_lock();
341 347  
342 348  
343 349  
344 350  
... ... @@ -343,18 +349,18 @@
343 349 get_pid_ns(ns);
344 350 rcu_read_unlock();
345 351  
346   - return ns;
  352 + return ns ? &ns->ns : NULL;
347 353 }
348 354  
349   -static void pidns_put(void *ns)
  355 +static void pidns_put(struct ns_common *ns)
350 356 {
351   - put_pid_ns(ns);
  357 + put_pid_ns(to_pid_ns(ns));
352 358 }
353 359  
354   -static int pidns_install(struct nsproxy *nsproxy, void *ns)
  360 +static int pidns_install(struct nsproxy *nsproxy, struct ns_common *ns)
355 361 {
356 362 struct pid_namespace *active = task_active_pid_ns(current);
357   - struct pid_namespace *ancestor, *new = ns;
  363 + struct pid_namespace *ancestor, *new = to_pid_ns(ns);
358 364  
359 365 if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) ||
360 366 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
361 367  
... ... @@ -382,19 +388,12 @@
382 388 return 0;
383 389 }
384 390  
385   -static unsigned int pidns_inum(void *ns)
386   -{
387   - struct pid_namespace *pid_ns = ns;
388   - return pid_ns->proc_inum;
389   -}
390   -
391 391 const struct proc_ns_operations pidns_operations = {
392 392 .name = "pid",
393 393 .type = CLONE_NEWPID,
394 394 .get = pidns_get,
395 395 .put = pidns_put,
396 396 .install = pidns_install,
397   - .inum = pidns_inum,
398 397 };
399 398  
400 399 static __init int pid_namespaces_init(void)
... ... @@ -50,7 +50,10 @@
50 50 .count = ATOMIC_INIT(3),
51 51 .owner = GLOBAL_ROOT_UID,
52 52 .group = GLOBAL_ROOT_GID,
53   - .proc_inum = PROC_USER_INIT_INO,
  53 + .ns.inum = PROC_USER_INIT_INO,
  54 +#ifdef CONFIG_USER_NS
  55 + .ns.ops = &userns_operations,
  56 +#endif
54 57 #ifdef CONFIG_PERSISTENT_KEYRINGS
55 58 .persistent_keyring_register_sem =
56 59 __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem),
kernel/user_namespace.c
... ... @@ -86,11 +86,12 @@
86 86 if (!ns)
87 87 return -ENOMEM;
88 88  
89   - ret = proc_alloc_inum(&ns->proc_inum);
  89 + ret = ns_alloc_inum(&ns->ns);
90 90 if (ret) {
91 91 kmem_cache_free(user_ns_cachep, ns);
92 92 return ret;
93 93 }
  94 + ns->ns.ops = &userns_operations;
94 95  
95 96 atomic_set(&ns->count, 1);
96 97 /* Leave the new->user_ns reference with the new user namespace. */
... ... @@ -136,7 +137,7 @@
136 137 #ifdef CONFIG_PERSISTENT_KEYRINGS
137 138 key_put(ns->persistent_keyring_register);
138 139 #endif
139   - proc_free_inum(ns->proc_inum);
  140 + ns_free_inum(&ns->ns);
140 141 kmem_cache_free(user_ns_cachep, ns);
141 142 ns = parent;
142 143 } while (atomic_dec_and_test(&parent->count));
143 144  
144 145  
145 146  
146 147  
147 148  
148 149  
... ... @@ -841,25 +842,30 @@
841 842 return false;
842 843 }
843 844  
844   -static void *userns_get(struct task_struct *task)
  845 +static inline struct user_namespace *to_user_ns(struct ns_common *ns)
845 846 {
  847 + return container_of(ns, struct user_namespace, ns);
  848 +}
  849 +
  850 +static struct ns_common *userns_get(struct task_struct *task)
  851 +{
846 852 struct user_namespace *user_ns;
847 853  
848 854 rcu_read_lock();
849 855 user_ns = get_user_ns(__task_cred(task)->user_ns);
850 856 rcu_read_unlock();
851 857  
852   - return user_ns;
  858 + return user_ns ? &user_ns->ns : NULL;
853 859 }
854 860  
855   -static void userns_put(void *ns)
  861 +static void userns_put(struct ns_common *ns)
856 862 {
857   - put_user_ns(ns);
  863 + put_user_ns(to_user_ns(ns));
858 864 }
859 865  
860   -static int userns_install(struct nsproxy *nsproxy, void *ns)
  866 +static int userns_install(struct nsproxy *nsproxy, struct ns_common *ns)
861 867 {
862   - struct user_namespace *user_ns = ns;
  868 + struct user_namespace *user_ns = to_user_ns(ns);
863 869 struct cred *cred;
864 870  
865 871 /* Don't allow gaining capabilities by reentering
866 872  
... ... @@ -888,19 +894,12 @@
888 894 return commit_creds(cred);
889 895 }
890 896  
891   -static unsigned int userns_inum(void *ns)
892   -{
893   - struct user_namespace *user_ns = ns;
894   - return user_ns->proc_inum;
895   -}
896   -
897 897 const struct proc_ns_operations userns_operations = {
898 898 .name = "user",
899 899 .type = CLONE_NEWUSER,
900 900 .get = userns_get,
901 901 .put = userns_put,
902 902 .install = userns_install,
903   - .inum = userns_inum,
904 903 };
905 904  
906 905 static __init int user_namespaces_init(void)
... ... @@ -42,12 +42,14 @@
42 42 if (!ns)
43 43 return ERR_PTR(-ENOMEM);
44 44  
45   - err = proc_alloc_inum(&ns->proc_inum);
  45 + err = ns_alloc_inum(&ns->ns);
46 46 if (err) {
47 47 kfree(ns);
48 48 return ERR_PTR(err);
49 49 }
50 50  
  51 + ns->ns.ops = &utsns_operations;
  52 +
51 53 down_read(&uts_sem);
52 54 memcpy(&ns->name, &old_ns->name, sizeof(ns->name));
53 55 ns->user_ns = get_user_ns(user_ns);
54 56  
55 57  
... ... @@ -84,12 +86,17 @@
84 86  
85 87 ns = container_of(kref, struct uts_namespace, kref);
86 88 put_user_ns(ns->user_ns);
87   - proc_free_inum(ns->proc_inum);
  89 + ns_free_inum(&ns->ns);
88 90 kfree(ns);
89 91 }
90 92  
91   -static void *utsns_get(struct task_struct *task)
  93 +static inline struct uts_namespace *to_uts_ns(struct ns_common *ns)
92 94 {
  95 + return container_of(ns, struct uts_namespace, ns);
  96 +}
  97 +
  98 +static struct ns_common *utsns_get(struct task_struct *task)
  99 +{
93 100 struct uts_namespace *ns = NULL;
94 101 struct nsproxy *nsproxy;
95 102  
96 103  
97 104  
98 105  
99 106  
... ... @@ -101,17 +108,17 @@
101 108 }
102 109 task_unlock(task);
103 110  
104   - return ns;
  111 + return ns ? &ns->ns : NULL;
105 112 }
106 113  
107   -static void utsns_put(void *ns)
  114 +static void utsns_put(struct ns_common *ns)
108 115 {
109   - put_uts_ns(ns);
  116 + put_uts_ns(to_uts_ns(ns));
110 117 }
111 118  
112   -static int utsns_install(struct nsproxy *nsproxy, void *new)
  119 +static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new)
113 120 {
114   - struct uts_namespace *ns = new;
  121 + struct uts_namespace *ns = to_uts_ns(new);
115 122  
116 123 if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
117 124 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
118 125  
... ... @@ -123,19 +130,11 @@
123 130 return 0;
124 131 }
125 132  
126   -static unsigned int utsns_inum(void *vp)
127   -{
128   - struct uts_namespace *ns = vp;
129   -
130   - return ns->proc_inum;
131   -}
132   -
133 133 const struct proc_ns_operations utsns_operations = {
134 134 .name = "uts",
135 135 .type = CLONE_NEWUTS,
136 136 .get = utsns_get,
137 137 .put = utsns_put,
138 138 .install = utsns_install,
139   - .inum = utsns_inum,
140 139 };
... ... @@ -5,8 +5,6 @@
5 5 # Rewritten to use lists instead of if-statements.
6 6 #
7 7  
8   -obj-y := nonet.o
9   -
10 8 obj-$(CONFIG_NET) := socket.o core/
11 9  
12 10 tmp-$(CONFIG_COMPAT) := compat.o
net/core/net_namespace.c
... ... @@ -337,17 +337,17 @@
337 337  
338 338 struct net *get_net_ns_by_fd(int fd)
339 339 {
340   - struct proc_ns *ei;
341 340 struct file *file;
  341 + struct ns_common *ns;
342 342 struct net *net;
343 343  
344 344 file = proc_ns_fget(fd);
345 345 if (IS_ERR(file))
346 346 return ERR_CAST(file);
347 347  
348   - ei = get_proc_ns(file_inode(file));
349   - if (ei->ns_ops == &netns_operations)
350   - net = get_net(ei->ns);
  348 + ns = get_proc_ns(file_inode(file));
  349 + if (ns->ops == &netns_operations)
  350 + net = get_net(container_of(ns, struct net, ns));
351 351 else
352 352 net = ERR_PTR(-EINVAL);
353 353  
354 354  
... ... @@ -386,12 +386,15 @@
386 386  
387 387 static __net_init int net_ns_net_init(struct net *net)
388 388 {
389   - return proc_alloc_inum(&net->proc_inum);
  389 +#ifdef CONFIG_NET_NS
  390 + net->ns.ops = &netns_operations;
  391 +#endif
  392 + return ns_alloc_inum(&net->ns);
390 393 }
391 394  
392 395 static __net_exit void net_ns_net_exit(struct net *net)
393 396 {
394   - proc_free_inum(net->proc_inum);
  397 + ns_free_inum(&net->ns);
395 398 }
396 399  
397 400 static struct pernet_operations __net_initdata net_ns_ops = {
... ... @@ -629,7 +632,7 @@
629 632 EXPORT_SYMBOL_GPL(unregister_pernet_device);
630 633  
631 634 #ifdef CONFIG_NET_NS
632   -static void *netns_get(struct task_struct *task)
  635 +static struct ns_common *netns_get(struct task_struct *task)
633 636 {
634 637 struct net *net = NULL;
635 638 struct nsproxy *nsproxy;
636 639  
637 640  
638 641  
639 642  
640 643  
... ... @@ -640,18 +643,23 @@
640 643 net = get_net(nsproxy->net_ns);
641 644 task_unlock(task);
642 645  
643   - return net;
  646 + return net ? &net->ns : NULL;
644 647 }
645 648  
646   -static void netns_put(void *ns)
  649 +static inline struct net *to_net_ns(struct ns_common *ns)
647 650 {
648   - put_net(ns);
  651 + return container_of(ns, struct net, ns);
649 652 }
650 653  
651   -static int netns_install(struct nsproxy *nsproxy, void *ns)
  654 +static void netns_put(struct ns_common *ns)
652 655 {
653   - struct net *net = ns;
  656 + put_net(to_net_ns(ns));
  657 +}
654 658  
  659 +static int netns_install(struct nsproxy *nsproxy, struct ns_common *ns)
  660 +{
  661 + struct net *net = to_net_ns(ns);
  662 +
655 663 if (!ns_capable(net->user_ns, CAP_SYS_ADMIN) ||
656 664 !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
657 665 return -EPERM;
658 666  
... ... @@ -661,19 +669,12 @@
661 669 return 0;
662 670 }
663 671  
664   -static unsigned int netns_inum(void *ns)
665   -{
666   - struct net *net = ns;
667   - return net->proc_inum;
668   -}
669   -
670 672 const struct proc_ns_operations netns_operations = {
671 673 .name = "net",
672 674 .type = CLONE_NEWNET,
673 675 .get = netns_get,
674 676 .put = netns_put,
675 677 .install = netns_install,
676   - .inum = netns_inum,
677 678 };
678 679 #endif
1   -/*
2   - * net/nonet.c
3   - *
4   - * Dummy functions to allow us to configure network support entirely
5   - * out of the kernel.
6   - *
7   - * Distributed under the terms of the GNU GPL version 2.
8   - * Copyright (c) Matthew Wilcox 2003
9   - */
10   -
11   -#include <linux/module.h>
12   -#include <linux/errno.h>
13   -#include <linux/fs.h>
14   -#include <linux/init.h>
15   -#include <linux/kernel.h>
16   -
17   -static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
18   -{
19   - return -ENXIO;
20   -}
21   -
22   -const struct file_operations bad_sock_fops = {
23   - .owner = THIS_MODULE,
24   - .open = sock_no_open,
25   - .llseek = noop_llseek,
26   -};
... ... @@ -113,7 +113,6 @@
113 113 unsigned int sysctl_net_busy_poll __read_mostly;
114 114 #endif
115 115  
116   -static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
117 116 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
118 117 unsigned long nr_segs, loff_t pos);
119 118 static ssize_t sock_aio_write(struct kiocb *iocb, const struct iovec *iov,
... ... @@ -151,7 +150,6 @@
151 150 .compat_ioctl = compat_sock_ioctl,
152 151 #endif
153 152 .mmap = sock_mmap,
154   - .open = sock_no_open, /* special open code to disallow open via /proc */
155 153 .release = sock_close,
156 154 .fasync = sock_fasync,
157 155 .sendpage = sock_sendpage,
... ... @@ -558,23 +556,6 @@
558 556 this_cpu_add(sockets_in_use, 1);
559 557 return sock;
560 558 }
561   -
562   -/*
563   - * In theory you can't get an open on this inode, but /proc provides
564   - * a back door. Remember to keep it shut otherwise you'll let the
565   - * creepy crawlies in.
566   - */
567   -
568   -static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
569   -{
570   - return -ENXIO;
571   -}
572   -
573   -const struct file_operations bad_sock_fops = {
574   - .owner = THIS_MODULE,
575   - .open = sock_no_open,
576   - .llseek = noop_llseek,
577   -};
578 559  
579 560 /**
580 561 * sock_release - close a socket