aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDenis V. Lunev <[email protected]>2008-04-29 01:02:00 -0700
committerLinus Torvalds <[email protected]>2008-04-29 08:06:20 -0700
commit59b7435149eab2dd06dd678742faff6049cb655f (patch)
treeceadbf157a001b83a3ab2c89156426e88a782208 /include/linux
parentb640a89ddd742782bd2d83873da30d4776d1b9c6 (diff)
proc: introduce proc_create_data to setup de->data
This set of patches fixes an proc ->open'less usage due to ->proc_fops flip in the most part of the kernel code. The original OOPS is described in the commit 2d3a4e3666325a9709cc8ea2e88151394e8f20fc: Typical PDE creation code looks like: pde = create_proc_entry("foo", 0, NULL); if (pde) pde->proc_fops = &foo_proc_fops; Notice that PDE is first created, only then ->proc_fops is set up to final value. This is a problem because right after creation a) PDE is fully visible in /proc , and b) ->proc_fops are proc_file_operations which do not have ->open callback. So, it's possible to ->read without ->open (see one class of oopses below). The fix is new API called proc_create() which makes sure ->proc_fops are set up before gluing PDE to main tree. Typical new code looks like: pde = proc_create("foo", 0, NULL, &foo_proc_fops); if (!pde) return -ENOMEM; Fix most networking users for a start. In the long run, create_proc_entry() for regular files will go. In addition to this, proc_create_data is introduced to fix reading from proc without PDE->data. The race is basically the same as above. create_proc_entries is replaced in the entire kernel code as new method is also simply better. This patch: The problem is the same as for de->proc_fops. Right now PDE becomes visible without data set. So, the entry could be looked up without data. This, in most cases, will simply OOPS. proc_create_data call is created to address this issue. proc_create now becomes a wrapper around it. Signed-off-by: Denis V. Lunev <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: "J. Bruce Fields" <[email protected]> Cc: Alessandro Zummo <[email protected]> Cc: Alexey Dobriyan <[email protected]> Cc: Bartlomiej Zolnierkiewicz <[email protected]> Cc: Benjamin Herrenschmidt <[email protected]> Cc: Bjorn Helgaas <[email protected]> Cc: Chris Mason <[email protected]> Acked-by: David Howells <[email protected]> Cc: Dmitry Torokhov <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Grant Grundler <[email protected]> Cc: Greg Kroah-Hartman <[email protected]> Cc: Haavard Skinnemoen <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Bottomley <[email protected]> Cc: Jaroslav Kysela <[email protected]> Cc: Jeff Garzik <[email protected]> Cc: Jeff Mahoney <[email protected]> Cc: Jesper Nilsson <[email protected]> Cc: Karsten Keil <[email protected]> Cc: Kyle McMartin <[email protected]> Cc: Len Brown <[email protected]> Cc: Martin Schwidefsky <[email protected]> Cc: Mathieu Desnoyers <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Mauro Carvalho Chehab <[email protected]> Cc: Mikael Starvik <[email protected]> Cc: Nadia Derbey <[email protected]> Cc: Neil Brown <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Peter Osterlund <[email protected]> Cc: Pierre Peiffer <[email protected]> Cc: Russell King <[email protected]> Cc: Takashi Iwai <[email protected]> Cc: Tony Luck <[email protected]> Cc: Trond Myklebust <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/proc_fs.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 29abcb805754..9883bc942262 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -116,9 +116,10 @@ void de_put(struct proc_dir_entry *de);
extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
struct proc_dir_entry *parent);
-struct proc_dir_entry *proc_create(const char *name, mode_t mode,
+struct proc_dir_entry *proc_create_data(const char *name, mode_t mode,
struct proc_dir_entry *parent,
- const struct file_operations *proc_fops);
+ const struct file_operations *proc_fops,
+ void *data);
extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
extern struct vfsmount *proc_mnt;
@@ -173,6 +174,12 @@ extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
extern struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
struct proc_dir_entry *parent);
+static inline struct proc_dir_entry *proc_create(const char *name, mode_t mode,
+ struct proc_dir_entry *parent, const struct file_operations *proc_fops)
+{
+ return proc_create_data(name, mode, parent, proc_fops, NULL);
+}
+
static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
mode_t mode, struct proc_dir_entry *base,
read_proc_t *read_proc, void * data)
@@ -214,6 +221,12 @@ static inline struct proc_dir_entry *proc_create(const char *name,
{
return NULL;
}
+static inline struct proc_dir_entry *proc_create_data(const char *name,
+ mode_t mode, struct proc_dir_entry *parent,
+ const struct file_operations *proc_fops, void *data)
+{
+ return NULL;
+}
#define remove_proc_entry(name, parent) do {} while (0)
static inline struct proc_dir_entry *proc_symlink(const char *name,