2005-04-17 06:20:36 +08:00
|
|
|
/*
|
|
|
|
* The proc filesystem constants/structures
|
|
|
|
*/
|
2013-04-11 20:34:43 +08:00
|
|
|
#ifndef _LINUX_PROC_FS_H
|
|
|
|
#define _LINUX_PROC_FS_H
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2013-04-11 20:34:43 +08:00
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/fs.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2013-04-11 20:34:43 +08:00
|
|
|
struct proc_dir_entry;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
|
|
|
|
extern void proc_root_init(void);
|
2013-04-11 20:34:43 +08:00
|
|
|
extern void proc_flush_task(struct task_struct *);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
extern struct proc_dir_entry *proc_symlink(const char *,
|
|
|
|
struct proc_dir_entry *, const char *);
|
2013-04-11 20:34:43 +08:00
|
|
|
extern struct proc_dir_entry *proc_mkdir(const char *, struct proc_dir_entry *);
|
2013-04-12 09:48:30 +08:00
|
|
|
extern struct proc_dir_entry *proc_mkdir_data(const char *, umode_t,
|
|
|
|
struct proc_dir_entry *, void *);
|
2013-04-11 20:34:43 +08:00
|
|
|
extern struct proc_dir_entry *proc_mkdir_mode(const char *, umode_t,
|
|
|
|
struct proc_dir_entry *);
|
|
|
|
|
|
|
|
extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
|
|
|
|
struct proc_dir_entry *,
|
|
|
|
const struct file_operations *,
|
|
|
|
void *);
|
|
|
|
|
|
|
|
static inline struct proc_dir_entry *proc_create(
|
|
|
|
const char *name, umode_t mode, struct proc_dir_entry *parent,
|
|
|
|
const struct file_operations *proc_fops)
|
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>
2008-04-29 16:02:00 +08:00
|
|
|
{
|
|
|
|
return proc_create_data(name, mode, parent, proc_fops, NULL);
|
|
|
|
}
|
2013-04-11 20:34:43 +08:00
|
|
|
|
2013-04-12 07:38:51 +08:00
|
|
|
extern void proc_set_size(struct proc_dir_entry *, loff_t);
|
|
|
|
extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t);
|
2013-04-13 01:03:36 +08:00
|
|
|
extern void *PDE_DATA(const struct inode *);
|
2013-04-12 21:06:01 +08:00
|
|
|
extern void *proc_get_parent_data(const struct inode *);
|
2013-04-11 20:34:43 +08:00
|
|
|
extern void proc_remove(struct proc_dir_entry *);
|
|
|
|
extern void remove_proc_entry(const char *, struct proc_dir_entry *);
|
|
|
|
extern int remove_proc_subtree(const char *, struct proc_dir_entry *);
|
|
|
|
|
|
|
|
#else /* CONFIG_PROC_FS */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2014-06-05 07:12:20 +08:00
|
|
|
static inline void proc_root_init(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-10-19 14:40:03 +08:00
|
|
|
static inline void proc_flush_task(struct task_struct *task)
|
|
|
|
{
|
|
|
|
}
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
static inline struct proc_dir_entry *proc_symlink(const char *name,
|
2013-04-11 20:34:43 +08:00
|
|
|
struct proc_dir_entry *parent,const char *dest) { return NULL;}
|
2005-04-17 06:20:36 +08:00
|
|
|
static inline struct proc_dir_entry *proc_mkdir(const char *name,
|
|
|
|
struct proc_dir_entry *parent) {return NULL;}
|
2013-04-12 09:48:30 +08:00
|
|
|
static inline struct proc_dir_entry *proc_mkdir_data(const char *name,
|
|
|
|
umode_t mode, struct proc_dir_entry *parent, void *data) { return NULL; }
|
2011-05-18 06:44:12 +08:00
|
|
|
static inline struct proc_dir_entry *proc_mkdir_mode(const char *name,
|
2011-07-24 15:36:29 +08:00
|
|
|
umode_t mode, struct proc_dir_entry *parent) { return NULL; }
|
2013-04-11 20:34:43 +08:00
|
|
|
#define proc_create(name, mode, parent, proc_fops) ({NULL;})
|
|
|
|
#define proc_create_data(name, mode, parent, proc_fops, data) ({NULL;})
|
|
|
|
|
2013-04-12 07:38:51 +08:00
|
|
|
static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {}
|
|
|
|
static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {}
|
2013-04-13 01:03:36 +08:00
|
|
|
static inline void *PDE_DATA(const struct inode *inode) {BUG(); return NULL;}
|
2013-04-11 20:34:43 +08:00
|
|
|
static inline void *proc_get_parent_data(const struct inode *inode) { BUG(); return NULL; }
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2013-04-11 20:34:43 +08:00
|
|
|
static inline void proc_remove(struct proc_dir_entry *de) {}
|
|
|
|
#define remove_proc_entry(name, parent) do {} while (0)
|
|
|
|
static inline int remove_proc_subtree(const char *name, struct proc_dir_entry *parent) { return 0; }
|
2008-07-15 20:54:06 +08:00
|
|
|
|
2013-04-11 20:34:43 +08:00
|
|
|
#endif /* CONFIG_PROC_FS */
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2013-04-12 09:48:30 +08:00
|
|
|
static inline struct proc_dir_entry *proc_net_mkdir(
|
|
|
|
struct net *net, const char *name, struct proc_dir_entry *parent)
|
|
|
|
{
|
|
|
|
return proc_mkdir_data(name, 0, parent, net);
|
|
|
|
}
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
#endif /* _LINUX_PROC_FS_H */
|