[PATCH v2 7/7] drivers/net: cfg: fix config file load up
Philippe Gerum
rpm at xenomai.org
Tue May 4 19:18:32 CEST 2021
Jan Kiszka <jan.kiszka at siemens.com> writes:
> On 27.03.21 11:19, Philippe Gerum wrote:
>> From: Philippe Gerum <rpm at xenomai.org>
>>
>> set_fs() is on its way out, so we cannot open code a file read
>> operation by calling the VFS handler directly anymore, faking a user
>> address space.
>>
>> We do have kernel interfaces for loading files though, particularly
>> kernel_read_file(). So let's use that one for loading the
>> configuration file contents. Unfortunately, the signature of this
>> service changed during the 5.9-rc cycle, so we have to resort to an
>> ugly wrapper to cope with all supported kernels once again. Sigh.
>>
>> Signed-off-by: Philippe Gerum <rpm at xenomai.org>
>> ---
>> .../include/asm-generic/xenomai/wrappers.h | 15 ++++
>> kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c | 74 +++++++++----------
>> 2 files changed, 52 insertions(+), 37 deletions(-)
>>
>> diff --git a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
>> index cfd28fc47..f15fe4389 100644
>> --- a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
>> +++ b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
>> @@ -220,4 +220,19 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name,
>> })
>> #endif
>>
>> +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0)
>> +#define read_file_from_kernel(__file, __buf, __buf_size, __file_size, __id) \
>> + ({ \
>> + loff_t ___file_size; \
>> + int __ret; \
>> + __ret = kernel_read_file(__file, __buf, &___file_size, \
>> + __buf_size, __id); \
>> + (*__file_size) = ___file_size; \
>> + __ret; \
>> + })
>> +#else
>> +#define read_file_from_kernel(__file, __buf, __buf_size, __file_size, __id) \
>> + kernel_read_file(__file, 0, __buf, __buf_size, __file_size, __id)
>> +#endif
>> +
>> #endif /* _COBALT_ASM_GENERIC_WRAPPERS_H */
>> diff --git a/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c b/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c
>> index 769b4e143..e460571c2 100644
>> --- a/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c
>> +++ b/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c
>> @@ -22,6 +22,7 @@
>> *
>> */
>>
>> +#include <linux/fs.h>
>> #include <linux/file.h>
>> #include <linux/vmalloc.h>
>>
>> @@ -196,6 +197,40 @@ void cleanup_cmd_detach(void *priv_data)
>> kfree_rtskb(cmd->args.detach.stage2_chain);
>> }
>>
>> +static int load_cfg_file(struct rtcfg_file *cfgfile, struct rtcfg_cmd *cmd)
>> +{
>> + size_t file_size = 0;
>> + struct file *filp;
>> + loff_t i_size;
>> + int ret;
>> +
>> + filp = filp_open(cfgfile->name, O_RDONLY, 0);
>> + if (IS_ERR(filp))
>> + return PTR_ERR(filp);
>> +
>> + i_size = i_size_read(file_inode(filp));
>> + if (i_size <= 0) {
>> + /* allocate buffer even for empty files */
>> + cfgfile->buffer = vmalloc(1);
>> + } else {
>> + cfgfile->buffer = NULL;
>> + /* Assume 1Mb should be enough for a config file... */
>
> This limitation is new, and I'm not sure if that would be a good idea.
This would be the size of a config file. 1MB would be too tight in some
real world scenario(s)? Anyway, we don't need to impose this limit, I
agree.
> But I need to read up the protocol details again.
>
> Why do we need that limit? We know i_size already, no?
>
Yes we do. So here is a better option I'm going to push upstream
instead:
diff --git a/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c b/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c
index e460571c2..158d7118f 100644
--- a/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c
+++ b/kernel/drivers/net/stack/rtcfg/rtcfg_ioctl.c
@@ -213,10 +213,10 @@ static int load_cfg_file(struct rtcfg_file *cfgfile, struct rtcfg_cmd *cmd)
/* allocate buffer even for empty files */
cfgfile->buffer = vmalloc(1);
} else {
- cfgfile->buffer = NULL;
- /* Assume 1Mb should be enough for a config file... */
+ cfgfile->buffer = NULL; /* Leave allocation to the kernel. */
ret = read_file_from_kernel(filp, &cfgfile->buffer,
- 1UL << 30, &file_size, READING_UNKNOWN);
+ i_size_read(file_inode(filp)),
+ &file_size, READING_UNKNOWN);
if (ret < 0) {
fput(filp);
return ret;
--
Philippe.
More information about the Xenomai
mailing list