From: NeilBrown <neilb@suse.de>
To: Tejun Heo <tj@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-kernel@vger.kernel.org, Al Viro <viro@ZenIV.linux.org.uk>
Subject: [PATCH 2/2] sysfs/kernfs: make read requests on pre-alloc files use the buffer.
Date: Tue, 30 Sep 2014 12:33:34 +1000 [thread overview]
Message-ID: <20140930023334.13407.61093.stgit@notabene.brown> (raw)
In-Reply-To: <20140930022205.13407.99210.stgit@notabene.brown>
To match the previous patch which used the pre-alloc buffer for
writes, this patch causes reads to use the same buffer.
This is not strictly necessary as the current seq_read() will allocate
on first read, so user-space can trigger the required pre-alloc. But
consistency is valuable.
The read function is somewhat simpler than seq_read() and, for example,
does not support reading from an offset into the file: reads must be
at the start of the file.
As the buffer is shared with writes and other reads, the mutex is
extended to cover the copy_to_user.
Signed-off-by: NeilBrown <neilb@suse.de>
---
fs/kernfs/file.c | 17 ++++++++++-------
fs/sysfs/file.c | 28 ++++++++++++++++++++++++----
2 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 73bd5ed143cd..7072240604f5 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -189,7 +189,9 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of,
const struct kernfs_ops *ops;
char *buf;
- buf = kmalloc(len, GFP_KERNEL);
+ buf = of->buf;
+ if (!buf)
+ buf = kmalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -210,21 +212,22 @@ static ssize_t kernfs_file_direct_read(struct kernfs_open_file *of,
else
len = -EINVAL;
- kernfs_put_active(of->kn);
- mutex_unlock(&of->mutex);
-
if (len < 0)
- goto out_free;
+ goto out_unlock;
if (copy_to_user(user_buf, buf, len)) {
len = -EFAULT;
- goto out_free;
+ goto out_unlock;
}
*ppos += len;
+ out_unlock:
+ kernfs_put_active(of->kn);
+ mutex_unlock(&of->mutex);
out_free:
- kfree(buf);
+ if (buf != of->buf)
+ kfree(buf);
return len;
}
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 4a959d231b43..3f7e4d341546 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -102,6 +102,18 @@ static ssize_t sysfs_kf_bin_read(struct kernfs_open_file *of, char *buf,
return battr->read(of->file, kobj, battr, buf, pos, count);
}
+/* kernfs read callback for regular sysfs files with pre-alloc */
+static ssize_t sysfs_kf_read(struct kernfs_open_file *of, char *buf,
+ size_t count, loff_t pos)
+{
+ const struct sysfs_ops *ops = sysfs_file_ops(of->kn);
+ struct kobject *kobj = of->kn->parent->priv;
+
+ if (pos)
+ return 0;
+ return ops->show(kobj, of->kn->priv, buf);
+}
+
/* kernfs write callback for regular sysfs files */
static ssize_t sysfs_kf_write(struct kernfs_open_file *of, char *buf,
size_t count, loff_t pos)
@@ -184,13 +196,18 @@ static const struct kernfs_ops sysfs_file_kfops_rw = {
.write = sysfs_kf_write,
};
+static const struct kernfs_ops sysfs_prealloc_kfops_ro = {
+ .read = sysfs_kf_read,
+ .prealloc = true,
+};
+
static const struct kernfs_ops sysfs_prealloc_kfops_wo = {
.write = sysfs_kf_write,
.prealloc = true,
};
static const struct kernfs_ops sysfs_prealloc_kfops_rw = {
- .seq_show = sysfs_kf_seq_show,
+ .read = sysfs_kf_read,
.write = sysfs_kf_write,
.prealloc = true,
};
@@ -238,9 +255,12 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent,
ops = &sysfs_prealloc_kfops_rw;
else
ops = &sysfs_file_kfops_rw;
- } else if (sysfs_ops->show)
- ops = &sysfs_file_kfops_ro;
- else if (sysfs_ops->store) {
+ } else if (sysfs_ops->show) {
+ if (mode & SYSFS_PREALLOC)
+ ops = &sysfs_prealloc_kfops_ro;
+ else
+ ops = &sysfs_file_kfops_ro;
+ } else if (sysfs_ops->store) {
if (mode & SYSFS_PREALLOC)
ops = &sysfs_prealloc_kfops_wo;
else
next prev parent reply other threads:[~2014-09-30 2:42 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-30 2:33 [PATCH 0/2] Allow access to sysfs attributes without mem allocations NeilBrown
2014-09-30 2:33 ` NeilBrown [this message]
2014-10-05 20:02 ` [PATCH 2/2] sysfs/kernfs: make read requests on pre-alloc files use the buffer Tejun Heo
2014-09-30 2:33 ` [PATCH 1/2] sysfs - allow attributes to request write buffer be pre-allocated NeilBrown
2014-10-05 19:56 ` Tejun Heo
2014-10-05 19:46 ` [PATCH 0/2] Allow access to sysfs attributes without mem allocations Tejun Heo
-- strict thread matches above, loose matches on Subject: below --
2014-10-08 23:57 [PATCH 0/2 V2] " NeilBrown
2014-10-08 23:57 ` [PATCH 2/2] sysfs/kernfs: make read requests on pre-alloc files use the buffer NeilBrown
2014-10-09 13:52 ` Tejun Heo
2014-10-13 5:41 [PATCH 0/2 V3] Allow access to sysfs attributes without mem allocations NeilBrown
2014-10-13 5:41 ` [PATCH 2/2] sysfs/kernfs: make read requests on pre-alloc files use the buffer NeilBrown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140930023334.13407.61093.stgit@notabene.brown \
--to=neilb@suse.de \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=tj@kernel.org \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox