Skip to content

Commit 9a58a80

Browse files
Alexey Dobriyandavem330
Alexey Dobriyan
authored andcommitted
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 786d7e1 "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>
1 parent 508e14b commit 9a58a80

File tree

21 files changed

+411
-458
lines changed

21 files changed

+411
-458
lines changed

Documentation/isdn/INTERFACE.CAPI

+5-4
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,11 @@ char *(*procinfo)(struct capi_ctr *ctrlr)
149149
pointer to a callback function returning the entry for the device in
150150
the CAPI controller info table, /proc/capi/controller
151151

152-
read_proc_t *ctr_read_proc
153-
pointer to the read_proc callback function for the device's proc file
154-
system entry, /proc/capi/controllers/<n>; will be called with a
155-
pointer to the device's capi_ctr structure as the last (data) argument
152+
const struct file_operations *proc_fops
153+
pointers to callback functions for the device's proc file
154+
system entry, /proc/capi/controllers/<n>; pointer to the device's
155+
capi_ctr structure is available from struct proc_dir_entry::data
156+
which is available from struct inode.
156157

157158
Note: Callback functions except send_message() are never called in interrupt
158159
context.

drivers/isdn/capi/capi.c

+35-64
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
3434
#include <linux/skbuff.h>
3535
#include <linux/proc_fs.h>
36+
#include <linux/seq_file.h>
3637
#include <linux/poll.h>
3738
#include <linux/capi.h>
3839
#include <linux/kernelcapi.h>
@@ -1407,114 +1408,84 @@ static void capinc_tty_exit(void)
14071408
* /proc/capi/capi20:
14081409
* minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
14091410
*/
1410-
static int proc_capidev_read_proc(char *page, char **start, off_t off,
1411-
int count, int *eof, void *data)
1411+
static int capi20_proc_show(struct seq_file *m, void *v)
14121412
{
14131413
struct capidev *cdev;
14141414
struct list_head *l;
1415-
int len = 0;
14161415

14171416
read_lock(&capidev_list_lock);
14181417
list_for_each(l, &capidev_list) {
14191418
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",
14211420
cdev->ap.applid,
14221421
cdev->ap.nrecvctlpkt,
14231422
cdev->ap.nrecvdatapkt,
14241423
cdev->ap.nsentctlpkt,
14251424
cdev->ap.nsentdatapkt);
1426-
if (len <= off) {
1427-
off -= len;
1428-
len = 0;
1429-
} else {
1430-
if (len-off > count)
1431-
goto endloop;
1432-
}
14331425
}
1434-
1435-
endloop:
14361426
read_unlock(&capidev_list_lock);
1437-
if (len < count)
1438-
*eof = 1;
1439-
if (len > count) len = count;
1440-
if (len < 0) len = 0;
1441-
return len;
1427+
return 0;
14421428
}
14431429

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+
14441443
/*
14451444
* /proc/capi/capi20ncci:
14461445
* applid ncci
14471446
*/
1448-
static int proc_capincci_read_proc(char *page, char **start, off_t off,
1449-
int count, int *eof, void *data)
1447+
static int capi20ncci_proc_show(struct seq_file *m, void *v)
14501448
{
14511449
struct capidev *cdev;
14521450
struct capincci *np;
14531451
struct list_head *l;
1454-
int len = 0;
14551452

14561453
read_lock(&capidev_list_lock);
14571454
list_for_each(l, &capidev_list) {
14581455
cdev = list_entry(l, struct capidev, list);
14591456
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",
14611458
cdev->ap.applid,
14621459
np->ncci);
1463-
if (len <= off) {
1464-
off -= len;
1465-
len = 0;
1466-
} else {
1467-
if (len-off > count)
1468-
goto endloop;
1469-
}
14701460
}
14711461
}
1472-
endloop:
14731462
read_unlock(&capidev_list_lock);
1474-
*start = page+off;
1475-
if (len < count)
1476-
*eof = 1;
1477-
if (len>count) len = count;
1478-
if (len<0) len = 0;
1479-
return len;
1463+
return 0;
14801464
}
14811465

