kernfs: sysfs: support custom llseek method for sysfs entries
As of now, seeking in sysfs files is handled by generic_file_llseek().
There are situations where one may want to customize seeking logic:
- Many sysfs entries are fixed files while generic_file_llseek() accepts
past-the-end positions. Not only being useless by itself, this
also means a bug in userspace code will trigger not at lseek(), but at
some later point making debugging harder.
- generic_file_llseek() relies on f_mapping->host to get the file size
which might not be correct for all sysfs entries.
See commit 636b21b501 ("PCI: Revoke mappings like devmem") as an example.
Implement llseek method to override this behavior at sysfs attribute
level. The method is optional, and if it is absent,
generic_file_llseek() is called to preserve backwards compatibility.
Signed-off-by: Valentine Sinitsyn <valesini@yandex-team.ru>
Link: https://lore.kernel.org/r/20230925084013.309399-1-valesini@yandex-team.ru
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
7360a48bd0
commit
0fedefd4c4
@@ -167,6 +167,18 @@ static int sysfs_kf_bin_mmap(struct kernfs_open_file *of,
|
||||
return battr->mmap(of->file, kobj, battr, vma);
|
||||
}
|
||||
|
||||
static loff_t sysfs_kf_bin_llseek(struct kernfs_open_file *of, loff_t offset,
|
||||
int whence)
|
||||
{
|
||||
struct bin_attribute *battr = of->kn->priv;
|
||||
struct kobject *kobj = of->kn->parent->priv;
|
||||
|
||||
if (battr->llseek)
|
||||
return battr->llseek(of->file, kobj, battr, offset, whence);
|
||||
else
|
||||
return generic_file_llseek(of->file, offset, whence);
|
||||
}
|
||||
|
||||
static int sysfs_kf_bin_open(struct kernfs_open_file *of)
|
||||
{
|
||||
struct bin_attribute *battr = of->kn->priv;
|
||||
@@ -249,6 +261,7 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
|
||||
.write = sysfs_kf_bin_write,
|
||||
.mmap = sysfs_kf_bin_mmap,
|
||||
.open = sysfs_kf_bin_open,
|
||||
.llseek = sysfs_kf_bin_llseek,
|
||||
};
|
||||
|
||||
int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
||||
|
||||
Reference in New Issue
Block a user