These are error prone, so return void adn use seq_has_overflowed instead
Joe Perches (2):
seq_puts: Convert to return void and convert uses too.
seq_putc: Convert to return void and convert uses too.
drivers/char/ipmi/ipmi_msghandler.c | 4 +-
drivers/parisc/ccio-dma.c | 7 +-
drivers/regulator/dbx500-prcmu.c | 21 ++----
drivers/usb/gadget/udc/goku_udc.c | 81 +++++++++++-----------
drivers/watchdog/bcm_kona_wdt.c | 43 +++++++-----
fs/seq_file.c | 26 +++----
include/linux/seq_file.h | 4 +-
ipc/util.c | 6 +-
.../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 +-
net/netfilter/nf_conntrack_expect.c | 4 +-
10 files changed, 105 insertions(+), 95 deletions(-)
--
2.1.2
Using the return value of seq_puts is error-prone, so
make it return void instead.
Use seq_has_overflowed where appropriate instead of the
old return value.
Signed-off-by: Joe Perches <[email protected]>
---
drivers/parisc/ccio-dma.c | 7 ++--
drivers/regulator/dbx500-prcmu.c | 21 ++++------
drivers/usb/gadget/udc/goku_udc.c | 81 ++++++++++++++++++++-------------------
drivers/watchdog/bcm_kona_wdt.c | 43 ++++++++++++---------
fs/seq_file.c | 15 ++++----
include/linux/seq_file.h | 2 +-
ipc/util.c | 6 ++-
7 files changed, 89 insertions(+), 86 deletions(-)
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 8b490d7..c40cc98 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1101,7 +1101,6 @@ static const struct file_operations ccio_proc_info_fops = {
static int ccio_proc_bitmap_info(struct seq_file *m, void *p)
{
- int len = 0;
struct ioc *ioc = ioc_list;
while (ioc != NULL) {
@@ -1110,11 +1109,11 @@ static int ccio_proc_bitmap_info(struct seq_file *m, void *p)
for (j = 0; j < (ioc->res_size / sizeof(u32)); j++) {
if ((j & 7) == 0)
- len += seq_puts(m, "\n ");
- len += seq_printf(m, "%08x", *res_ptr);
+ seq_puts(m, "\n ");
+ seq_printf(m, "%08x", *res_ptr);
res_ptr++;
}
- len += seq_puts(m, "\n\n");
+ seq_puts(m, "\n\n");
ioc = ioc->next;
break; /* XXX - remove me */
}
diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c
index 2d16b9f..b778ca9 100644
--- a/drivers/regulator/dbx500-prcmu.c
+++ b/drivers/regulator/dbx500-prcmu.c
@@ -129,14 +129,8 @@ static int ux500_regulator_status_print(struct seq_file *s, void *p)
int i;
/* print dump header */
- err = seq_puts(s, "ux500-regulator status:\n");
- if (err < 0)
- dev_err(dev, "seq_puts overflow\n");
-
- err = seq_printf(s, "%31s : %8s : %8s\n", "current",
- "before", "after");
- if (err < 0)
- dev_err(dev, "seq_printf overflow\n");
+ seq_puts(s, "ux500-regulator status:\n");
+ seq_printf(s, "%31s : %8s : %8s\n", "current", "before", "after");
for (i = 0; i < rdebug.num_regulators; i++) {
struct dbx500_regulator_info *info;
@@ -144,12 +138,11 @@ static int ux500_regulator_status_print(struct seq_file *s, void *p)
info = &rdebug.regulator_array[i];
/* print status */
- err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name,
- info->is_enabled ? "enabled" : "disabled",
- rdebug.state_before_suspend[i] ? "enabled" : "disabled",
- rdebug.state_after_suspend[i] ? "enabled" : "disabled");
- if (err < 0)
- dev_err(dev, "seq_printf overflow\n");
+ seq_printf(s, "%20s : %8s : %8s : %8s\n",
+ info->desc.name,
+ info->is_enabled ? "enabled" : "disabled",
+ rdebug.state_before_suspend[i] ? "enabled" : "disabled",
+ rdebug.state_after_suspend[i] ? "enabled" : "disabled");
}
return 0;
diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c
index 5b9176e..c16b4d9 100644
--- a/drivers/usb/gadget/udc/goku_udc.c
+++ b/drivers/usb/gadget/udc/goku_udc.c
@@ -1135,44 +1135,47 @@ static int udc_proc_read(struct seq_file *m, void *v)
continue;
tmp = readl(ep->reg_status);
- if (seq_printf(m,
- "%s %s max %u %s, irqs %lu, "
- "status %02x (%s) " FOURBITS "\n",
- ep->ep.name,
- ep->is_in ? "in" : "out",
- ep->ep.maxpacket,
- ep->dma ? "dma" : "pio",
- ep->irqs,
- tmp, ({ char *s;
- switch (tmp & EPxSTATUS_EP_MASK) {
- case EPxSTATUS_EP_READY:
- s = "ready"; break;
- case EPxSTATUS_EP_DATAIN:
- s = "packet"; break;
- case EPxSTATUS_EP_FULL:
- s = "full"; break;
- case EPxSTATUS_EP_TX_ERR: // host will retry
- s = "tx_err"; break;
- case EPxSTATUS_EP_RX_ERR:
- s = "rx_err"; break;
- case EPxSTATUS_EP_BUSY: /* ep0 only */
- s = "busy"; break;
- case EPxSTATUS_EP_STALL:
- s = "stall"; break;
- case EPxSTATUS_EP_INVALID: // these "can't happen"
- s = "invalid"; break;
- default:
- s = "?"; break;
- } s; }),
- (tmp & EPxSTATUS_TOGGLE) ? "data1" : "data0",
- (tmp & EPxSTATUS_SUSPEND) ? " suspend" : "",
- (tmp & EPxSTATUS_FIFO_DISABLE) ? " disable" : "",
- (tmp & EPxSTATUS_STAGE_ERROR) ? " ep0stat" : ""
- ) < 0)
+ seq_printf(m, "%s %s max %u %s, irqs %lu, status %02x (%s) " FOURBITS "\n",
+ ep->ep.name,
+ ep->is_in ? "in" : "out",
+ ep->ep.maxpacket,
+ ep->dma ? "dma" : "pio",
+ ep->irqs,
+ tmp,
+ ({
+ char *s;
+ switch (tmp & EPxSTATUS_EP_MASK) {
+ case EPxSTATUS_EP_READY:
+ s = "ready"; break;
+ case EPxSTATUS_EP_DATAIN:
+ s = "packet"; break;
+ case EPxSTATUS_EP_FULL:
+ s = "full"; break;
+ case EPxSTATUS_EP_TX_ERR: /* host will retry */
+ s = "tx_err"; break;
+ case EPxSTATUS_EP_RX_ERR:
+ s = "rx_err"; break;
+ case EPxSTATUS_EP_BUSY: /* ep0 only */
+ s = "busy"; break;
+ case EPxSTATUS_EP_STALL:
+ s = "stall"; break;
+ case EPxSTATUS_EP_INVALID: /* "can't happen" */
+ s = "invalid"; break;
+ default:
+ s = "?"; break;
+ }
+ s;
+ }),
+ (tmp & EPxSTATUS_TOGGLE) ? "data1" : "data0",
+ (tmp & EPxSTATUS_SUSPEND) ? " suspend" : "",
+ (tmp & EPxSTATUS_FIFO_DISABLE) ? " disable" : "",
+ (tmp & EPxSTATUS_STAGE_ERROR) ? " ep0stat" : "");
+ if (seq_has_overflowed(m) < 0)
goto done;
if (list_empty(&ep->queue)) {
- if (seq_puts(m, "\t(nothing queued)\n") < 0)
+ seq_puts(m, "\t(nothing queued)\n");
+ if (seq_has_overflowed(m))
goto done;
continue;
}
@@ -1187,10 +1190,10 @@ static int udc_proc_read(struct seq_file *m, void *v)
} else
tmp = req->req.actual;
- if (seq_printf(m,
- "\treq %p len %u/%u buf %p\n",
- &req->req, tmp, req->req.length,
- req->req.buf) < 0)
+ seq_printf(m, "\treq %p len %u/%u buf %p\n",
+ &req->req, tmp, req->req.length,
+ req->req.buf);
+ if (seq_has_overflowed(m))
goto done;
}
}
diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c
index 4e37db3..0e5ec3c 100644
--- a/drivers/watchdog/bcm_kona_wdt.c
+++ b/drivers/watchdog/bcm_kona_wdt.c
@@ -102,34 +102,39 @@ static int bcm_kona_wdt_dbg_show(struct seq_file *s, void *data)
int ctl_val, cur_val, ret;
unsigned long flags;
struct bcm_kona_wdt *wdt = s->private;
+ int ctl, cur, ctl_sec, cur_sec, res;
- if (!wdt)
- return seq_puts(s, "No device pointer\n");
-
+ if (!wdt) {
+ seq_puts(s, "No device pointer\n");
+ return 0;
+ }
spin_lock_irqsave(&wdt->lock, flags);
ctl_val = secure_register_read(wdt, SECWDOG_CTRL_REG);
cur_val = secure_register_read(wdt, SECWDOG_COUNT_REG);
spin_unlock_irqrestore(&wdt->lock, flags);
if (ctl_val < 0 || cur_val < 0) {
- ret = seq_puts(s, "Error accessing hardware\n");
- } else {
- int ctl, cur, ctl_sec, cur_sec, res;
-
- ctl = ctl_val & SECWDOG_COUNT_MASK;
- res = (ctl_val & SECWDOG_RES_MASK) >> SECWDOG_CLKS_SHIFT;
- cur = cur_val & SECWDOG_COUNT_MASK;
- ctl_sec = TICKS_TO_SECS(ctl, wdt);
- cur_sec = TICKS_TO_SECS(cur, wdt);
- ret = seq_printf(s, "Resolution: %d / %d\n"
- "Control: %d s / %d (%#x) ticks\n"
- "Current: %d s / %d (%#x) ticks\n"
- "Busy count: %lu\n", res,
- wdt->resolution, ctl_sec, ctl, ctl, cur_sec,
- cur, cur, wdt->busy_count);
+ seq_puts(s, "Error accessing hardware\n");
+ return 0;
}
- return ret;
+ ctl = ctl_val & SECWDOG_COUNT_MASK;
+ res = (ctl_val & SECWDOG_RES_MASK) >> SECWDOG_CLKS_SHIFT;
+ cur = cur_val & SECWDOG_COUNT_MASK;
+ ctl_sec = TICKS_TO_SECS(ctl, wdt);
+ cur_sec = TICKS_TO_SECS(cur, wdt);
+ seq_printf(s,
+ "Resolution: %d / %d\n"
+ "Control: %d s / %d (%#x) ticks\n"
+ "Current: %d s / %d (%#x) ticks\n"
+ "Busy count: %lu\n",
+ res, wdt->resolution,
+ ctl_sec, ctl, ctl,
+ cur_sec, cur, cur,
+ wdt->busy_count);
+ }
+
+ return 0;
}
static int bcm_kona_dbg_open(struct inode *inode, struct file *file)
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 353948b..e6be05a 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -683,16 +683,17 @@ int seq_putc(struct seq_file *m, char c)
}
EXPORT_SYMBOL(seq_putc);
-int seq_puts(struct seq_file *m, const char *s)
+void seq_puts(struct seq_file *m, const char *s)
{
int len = strlen(s);
- if (m->count + len < m->size) {
- memcpy(m->buf + m->count, s, len);
- m->count += len;
- return 0;
+
+ if (m->count + len >= m->size) {
+ seq_set_overflow(m);
+ return;
}
- seq_set_overflow(m);
- return -1;
+
+ memcpy(m->buf + m->count, s, len);
+ m->count += len;
}
EXPORT_SYMBOL(seq_puts);
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index cf6a9da..9b02cb6 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -116,7 +116,7 @@ loff_t seq_lseek(struct file *, loff_t, int);
int seq_release(struct inode *, struct file *);
int seq_escape(struct seq_file *, const char *, const char *);
int seq_putc(struct seq_file *m, char c);
-int seq_puts(struct seq_file *m, const char *s);
+void seq_puts(struct seq_file *m, const char *s);
int seq_write(struct seq_file *seq, const void *data, size_t len);
__printf(2, 3) int seq_printf(struct seq_file *, const char *, ...);
diff --git a/ipc/util.c b/ipc/util.c
index 106bed0..4f726b7 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -837,8 +837,10 @@ static int sysvipc_proc_show(struct seq_file *s, void *it)
struct ipc_proc_iter *iter = s->private;
struct ipc_proc_iface *iface = iter->iface;
- if (it == SEQ_START_TOKEN)
- return seq_puts(s, iface->header);
+ if (it == SEQ_START_TOKEN) {
+ seq_puts(s, iface->header);
+ return seq_has_overflowed(s);
+ }
return iface->show(s, it);
}
--
2.1.2
Using the return value of seq_putc is error-prone, so
make it return void instead.
Reverse the logic in seq_putc to make it like seq_puts.
Signed-off-by: Joe Perches <[email protected]>
---
drivers/char/ipmi/ipmi_msghandler.c | 4 +++-
fs/seq_file.c | 11 ++++++-----
include/linux/seq_file.h | 2 +-
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 +++-
net/netfilter/nf_conntrack_expect.c | 4 +++-
5 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index f816211..c12fb30 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -1953,7 +1953,9 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v)
seq_printf(m, "%x", intf->channels[0].address);
for (i = 1; i < IPMI_MAX_CHANNELS; i++)
seq_printf(m, " %x", intf->channels[i].address);
- return seq_putc(m, '\n');
+ seq_putc(m, '\n');
+
+ return 0;
}
static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
diff --git a/fs/seq_file.c b/fs/seq_file.c
index e6be05a..5ca5af9 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -673,13 +673,14 @@ int seq_open_private(struct file *filp, const struct seq_operations *ops,
}
EXPORT_SYMBOL(seq_open_private);
-int seq_putc(struct seq_file *m, char c)
+void seq_putc(struct seq_file *m, char c)
{
- if (m->count < m->size) {
- m->buf[m->count++] = c;
- return 0;
+ if (m->count >= m->size) {
+ seq_set_overflow(m);
+ return;
}
- return -1;
+
+ m->buf[m->count++] = c;
}
EXPORT_SYMBOL(seq_putc);
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 9b02cb6..c1e47ff 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -115,7 +115,7 @@ ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
loff_t seq_lseek(struct file *, loff_t, int);
int seq_release(struct inode *, struct file *);
int seq_escape(struct seq_file *, const char *, const char *);
-int seq_putc(struct seq_file *m, char c);
+void seq_putc(struct seq_file *m, char c);
void seq_puts(struct seq_file *m, const char *s);
int seq_write(struct seq_file *seq, const void *data, size_t len);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index a460a87..f0dfe92 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
__nf_ct_l3proto_find(exp->tuple.src.l3num),
__nf_ct_l4proto_find(exp->tuple.src.l3num,
exp->tuple.dst.protonum));
- return seq_putc(s, '\n');
+ seq_putc(s, '\n');
+
+ return 0;
}
static const struct seq_operations exp_seq_ops = {
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 91a1837..7a17070 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
helper->expect_policy[expect->class].name);
}
- return seq_putc(s, '\n');
+ seq_putc(s, '\n');
+
+ return 0;
}
static const struct seq_operations exp_seq_ops = {
--
2.1.2
On Mon, Nov 10, 2014 at 10:58:56AM -0800, Joe Perches wrote:
> Using the return value of seq_puts is error-prone, so
> make it return void instead.
Acked-by: Mark Brown <[email protected]>
On Mon 2014-11-10 10:58:56, Joe Perches wrote:
> diff --git a/ipc/util.c b/ipc/util.c
> index 106bed0..4f726b7 100644
> --- a/ipc/util.c
> +++ b/ipc/util.c
> @@ -837,8 +837,10 @@ static int sysvipc_proc_show(struct seq_file *s, void *it)
> struct ipc_proc_iter *iter = s->private;
> struct ipc_proc_iface *iface = iter->iface;
>
> - if (it == SEQ_START_TOKEN)
> - return seq_puts(s, iface->header);
> + if (it == SEQ_START_TOKEN) {
> + seq_puts(s, iface->header);
> + return seq_has_overflowed(s);
It should return 0. The overflow is detected by traverse() that is
called from seq_read(). If the overflow happens, the size of the
buffer is increased and show() is called again.
> + }
>
> return iface->show(s, it);
This should stay as is. It seems that the show() function might also
return negative value in case of some other failure. See the error
handling of "error = m->op->show(m, p);" in traverse() in fs/seq_file.c
The rest of the patch looks fine.
Best Regards,
Petr
On Mon 2014-11-10 10:58:57, Joe Perches wrote:
> Using the return value of seq_putc is error-prone, so
> make it return void instead.
>
> Reverse the logic in seq_putc to make it like seq_puts.
>
> Signed-off-by: Joe Perches <[email protected]>
Reviewed-by: Petr Mladek <[email protected]>
The changes are correct. The show() functions should return 0
even when there is an overflow. They are called by traverse()
from seq_read() that might increase the buffer size and try again.
Best Regards,
Petr
On Tue, Nov 11, 2014 at 02:47:40PM +0100, Petr Mladek wrote:
> On Mon 2014-11-10 10:58:57, Joe Perches wrote:
> > Using the return value of seq_putc is error-prone, so
> > make it return void instead.
> >
> > Reverse the logic in seq_putc to make it like seq_puts.
> >
> > Signed-off-by: Joe Perches <[email protected]>
>
> Reviewed-by: Petr Mladek <[email protected]>
>
> The changes are correct. The show() functions should return 0
> even when there is an overflow. They are called by traverse()
> from seq_read() that might increase the buffer size and try again.
Just in case you need this for the netfilter chunks:
Acked-by: Pablo Neira Ayuso <[email protected]>
Thanks.
Ok by me for the IPMI part.
Reviewed-by: Corey Minyard <[email protected]>
On 11/10/2014 12:58 PM, Joe Perches wrote:
> Using the return value of seq_putc is error-prone, so
> make it return void instead.
>
> Reverse the logic in seq_putc to make it like seq_puts.
>
> Signed-off-by: Joe Perches <[email protected]>
> ---
> drivers/char/ipmi/ipmi_msghandler.c | 4 +++-
> fs/seq_file.c | 11 ++++++-----
> include/linux/seq_file.h | 2 +-
> net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 4 +++-
> net/netfilter/nf_conntrack_expect.c | 4 +++-
> 5 files changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
> index f816211..c12fb30 100644
> --- a/drivers/char/ipmi/ipmi_msghandler.c
> +++ b/drivers/char/ipmi/ipmi_msghandler.c
> @@ -1953,7 +1953,9 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v)
> seq_printf(m, "%x", intf->channels[0].address);
> for (i = 1; i < IPMI_MAX_CHANNELS; i++)
> seq_printf(m, " %x", intf->channels[i].address);
> - return seq_putc(m, '\n');
> + seq_putc(m, '\n');
> +
> + return 0;
> }
>
> static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
> diff --git a/fs/seq_file.c b/fs/seq_file.c
> index e6be05a..5ca5af9 100644
> --- a/fs/seq_file.c
> +++ b/fs/seq_file.c
> @@ -673,13 +673,14 @@ int seq_open_private(struct file *filp, const struct seq_operations *ops,
> }
> EXPORT_SYMBOL(seq_open_private);
>
> -int seq_putc(struct seq_file *m, char c)
> +void seq_putc(struct seq_file *m, char c)
> {
> - if (m->count < m->size) {
> - m->buf[m->count++] = c;
> - return 0;
> + if (m->count >= m->size) {
> + seq_set_overflow(m);
> + return;
> }
> - return -1;
> +
> + m->buf[m->count++] = c;
> }
> EXPORT_SYMBOL(seq_putc);
>
> diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
> index 9b02cb6..c1e47ff 100644
> --- a/include/linux/seq_file.h
> +++ b/include/linux/seq_file.h
> @@ -115,7 +115,7 @@ ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
> loff_t seq_lseek(struct file *, loff_t, int);
> int seq_release(struct inode *, struct file *);
> int seq_escape(struct seq_file *, const char *, const char *);
> -int seq_putc(struct seq_file *m, char c);
> +void seq_putc(struct seq_file *m, char c);
> void seq_puts(struct seq_file *m, const char *s);
> int seq_write(struct seq_file *seq, const void *data, size_t len);
>
> diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
> index a460a87..f0dfe92 100644
> --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
> +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
> @@ -300,7 +300,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
> __nf_ct_l3proto_find(exp->tuple.src.l3num),
> __nf_ct_l4proto_find(exp->tuple.src.l3num,
> exp->tuple.dst.protonum));
> - return seq_putc(s, '\n');
> + seq_putc(s, '\n');
> +
> + return 0;
> }
>
> static const struct seq_operations exp_seq_ops = {
> diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
> index 91a1837..7a17070 100644
> --- a/net/netfilter/nf_conntrack_expect.c
> +++ b/net/netfilter/nf_conntrack_expect.c
> @@ -561,7 +561,9 @@ static int exp_seq_show(struct seq_file *s, void *v)
> helper->expect_policy[expect->class].name);
> }
>
> - return seq_putc(s, '\n');
> + seq_putc(s, '\n');
> +
> + return 0;
> }
>
> static const struct seq_operations exp_seq_ops = {