1482-
static struct procfsentries {
1483-
char *name;
1484-
mode_t mode;
1485-
int (*read_proc)(char *page, char **start, off_t off,
1486-
int count, int *eof, void *data);
1487-
struct proc_dir_entry *procent;
1488-
} procfsentries[] = {
1489-
/* { "capi", S_IFDIR, 0 }, */
1490-
{ "capi/capi20", 0 , proc_capidev_read_proc },
1491-
{ "capi/capi20ncci", 0 , proc_capincci_read_proc },
1466+
static int capi20ncci_proc_open(struct inode *inode, struct file *file)
1467+
{
1468+
return single_open(file, capi20ncci_proc_show, NULL);
1469+
}
1470+
1471+
static const struct file_operations capi20ncci_proc_fops = {
1472+
.owner = THIS_MODULE,
1473+
.open = capi20ncci_proc_open,
1474+
.read = seq_read,
1475+
.llseek = seq_lseek,
1476+
.release = single_release,
14921477
};
14931478

14941479
static void __init proc_init(void)
14951480
{
1496-
int nelem = ARRAY_SIZE(procfsentries);
1497-
int i;
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-
}
1481+
proc_create("capi/capi20", 0, NULL, &capi20_proc_fops);
1482+
proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops);
15041483
}
15051484

15061485
static void __exit proc_exit(void)
15071486
{
1508-
int nelem = ARRAY_SIZE(procfsentries);
1509-
int i;
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-
}
1487+
remove_proc_entry("capi/capi20", NULL);
1488+
remove_proc_entry("capi/capi20ncci", NULL);
15181489
}
15191490

15201491
/* -------- init function and module interface ---------------------- */

drivers/isdn/capi/capidrv.c

+17-38
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <linux/isdn.h>
2525
#include <linux/isdnif.h>
2626
#include <linux/proc_fs.h>
27+
#include <linux/seq_file.h>
2728
#include <linux/capi.h>
2829
#include <linux/kernelcapi.h>
2930
#include <linux/ctype.h>
@@ -2229,59 +2230,37 @@ static void lower_callback(unsigned int cmd, u32 contr, void *data)
22292230
* /proc/capi/capidrv:
22302231
* nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
22312232
*/
2232-
static int proc_capidrv_read_proc(char *page, char **start, off_t off,
2233-
int count, int *eof, void *data)
2233+
static int capidrv_proc_show(struct seq_file *m, void *v)
22342234
{
2235-
int len = 0;
2236-
2237-
len += sprintf(page+len, "%lu %lu %lu %lu\n",
2235+
seq_printf(m, "%lu %lu %lu %lu\n",
22382236
global.ap.nrecvctlpkt,
22392237
global.ap.nrecvdatapkt,
22402238
global.ap.nsentctlpkt,
22412239
global.ap.nsentdatapkt);
2242-
if (off+count >= len)
2243-
*eof = 1;
2244-
if (len < off)
2245-
return 0;
2246-
*start = page + off;
2247-
return ((count < len-off) ? count : len-off);
2240+
return 0;
2241+
}
2242+
2243+
static int capidrv_proc_open(struct inode *inode, struct file *file)
2244+
{
2245+
return single_open(file, capidrv_proc_show, NULL);
22482246
}
22492247

2250-
static struct procfsentries {
2251-
char *name;
2252-
mode_t mode;
2253-
int (*read_proc)(char *page, char **start, off_t off,
2254-
int count, int *eof, void *data);
2255-
struct proc_dir_entry *procent;
2256-
} procfsentries[] = {
2257-
/* { "capi", S_IFDIR, 0 }, */
2258-
{ "capi/capidrv", 0 , proc_capidrv_read_proc },
2248+
static const struct file_operations capidrv_proc_fops = {
2249+
.owner = THIS_MODULE,
2250+
.open = capidrv_proc_open,
2251+
.read = seq_read,
2252+
.llseek = seq_lseek,
2253+
.release = single_release,
22592254
};
22602255

22612256
static void __init proc_init(void)
22622257
{
2263-
int nelem = ARRAY_SIZE(procfsentries);
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-
}
2258+
proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
22712259
}
22722260

22732261
static void __exit proc_exit(void)
22742262
{
2275-
int nelem = ARRAY_SIZE(procfsentries);
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-
}
2263+
remove_proc_entry("capi/capidrv", NULL);
22852264
}
22862265

22872266
static int __init capidrv_init(void)

drivers/isdn/capi/kcapi.c

+1-7
Original file line numberDiff line numberDiff line change
@@ -490,13 +490,7 @@ attach_capi_ctr(struct capi_ctr *card)
490490
card->traceflag = showcapimsgs;
491491

492492
sprintf(card->procfn, "capi/controllers/%d", card->cnr);
493-
card->procent = create_proc_entry(card->procfn, 0, NULL);
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-
}
493+
card->procent = proc_create_data(card->procfn, 0, NULL, card->proc_fops, card);
500494

501495
ncards++;
502496
printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n",

0 commit comments

Comments
 (0)