diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2010-01-14 06:10:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-01-14 06:10:54 -0500 |
commit | 9a58a80a701bdb2d220cdab4914218df5b48d781 (patch) | |
tree | 01eeb65ec70f22ec326d0938d002cc6a2aec73e8 /drivers/isdn/capi | |
parent | 508e14b4a4fb1a824a14f2c5b8d7df67b313f8e4 (diff) |
proc_fops: convert drivers/isdn/ 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"
[akpm@linux-foundation.org: CONFIG_PROC_FS=n build fix]
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: Karsten Keil <keil@b1-systems.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/capi')
-rw-r--r-- | drivers/isdn/capi/capi.c | 99 | ||||
-rw-r--r-- | drivers/isdn/capi/capidrv.c | 55 | ||||
-rw-r--r-- | drivers/isdn/capi/kcapi.c | 8 |
3 files changed, 53 insertions, 109 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 65bf91e16a42..79f9364aded6 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | 33 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ |
34 | #include <linux/skbuff.h> | 34 | #include <linux/skbuff.h> |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/seq_file.h> | ||
36 | #include <linux/poll.h> | 37 | #include <linux/poll.h> |
37 | #include <linux/capi.h> | 38 | #include <linux/capi.h> |
38 | #include <linux/kernelcapi.h> | 39 | #include <linux/kernelcapi.h> |
@@ -1407,114 +1408,84 @@ static void capinc_tty_exit(void) | |||
1407 | * /proc/capi/capi20: | 1408 | * /proc/capi/capi20: |
1408 | * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt | 1409 | * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt |
1409 | */ | 1410 | */ |
1410 | static int proc_capidev_read_proc(char *page, char **start, off_t off, | 1411 | static int capi20_proc_show(struct seq_file *m, void *v) |
1411 | int count, int *eof, void *data) | ||
1412 | { | 1412 | { |
1413 | struct capidev *cdev; | 1413 | struct capidev *cdev; |
1414 | struct list_head *l; | 1414 | struct list_head *l; |
1415 | int len = 0; | ||
1416 | 1415 | ||
1417 | read_lock(&capidev_list_lock); | 1416 | read_lock(&capidev_list_lock); |
1418 | list_for_each(l, &capidev_list) { | 1417 | list_for_each(l, &capidev_list) { |
1419 | cdev = list_entry(l, struct capidev, list); | 1418 | cdev = list_entry(l, struct capidev, list); |
1420 | len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n", | 1419 | seq_printf(m, "0 %d %lu %lu %lu %lu\n", |
1421 | cdev->ap.applid, | 1420 | cdev->ap.applid, |
1422 | cdev->ap.nrecvctlpkt, | 1421 | cdev->ap.nrecvctlpkt, |
1423 | cdev->ap.nrecvdatapkt, | 1422 | cdev->ap.nrecvdatapkt, |
1424 | cdev->ap.nsentctlpkt, | 1423 | cdev->ap.nsentctlpkt, |
1425 | cdev->ap.nsentdatapkt); | 1424 | cdev->ap.nsentdatapkt); |
1426 | if (len <= off) { | ||
1427 | off -= len; | ||
1428 | len = 0; | ||
1429 | } else { | ||
1430 | if (len-off > count) | ||
1431 | goto endloop; | ||
1432 | } | ||
1433 | } | 1425 | } |
1434 | |||
1435 | endloop: | ||
1436 | read_unlock(&capidev_list_lock); | 1426 | read_unlock(&capidev_list_lock); |
1437 | if (len < count) | 1427 | return 0; |
1438 | *eof = 1; | ||
1439 | if (len > count) len = count; | ||
1440 | if (len < 0) len = 0; | ||
1441 | return len; | ||
1442 | } | 1428 | } |
1443 | 1429 | ||
1430 | static int capi20_proc_open(struct inode *inode, struct file *file) | ||
1431 | { | ||
1432 | return single_open(file, capi20_proc_show, NULL); | ||
1433 | } | ||
1434 | |||
1435 | static const struct file_operations capi20_proc_fops = { | ||
1436 | .owner = THIS_MODULE, | ||
1437 | .open = capi20_proc_open, | ||
1438 | .read = seq_read, | ||
1439 | .llseek = seq_lseek, | ||
1440 | .release = single_release, | ||
1441 | }; | ||
1442 | |||
1444 | /* | 1443 | /* |
1445 | * /proc/capi/capi20ncci: | 1444 | * /proc/capi/capi20ncci: |
1446 | * applid ncci | 1445 | * applid ncci |
1447 | */ | 1446 | */ |
1448 | static int proc_capincci_read_proc(char *page, char **start, off_t off, | 1447 | static int capi20ncci_proc_show(struct seq_file *m, void *v) |
1449 | int count, int *eof, void *data) | ||
1450 | { | 1448 | { |
1451 | struct capidev *cdev; | 1449 | struct capidev *cdev; |
1452 | struct capincci *np; | 1450 | struct capincci *np; |
1453 | struct list_head *l; | 1451 | struct list_head *l; |
1454 | int len = 0; | ||
1455 | 1452 | ||
1456 | read_lock(&capidev_list_lock); | 1453 | read_lock(&capidev_list_lock); |
1457 | list_for_each(l, &capidev_list) { | 1454 | list_for_each(l, &capidev_list) { |
1458 | cdev = list_entry(l, struct capidev, list); | 1455 | cdev = list_entry(l, struct capidev, list); |
1459 | for (np=cdev->nccis; np; np = np->next) { | 1456 | for (np=cdev->nccis; np; np = np->next) { |
1460 | len += sprintf(page+len, "%d 0x%x\n", | 1457 | seq_printf(m, "%d 0x%x\n", |
1461 | cdev->ap.applid, | 1458 | cdev->ap.applid, |
1462 | np->ncci); | 1459 | np->ncci); |
1463 | if (len <= off) { | ||
1464 | off -= len; | ||
1465 | len = 0; | ||
1466 | } else { | ||
1467 | if (len-off > count) | ||
1468 | goto endloop; | ||
1469 | } | ||
1470 | } | 1460 | } |
1471 | } | 1461 | } |
1472 | endloop: | ||
1473 | read_unlock(&capidev_list_lock); | 1462 | read_unlock(&capidev_list_lock); |
1474 | *start = page+off; | 1463 | return 0; |
1475 | if (len < count) | ||
1476 | *eof = 1; | ||
1477 | if (len>count) len = count; | ||
1478 | if (len<0) len = 0; | ||
1479 | return len; | ||
1480 | } | 1464 | } |
1481 | 1465 | ||
1482 | static struct procfsentries { | 1466 | static int capi20ncci_proc_open(struct inode *inode, struct file *file) |
1483 | char *name; | 1467 | { |
1484 | mode_t mode; | 1468 | return single_open(file, capi20ncci_proc_show, NULL); |
1485 | int (*read_proc)(char *page, char **start, off_t off, | 1469 | } |
1486 | int count, int *eof, void *data); | 1470 | |
1487 | struct proc_dir_entry *procent; | 1471 | static const struct file_operations capi20ncci_proc_fops = { |
1488 | } procfsentries[] = { | 1472 | .owner = THIS_MODULE, |
1489 | /* { "capi", S_IFDIR, 0 }, */ | 1473 | .open = capi20ncci_proc_open, |
1490 | { "capi/capi20", 0 , proc_capidev_read_proc }, | 1474 | .read = seq_read, |
1491 | { "capi/capi20ncci", 0 , proc_capincci_read_proc }, | 1475 | .llseek = seq_lseek, |
1476 | .release = single_release, | ||
1492 | }; | 1477 | }; |
1493 | 1478 | ||
1494 | static void __init proc_init(void) | 1479 | static void __init proc_init(void) |
1495 | { | 1480 | { |
1496 | int nelem = ARRAY_SIZE(procfsentries); | 1481 | proc_create("capi/capi20", 0, NULL, &capi20_proc_fops); |
1497 | int i; | 1482 | proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops); |
1498 | |||
1499 | for (i=0; i < nelem; i++) { | ||
1500 | struct procfsentries *p = procfsentries + i; | ||
1501 | p->procent = create_proc_entry(p->name, p->mode, NULL); | ||
1502 | if (p->procent) p->procent->read_proc = p->read_proc; | ||
1503 | } | ||
1504 | } | 1483 | } |
1505 | 1484 | ||
1506 | static void __exit proc_exit(void) | 1485 | static void __exit proc_exit(void) |
1507 | { | 1486 | { |
1508 | int nelem = ARRAY_SIZE(procfsentries); | 1487 | remove_proc_entry("capi/capi20", NULL); |
1509 | int i; | 1488 | remove_proc_entry("capi/capi20ncci", NULL); |
1510 | |||
1511 | for (i=nelem-1; i >= 0; i--) { | ||
1512 | struct procfsentries *p = procfsentries + i; | ||
1513 | if (p->procent) { | ||
1514 | remove_proc_entry(p->name, NULL); | ||
1515 | p->procent = NULL; | ||
1516 | } | ||
1517 | } | ||
1518 | } | 1489 | } |
1519 | 1490 | ||
1520 | /* -------- init function and module interface ---------------------- */ | 1491 | /* -------- init function and module interface ---------------------- */ |
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 66b7d7a86474..bb450152fb74 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/isdn.h> | 24 | #include <linux/isdn.h> |
25 | #include <linux/isdnif.h> | 25 | #include <linux/isdnif.h> |
26 | #include <linux/proc_fs.h> | 26 | #include <linux/proc_fs.h> |
27 | #include <linux/seq_file.h> | ||
27 | #include <linux/capi.h> | 28 | #include <linux/capi.h> |
28 | #include <linux/kernelcapi.h> | 29 | #include <linux/kernelcapi.h> |
29 | #include <linux/ctype.h> | 30 | #include <linux/ctype.h> |
@@ -2229,59 +2230,37 @@ static void lower_callback(unsigned int cmd, u32 contr, void *data) | |||
2229 | * /proc/capi/capidrv: | 2230 | * /proc/capi/capidrv: |
2230 | * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt | 2231 | * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt |
2231 | */ | 2232 | */ |
2232 | static int proc_capidrv_read_proc(char *page, char **start, off_t off, | 2233 | static int capidrv_proc_show(struct seq_file *m, void *v) |
2233 | int count, int *eof, void *data) | ||
2234 | { | 2234 | { |
2235 | int len = 0; | 2235 | seq_printf(m, "%lu %lu %lu %lu\n", |
2236 | |||
2237 | len += sprintf(page+len, "%lu %lu %lu %lu\n", | ||
2238 | global.ap.nrecvctlpkt, | 2236 | global.ap.nrecvctlpkt, |
2239 | global.ap.nrecvdatapkt, | 2237 | global.ap.nrecvdatapkt, |
2240 | global.ap.nsentctlpkt, | 2238 | global.ap.nsentctlpkt, |
2241 | global.ap.nsentdatapkt); | 2239 | global.ap.nsentdatapkt); |
2242 | if (off+count >= len) | 2240 | return 0; |
2243 | *eof = 1; | 2241 | } |
2244 | if (len < off) | 2242 | |
2245 | return 0; | 2243 | static int capidrv_proc_open(struct inode *inode, struct file *file) |
2246 | *start = page + off; | 2244 | { |
2247 | return ((count < len-off) ? count : len-off); | 2245 | return single_open(file, capidrv_proc_show, NULL); |
2248 | } | 2246 | } |
2249 | 2247 | ||
2250 | static struct procfsentries { | 2248 | static const struct file_operations capidrv_proc_fops = { |
2251 | char *name; | 2249 | .owner = THIS_MODULE, |
2252 | mode_t mode; | 2250 | .open = capidrv_proc_open, |
2253 | int (*read_proc)(char *page, char **start, off_t off, | 2251 | .read = seq_read, |
2254 | int count, int *eof, void *data); | 2252 | .llseek = seq_lseek, |
2255 | struct proc_dir_entry *procent; | 2253 | .release = single_release, |
2256 | } procfsentries[] = { | ||
2257 | /* { "capi", S_IFDIR, 0 }, */ | ||
2258 | { "capi/capidrv", 0 , proc_capidrv_read_proc }, | ||
2259 | }; | 2254 | }; |
2260 | 2255 | ||
2261 | static void __init proc_init(void) | 2256 | static void __init proc_init(void) |
2262 | { | 2257 | { |
2263 | int nelem = ARRAY_SIZE(procfsentries); | 2258 | proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops); |
2264 | int i; | ||
2265 | |||
2266 | for (i=0; i < nelem; i++) { | ||
2267 | struct procfsentries *p = procfsentries + i; | ||
2268 | p->procent = create_proc_entry(p->name, p->mode, NULL); | ||
2269 | if (p->procent) p->procent->read_proc = p->read_proc; | ||
2270 | } | ||
2271 | } | 2259 | } |
2272 | 2260 | ||
2273 | static void __exit proc_exit(void) | 2261 | static void __exit proc_exit(void) |
2274 | { | 2262 | { |
2275 | int nelem = ARRAY_SIZE(procfsentries); | 2263 | remove_proc_entry("capi/capidrv", NULL); |
2276 | int i; | ||
2277 | |||
2278 | for (i=nelem-1; i >= 0; i--) { | ||
2279 | struct procfsentries *p = procfsentries + i; | ||
2280 | if (p->procent) { | ||
2281 | remove_proc_entry(p->name, NULL); | ||
2282 | p->procent = NULL; | ||
2283 | } | ||
2284 | } | ||
2285 | } | 2264 | } |
2286 | 2265 | ||
2287 | static int __init capidrv_init(void) | 2266 | static int __init capidrv_init(void) |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index dc506ab99cac..b0bacf377c18 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -490,13 +490,7 @@ attach_capi_ctr(struct capi_ctr *card) | |||
490 | card->traceflag = showcapimsgs; | 490 | card->traceflag = showcapimsgs; |
491 | 491 | ||
492 | sprintf(card->procfn, "capi/controllers/%d", card->cnr); | 492 | sprintf(card->procfn, "capi/controllers/%d", card->cnr); |
493 | card->procent = create_proc_entry(card->procfn, 0, NULL); | 493 | card->procent = proc_create_data(card->procfn, 0, NULL, card->proc_fops, card); |
494 | if (card->procent) { | ||
495 | card->procent->read_proc = | ||
496 | (int (*)(char *,char **,off_t,int,int *,void *)) | ||
497 | card->ctr_read_proc; | ||
498 | card->procent->data = card; | ||
499 | } | ||
500 | 494 | ||
501 | ncards++; | 495 | ncards++; |
502 | printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", | 496 | printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", |