[Concept,07/19] linux: Add fs_context.h and fs_parser.h headers

Message ID 20260117011448.3007171-8-sjg@u-boot.org
State New
Headers
Series ext4l: Reduce ext4_uboot.h size by moving code to include/linux |

Commit Message

Simon Glass Jan. 17, 2026, 1:14 a.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Move filesystem context and parameter parsing stubs to dedicated
header files that mirror the Linux kernel organisation.

fs_context.h provides:
- enum fs_context_purpose
- struct fs_context_operations
- struct file_system_type with FS_* flags
- struct fs_context
- struct fs_parameter
- get_tree_bdev(), get_tree_nodev(), kill_block_super() stubs

fs_parser.h provides:
- struct constant_table
- struct fs_parameter_spec with fs_param_is_* constants
- struct fs_parse_result
- fsparam_*() macros for mount option specification
- fs_parse() and fs_lookup_param() stubs

These are stubs for U-Boot since filesystem mounting is simpler
than in the Linux kernel, but they allow ext4l code to compile.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/ext4l/ext4_uboot.h      | 150 +-----------------------------------
 include/linux/fs_context.h | 154 +++++++++++++++++++++++++++++++++++++
 include/linux/fs_parser.h  | 110 ++++++++++++++++++++++++++
 3 files changed, 266 insertions(+), 148 deletions(-)
 create mode 100644 include/linux/fs_context.h
 create mode 100644 include/linux/fs_parser.h
  

Patch

diff --git a/fs/ext4l/ext4_uboot.h b/fs/ext4l/ext4_uboot.h
index b49e6604589..a1047607e79 100644
--- a/fs/ext4l/ext4_uboot.h
+++ b/fs/ext4l/ext4_uboot.h
@@ -84,6 +84,8 @@ 
 #include <linux/jiffies.h>
 #include <linux/blkdev.h>
 #include <linux/blk_types.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 
 /* atomic_dec_if_positive, atomic_add_unless, etc. are now in asm-generic/atomic.h */
 
