Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754569AbcJLMIK (ORCPT ); Wed, 12 Oct 2016 08:08:10 -0400 Received: from mga11.intel.com ([192.55.52.93]:56345 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753866AbcJLMIA (ORCPT ); Wed, 12 Oct 2016 08:08:00 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,482,1473145200"; d="scan'208";a="19259273" From: Tomasz Majchrzak To: linux-kernel@vger.kernel.org Cc: dan.j.williams@intel.com, viro@zeniv.linux.org.uk, aleksey.obitotskiy@intel.com, pawel.baldysiak@intel.com, artur.paszkiewicz@intel.com, maksymilian.kunt@intel.com, Tomasz Majchrzak Subject: [PATCH v2][RESEND] seq_file: don't set read position for invalid iterator Date: Wed, 12 Oct 2016 14:07:40 +0200 Message-Id: <1476274060-1785-1-git-send-email-tomasz.majchrzak@intel.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1544 Lines: 43 If kernfs file is empty on a first read, successive read operations using the same file descriptor will return no data, even when data is available. Default kernfs 'seq_next' implementation advances iterator position even when next object is not there. Kernfs 'seq_start' for following requests will not return iterator as position is already on the second object. This bug doesn't allow to monitor badblocks sysfs files from MD raid. They are initially empty but if data appears at some stage, userspace is not able to read it. It doesn't affect any released applications but it is necessary for upcoming bad block support for external metadata in MD raid. Signed-off-by: Tomasz Majchrzak Reviewed-by: Dan Williams --- fs/seq_file.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/seq_file.c b/fs/seq_file.c index 6dc4296..74197f4 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -235,7 +235,7 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) p = m->op->start(m, &pos); while (1) { err = PTR_ERR(p); - if (!p || IS_ERR(p)) + if (IS_ERR_OR_NULL(p)) break; err = m->op->show(m, p); if (err < 0) @@ -244,7 +244,8 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) m->count = 0; if (unlikely(!m->count)) { p = m->op->next(m, p, &pos); - m->index = pos; + if (!IS_ERR_OR_NULL(p)) + m->index = pos; continue; } if (m->count < m->size) -- 1.8.3.1