Commit 734550921e9b7ab924a43aa3d0bd4239dac4fbf1

Authored by Al Viro
1 parent 7ac6cd653d

[PATCH] beginning of sysctl cleanup - ctl_table_set

New object: set of sysctls [currently - root and per-net-ns].
Contains: pointer to parent set, list of tables and "should I see this set?"
method (->is_seen(set)).
Current lists of tables are subsumed by that; net-ns contains such a beast.
->lookup() for ctl_table_root returns pointer to ctl_table_set instead of
that to ->list of that ctl_table_set.

[folded compile fixes by rdd for configs without sysctl]

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 4 changed files with 57 additions and 25 deletions Side-by-side Diff

include/linux/sysctl.h
... ... @@ -947,6 +947,16 @@
947 947 struct nsproxy;
948 948 struct ctl_table_root;
949 949  
  950 +struct ctl_table_set {
  951 + struct list_head list;
  952 + struct ctl_table_set *parent;
  953 + int (*is_seen)(struct ctl_table_set *);
  954 +};
  955 +
  956 +extern void setup_sysctl_set(struct ctl_table_set *p,
  957 + struct ctl_table_set *parent,
  958 + int (*is_seen)(struct ctl_table_set *));
  959 +
950 960 extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev);
951 961 extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
952 962 struct ctl_table_header *prev);
... ... @@ -1049,8 +1059,8 @@
1049 1059  
1050 1060 struct ctl_table_root {
1051 1061 struct list_head root_list;
1052   - struct list_head header_list;
1053   - struct list_head *(*lookup)(struct ctl_table_root *root,
  1062 + struct ctl_table_set default_set;
  1063 + struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
1054 1064 struct nsproxy *namespaces);
1055 1065 int (*permissions)(struct ctl_table_root *root,
1056 1066 struct nsproxy *namespaces, struct ctl_table *table);
... ... @@ -1066,6 +1076,7 @@
1066 1076 struct completion *unregistering;
1067 1077 struct ctl_table *ctl_table_arg;
1068 1078 struct ctl_table_root *root;
  1079 + struct ctl_table_set *set;
1069 1080 };
1070 1081  
1071 1082 /* struct ctl_path describes where in the hierarchy a table is added */
include/net/net_namespace.h
... ... @@ -38,7 +38,9 @@
38 38 struct proc_dir_entry *proc_net;
39 39 struct proc_dir_entry *proc_net_stat;
40 40  
41   - struct list_head sysctl_table_headers;
  41 +#ifdef CONFIG_SYSCTL
  42 + struct ctl_table_set sysctls;
  43 +#endif
42 44  
43 45 struct net_device *loopback_dev; /* The loopback */
44 46  
... ... @@ -160,12 +160,13 @@
160 160 static struct ctl_table_root sysctl_table_root;
161 161 static struct ctl_table_header root_table_header = {
162 162 .ctl_table = root_table,
163   - .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list),
  163 + .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
164 164 .root = &sysctl_table_root,
  165 + .set = &sysctl_table_root.default_set,
165 166 };
166 167 static struct ctl_table_root sysctl_table_root = {
167 168 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
168   - .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry),
  169 + .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
169 170 };
170 171  
171 172 static struct ctl_table kern_table[];
172 173  
... ... @@ -1403,14 +1404,20 @@
1403 1404 spin_unlock(&sysctl_lock);
1404 1405 }
1405 1406  
  1407 +static struct ctl_table_set *
  1408 +lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
  1409 +{
  1410 + struct ctl_table_set *set = &root->default_set;
  1411 + if (root->lookup)
  1412 + set = root->lookup(root, namespaces);
  1413 + return set;
  1414 +}
  1415 +
