diff options
| author | Denis V. Lunev <[email protected]> | 2008-04-29 01:02:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <[email protected]> | 2008-04-29 08:06:20 -0700 |
| commit | 59b7435149eab2dd06dd678742faff6049cb655f (patch) | |
| tree | ceadbf157a001b83a3ab2c89156426e88a782208 /include/linux | |
| parent | b640a89ddd742782bd2d83873da30d4776d1b9c6 (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.h | 17 |
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, |