gl-infra-builder-FUjr/patches-mt798x-7.6.6.1/2009-kernel-block-support-partition-split.patch
Jianhui Zhao b5ee06b0bc mt798x: split some patchs
Signed-off-by: Jianhui Zhao <jianhui.zhao@gl-inet.com>
2023-05-16 18:21:21 +08:00

207 lines
6.0 KiB
Diff

From a5fb2fb2faa520dabb8b3515918f725678d3ed80 Mon Sep 17 00:00:00 2001
From: Jianhui Zhao <jianhui.zhao@gl-inet.com>
Date: Tue, 16 May 2023 18:19:30 +0800
Subject: [PATCH] kernel: block: support partition split
Signed-off-by: Jianhui Zhao <jianhui.zhao@gl-inet.com>
---
.../9999-support-partition-split.patch | 186 ++++++++++++++++++
1 file changed, 186 insertions(+)
create mode 100644 target/linux/generic/hack-5.4/9999-support-partition-split.patch
diff --git a/target/linux/generic/hack-5.4/9999-support-partition-split.patch b/target/linux/generic/hack-5.4/9999-support-partition-split.patch
new file mode 100644
index 0000000000..8e0026c216
--- /dev/null
+++ b/target/linux/generic/hack-5.4/9999-support-partition-split.patch
@@ -0,0 +1,186 @@
+Index: linux-5.4.188/block/Kconfig
+===================================================================
+--- linux-5.4.188.orig/block/Kconfig
++++ linux-5.4.188/block/Kconfig
+@@ -105,6 +105,9 @@ config BLK_DEV_THROTTLING_LOW
+
+ Note, this is an experimental interface and could be changed someday.
+
++config PARTITION_SPLIT
++ bool "Openwrt Block device partition rootfs split"
++
+ config BLK_CMDLINE_PARSER
+ bool "Block device command line partition parser"
+ ---help---
+Index: linux-5.4.188/block/Makefile
+===================================================================
+--- linux-5.4.188.orig/block/Makefile
++++ linux-5.4.188/block/Makefile
+@@ -36,3 +36,4 @@ obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-deb
+ obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o
+ obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o
+ obj-$(CONFIG_BLK_PM) += blk-pm.o
++obj-$(CONFIG_PARTITION_SPLIT) += partition-split.o
+Index: linux-5.4.188/block/partition-generic.c
+===================================================================
+--- linux-5.4.188.orig/block/partition-generic.c
++++ linux-5.4.188/block/partition-generic.c
+@@ -21,6 +21,10 @@
+
+ #include "partitions/check.h"
+
++#ifdef CONFIG_PARTITION_SPLIT
++#include "partition-split.h"
++#endif
++
+ #ifdef CONFIG_BLK_DEV_MD
+ extern void md_autodetect_dev(dev_t dev);
+ #endif
+@@ -569,6 +573,9 @@ rescan:
+ highest = p;
+
+ disk_expand_part_tbl(disk, highest);
++#ifdef CONFIG_PARTITION_SPLIT
++ partition_split(bdev, state);
++#endif
+
+ /* add partitions */
+ for (p = 1; p < state->limit; p++) {
+Index: linux-5.4.188/block/partition-split.c
+===================================================================
+--- /dev/null
++++ linux-5.4.188/block/partition-split.c
+@@ -0,0 +1,111 @@
++#include <linux/blkdev.h>
++#include <linux/magic.h>
++#include <linux/module.h>
++#include "partitions/check.h"
++#include "partition-split.h"
++
++void print_sblock_value(char *buf)
++{
++ int i, j;
++ for (i = 0; i < sizeof(struct squashfs_sblock);) {
++ for (j = 0; j < 16; j++) {
++ printk("%02x ", buf[i]);
++ i++;
++ }
++ printk("\n");
++ }
++}
++
++unsigned char *fs_read_super_block(struct block_device *bdev, sector_t from, Sector *sector)
++{
++ if (from >= get_capacity(bdev->bd_disk)) {
++ return NULL;
++ }
++ return read_dev_sector(bdev, from, sector);
++}
++
++
++int get_squashfs_len(struct block_device *bdev, sector_t from, size_t *squashfs_len)
++{
++ struct squashfs_sblock sb;
++ unsigned char *buf;
++ Sector sector;
++ size_t retlen;
++
++ buf = fs_read_super_block(bdev, from, &sector);
++ if (!buf) {
++ printk("failed to get super\n");
++ return -EIO;
++ }
++ memcpy((void *)&sb, buf, sizeof(sb));
++ put_dev_sector(sector);
++
++ if (le32_to_cpu(sb.s_magic) != SQUASHFS_MAGIC) {
++ printk("no squashfs found in\n");
++ //print_sblock_value((char *)&sb);
++ return -EINVAL;
++ }
++
++ retlen = le64_to_cpu(sb.bytes_used);
++ if (retlen <= 0) {
++ printk("squashfs is empty in \n");
++ return -ENODEV;
++ }
++
++ *squashfs_len = retlen;
++ return 0;
++}
++
++static int find_part_by_lable(struct parsed_partitions *state, const char *lable)
++{
++ int p;
++ /* add partitions */
++ for (p = 1; p < state->limit; p++) {
++ if (!strcmp(state->parts[p].info.volname, lable))
++ return p;
++ }
++ return 0;
++}
++
++int partition_split(struct block_device *bdev, struct parsed_partitions *state)
++{
++ int p, insert;
++ size_t sqfs_size;
++ sector_t new_size, new_from;
++ struct partition_meta_info *info;
++ char tmp[sizeof(info->volname) + 4];
++
++ p = find_part_by_lable(state, ROOTFS_PART);
++ if (p == 0)
++ return 0;
++ if (get_squashfs_len(bdev, state->parts[p].from, &sqfs_size))
++ return 0;
++
++ sqfs_size = (sqfs_size + (ALING_SQFS - 1)) & ~(ALING_SQFS - 1); //squashfs 64k对齐
++
++ //计算新分区大小和起始位置
++
++ new_size = state->parts[p].size - (sqfs_size >> 9);
++ new_from = state->parts[p].from + (sqfs_size >> 9);
++
++ for (insert = 1; insert < state->limit; insert++) {
++ if (!state->parts[insert].size)
++ break;
++ }
++
++ if (insert >= state->limit)
++ return 0;
++
++ //追加一个新分区并设置相关信息
++ put_partition(state, insert, new_from, new_size);
++
++ info = &state->parts[insert].info;
++
++ strncpy(info->volname, ROOTFS_PART_DATA, strlen(ROOTFS_PART_DATA) + 1);
++ snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
++ strlcat(state->pp_buf, tmp, PAGE_SIZE);
++
++ state->parts[insert].has_info = true;
++ return 0;
++
++}
+Index: linux-5.4.188/block/partition-split.h
+===================================================================
+--- /dev/null
++++ linux-5.4.188/block/partition-split.h
+@@ -0,0 +1,17 @@
++#ifndef __PARTITION_SPLIT_H
++#define __PARTITION_SPLIT_H
++
++#define ROOTFS_PART "rootfs"
++#define ROOTFS_PART_DATA "rootfs_data"
++
++#define ALING_SQFS 0X10000
++
++struct squashfs_sblock {
++ __le32 s_magic;
++ __le32 pad0[9];
++ __le64 bytes_used;
++};
++
++extern int partition_split(struct block_device *bdev, struct parsed_partitions *state);
++
++#endif
--
2.34.1