[PATCH 3/7] drivers/net: cfg: fix config file load up

Jan Kiszka jan.kiszka at siemens.com
Wed May 12 12:05:53 CEST 2021


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 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




More information about the Xenomai mailing list