@@ -1302,88 +1304,11 @@  static inline const char *simple_get_link(struct dentry *dentry,
  * Additional stubs for super.c
  */
 
-/* fs_context and fs_parser stubs */
-struct constant_table {
-	const char *name;
-	int value;
-};
-
-struct fs_parameter_spec {
-	const char *name;
-	int opt;
-	unsigned short type;
-	const struct constant_table *data;
-};
-
-/* fs_parameter spec types */
-#define fs_param_is_flag	0
-#define fs_param_is_u32		1
-#define fs_param_is_s32		2
-#define fs_param_is_u64		3
-#define fs_param_is_enum	4
-#define fs_param_is_string	5
-#define fs_param_is_blob	6
-#define fs_param_is_fd		7
-#define fs_param_is_uid		8
-#define fs_param_is_gid		9
-#define fs_param_is_blockdev	10
-
-/* fsparam_* macros for mount option parsing - use literal values */
-#define fsparam_flag(name, opt) \
-	{(name), (opt), 0, NULL}
-#define fsparam_u32(name, opt) \
-	{(name), (opt), 1, NULL}
-#define fsparam_s32(name, opt) \
-	{(name), (opt), 2, NULL}
-#define fsparam_u64(name, opt) \
-	{(name), (opt), 3, NULL}
-#define fsparam_string(name, opt) \
-	{(name), (opt), 5, NULL}
-#define fsparam_string_empty(name, opt) \
-	{(name), (opt), 5, NULL}
-#define fsparam_enum(name, opt, array) \
-	{(name), (opt), 4, (array)}
-#define fsparam_bdev(name, opt) \
-	{(name), (opt), 10, NULL}
-#define fsparam_uid(name, opt) \
-	{(name), (opt), 8, NULL}
-#define fsparam_gid(name, opt) \
-	{(name), (opt), 9, NULL}
-#define __fsparam(type, name, opt, flags, data) \
-	{(name), (opt), (type), (data)}
-
 /* Quota format constants */
 #define QFMT_VFS_OLD		1
 #define QFMT_VFS_V0		2
 #define QFMT_VFS_V1		4
 
-struct fs_context;
-struct fs_parameter;
-
-struct fs_context_operations {
-	int (*parse_param)(struct fs_context *, struct fs_parameter *);
-	int (*get_tree)(struct fs_context *);
-	int (*reconfigure)(struct fs_context *);
-	void (*free)(struct fs_context *);
-};
-
-struct file_system_type {
-	struct module *owner;
-	const char *name;
-	int (*init_fs_context)(struct fs_context *);
-	const struct fs_parameter_spec *parameters;
-	void (*kill_sb)(struct super_block *);
-	int fs_flags;
-	struct list_head fs_supers;
-};
-
-#define FS_REQUIRES_DEV		1
-#define FS_BINARY_MOUNTDATA	2
-#define FS_HAS_SUBTYPE		4
-#define FS_USERNS_MOUNT		8
-#define FS_DISALLOW_NOTIFY_PERM	16
-#define FS_ALLOW_IDMAP		32
-
 /* Buffer read sync */
 static inline void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
 {
@@ -1510,82 +1435,11 @@  struct kstatfs {
 #define EXT4_GOING_FLAGS_LOGFLUSH	1
 #define EXT4_GOING_FLAGS_NOLOGFLUSH	2
 
-/* fs_context stubs */
-/* fs_context_purpose - what the context is for */
-enum fs_context_purpose {
-	FS_CONTEXT_FOR_MOUNT,
-	FS_CONTEXT_FOR_SUBMOUNT,
-	FS_CONTEXT_FOR_RECONFIGURE,
-};
-
-struct fs_context {
-	const struct fs_context_operations *ops;
-	struct file_system_type *fs_type;
-	void *fs_private;
-	struct dentry *root;
-	struct user_namespace *user_ns;
-	void *s_fs_info;		/* Filesystem specific info */
-	unsigned int sb_flags;
-	unsigned int sb_flags_mask;
-	unsigned int lsm_flags;
-	enum fs_context_purpose purpose;
-	bool sloppy;
-	bool silent;
-};
-
 /* ext4 superblock initialisation and commit */
 int ext4_fill_super(struct super_block *sb, struct fs_context *fc);
 int ext4_commit_super(struct super_block *sb);
 void ext4_unregister_li_request(struct super_block *sb);
 
-/* fs_parameter stubs */
-struct fs_parameter {
-	const char *key;
-	int type;
-	size_t size;
-	int dirfd;
-	union {
-		char *string;
-		int boolean;
-		int integer;
-	};
-};
-
-/* fs_value types - result type from parsing */
-enum fs_value_type {
-	fs_value_is_undefined,
-	fs_value_is_flag,
-	fs_value_is_string,
-	fs_value_is_blob,
-	fs_value_is_filename,
-	fs_value_is_file,
-};
-
-/* fs_parse_result - result of parsing a parameter */
-struct fs_parse_result {
-	bool negated;
-	union {
-		bool boolean;
-		int int_32;
-		unsigned int uint_32;
-		u64 uint_64;
-		kuid_t uid;
-		kgid_t gid;
-	};
-};
-
-/* fs_parse stubs */
-#define fs_parse(fc, desc, param, result) ({ (void)(fc); (void)(desc); (void)(param); (void)(result); -ENOPARAM; })
-#define ENOPARAM			519
-#define fs_lookup_param(fc, p, bdev, fl, path) ({ (void)(fc); (void)(p); (void)(bdev); (void)(fl); (void)(path); -EINVAL; })
-
-/* get_tree helpers */
-#define get_tree_bdev(fc, fill_super)	({ (void)(fc); (void)(fill_super); -ENODEV; })
-#define get_tree_nodev(fc, fill_super)	({ (void)(fc); (void)(fill_super); -ENODEV; })
-
-/* kill_sb helpers */
-#define kill_block_super(sb)		do { } while (0)
-
 /* prandom */
 #define get_random_u32()		0
 #define prandom_u32_max(max)		0
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h
new file mode 100644
index 00000000000..66cb462c656
--- /dev/null
+++ b/include/linux/fs_context.h
@@ -0,0 +1,154 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Filesystem context stubs for U-Boot
+ *
+ * Based on Linux fs_context.h - U-Boot doesn't have real mount contexts,
+ * so these are stubs for compilation.
+ */
+#ifndef _LINUX_FS_CONTEXT_H
+#define _LINUX_FS_CONTEXT_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+/* Forward declarations */
+struct dentry;
+struct fs_parameter;
+struct module;
+struct super_block;
+struct user_namespace;
+
+/**
+ * enum fs_context_purpose - what the context is for
+ * @FS_CONTEXT_FOR_MOUNT: New superblock for explicit mount
+ * @FS_CONTEXT_FOR_SUBMOUNT: New superblock for automatic submount
+ * @FS_CONTEXT_FOR_RECONFIGURE: Superblock reconfiguration (remount)
+ */
+enum fs_context_purpose {
+	FS_CONTEXT_FOR_MOUNT,
+	FS_CONTEXT_FOR_SUBMOUNT,
+	FS_CONTEXT_FOR_RECONFIGURE,
+};
+
+/**
+ * enum fs_value_type - type of parameter value
+ * @fs_value_is_undefined: Value not specified
+ * @fs_value_is_flag: Value not given a value
+ * @fs_value_is_string: Value is a string
+ * @fs_value_is_blob: Value is a binary blob
+ * @fs_value_is_filename: Value is a filename + dirfd
+ * @fs_value_is_file: Value is a file pointer
+ */
+enum fs_value_type {
+	fs_value_is_undefined,
+	fs_value_is_flag,
+	fs_value_is_string,
+	fs_value_is_blob,
+	fs_value_is_filename,
+	fs_value_is_file,
+};
+
+struct fs_context;
+
+/**
+ * struct fs_context_operations - filesystem context operations
+ * @parse_param: parse a single parameter
+ * @get_tree: get the superblock
+ * @reconfigure: reconfigure the superblock
+ * @free: free the context
+ */
+struct fs_context_operations {
+	int (*parse_param)(struct fs_context *, struct fs_parameter *);
+	int (*get_tree)(struct fs_context *);
+	int (*reconfigure)(struct fs_context *);
+	void (*free)(struct fs_context *);
+};
+
+/**
+ * struct file_system_type - filesystem type descriptor
+ * @owner: module owner
+ * @name: filesystem name
+ * @init_fs_context: initialise a filesystem context
+ * @parameters: mount parameter specification
+ * @kill_sb: destroy a superblock
+ * @fs_flags: filesystem flags
+ * @fs_supers: list of superblocks of this type
+ */
+struct file_system_type {
+	struct module *owner;
+	const char *name;
+	int (*init_fs_context)(struct fs_context *);
+	const struct fs_parameter_spec *parameters;
+	void (*kill_sb)(struct super_block *);
+	int fs_flags;
+	struct list_head fs_supers;
+};
+
+/* Filesystem type flags */
+#define FS_REQUIRES_DEV		1
+#define FS_BINARY_MOUNTDATA	2
+#define FS_HAS_SUBTYPE		4
+#define FS_USERNS_MOUNT		8
+#define FS_DISALLOW_NOTIFY_PERM	16
+#define FS_ALLOW_IDMAP		32
+
+/**
+ * struct fs_context - filesystem context for mount/reconfigure
+ * @ops: operations for this context
+ * @fs_type: filesystem type
+ * @fs_private: filesystem private data
+ * @root: root dentry (for reconfigure)
+ * @user_ns: user namespace for this mount
+ * @s_fs_info: proposed s_fs_info
+ * @sb_flags: proposed superblock flags
+ * @sb_flags_mask: superblock flags that changed
+ * @lsm_flags: LSM flags
+ * @purpose: what this context is for
+ * @sloppy: permit unrecognised options
+ * @silent: suppress mount errors
+ */
+struct fs_context {
+	const struct fs_context_operations *ops;
+	struct file_system_type *fs_type;
+	void *fs_private;
+	struct dentry *root;
+	struct user_namespace *user_ns;
+	void *s_fs_info;
+	unsigned int sb_flags;
+	unsigned int sb_flags_mask;
+	unsigned int lsm_flags;
+	enum fs_context_purpose purpose;
+	bool sloppy;
+	bool silent;
+};
+
+/**
+ * struct fs_parameter - filesystem mount parameter
+ * @key: parameter name
+ * @type: value type
+ * @size: size of value
+ * @dirfd: directory fd for filename values
+ * @string: string value
+ * @boolean: boolean value
+ * @integer: integer value
+ */
+struct fs_parameter {
+	const char *key;
+	int type;
+	size_t size;
+	int dirfd;
+	union {
+		char *string;
+		int boolean;
+		int integer;
+	};
+};
+
+/* get_tree helpers - stubs */
+#define get_tree_bdev(fc, fill_super)	({ (void)(fc); (void)(fill_super); -ENODEV; })
+#define get_tree_nodev(fc, fill_super)	({ (void)(fc); (void)(fill_super); -ENODEV; })
+
+/* kill_sb helpers - stubs */
+#define kill_block_super(sb)		do { } while (0)
+
+#endif /* _LINUX_FS_CONTEXT_H */
diff --git a/include/linux/fs_parser.h b/include/linux/fs_parser.h
new file mode 100644
index 00000000000..b3f1014fb98
--- /dev/null
+++ b/include/linux/fs_parser.h
@@ -0,0 +1,110 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Filesystem parameter parser stubs for U-Boot
+ *
+ * Based on Linux fs_parser.h - U-Boot doesn't have real mount option
+ * parsing, so these are stubs for compilation.
+ */
+#ifndef _LINUX_FS_PARSER_H
+#define _LINUX_FS_PARSER_H
+
+#include <linux/fs_context.h>
+
+/**
+ * struct constant_table - table of named constants
+ * @name: constant name
+ * @value: constant value
+ */
+struct constant_table {
+	const char *name;
+	int value;
+};
+
+/**
+ * struct fs_parameter_spec - mount parameter specification
+ * @name: parameter name
+ * @opt: option number returned by fs_parse()
+ * @type: parameter type (fs_param_is_* constants)
+ * @data: type-specific data (e.g., enum table)
+ */
+struct fs_parameter_spec {
+	const char *name;
+	int opt;
+	unsigned short type;
+	const struct constant_table *data;
+};
+
+/* fs_parameter spec types - simplified numeric types for U-Boot */
+#define fs_param_is_flag	0
+#define fs_param_is_u32		1
+#define fs_param_is_s32		2
+#define fs_param_is_u64		3
+#define fs_param_is_enum	4
+#define fs_param_is_string	5
+#define fs_param_is_blob	6
+#define fs_param_is_fd		7
+#define fs_param_is_uid		8
+#define fs_param_is_gid		9
+#define fs_param_is_blockdev	10
+
+/**
+ * struct fs_parse_result - result of parsing a parameter
+ * @negated: true if param was "noxxx"
+ * @boolean: boolean result
+ * @int_32: 32-bit signed integer result
+ * @uint_32: 32-bit unsigned integer result
+ * @uint_64: 64-bit unsigned integer result
+ * @uid: UID result
+ * @gid: GID result
+ */
+struct fs_parse_result {
+	bool negated;
+	union {
+		bool boolean;
+		int int_32;
+		unsigned int uint_32;
+		u64 uint_64;
+		kuid_t uid;
+		kgid_t gid;
+	};
+};
+
+/*
+ * fsparam_* macros for mount option parsing - use literal type values
+ * These macros build fs_parameter_spec entries.
+ */
+#define fsparam_flag(name, opt) \
+	{(name), (opt), 0, NULL}
+#define fsparam_u32(name, opt) \
+	{(name), (opt), 1, NULL}
+#define fsparam_s32(name, opt) \
+	{(name), (opt), 2, NULL}
+#define fsparam_u64(name, opt) \
+	{(name), (opt), 3, NULL}
+#define fsparam_string(name, opt) \
+	{(name), (opt), 5, NULL}
+#define fsparam_string_empty(name, opt) \
+	{(name), (opt), 5, NULL}
+#define fsparam_enum(name, opt, array) \
+	{(name), (opt), 4, (array)}
+#define fsparam_bdev(name, opt) \
+	{(name), (opt), 10, NULL}
+#define fsparam_uid(name, opt) \
+	{(name), (opt), 8, NULL}
+#define fsparam_gid(name, opt) \
+	{(name), (opt), 9, NULL}
+#define __fsparam(type, name, opt, flags, data) \
+	{(name), (opt), (type), (data)}
+
+/* ENOPARAM - parameter not found */
+#define ENOPARAM	519
+
+/* fs_parse - parse a mount option - stub */
+#define fs_parse(fc, desc, param, result) \
+	({ (void)(fc); (void)(desc); (void)(param); (void)(result); -ENOPARAM; })
+
+/* fs_lookup_param - lookup parameter path - stub */
+#define fs_lookup_param(fc, p, bdev, fl, path) \
+	({ (void)(fc); (void)(p); (void)(bdev); (void)(fl); (void)(path); -EINVAL; })
+
+#endif /* _LINUX_FS_PARSER_H */