aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-04-29 04:02:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:20 -0400
commit59b7435149eab2dd06dd678742faff6049cb655f (patch)
treeceadbf157a001b83a3ab2c89156426e88a782208 /fs/proc
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 <den@openvz.org> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: "J. Bruce Fields" <bfields@fieldses.org> Cc: Alessandro Zummo <a.zummo@towertech.it> Cc: Alexey Dobriyan <adobriyan@gmail.com> Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Bjorn Helgaas <bjorn.helgaas@hp.com> Cc: Chris Mason <chris.mason@oracle.com> Acked-by: David Howells <dhowells@redhat.com> Cc: Dmitry Torokhov <dtor@mail.ru> Cc: Geert Uytterhoeven <geert@linux-m68k.org> Cc: Grant Grundler <grundler@parisc-linux.org> Cc: Greg Kroah-Hartman <gregkh@suse.de> Cc: Haavard Skinnemoen <hskinnemoen@atmel.com> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: Jaroslav Kysela <perex@suse.cz> Cc: Jeff Garzik <jgarzik@pobox.com> Cc: Jeff Mahoney <jeffm@suse.com> Cc: Jesper Nilsson <jesper.nilsson@axis.com> Cc: Karsten Keil <kkeil@suse.de> Cc: Kyle McMartin <kyle@parisc-linux.org> Cc: Len Brown <lenb@kernel.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Cc: Matthew Wilcox <matthew@wil.cx> Cc: Mauro Carvalho Chehab <mchehab@infradead.org> Cc: Mikael Starvik <starvik@axis.com> Cc: Nadia Derbey <Nadia.Derbey@bull.net> Cc: Neil Brown <neilb@suse.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Osterlund <petero2@telia.com> Cc: Pierre Peiffer <peifferp@gmail.com> Cc: Russell King <rmk@arm.linux.org.uk> Cc: Takashi Iwai <tiwai@suse.de> Cc: Tony Luck <tony.luck@intel.com> Cc: Trond Myklebust <trond.myklebust@fys.uio.no> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/proc')
-rw-r--r--fs/proc/generic.c8
-rw-r--r--fs/proc/root.c2
2 files changed, 6 insertions, 4 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 0f3d97d41b0f..9d53b39a9cf8 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -675,9 +675,10 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
675 return ent; 675 return ent;
676} 676}
677 677
678struct proc_dir_entry *proc_create(const char *name, mode_t mode, 678struct proc_dir_entry *proc_create_data(const char *name, mode_t mode,
679 struct proc_dir_entry *parent, 679 struct proc_dir_entry *parent,
680 const struct file_operations *proc_fops) 680 const struct file_operations *proc_fops,
681 void *data)
681{ 682{
682 struct proc_dir_entry *pde; 683 struct proc_dir_entry *pde;
683 nlink_t nlink; 684 nlink_t nlink;
@@ -698,6 +699,7 @@ struct proc_dir_entry *proc_create(const char *name, mode_t mode,
698 if (!pde) 699 if (!pde)
699 goto out; 700 goto out;
700 pde->proc_fops = proc_fops; 701 pde->proc_fops = proc_fops;
702 pde->data = data;
701 if (proc_register(parent, pde) < 0) 703 if (proc_register(parent, pde) < 0)
702 goto out_free; 704 goto out_free;
703 return pde; 705 return pde;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index c741b45a5503..95117538a4f6 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -230,5 +230,5 @@ void pid_ns_release_proc(struct pid_namespace *ns)
230EXPORT_SYMBOL(proc_symlink); 230EXPORT_SYMBOL(proc_symlink);
231EXPORT_SYMBOL(proc_mkdir); 231EXPORT_SYMBOL(proc_mkdir);
232EXPORT_SYMBOL(create_proc_entry); 232EXPORT_SYMBOL(create_proc_entry);
233EXPORT_SYMBOL(proc_create); 233EXPORT_SYMBOL(proc_create_data);
234EXPORT_SYMBOL(remove_proc_entry); 234EXPORT_SYMBOL(remove_proc_entry);