Commit 0ead0f84e81a41c3e98aeceab04af8ab1bb08d1f

Authored by Alexey Dobriyan
Committed by Linus Torvalds
1 parent 4614a696bd

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>

Showing 1 changed file with 33 additions and 32 deletions Side-by-side Diff

arch/alpha/kernel/srm_env.c
... ... @@ -33,6 +33,7 @@
33 33 #include <linux/module.h>
34 34 #include <linux/init.h>
35 35 #include <linux/proc_fs.h>
  36 +#include <linux/seq_file.h>
36 37 #include <asm/console.h>
37 38 #include <asm/uaccess.h>
38 39 #include <asm/machvec.h>
39 40  
40 41  
41 42  
42 43  
43 44  
44 45  
45 46  
46 47  
47 48  
48 49  
... ... @@ -79,42 +80,41 @@
79 80 static srm_env_t srm_numbered_entries[256];
80 81  
81 82  
82   -static int
83   -srm_env_read(char *page, char **start, off_t off, int count, int *eof,
84   - void *data)
  83 +static int srm_env_proc_show(struct seq_file *m, void *v)
85 84 {
86   - int nbytes;
87 85 unsigned long ret;
88 86 srm_env_t *entry;
  87 + char *page;
89 88  
90   - if (off != 0) {
91   - *eof = 1;
92   - return 0;
93   - }
  89 + entry = (srm_env_t *)m->private;
  90 + page = (char *)__get_free_page(GFP_USER);
  91 + if (!page)
  92 + return -ENOMEM;
94 93  
95   - entry = (srm_env_t *) data;
96   - ret = callback_getenv(entry->id, page, count);
  94 + ret = callback_getenv(entry->id, page, PAGE_SIZE);
97 95  
98 96 if ((ret >> 61) == 0) {
99   - nbytes = (int) ret;
100   - *eof = 1;
  97 + seq_write(m, page, ret);
  98 + ret = 0;
101 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
108   -srm_env_write(struct file *file, const char __user *buffer, unsigned long count,
109   - void *data)
  110 +static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
  111 + size_t count, loff_t *pos)
110 112 {
111 113 int res;
112   - srm_env_t *entry;
  114 + srm_env_t *entry = PDE(file->f_path.dentry->d_inode)->data;
113 115 char *buf = (char *) __get_free_page(GFP_USER);
114 116 unsigned long ret1, ret2;
115 117  
116   - entry = (srm_env_t *) data;
117   -
118 118 if (!buf)
119 119 return -ENOMEM;
120 120  
... ... @@ -140,6 +140,15 @@
140 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 152 static void
144 153 srm_env_cleanup(void)
145 154 {
146 155  
... ... @@ -245,15 +254,10 @@
245 254 */
246 255 entry = srm_named_entries;
247 256 while (entry->name && entry->id) {
248   - entry->proc_entry = create_proc_entry(entry->name,
249   - 0644, named_dir);
  257 + entry->proc_entry = proc_create_data(entry->name, 0644, named_dir,
  258 + &srm_env_proc_fops, entry);
250 259 if (!entry->proc_entry)
251 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 261 entry++;
258 262 }
259 263  
260 264  
... ... @@ -264,15 +268,12 @@
264 268 entry = &srm_numbered_entries[var_num];
265 269 entry->name = number[var_num];
266 270  
267   - entry->proc_entry = create_proc_entry(entry->name,
268   - 0644, numbered_dir);
  271 + entry->proc_entry = proc_create_data(entry->name, 0644, numbered_dir,
  272 + &srm_env_proc_fops, entry);
269 273 if (!entry->proc_entry)
270 274 goto cleanup;
271 275  
272 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 279 printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,