summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2015-08-06 08:27:55 +1000
committerSasha Levin <alexander.levin@verizon.com>2016-09-15 18:53:30 -0400
commitf53680b1d8b0f1cd039b5328d194b8e72973919f (patch)
tree936d9aa7bfd5c41bf9915d181667d2e3a763f866
parent33d720d9108912b42b77bd4c6fa63d81032d773a (diff)
downloadlwn-f53680b1d8b0f1cd039b5328d194b8e72973919f.tar.gz
lwn-f53680b1d8b0f1cd039b5328d194b8e72973919f.zip
sysfs: correctly handle short reads on PREALLOC attrs.
[ Upstream commit 65da3484d9be5664f5f7d2378e438bb2794f40b8 ] attributes declared with __ATTR_PREALLOC use sysfs_kf_read() which ignores the 'count' arg. So a 1-byte read request can return more bytes than that. This is seen with the 'dash' shell when 'read' is used on some 'md' sysfs attributes. So only return the 'min' of count and the attribute length. Signed-off-by: NeilBrown <neilb@suse.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
-rw-r--r--fs/sysfs/file.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 7c2867b44141..9905595ef41d 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -108,6 +108,7 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
{
const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
struct kobject *kobj = of->kn->parent->priv;
+ size_t len;
/*
* If buf != of->prealloc_buf, we don't know how
@@ -115,7 +116,8 @@ static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
*/
if (pos || WARN_ON_ONCE(buf != of->prealloc_buf))
return 0;
- return ops->show(kobj, of->kn->priv, buf);
+ len = ops->show(kobj, of->kn->priv, buf);
+ return min(count, len);
}
/* kernfs write callback for regular sysfs files */