In commit 1f4aace60b0e ("fs/seq_file.c: simplify seq_file iteration code and interface"), it broke a behavior: op show() is always called when op next() returns an available obj. This caused a refcnt leak in net/sctp/proc.c, as of the seq_operations sctp_assoc_ops, transport obj is held in op next() and released in op show(). Here fix it by moving count check against iov_iter_count after calling op show() so that op show() can still be called when op next() returns an available obj. Note that m->index needs to increase so that op start() could go fetch the next obj in the next round. Fixes: 1f4aace60b0e ("fs/seq_file.c: simplify seq_file iteration code and interface") Reported-by: Prijesh <prpatel@xxxxxxxxxx> Signed-off-by: Xin Long <lucien.xin@xxxxxxxxx> --- fs/seq_file.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index 03a369c..da304f7 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -264,8 +264,6 @@ ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter) } if (!p || IS_ERR(p)) // no next record for us break; - if (m->count >= iov_iter_count(iter)) - break; err = m->op->show(m, p); if (err > 0) { // ->show() says "skip it" m->count = offs; @@ -273,6 +271,10 @@ ssize_t seq_read_iter(struct kiocb *iocb, struct iov_iter *iter) m->count = offs; break; } + if (m->count >= iov_iter_count(iter)) { + m->index++; + break; + } } m->op->stop(m, p); n = copy_to_iter(m->buf, m->count, iter); -- 2.1.0