diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2009-12-14 21:00:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-15 11:53:24 -0500 |
commit | 0ead0f84e81a41c3e98aeceab04af8ab1bb08d1f (patch) | |
tree | ba5d354818d2ec0a8251b3f4a5c9b9bef1092e07 /arch/alpha/kernel | |
parent | 4614a696bd1c3a9af3a08f0e5874830a85b889d4 (diff) |
alpha: convert srm code to seq_file
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: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/alpha/kernel')
-rw-r--r-- | arch/alpha/kernel/srm_env.c | 65 |
1 files changed, 33 insertions, 32 deletions
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index d12af472e1c0..dbbf04f9230e 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/seq_file.h> | ||
36 | #include <asm/console.h> | 37 | #include <asm/console.h> |
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | #include <asm/machvec.h> | 39 | #include <asm/machvec.h> |
@@ -79,42 +80,41 @@ static srm_env_t srm_named_entries[] = { | |||
79 | static srm_env_t srm_numbered_entries[256]; | 80 | static srm_env_t srm_numbered_entries[256]; |
80 | 81 | ||
81 | 82 | ||
82 | static int | 83 | static int srm_env_proc_show(struct seq_file *m, void *v) |
83 | srm_env_read(char *page, char **start, off_t off, int count, int *eof, | ||
84 | void *data) | ||
85 | { | 84 | { |
86 | int nbytes; | ||
87 | unsigned long ret; | 85 | unsigned long ret; |
88 | srm_env_t *entry; | 86 | srm_env_t *entry; |
87 | char *page; | ||
89 | 88 | ||
90 | if (off != 0) { | 89 | entry = (srm_env_t *)m->private; |
91 | *eof = 1; | 90 | page = (char *)__get_free_page(GFP_USER); |
92 | return 0; | 91 | if (!page) |
93 | } | 92 | return -ENOMEM; |
94 | 93 | ||
95 | entry = (srm_env_t *) data; | 94 | ret = callback_getenv(entry->id, page, PAGE_SIZE); |
96 | ret = callback_getenv(entry->id, page, count); | ||
97 | 95 | ||
98 | if ((ret >> 61) == 0) { | 96 | if ((ret >> 61) == 0) { |
99 | nbytes = (int) ret; | 97 | seq_write(m, page, ret); |
100 | *eof = 1; | 98 | ret = 0; |
101 | } else | 99 | } else |
102 | nbytes = -EFAULT; | 100 | ret = -EFAULT; |
101 | free_page((unsigned long)page); | ||
102 | return ret; | ||
103 | } | ||
103 | 104 | ||
104 | return nbytes; | 105 | static int srm_env_proc_open(struct inode *inode, struct file *file) |
106 | { | ||
107 | return single_open(file, srm_env_proc_show, PDE(inode)->data); | ||
105 | } | 108 | } |
106 | 109 | ||
107 | static int | 110 | static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer, |
108 | srm_env_write(struct file *file, const char __user *buffer, unsigned long count, | 111 | size_t count, loff_t *pos) |
109 | void *data) | ||
110 | { | 112 | { |
111 | int res; | 113 | int res; |
112 | srm_env_t *entry; | 114 | srm_env_t *entry = PDE(file->f_path.dentry->d_inode)->data; |
113 | char *buf = (char *) __get_free_page(GFP_USER); | 115 | char *buf = (char *) __get_free_page(GFP_USER); |
114 | unsigned long ret1, ret2; | 116 | unsigned long ret1, ret2; |
115 | 117 | ||
116 | entry = (srm_env_t *) data; | ||
117 | |||
118 | if (!buf) | 118 | if (!buf) |
119 | return -ENOMEM; | 119 | return -ENOMEM; |
120 | 120 | ||
@@ -140,6 +140,15 @@ srm_env_write(struct file *file, const char __user *buffer, unsigned long count, | |||
140 | return res; | 140 | return res; |
141 | } | 141 | } |
142 | 142 | ||
143 | static const struct file_operations srm_env_proc_fops = { | ||
144 | .owner = THIS_MODULE, | ||
145 | .open = srm_env_proc_open, | ||
146 | .read = seq_read, | ||
147 | .llseek = seq_lseek, | ||
148 | .release = single_release, | ||
149 | .write = srm_env_proc_write, | ||
150 | }; | ||
151 | |||
143 | static void | 152 | static void |
144 | srm_env_cleanup(void) | 153 | srm_env_cleanup(void) |
145 | { | 154 | { |
@@ -245,15 +254,10 @@ srm_env_init(void) | |||
245 | */ | 254 | */ |
246 | entry = srm_named_entries; | 255 | entry = srm_named_entries; |
247 | while (entry->name && entry->id) { | 256 | while (entry->name && entry->id) { |
248 | entry->proc_entry = create_proc_entry(entry->name, | 257 | entry->proc_entry = proc_create_data(entry->name, 0644, named_dir, |
249 | 0644, named_dir); | 258 | &srm_env_proc_fops, entry); |
250 | if (!entry->proc_entry) | 259 | if (!entry->proc_entry) |
251 | goto cleanup; | 260 | goto cleanup; |
252 | |||
253 | entry->proc_entry->data = (void *) entry; | ||
254 | entry->proc_entry->read_proc = srm_env_read; | ||
255 | entry->proc_entry->write_proc = srm_env_write; | ||
256 | |||
257 | entry++; | 261 | entry++; |
258 | } | 262 | } |
259 | 263 | ||
@@ -264,15 +268,12 @@ srm_env_init(void) | |||
264 | entry = &srm_numbered_entries[var_num]; | 268 | entry = &srm_numbered_entries[var_num]; |
265 | entry->name = number[var_num]; | 269 | entry->name = number[var_num]; |
266 | 270 | ||
267 | entry->proc_entry = create_proc_entry(entry->name, | 271 | entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir, |
268 | 0644, numbered_dir); | 272 | &srm_env_proc_fops, entry); |
269 | if (!entry->proc_entry) | 273 | if (!entry->proc_entry) |
270 | goto cleanup; | 274 | goto cleanup; |
271 | 275 | ||
272 | entry->id = var_num; | 276 | entry->id = var_num; |
273 | entry->proc_entry->data = (void *) entry; | ||
274 | entry->proc_entry->read_proc = srm_env_read; | ||
275 | entry->proc_entry->write_proc = srm_env_write; | ||
276 | } | 277 | } |
277 | 278 | ||
278 | printk(KERN_INFO "%s: version %s loaded successfully\n", NAME, | 279 | printk(KERN_INFO "%s: version %s loaded successfully\n", NAME, |