Hi, Anyone working on reviewing this? Neil? On Fri, Jan 22, 2021 at 7:03 PM Xin Long <lucien.xin@xxxxxxxxx> wrote: > > 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 >