diff --git a/config/Config-build.in b/config/Config-build.in index ae4498554..2fdcc457d 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -384,6 +384,7 @@ menu "Global build settings" config TARGET_ROOTFS_SECURITY_LABELS bool select KERNEL_SQUASHFS_XATTR + select KERNEL_EROFS_FS_SECURITY select KERNEL_EXT4_FS_SECURITY select KERNEL_F2FS_FS_SECURITY select KERNEL_UBIFS_FS_SECURITY diff --git a/config/Config-images.in b/config/Config-images.in index 6b478bd6e..c3d243b51 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -89,6 +89,23 @@ menu "Target Images" comment "Root filesystem images" + menuconfig TARGET_ROOTFS_EROFS + bool "erofs" + default y if USES_EROFS + select KERNEL_EROFS_FS + help + Build a EROFS root filesystem. + + config TARGET_EROFS_PCLUSTER_SIZE + int "physical cluster size (in KiB)" + depends on TARGET_ROOTFS_EROFS + default 64 if LOW_MEMORY_FOOTPRINT + default 1024 if (SMALL_FLASH && !LOW_MEMORY_FOOTPRINT) + default 256 + help + Specify the EROFS physical cluster size (must be equal + to or a multiple of the filesystem block size). + menuconfig TARGET_ROOTFS_EXT4FS bool "ext4" default y if USES_EXT4 diff --git a/config/Config-kernel.in b/config/Config-kernel.in index 7378cd724..3f9586e22 100644 --- a/config/Config-kernel.in +++ b/config/Config-kernel.in @@ -1305,6 +1305,23 @@ config KERNEL_BTRFS_FS Say Y here if you want to make the kernel to be able to boot off a BTRFS partition. +config KERNEL_EROFS_FS + bool "Compile the kernel with built-in EROFS support" + help + Say Y here if you want to make the kernel to be able to boot off a + EROFS partition. + +config KERNEL_EROFS_FS_XATTR + bool "EROFS XATTR support" + +config KERNEL_EROFS_FS_ZIP + bool + default y if KERNEL_EROFS_FS + +config KERNEL_EROFS_FS_ZIP_LZMA + bool + default y if KERNEL_EROFS_FS + menu "Filesystem ACL and attr support options" config USE_FS_ACL_ATTR bool "Use filesystem ACL and attr support by default" @@ -1325,6 +1342,11 @@ menu "Filesystem ACL and attr support options" select KERNEL_FS_POSIX_ACL default y if USE_FS_ACL_ATTR + config KERNEL_EROFS_FS_POSIX_ACL + bool "Enable POSIX ACL for EROFS Filesystems" + select KERNEL_FS_POSIX_ACL + default y if USE_FS_ACL_ATTR + config KERNEL_EXT4_FS_POSIX_ACL bool "Enable POSIX ACL for Ext4 Filesystems" select KERNEL_FS_POSIX_ACL @@ -1478,6 +1500,11 @@ config KERNEL_LSM default "lockdown,yama,loadpin,safesetid,integrity,selinux" depends on KERNEL_SECURITY_SELINUX +config KERNEL_EROFS_FS_SECURITY + bool "EROFS Security Labels" + default y if !SMALL_FLASH + select KERNEL_EROFS_FS_XATTR + config KERNEL_EXT4_FS_SECURITY bool "Ext4 Security Labels" default y if !SMALL_FLASH diff --git a/include/image.mk b/include/image.mk index e99bd65e2..3bdf579da 100644 --- a/include/image.mk +++ b/include/image.mk @@ -87,11 +87,21 @@ endif JFFS2_BLOCKSIZE ?= 64k 128k +EROFS_PCLUSTERSIZE = $(shell echo $$(($(CONFIG_TARGET_EROFS_PCLUSTER_SIZE)*1024))) +EROFSOPT := -Efragments,dedupe,ztailpacking -Uclear --all-root +EROFSOPT += $(if $(SOURCE_DATE_EPOCH),-T$(SOURCE_DATE_EPOCH) --ignore-mtime) +EROFSOPT += $(if $(CONFIG_SELINUX),,-x-1) +EROFSCOMP := lz4hc,12 +ifeq ($(CONFIG_EROFS_FS_ZIP_LZMA),y) +EROFSCOMP := lzma,109 +endif + fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE)) fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE)) fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4 fs-types-$(CONFIG_TARGET_ROOTFS_UBIFS) += ubifs +fs-types-$(CONFIG_TARGET_ROOTFS_EROFS) += erofs fs-subtypes-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addsuffix -raw,$(addprefix jffs2-,$(JFFS2_BLOCKSIZE))) TARGET_FILESYSTEMS := $(fs-types-y) @@ -275,6 +285,13 @@ define Image/mkfs/ext4 $@ $(call mkfs_target_dir,$(1))/ endef +# Don't use the mkfs.erofs builtin $SOURCE_DATE_EPOCH behavior +define Image/mkfs/erofs + env -u SOURCE_DATE_EPOCH $(STAGING_DIR_HOST)/bin/mkfs.erofs -z$(EROFSCOMP) \ + -C$(EROFS_PCLUSTERSIZE) $(EROFSOPT) \ + $@ $(call mkfs_target_dir,$(1)) +endef + define Image/Manifest $(call opkg,$(TARGET_DIR_ORIG)) list-installed > \ $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).manifest diff --git a/package/system/fstools/patches/0001-EroFS.patch b/package/system/fstools/patches/0001-EroFS.patch new file mode 100644 index 000000000..31800a6b1 --- /dev/null +++ b/package/system/fstools/patches/0001-EroFS.patch @@ -0,0 +1,139 @@ +From e8cd820cdbb8fba990fd79efda90c5dc10d8e45c Mon Sep 17 00:00:00 2001 +From: Gao Xiang +Subject: [PATCH] libfstools: add support for EroFS based images + +Add support to libfstools to parse and support EroFS based images to +permit correct mounting of OverlayFS with it. (in addition to SquashFS +support) + +While at it rework the code to better handle the 2 different filesystem +introducing a similar pattern. + +Signed-off-by: Gao Xiang +Signed-off-by: Christian Marangi +--- + libfstools/rootdisk.c | 83 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 77 insertions(+), 6 deletions(-) + +--- a/libfstools/rootdisk.c ++++ b/libfstools/rootdisk.c +@@ -15,6 +15,8 @@ + + #include + ++#define SQUASHFS_MAGIC "hsqs" ++#define EROFS_MAGIC 0xE0F5E1E2 + #define ROOTDEV_OVERLAY_ALIGN (64ULL * 1024ULL) + #define F2FS_MINSIZE (100ULL * 1024ULL * 1024ULL) + +@@ -24,6 +26,14 @@ struct squashfs_super_block { + uint64_t bytes_used; + }; + ++struct erofs_super_block { ++ uint32_t s_magic; ++ uint32_t pad0[2]; ++ uint8_t blkszbits; ++ uint8_t pad1[23]; ++ uint32_t blocks; ++}; ++ + struct rootdev_volume { + struct volume v; + uint64_t offset; +@@ -93,10 +103,66 @@ static int get_squashfs(struct squashfs_ + return 0; + } + +-static struct volume *rootdisk_volume_find(char *name) ++static int check_squashfs(uint64_t *offset) + { ++ const char *s_magic = SQUASHFS_MAGIC; + struct squashfs_super_block sb; ++ int ret; ++ ++ ret = get_squashfs(&sb); ++ if (ret) ++ return ret; ++ ++ if (memcmp(&sb.s_magic, s_magic, sizeof(sb.s_magic))) ++ return -1; ++ ++ *offset = le64_to_cpu(sb.bytes_used); ++ return 0; ++} ++ ++static int get_erofs(struct erofs_super_block *sb) ++{ ++ FILE *f; ++ int len; ++ ++ f = fopen(rootdev, "r"); ++ if (!f) ++ return -1; ++ ++ if (fseek(f, 1024, SEEK_SET)) ++ return -1; ++ ++ len = fread(sb, sizeof(*sb), 1, f); ++ fclose(f); ++ ++ if (len != 1) ++ return -1; ++ ++ return 0; ++} ++ ++static int check_erofs(uint64_t *offset) ++{ ++ uint32_t s_magic = cpu_to_le32(EROFS_MAGIC); ++ struct erofs_super_block sb; ++ int ret; ++ ++ ret = get_erofs(&sb); ++ if (ret) ++ return ret; ++ ++ if (memcmp(&sb.s_magic, &s_magic, sizeof(sb.s_magic))) ++ return -1; ++ ++ *offset = (uint64_t)le32_to_cpu(sb.blocks) << sb.blkszbits; ++ return 0; ++} ++ ++static struct volume *rootdisk_volume_find(char *name) ++{ + struct rootdev_volume *p; ++ uint64_t offset; ++ int ret; + + if (strcmp(name, "rootfs_data") != 0) + return NULL; +@@ -108,17 +174,22 @@ static struct volume *rootdisk_volume_fi + if (!rootdev) + return NULL; + +- if (get_squashfs(&sb)) +- return NULL; +- +- if (memcmp(&sb.s_magic, "hsqs", sizeof(sb.s_magic)) != 0) ++ /* ++ * We support both SquashFS and EroFS. ++ * First check for SquashFS and then check ++ * for EroFS on new images. ++ */ ++ ret = check_squashfs(&offset); ++ if (ret < 0 || !offset) ++ ret = check_erofs(&offset); ++ if (ret < 0 || !offset) + return NULL; + + p = calloc(1, sizeof(*p)); + p->v.drv = &rootdisk_driver; + p->v.name = "rootfs_data"; + +- p->offset = le64_to_cpu(sb.bytes_used); ++ p->offset = offset; + p->offset = ((p->offset + (ROOTDEV_OVERLAY_ALIGN - 1)) & + ~(ROOTDEV_OVERLAY_ALIGN - 1)); + diff --git a/scripts/target-metadata.pl b/scripts/target-metadata.pl index 223b5aaec..79ae50087 100755 --- a/scripts/target-metadata.pl +++ b/scripts/target-metadata.pl @@ -18,6 +18,7 @@ sub target_config_features(@) { /^dt$/ and $ret .= "\tselect USES_DEVICETREE\n"; /^dt-overlay$/ and $ret .= "\tselect HAS_DT_OVERLAY_SUPPORT\n"; /^emmc$/ and $ret .= "\tselect EMMC_SUPPORT\n"; + /^erofs$/ and $ret .= "\tselect USES_EROFS\n"; /^ext4$/ and $ret .= "\tselect USES_EXT4\n"; /^fpu$/ and $ret .= "\tselect HAS_FPU\n"; /^gpio$/ and $ret .= "\tselect GPIO_SUPPORT\n"; diff --git a/target/Config.in b/target/Config.in index c2395923d..c0f3237ca 100644 --- a/target/Config.in +++ b/target/Config.in @@ -69,6 +69,9 @@ config USES_JFFS2_NAND config USES_EXT4 bool +config USES_EROFS + bool + config USES_TARGZ bool diff --git a/target/linux/generic/config-6.1 b/target/linux/generic/config-6.1 index 406710a8d..9aedccfab 100644 --- a/target/linux/generic/config-6.1 +++ b/target/linux/generic/config-6.1 @@ -1978,6 +1978,12 @@ CONFIG_ENABLE_WARN_DEPRECATED=y CONFIG_EPOLL=y # CONFIG_EQUALIZER is not set # CONFIG_EROFS_FS is not set +# CONFIG_EROFS_FS_DEBUG is not set +# CONFIG_EROFS_FS_XATTR is not set +# CONFIG_EROFS_FS_POSIX_ACL is not set +# CONFIG_EROFS_FS_SECURITY is not set +# CONFIG_EROFS_FS_ZIP is not set +# CONFIG_EROFS_FS_ONDEMAND is not set # CONFIG_ET131X is not set CONFIG_ETHERNET=y # CONFIG_ETHOC is not set diff --git a/target/linux/generic/config-6.12 b/target/linux/generic/config-6.12 index f2fe8e400..5ce234195 100644 --- a/target/linux/generic/config-6.12 +++ b/target/linux/generic/config-6.12 @@ -1896,6 +1896,17 @@ CONFIG_ELFCORE=y CONFIG_EPOLL=y # CONFIG_EQUALIZER is not set # CONFIG_EROFS_FS is not set +# CONFIG_EROFS_FS_DEBUG is not set +# CONFIG_EROFS_FS_XATTR is not set +# CONFIG_EROFS_FS_POSIX_ACL is not set +# CONFIG_EROFS_FS_SECURITY is not set +# CONFIG_EROFS_FS_BACKED_BY_FILE is not set +# CONFIG_EROFS_FS_ZIP is not set +# CONFIG_EROFS_FS_ZIP_DEFLATE is not set +# CONFIG_EROFS_FS_ZIP_ZSTD is not set +# CONFIG_EROFS_FS_ONDEMAND is not set +CONFIG_EROFS_FS_PCPU_KTHREAD=y +CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI=y # CONFIG_ET131X is not set CONFIG_ETHERNET=y # CONFIG_ETHOC is not set diff --git a/target/linux/generic/config-6.6 b/target/linux/generic/config-6.6 index 2ca466ec0..0597242db 100644 --- a/target/linux/generic/config-6.6 +++ b/target/linux/generic/config-6.6 @@ -1840,6 +1840,15 @@ CONFIG_ELFCORE=y CONFIG_EPOLL=y # CONFIG_EQUALIZER is not set # CONFIG_EROFS_FS is not set +# CONFIG_EROFS_FS_DEBUG is not set +# CONFIG_EROFS_FS_XATTR is not set +# CONFIG_EROFS_FS_POSIX_ACL is not set +# CONFIG_EROFS_FS_SECURITY is not set +# CONFIG_EROFS_FS_ZIP is not set +# CONFIG_EROFS_FS_ZIP_DEFLATE is not set +# CONFIG_EROFS_FS_ONDEMAND is not set +CONFIG_EROFS_FS_PCPU_KTHREAD=y +CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI=y # CONFIG_ET131X is not set CONFIG_ETHERNET=y # CONFIG_ETHOC is not set