diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 18:08:58 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-23 18:08:58 -0700 | 
| commit | f1d38e423a697b7aa06e12d3ca4753bcc1aa3531 (patch) | |
| tree | 1cbfd86070f724d5ffe53146d4c67edf14cccf98 /include/linux | |
| parent | dae430c6f6e5d0b98c238c340a41a39e221e8940 (diff) | |
| parent | 4e474a00d7ff746ed177ddae14fa8b2d4bad7a00 (diff) | |
| download | olio-linux-3.10-f1d38e423a697b7aa06e12d3ca4753bcc1aa3531.tar.xz olio-linux-3.10-f1d38e423a697b7aa06e12d3ca4753bcc1aa3531.zip  | |
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.h | 106 | 
1 files changed, 67 insertions, 39 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index bb9127dd814..c34b4c82b0d 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -932,34 +932,14 @@ enum  #include <linux/list.h>  #include <linux/rcupdate.h>  #include <linux/wait.h> +#include <linux/rbtree.h>  /* For the /proc/sys support */  struct ctl_table;  struct nsproxy;  struct ctl_table_root; - -struct ctl_table_set { -	struct list_head list; -	struct ctl_table_set *parent; -	int (*is_seen)(struct ctl_table_set *); -}; - -extern void setup_sysctl_set(struct ctl_table_set *p, -	struct ctl_table_set *parent, -	int (*is_seen)(struct ctl_table_set *)); -  struct ctl_table_header; - -extern void sysctl_head_get(struct ctl_table_header *); -extern void sysctl_head_put(struct ctl_table_header *); -extern int sysctl_is_seen(struct ctl_table_header *); -extern struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *); -extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev); -extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, -						struct ctl_table_header *prev); -extern void sysctl_head_finish(struct ctl_table_header *prev); -extern int sysctl_perm(struct ctl_table_root *root, -		struct ctl_table *table, int op); +struct ctl_dir;  typedef struct ctl_table ctl_table; @@ -1023,8 +1003,6 @@ static inline void *proc_sys_poll_event(struct ctl_table_poll *poll)  	return (void *)(unsigned long)atomic_read(&poll->event);  } -void proc_sys_poll_notify(struct ctl_table_poll *poll); -  #define __CTL_TABLE_POLL_INITIALIZER(name) {				\  	.event = ATOMIC_INIT(0),					\  	.wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.wait) } @@ -1039,21 +1017,16 @@ struct ctl_table  	void *data;  	int maxlen;  	umode_t mode; -	struct ctl_table *child; -	struct ctl_table *parent;	/* Automatically set */ +	struct ctl_table *child;	/* Deprecated */  	proc_handler *proc_handler;	/* Callback for text formatting */  	struct ctl_table_poll *poll;  	void *extra1;  	void *extra2;  }; -struct ctl_table_root { -	struct list_head root_list; -	struct ctl_table_set default_set; -	struct ctl_table_set *(*lookup)(struct ctl_table_root *root, -					   struct nsproxy *namespaces); -	int (*permissions)(struct ctl_table_root *root, -			struct nsproxy *namespaces, struct ctl_table *table); +struct ctl_node { +	struct rb_node node; +	struct ctl_table_header *header;  };  /* struct ctl_table_header is used to maintain dynamic lists of @@ -1063,9 +1036,9 @@ struct ctl_table_header  	union {  		struct {  			struct ctl_table *ctl_table; -			struct list_head ctl_entry;  			int used;  			int count; +			int nreg;  		};  		struct rcu_head rcu;  	}; @@ -1073,9 +1046,27 @@ struct ctl_table_header  	struct ctl_table *ctl_table_arg;  	struct ctl_table_root *root;  	struct ctl_table_set *set; -	struct ctl_table *attached_by; -	struct ctl_table *attached_to; -	struct ctl_table_header *parent; +	struct ctl_dir *parent; +	struct ctl_node *node; +}; + +struct ctl_dir { +	/* Header must be at the start of ctl_dir */ +	struct ctl_table_header header; +	struct rb_root root; +}; + +struct ctl_table_set { +	int (*is_seen)(struct ctl_table_set *); +	struct ctl_dir dir; +}; + +struct ctl_table_root { +	struct ctl_table_set default_set; +	struct ctl_table_set *(*lookup)(struct ctl_table_root *root, +					   struct nsproxy *namespaces); +	int (*permissions)(struct ctl_table_root *root, +			struct nsproxy *namespaces, struct ctl_table *table);  };  /* struct ctl_path describes where in the hierarchy a table is added */ @@ -1083,16 +1074,53 @@ struct ctl_path {  	const char *procname;  }; +#ifdef CONFIG_SYSCTL + +void proc_sys_poll_notify(struct ctl_table_poll *poll); + +extern void setup_sysctl_set(struct ctl_table_set *p, +	struct ctl_table_root *root, +	int (*is_seen)(struct ctl_table_set *)); +extern void retire_sysctl_set(struct ctl_table_set *set); +  void register_sysctl_root(struct ctl_table_root *root); +struct ctl_table_header *__register_sysctl_table( +	struct ctl_table_set *set, +	const char *path, struct ctl_table *table);  struct ctl_table_header *__register_sysctl_paths( -	struct ctl_table_root *root, struct nsproxy *namespaces, +	struct ctl_table_set *set,  	const struct ctl_path *path, struct ctl_table *table); +struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table);  struct ctl_table_header *register_sysctl_table(struct ctl_table * table);  struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,  						struct ctl_table *table);  void unregister_sysctl_table(struct ctl_table_header * table); -int sysctl_check_table(struct nsproxy *namespaces, struct ctl_table *table); + +extern int sysctl_init(void); +#else /* CONFIG_SYSCTL */ +static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table) +{ +	return NULL; +} + +static inline struct ctl_table_header *register_sysctl_paths( +			const struct ctl_path *path, struct ctl_table *table) +{ +	return NULL; +} + +static inline void unregister_sysctl_table(struct ctl_table_header * table) +{ +} + +static inline void setup_sysctl_set(struct ctl_table_set *p, +	struct ctl_table_root *root, +	int (*is_seen)(struct ctl_table_set *)) +{ +} + +#endif /* CONFIG_SYSCTL */  #endif /* __KERNEL__ */  |