1406 1416 static struct list_head *
1407 1417 lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
1408 1418 {
1409   - struct list_head *header_list;
1410   - header_list = &root->header_list;
1411   - if (root->lookup)
1412   - header_list = root->lookup(root, namespaces);
1413   - return header_list;
  1419 + struct ctl_table_set *set = lookup_header_set(root, namespaces);
  1420 + return &set->list;
1414 1421 }
1415 1422  
1416 1423 struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
... ... @@ -1720,7 +1727,6 @@
1720 1727 struct nsproxy *namespaces,
1721 1728 const struct ctl_path *path, struct ctl_table *table)
1722 1729 {
1723   - struct list_head *header_list;
1724 1730 struct ctl_table_header *header;
1725 1731 struct ctl_table *new, **prevp;
1726 1732 unsigned int n, npath;
... ... @@ -1772,8 +1778,8 @@
1772 1778 }
1773 1779 #endif
1774 1780 spin_lock(&sysctl_lock);
1775   - header_list = lookup_header_list(root, namespaces);
1776   - list_add_tail(&header->ctl_entry, header_list);
  1781 + header->set = lookup_header_set(root, namespaces);
  1782 + list_add_tail(&header->ctl_entry, &header->set->list);
1777 1783 spin_unlock(&sysctl_lock);
1778 1784  
1779 1785 return header;
... ... @@ -1832,6 +1838,15 @@
1832 1838 kfree(header);
1833 1839 }
1834 1840  
  1841 +void setup_sysctl_set(struct ctl_table_set *p,
  1842 + struct ctl_table_set *parent,
  1843 + int (*is_seen)(struct ctl_table_set *))
  1844 +{
  1845 + INIT_LIST_HEAD(&p->list);
  1846 + p->parent = parent ? parent : &sysctl_table_root.default_set;
  1847 + p->is_seen = is_seen;
  1848 +}
  1849 +
1835 1850 #else /* !CONFIG_SYSCTL */
1836 1851 struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
1837 1852 {
... ... @@ -1845,6 +1860,12 @@
1845 1860 }
1846 1861  
1847 1862 void unregister_sysctl_table(struct ctl_table_header * table)
  1863 +{
  1864 +}
  1865 +
  1866 +void setup_sysctl_set(struct ctl_table_set *p,
  1867 + struct ctl_table_set *parent,
  1868 + int (*is_seen)(struct ctl_table_set *))
1848 1869 {
1849 1870 }
1850 1871  
... ... @@ -29,12 +29,17 @@
29 29 #include <linux/if_tr.h>
30 30 #endif
31 31  
32   -static struct list_head *
  32 +static struct ctl_table_set *
33 33 net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
34 34 {
35   - return &namespaces->net_ns->sysctl_table_headers;
  35 + return &namespaces->net_ns->sysctls;
36 36 }
37 37  
  38 +static int is_seen(struct ctl_table_set *set)
  39 +{
  40 + return &current->nsproxy->net_ns->sysctls == set;
  41 +}
  42 +
38 43 /* Return standard mode bits for table entry. */
39 44 static int net_ctl_permissions(struct ctl_table_root *root,
40 45 struct nsproxy *nsproxy,
... ... @@ -53,13 +58,6 @@
53 58 .permissions = net_ctl_permissions,
54 59 };
55 60  
56   -static LIST_HEAD(net_sysctl_ro_tables);
57   -static struct list_head *net_ctl_ro_header_lookup(struct ctl_table_root *root,
58   - struct nsproxy *namespaces)
59   -{
60   - return &net_sysctl_ro_tables;
61   -}
62   -
63 61 static int net_ctl_ro_header_perms(struct ctl_table_root *root,
64 62 struct nsproxy *namespaces, struct ctl_table *table)
65 63 {
66 64  
67 65  
... ... @@ -70,19 +68,18 @@
70 68 }
71 69  
72 70 static struct ctl_table_root net_sysctl_ro_root = {
73   - .lookup = net_ctl_ro_header_lookup,
74 71 .permissions = net_ctl_ro_header_perms,
75 72 };
76 73  
77 74 static int sysctl_net_init(struct net *net)
78 75 {
79   - INIT_LIST_HEAD(&net->sysctl_table_headers);
  76 + setup_sysctl_set(&net->sysctls, NULL, is_seen);
80 77 return 0;
81 78 }
82 79  
83 80 static void sysctl_net_exit(struct net *net)
84 81 {
85   - WARN_ON(!list_empty(&net->sysctl_table_headers));
  82 + WARN_ON(!list_empty(&net->sysctls.list));
86 83 return;
87 84 }
88 85  
... ... @@ -98,6 +95,7 @@
98 95 if (ret)
99 96 goto out;
100 97 register_sysctl_root(&net_sysctl_root);
  98 + setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL);
101 99 register_sysctl_root(&net_sysctl_ro_root);
102 100 out:
103 101 return ret;