diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2009-12-14 21:00:11 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 11:53:25 -0500 |
commit | 6613c5e8603bc41741487828f48c6a4d701f7814 (patch) | |
tree | 821a045f88cbe2a03aed9aa4d8c56b0015b2b208 | |
parent | 2886a8bdfa007053b414ab01741a98c18c376a85 (diff) |
uml: convert to seq_file/proc_fops
Convert code away from ->read_proc/->write_proc interfaces. Switch to
proc_create()/proc_create_data() which make addition of proc entries
reliable wrt NULL ->proc_fops, NULL ->data and so on.
Problem with ->read_proc et al is described here commit
786d7e1612f0b0adb6046f19b906609e4fe8b1ba "Fix rmmod/read/write races in
/proc entries"
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 14 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 36 | ||||
-rw-r--r-- | arch/um/kernel/exitcode.c | 43 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 31 |
4 files changed, 70 insertions, 54 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index e14629c87de4..f0fa47f10e6c 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c | |||
@@ -833,8 +833,8 @@ static int __init mconsole_init(void) | |||
833 | 833 | ||
834 | __initcall(mconsole_init); | 834 | __initcall(mconsole_init); |
835 | 835 | ||
836 | static int write_proc_mconsole(struct file *file, const char __user *buffer, | 836 | static ssize_t mconsole_proc_write(struct file *file, |
837 | unsigned long count, void *data) | 837 | const char __user *buffer, size_t count, loff_t *pos) |
838 | { | 838 | { |
839 | char *buf; | 839 | char *buf; |
840 | 840 | ||
@@ -855,6 +855,11 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer, | |||
855 | return count; | 855 | return count; |
856 | } | 856 | } |
857 | 857 | ||
858 | static const struct file_operations mconsole_proc_fops = { | ||
859 | .owner = THIS_MODULE, | ||
860 | .write = mconsole_proc_write, | ||
861 | }; | ||
862 | |||
858 | static int create_proc_mconsole(void) | 863 | static int create_proc_mconsole(void) |
859 | { | 864 | { |
860 | struct proc_dir_entry *ent; | 865 | struct proc_dir_entry *ent; |
@@ -862,15 +867,12 @@ static int create_proc_mconsole(void) | |||
862 | if (notify_socket == NULL) | 867 | if (notify_socket == NULL) |
863 | return 0; | 868 | return 0; |
864 | 869 | ||
865 | ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); | 870 | ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_fops); |
866 | if (ent == NULL) { | 871 | if (ent == NULL) { |
867 | printk(KERN_INFO "create_proc_mconsole : create_proc_entry " | 872 | printk(KERN_INFO "create_proc_mconsole : create_proc_entry " |
868 | "failed\n"); | 873 | "failed\n"); |
869 | return 0; | 874 | return 0; |
870 | } | 875 | } |
871 | |||
872 | ent->read_proc = NULL; | ||
873 | ent->write_proc = write_proc_mconsole; | ||
874 | return 0; | 876 | return 0; |
875 | } | 877 | } |
876 | 878 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 635d16d90a80..5ff554677f40 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "linux/init.h" | 27 | #include "linux/init.h" |
28 | #include "linux/cdrom.h" | 28 | #include "linux/cdrom.h" |
29 | #include "linux/proc_fs.h" | 29 | #include "linux/proc_fs.h" |
30 | #include "linux/seq_file.h" | ||
30 | #include "linux/ctype.h" | 31 | #include "linux/ctype.h" |
31 | #include "linux/capability.h" | 32 | #include "linux/capability.h" |
32 | #include "linux/mm.h" | 33 | #include "linux/mm.h" |
@@ -200,23 +201,25 @@ static void make_proc_ide(void) | |||
200 | proc_ide = proc_mkdir("ide0", proc_ide_root); | 201 | proc_ide = proc_mkdir("ide0", proc_ide_root); |
201 | } | 202 | } |
202 | 203 | ||
203 | static int proc_ide_read_media(char *page, char **start, off_t off, int count, | 204 | static int fake_ide_media_proc_show(struct seq_file *m, void *v) |
204 | int *eof, void *data) | ||
205 | { | 205 | { |
206 | int len; | 206 | seq_puts(m, "disk\n"); |
207 | 207 | return 0; | |
208 | strcpy(page, "disk\n"); | 208 | } |
209 | len = strlen("disk\n"); | 209 | |
210 | len -= off; | 210 | static int fake_ide_media_proc_open(struct inode *inode, struct file *file) |
211 | if (len < count){ | 211 | { |
212 | *eof = 1; | 212 | return single_open(file, fake_ide_media_proc_show, NULL); |
213 | if (len <= 0) return 0; | ||
214 | } | ||
215 | else len = count; | ||
216 | *start = page + off; | ||
217 | return len; | ||
218 | } | 213 | } |
219 | 214 | ||
215 | static const struct file_operations fake_ide_media_proc_fops = { | ||
216 | .owner = THIS_MODULE, | ||
217 | .open = fake_ide_media_proc_open, | ||
218 | .read = seq_read, | ||
219 | .llseek = seq_lseek, | ||
220 | .release = single_release, | ||
221 | }; | ||
222 | |||
220 | static void make_ide_entries(const char *dev_name) | 223 | static void make_ide_entries(const char *dev_name) |
221 | { | 224 | { |
222 | struct proc_dir_entry *dir, *ent; | 225 | struct proc_dir_entry *dir, *ent; |
@@ -227,11 +230,8 @@ static void make_ide_entries(const char *dev_name) | |||
227 | dir = proc_mkdir(dev_name, proc_ide); | 230 | dir = proc_mkdir(dev_name, proc_ide); |
228 | if(!dir) return; | 231 | if(!dir) return; |
229 | 232 | ||
230 | ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir); | 233 | ent = proc_create("media", S_IRUGO, dir, &fake_ide_media_proc_fops); |
231 | if(!ent) return; | 234 | if(!ent) return; |
232 | ent->data = NULL; | ||
233 | ent->read_proc = proc_ide_read_media; | ||
234 | ent->write_proc = NULL; | ||
235 | snprintf(name, sizeof(name), "ide0/%s", dev_name); | 235 | snprintf(name, sizeof(name), "ide0/%s", dev_name); |
236 | proc_symlink(dev_name, proc_ide_root, name); | 236 | proc_symlink(dev_name, proc_ide_root, name); |
237 | } | 237 | } |
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c index 6540d2c9fbb7..829df49dee99 100644 --- a/arch/um/kernel/exitcode.c +++ b/arch/um/kernel/exitcode.c | |||
@@ -6,7 +6,9 @@ | |||
6 | #include <linux/ctype.h> | 6 | #include <linux/ctype.h> |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/module.h> | ||
9 | #include <linux/proc_fs.h> | 10 | #include <linux/proc_fs.h> |
11 | #include <linux/seq_file.h> | ||
10 | #include <linux/types.h> | 12 | #include <linux/types.h> |
11 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
12 | 14 | ||
@@ -16,30 +18,26 @@ | |||
16 | */ | 18 | */ |
17 | int uml_exitcode = 0; | 19 | int uml_exitcode = 0; |
18 | 20 | ||
19 | static int read_proc_exitcode(char *page, char **start, off_t off, | 21 | static int exitcode_proc_show(struct seq_file *m, void *v) |
20 | int count, int *eof, void *data) | ||
21 | { | 22 | { |
22 | int len, val; | 23 | int val; |
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Save uml_exitcode in a local so that we don't need to guarantee | 26 | * Save uml_exitcode in a local so that we don't need to guarantee |
26 | * that sprintf accesses it atomically. | 27 | * that sprintf accesses it atomically. |
27 | */ | 28 | */ |
28 | val = uml_exitcode; | 29 | val = uml_exitcode; |
29 | len = sprintf(page, "%d\n", val); | 30 | seq_printf(m, "%d\n", val); |
30 | len -= off; | 31 | return 0; |
31 | if (len <= off+count) | 32 | } |
32 | *eof = 1; | 33 | |
33 | *start = page + off; | 34 | static int exitcode_proc_open(struct inode *inode, struct file *file) |
34 | if (len > count) | 35 | { |
35 | len = count; | 36 | return single_open(file, exitcode_proc_show, NULL); |
36 | if (len < 0) | ||
37 | len = 0; | ||
38 | return len; | ||
39 | } | 37 | } |
40 | 38 | ||
41 | static int write_proc_exitcode(struct file *file, const char __user *buffer, | 39 | static ssize_t exitcode_proc_write(struct file *file, |
42 | unsigned long count, void *data) | 40 | const char __user *buffer, size_t count, loff_t *pos) |
43 | { | 41 | { |
44 | char *end, buf[sizeof("nnnnn\0")]; | 42 | char *end, buf[sizeof("nnnnn\0")]; |
45 | int tmp; | 43 | int tmp; |
@@ -55,20 +53,25 @@ static int write_proc_exitcode(struct file *file, const char __user *buffer, | |||
55 | return count; | 53 | return count; |
56 | } | 54 | } |
57 | 55 | ||
56 | static const struct file_operations exitcode_proc_fops = { | ||
57 | .owner = THIS_MODULE, | ||
58 | .open = exitcode_proc_open, | ||
59 | .read = seq_read, | ||
60 | .llseek = seq_lseek, | ||
61 | .release = single_release, | ||
62 | .write = exitcode_proc_write, | ||
63 | }; | ||
64 | |||
58 | static int make_proc_exitcode(void) | 65 | static int make_proc_exitcode(void) |
59 | { | 66 | { |
60 | struct proc_dir_entry *ent; | 67 | struct proc_dir_entry *ent; |
61 | 68 | ||
62 | ent = create_proc_entry("exitcode", 0600, NULL); | 69 | ent = proc_create("exitcode", 0600, NULL, &exitcode_proc_fops); |
63 | if (ent == NULL) { | 70 | if (ent == NULL) { |
64 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " | 71 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " |
65 | "/proc/exitcode\n"); | 72 | "/proc/exitcode\n"); |
66 | return 0; | 73 | return 0; |
67 | } | 74 | } |
68 | |||
69 | ent->read_proc = read_proc_exitcode; | ||
70 | ent->write_proc = write_proc_exitcode; | ||
71 | |||
72 | return 0; | 75 | return 0; |
73 | } | 76 | } |
74 | 77 | ||
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 4a28a1568d85..2f910a1b7454 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -9,11 +9,13 @@ | |||
9 | #include <linux/hardirq.h> | 9 | #include <linux/hardirq.h> |
10 | #include <linux/gfp.h> | 10 | #include <linux/gfp.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/module.h> | ||
12 | #include <linux/personality.h> | 13 | #include <linux/personality.h> |
13 | #include <linux/proc_fs.h> | 14 | #include <linux/proc_fs.h> |
14 | #include <linux/ptrace.h> | 15 | #include <linux/ptrace.h> |
15 | #include <linux/random.h> | 16 | #include <linux/random.h> |
16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
18 | #include <linux/seq_file.h> | ||
17 | #include <linux/tick.h> | 19 | #include <linux/tick.h> |
18 | #include <linux/threads.h> | 20 | #include <linux/threads.h> |
19 | #include <asm/current.h> | 21 | #include <asm/current.h> |
@@ -336,16 +338,19 @@ int get_using_sysemu(void) | |||
336 | return atomic_read(&using_sysemu); | 338 | return atomic_read(&using_sysemu); |
337 | } | 339 | } |
338 | 340 | ||
339 | static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) | 341 | static int sysemu_proc_show(struct seq_file *m, void *v) |
340 | { | 342 | { |
341 | if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) | 343 | seq_printf(m, "%d\n", get_using_sysemu()); |
342 | /* No overflow */ | 344 | return 0; |
343 | *eof = 1; | 345 | } |
344 | 346 | ||
345 | return strlen(buf); | 347 | static int sysemu_proc_open(struct inode *inode, struct file *file) |
348 | { | ||
349 | return single_open(file, sysemu_proc_show, NULL); | ||
346 | } | 350 | } |
347 | 351 | ||
348 | static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data) | 352 | static ssize_t sysemu_proc_write(struct file *file, const char __user *buf, |
353 | size_t count, loff_t *pos) | ||
349 | { | 354 | { |
350 | char tmp[2]; | 355 | char tmp[2]; |
351 | 356 | ||
@@ -358,13 +363,22 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned | |||
358 | return count; | 363 | return count; |
359 | } | 364 | } |
360 | 365 | ||
366 | static const struct file_operations sysemu_proc_fops = { | ||
367 | .owner = THIS_MODULE, | ||
368 | .open = sysemu_proc_open, | ||
369 | .read = seq_read, | ||
370 | .llseek = seq_lseek, | ||
371 | .release = single_release, | ||
372 | .write = sysemu_proc_write, | ||
373 | }; | ||
374 | |||
361 | int __init make_proc_sysemu(void) | 375 | int __init make_proc_sysemu(void) |
362 | { | 376 | { |
363 | struct proc_dir_entry *ent; | 377 | struct proc_dir_entry *ent; |
364 | if (!sysemu_supported) | 378 | if (!sysemu_supported) |
365 | return 0; | 379 | return 0; |
366 | 380 | ||
367 | ent = create_proc_entry("sysemu", 0600, NULL); | 381 | ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops); |
368 | 382 | ||
369 | if (ent == NULL) | 383 | if (ent == NULL) |
370 | { | 384 | { |
@@ -372,9 +386,6 @@ int __init make_proc_sysemu(void) | |||
372 | return 0; | 386 | return 0; |
373 | } | 387 | } |
374 | 388 | ||
375 | ent->read_proc = proc_read_sysemu; | ||
376 | ent->write_proc = proc_write_sysemu; | ||
377 | |||
378 | return 0; | 389 | return 0; |
379 | } | 390 | } |
380 | 391 | ||