[PATCH] teach seq_file to discard entries

Allow ->show() return SEQ_SKIP; that will discard all
output from that element and move on.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
diff --git a/fs/pnode.h b/fs/pnode.h
index f249be2..973c3f8 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -35,4 +35,5 @@
 		struct list_head *);
 int propagate_umount(struct list_head *);
 int propagate_mount_busy(struct vfsmount *, int);
+void mnt_release_group_id(struct vfsmount *);
 #endif /* _LINUX_PNODE_H */
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 8537702..bf2bcfd 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -25,6 +25,7 @@
  *	into the buffer.  In case of error ->start() and ->next() return
  *	ERR_PTR(error).  In the end of sequence they return %NULL. ->show()
  *	returns 0 in case of success and negative number in case of error.
+ *	Returning SEQ_SKIP means "discard this element and move on".
  */
 int seq_open(struct file *file, const struct seq_operations *op)
 {
@@ -114,8 +115,10 @@
 		if (!p || IS_ERR(p))
 			break;
 		err = m->op->show(m, p);
-		if (err)
+		if (err < 0)
 			break;
+		if (unlikely(err))
+			m->count = 0;
 		if (m->count < m->size)
 			goto Fill;
 		m->op->stop(m, p);
@@ -140,9 +143,10 @@
 			break;
 		}
 		err = m->op->show(m, p);
-		if (err || m->count == m->size) {
+		if (m->count == m->size || err) {
 			m->count = offs;
-			break;
+			if (likely(err <= 0))
+				break;
 		}
 		pos = next;
 	}
@@ -199,8 +203,12 @@
 		if (IS_ERR(p))
 			break;
 		error = m->op->show(m, p);
-		if (error)
+		if (error < 0)
 			break;
+		if (unlikely(error)) {
+			error = 0;
+			m->count = 0;
+		}
 		if (m->count == m->size)
 			goto Eoverflow;
 		if (pos + m->count > offset) {