Commit 217bfb5190813d97e6003f7692f8014655ffc02a
Committed by
Kyle McMartin
1 parent
05920797ca
Exists in
master
and in
4 other branches
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; |