aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 21:08:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-23 21:08:58 -0400
commitf1d38e423a697b7aa06e12d3ca4753bcc1aa3531 (patch)
tree1cbfd86070f724d5ffe53146d4c67edf14cccf98 /include/linux
parentdae430c6f6e5d0b98c238c340a41a39e221e8940 (diff)
parent4e474a00d7ff746ed177ddae14fa8b2d4bad7a00 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/sysctl
Pull sysctl updates from Eric Biederman: - Rewrite of sysctl for speed and clarity. Insert/remove/Lookup in sysctl are all now O(NlogN) operations, and are no longer bottlenecks in the process of adding and removing network devices. sysctl is now focused on being a filesystem instead of system call and the code can all be found in fs/proc/proc_sysctl.c. Hopefully this means the code is now approachable. Much thanks is owed to Lucian Grinjincu for keeping at this until something was found that was usable. - The recent proc_sys_poll oops found by the fuzzer during hibernation is fixed. * git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/sysctl: (36 commits) sysctl: protect poll() in entries that may go away sysctl: Don't call sysctl_follow_link unless we are a link. sysctl: Comments to make the code clearer. sysctl: Correct error return from get_subdir sysctl: An easier to read version of find_subdir sysctl: fix memset parameters in setup_sysctl_set() sysctl: remove an unused variable sysctl: Add register_sysctl for normal sysctl users sysctl: Index sysctl directories with rbtrees. sysctl: Make the header lists per directory. sysctl: Move sysctl_check_dups into insert_header sysctl: Modify __register_sysctl_paths to take a set instead of a root and an nsproxy sysctl: Replace root_list with links between sysctl_table_sets. sysctl: Add sysctl_print_dir and use it in get_subdir sysctl: Stop requiring explicit management of sysctl directories sysctl: Add a root pointer to ctl_table_set sysctl: Rewrite proc_sys_readdir in terms of first_entry and next_entry sysctl: Rewrite proc_sys_lookup introducing find_entry and lookup_entry. sysctl: Normalize the root_table data structure. sysctl: Factor out insert_header and erase_header ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/sysctl.h106
1 files changed, 67 insertions, 39 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index bb9127dd814b..c34b4c82b0dc 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -932,34 +932,14 @@ enum
932#include <linux/list.h> 932#include <linux/list.h>
933#include <linux/rcupdate.h> 933#include <linux/rcupdate.h>
934#include <linux/wait.h> 934#include <linux/wait.h>
935#include <linux/rbtree.h>
935 936
936/* For the /proc/sys support */ 937/* For the /proc/sys support */
937struct ctl_table; 938struct ctl_table;
938struct nsproxy; 939struct nsproxy;
939struct ctl_table_root; 940struct ctl_table_root;
940
941struct ctl_table_set {
942 struct list_head list;
943 struct ctl_table_set *parent;
944 int (*is_seen)(struct ctl_table_set *);
945};
946
947extern void setup_sysctl_set(struct ctl_table_set *p,
948 struct ctl_table_set *parent,
949 int (*is_seen)(struct ctl_table_set *));
950
951struct ctl_table_header; 941struct ctl_table_header;
952 942struct ctl_dir;
953extern void sysctl_head_get(struct ctl_table_header *);
954extern void sysctl_head_put(struct ctl_table_header *);
955extern int sysctl_is_seen(struct ctl_table_header *);
956extern struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *);
957extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev);
958extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
959 struct ctl_table_header *prev);
960extern void sysctl_head_finish(struct ctl_table_header *prev);
961extern int sysctl_perm(struct ctl_table_root *root,
962 struct ctl_table *table, int op);
963 943
964typedef struct ctl_table ctl_table; 944typedef struct ctl_table ctl_table;
965 945
@@ -1023,8 +1003,6 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)
1023 return (void *)(unsigned long)atomic_read(&poll->event); 1003 return (void *)(unsigned long)atomic_read(&poll->event);
1024} 1004}
1025 1005
1026void proc_sys_poll_notify(struct ctl_table_poll *poll);
1027
1028#define __CTL_TABLE_POLL_INITIALIZER(name) { \ 1006#define __CTL_TABLE_POLL_INITIALIZER(name) { \
1029 .event = ATOMIC_INIT(0), \ 1007 .event = ATOMIC_INIT(0), \
1030 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait) } 1008 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait) }
@@ -1039,21 +1017,16 @@ struct ctl_table
1039 void *data; 1017 void *data;
1040 int maxlen; 1018 int maxlen;
1041 umode_t mode; 1019 umode_t mode;
1042 struct ctl_table *child; 1020 struct ctl_table *child; /* Deprecated */
1043 struct ctl_table *parent; /* Automatically set */
1044 proc_handler *proc_handler; /* Callback for text formatting */ 1021 proc_handler *proc_handler; /* Callback for text formatting */
1045 struct ctl_table_poll *poll; 1022 struct ctl_table_poll *poll;
1046 void *extra1; 1023 void *extra1;
1047 void *extra2; 1024 void *extra2;
1048}; 1025};
1049 1026
1050struct ctl_table_root { 1027struct ctl_node {
1051 struct list_head root_list; 1028 struct rb_node node;
1052 struct ctl_table_set default_set; 1029 struct ctl_table_header *header;
1053 struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
1054 struct nsproxy *namespaces);
1055 int (*permissions)(struct ctl_table_root *root,
1056 struct nsproxy *namespaces, struct ctl_table *table);
1057}; 1030};
1058 1031
1059/* struct ctl_table_header is used to maintain dynamic lists of 1032/* struct ctl_table_header is used to maintain dynamic lists of
@@ -1063,9 +1036,9 @@ struct ctl_table_header
1063 union { 1036 union {
1064 struct { 1037 struct {
1065 struct ctl_table *ctl_table; 1038 struct ctl_table *ctl_table;
1066 struct list_head ctl_entry;
1067 int used; 1039 int used;
1068 int count; 1040 int count;
1041 int nreg;
1069 }; 1042 };
1070 struct rcu_head rcu; 1043 struct rcu_head rcu;
1071 }; 1044 };
@@ -1073,9 +1046,27 @@ struct ctl_table_header
1073 struct ctl_table *ctl_table_arg; 1046 struct ctl_table *ctl_table_arg;
1074 struct ctl_table_root *root; 1047 struct ctl_table_root *root;
1075 struct ctl_table_set *set; 1048 struct ctl_table_set *set;
1076 struct ctl_table *attached_by; 1049 struct ctl_dir *parent;
1077 struct ctl_table *attached_to; 1050 struct ctl_node *node;
1078 struct ctl_table_header *parent; 1051};
1052
1053struct ctl_dir {
1054 /* Header must be at the start of ctl_dir */
1055 struct ctl_table_header header;
1056 struct rb_root root;
1057};
1058
1059struct ctl_table_set {
1060 int (*is_seen)(struct ctl_table_set *);
1061 struct ctl_dir dir;
1062};
1063
1064struct ctl_table_root {
1065 struct ctl_table_set default_set;
1066 struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
1067 struct nsproxy *namespaces);
1068 int (*permissions)(struct ctl_table_root *root,
1069 struct nsproxy *namespaces, struct ctl_table *table);
1079}; 1070};
1080 1071
1081/* struct ctl_path describes where in the hierarchy a table is added */ 1072/* struct ctl_path describes where in the hierarchy a table is added */
@@ -1083,16 +1074,53 @@ struct ctl_path {
1083 const char *procname; 1074 const char *procname;
1084}; 1075};
1085 1076
1077#ifdef CONFIG_SYSCTL
1078
1079void proc_sys_poll_notify(struct ctl_table_poll *poll);
1080
1081extern void setup_sysctl_set(struct ctl_table_set *p,
1082 struct ctl_table_root *root,
1083 int (*is_seen)(struct ctl_table_set *));
1084extern void retire_sysctl_set(struct ctl_table_set *set);
1085
1086void register_sysctl_root(struct ctl_table_root *root); 1086void register_sysctl_root(struct ctl_table_root *root);
1087struct ctl_table_header *__register_sysctl_table(
1088 struct ctl_table_set *set,
1089 const char *path, struct ctl_table *table);
1087struct ctl_table_header *__register_sysctl_paths( 1090struct ctl_table_header *__register_sysctl_paths(
1088 struct ctl_table_root *root, struct nsproxy *namespaces, 1091 struct ctl_table_set *set,
1089 const struct ctl_path *path, struct ctl_table *table); 1092 const struct ctl_path *path, struct ctl_table *table);
1093struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table);
1090struct ctl_table_header *register_sysctl_table(struct ctl_table * table); 1094struct ctl_table_header *register_sysctl_table(struct ctl_table * table);
1091struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path, 1095struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
1092 struct ctl_table *table); 1096 struct ctl_table *table);
1093 1097
1094void unregister_sysctl_table(struct ctl_table_header * table); 1098void unregister_sysctl_table(struct ctl_table_header * table);
1095int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table); 1099
1100extern int sysctl_init(void);
1101#else /* CONFIG_SYSCTL */
1102static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
1103{
1104 return NULL;
1105}
1106
1107static inline struct ctl_table_header *register_sysctl_paths(
1108 const struct ctl_path *path, struct ctl_table *table)
1109{
1110 return NULL;
1111}
1112
1113static inline void unregister_sysctl_table(struct ctl_table_header * table)
1114{
1115}
1116
1117static inline void setup_sysctl_set(struct ctl_table_set *p,
1118 struct ctl_table_root *root,
1119 int (*is_seen)(struct ctl_table_set *))
1120{
1121}
1122
1123#endif /* CONFIG_SYSCTL */
1096 1124
1097#endif /* __KERNEL__ */ 1125#endif /* __KERNEL__ */
1098 1126