Commit 217bfb5190813d97e6003f7692f8014655ffc02a

Authored by Alexey Dobriyan
Committed by Kyle McMartin
1 parent 05920797ca

parisc: convert /proc/pdc/{lcd,led} 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>
Reviewed-by: Grant Grundler <grundler@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@mcmartin.ca>

Showing 1 changed file with 29 additions and 30 deletions Side-by-side Diff

drivers/parisc/led.c
... ... @@ -38,6 +38,7 @@
38 38 #include <linux/kernel_stat.h>
39 39 #include <linux/reboot.h>
40 40 #include <linux/proc_fs.h>
  41 +#include <linux/seq_file.h>
41 42 #include <linux/ctype.h>
42 43 #include <linux/blkdev.h>
43 44 #include <linux/workqueue.h>
44 45  
45 46  
46 47  
47 48  
48 49  
49 50  
50 51  
51 52  
... ... @@ -147,41 +148,34 @@
147 148 static void (*led_func_ptr) (unsigned char) __read_mostly;
148 149  
149 150 #ifdef CONFIG_PROC_FS
150   -static int led_proc_read(char *page, char **start, off_t off, int count,
151   - int *eof, void *data)
  151 +static int led_proc_show(struct seq_file *m, void *v)
152 152 {
153   - char *out = page;
154   - int len;
155   -
156   - switch ((long)data)
  153 + switch ((long)m->private)
157 154 {
158 155 case LED_NOLCD:
159   - out += sprintf(out, "Heartbeat: %d\n", led_heartbeat);
160   - out += sprintf(out, "Disk IO: %d\n", led_diskio);
161   - out += sprintf(out, "LAN Rx/Tx: %d\n", led_lanrxtx);
  156 + seq_printf(m, "Heartbeat: %d\n", led_heartbeat);
  157 + seq_printf(m, "Disk IO: %d\n", led_diskio);
  158 + seq_printf(m, "LAN Rx/Tx: %d\n", led_lanrxtx);
162 159 break;
163 160 case LED_HASLCD:
164   - out += sprintf(out, "%s\n", lcd_text);
  161 + seq_printf(m, "%s\n", lcd_text);
165 162 break;
166 163 default:
167   - *eof = 1;
168 164 return 0;
169 165 }
  166 + return 0;
  167 +}
170 168  
171   - len = out - page - off;
172   - if (len < count) {
173   - *eof = 1;
174   - if (len <= 0) return 0;
175   - } else {
176   - len = count;
177   - }
178   - *start = page + off;
179   - return len;
  169 +static int led_proc_open(struct inode *inode, struct file *file)
  170 +{
  171 + return single_open(file, led_proc_show, PDE(inode)->data);
180 172 }
181 173  
182   -static int led_proc_write(struct file *file, const char *buf,
183   - unsigned long count, void *data)
  174 +
  175 +static ssize_t led_proc_write(struct file *file, const char *buf,
  176 + size_t count, loff_t *pos)
184 177 {
  178 + void *data = PDE(file->f_path.dentry->d_inode)->data;
185 179 char *cur, lbuf[count + 1];
186 180 int d;
187 181  
... ... @@ -234,6 +228,15 @@
234 228 return -EINVAL;
235 229 }
236 230  
  231 +static const struct file_operations led_proc_fops = {
  232 + .owner = THIS_MODULE,
  233 + .open = led_proc_open,
  234 + .read = seq_read,
  235 + .llseek = seq_lseek,
  236 + .release = single_release,
  237 + .write = led_proc_write,
  238 +};
  239 +
237 240 static int __init led_create_procfs(void)
238 241 {
239 242 struct proc_dir_entry *proc_pdc_root = NULL;
240 243  
241 244  
242 245  
... ... @@ -243,19 +246,15 @@
243 246  
244 247 proc_pdc_root = proc_mkdir("pdc", 0);
245 248 if (!proc_pdc_root) return -1;
246   - ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
  249 + ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
  250 + &led_proc_fops, (void *)LED_NOLCD); /* LED */
247 251 if (!ent) return -1;
248   - ent->data = (void *)LED_NOLCD; /* LED */
249   - ent->read_proc = led_proc_read;
250   - ent->write_proc = led_proc_write;
251 252  
252 253 if (led_type == LED_HASLCD)
253 254 {
254   - ent = create_proc_entry("lcd", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
  255 + ent = proc_create_data("lcd", S_IRUGO|S_IWUSR, proc_pdc_root,
  256 + &led_proc_fops, (void *)LED_HASLCD); /* LCD */
255 257 if (!ent) return -1;
256   - ent->data = (void *)LED_HASLCD; /* LCD */
257   - ent->read_proc = led_proc_read;
258   - ent->write_proc = led_proc_write;
259 258 }
260 259  
261 260 return 0;