From: Philippe Gerum <r...@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 <r...@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 652a04759f..54fdc8b05e 100644 --- a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h +++ b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h @@ -216,4 +216,19 @@ devm_hwmon_device_register_with_groups(struct device *dev, const char *name, #define vmalloc_kernel(__size, __flags) __vmalloc(__size, GFP_KERNEL|__flags) #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 769b4e143c..158d7118f2 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; /* Leave allocation to the kernel. */ + ret = read_file_from_kernel(filp, &cfgfile->buffer, + i_size_read(file_inode(filp)), + &file_size, READING_UNKNOWN); + if (ret < 0) { + fput(filp); + return ret; + } + } + + fput(filp); + cfgfile->size = file_size; + + /* dispatch again, this time with new file attached */ + return rtpc_dispatch_call(rtcfg_event_handler, 0, cmd, + sizeof(*cmd), NULL, cleanup_cmd_add); +} + int rtcfg_ioctl_add(struct rtnet_device *rtdev, struct rtcfg_cmd *cmd) { struct rtcfg_connection *conn_buf; @@ -264,46 +299,11 @@ int rtcfg_ioctl_add(struct rtnet_device *rtdev, struct rtcfg_cmd *cmd) /* load file if missing */ if (ret > 0) { - struct file *filp; - mm_segment_t oldfs; - - filp = filp_open(file->name, O_RDONLY, 0); - if (IS_ERR(filp)) { + ret = load_cfg_file(file, cmd); + if (ret) { rtcfg_unlockwr_proc(cmd->internal.data.ifindex); - ret = PTR_ERR(filp); goto err; } - - file->size = filp->f_path.dentry->d_inode->i_size; - - /* allocate buffer even for empty files */ - file->buffer = vmalloc((file->size) ? file->size : 1); - if (file->buffer == NULL) { - rtcfg_unlockwr_proc(cmd->internal.data.ifindex); - fput(filp); - ret = -ENOMEM; - goto err; - } - - oldfs = get_fs(); - set_fs(KERNEL_DS); - filp->f_pos = 0; - - ret = filp->f_op->read(filp, file->buffer, file->size, - &filp->f_pos); - - set_fs(oldfs); - fput(filp); - - if (ret != (int)file->size) { - rtcfg_unlockwr_proc(cmd->internal.data.ifindex); - ret = -EIO; - goto err; - } - - /* dispatch again, this time with new file attached */ - ret = rtpc_dispatch_call(rtcfg_event_handler, 0, cmd, - sizeof(*cmd), NULL, cleanup_cmd_add); } return ret; -- 2.26.2