diff options
Diffstat (limited to 'target/linux/generic/patches-2.6.37/400-rootfs_split.patch')
-rw-r--r-- | target/linux/generic/patches-2.6.37/400-rootfs_split.patch | 331 |
1 files changed, 0 insertions, 331 deletions
diff --git a/target/linux/generic/patches-2.6.37/400-rootfs_split.patch b/target/linux/generic/patches-2.6.37/400-rootfs_split.patch deleted file mode 100644 index 0eeef62..0000000 --- a/target/linux/generic/patches-2.6.37/400-rootfs_split.patch +++ /dev/null @@ -1,331 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -53,6 +53,16 @@ config MTD_PARTITIONS - devices. Partitioning on NFTL 'devices' is a different - that's the - 'normal' form of partitioning used on a block device. - -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ depends on MTD_PARTITIONS -+ default y -+ -+config MTD_ROOTFS_SPLIT -+ bool "Automatically split 'rootfs' partition for squashfs" -+ depends on MTD_PARTITIONS -+ default y -+ - config MTD_REDBOOT_PARTS - tristate "RedBoot partition table parsing" - depends on MTD_PARTITIONS ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -29,6 +29,8 @@ - #include <linux/kmod.h> - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> -+#include <linux/root_dev.h> -+#include <linux/magic.h> - #include <linux/err.h> - - /* Our partition linked list */ -@@ -48,7 +50,7 @@ struct mtd_part { - * the pointer to that structure with this macro. - */ - #define PART(x) ((struct mtd_part *)(x)) -- -+#define IS_PART(mtd) (mtd->read == part_read) - - /* - * MTD methods which simply translate the effective address and pass through -@@ -618,6 +620,155 @@ int mtd_del_partition(struct mtd_info *m - } - EXPORT_SYMBOL_GPL(mtd_del_partition); - -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+#define ROOTFS_SPLIT_NAME "rootfs_data" -+#define ROOTFS_REMOVED_NAME "<removed>" -+ -+struct squashfs_super_block { -+ __le32 s_magic; -+ __le32 pad0[9]; -+ __le64 bytes_used; -+}; -+ -+ -+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) -+{ -+ struct squashfs_super_block sb; -+ int len, ret; -+ -+ ret = master->read(master, offset, sizeof(sb), &len, (void *) &sb); -+ if (ret || (len != sizeof(sb))) { -+ printk(KERN_ALERT "split_squashfs: error occured while reading " -+ "from \"%s\"\n", master->name); -+ return -EINVAL; -+ } -+ -+ if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) { -+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n", -+ master->name); -+ *split_offset = 0; -+ return 0; -+ } -+ -+ if (le64_to_cpu((sb.bytes_used)) <= 0) { -+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n", -+ master->name); -+ *split_offset = 0; -+ return 0; -+ } -+ -+ len = (u32) le64_to_cpu(sb.bytes_used); -+ len += (offset & 0x000fffff); -+ len += (master->erasesize - 1); -+ len &= ~(master->erasesize - 1); -+ len -= (offset & 0x000fffff); -+ *split_offset = offset + len; -+ -+ return 0; -+} -+ -+static int split_rootfs_data(struct mtd_info *master, struct mtd_info *rpart, const struct mtd_partition *part) -+{ -+ struct mtd_partition *dpart; -+ struct mtd_part *slave = NULL; -+ struct mtd_part *spart; -+ int ret, split_offset = 0; -+ -+ spart = PART(rpart); -+ ret = split_squashfs(master, spart->offset, &split_offset); -+ if (ret) -+ return ret; -+ -+ if (split_offset <= 0) -+ return 0; -+ -+ dpart = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL); -+ if (dpart == NULL) { -+ printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n", -+ ROOTFS_SPLIT_NAME); -+ return -ENOMEM; -+ } -+ -+ memcpy(dpart, part, sizeof(*part)); -+ strcpy((char *)&dpart[1], ROOTFS_SPLIT_NAME); -+ dpart->name = (unsigned char *)&dpart[1]; -+ -+ dpart->size = rpart->size - (split_offset - spart->offset); -+ dpart->offset = split_offset; -+ -+ if (dpart == NULL) -+ return 1; -+ -+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%llX, len=%llX \n", -+ ROOTFS_SPLIT_NAME, dpart->offset, dpart->size); -+ -+ slave = allocate_partition(master, dpart, 0, split_offset); -+ if (IS_ERR(slave)) -+ return PTR_ERR(slave); -+ mutex_lock(&mtd_partitions_mutex); -+ list_add(&slave->list, &mtd_partitions); -+ mutex_unlock(&mtd_partitions_mutex); -+ -+ add_mtd_device(&slave->mtd); -+ -+ rpart->split = &slave->mtd; -+ -+ return 0; -+} -+ -+static int refresh_rootfs_split(struct mtd_info *mtd) -+{ -+ struct mtd_partition tpart; -+ struct mtd_part *part; -+ char *name; -+ //int index = 0; -+ int offset, size; -+ int ret; -+ -+ part = PART(mtd); -+ -+ /* check for the new squashfs offset first */ -+ ret = split_squashfs(part->master, part->offset, &offset); -+ if (ret) -+ return ret; -+ -+ if ((offset > 0) && !mtd->split) { -+ printk(KERN_INFO "%s: creating new split partition for \"%s\"\n", __func__, mtd->name); -+ /* if we don't have a rootfs split partition, create a new one */ -+ tpart.name = (char *) mtd->name; -+ tpart.size = mtd->size; -+ tpart.offset = part->offset; -+ -+ return split_rootfs_data(part->master, &part->mtd, &tpart); -+ } else if ((offset > 0) && mtd->split) { -+ /* update the offsets of the existing partition */ -+ size = mtd->size + part->offset - offset; -+ -+ part = PART(mtd->split); -+ part->offset = offset; -+ part->mtd.size = size; -+ printk(KERN_INFO "%s: %s partition \"" ROOTFS_SPLIT_NAME "\", offset: 0x%06x (0x%06x)\n", -+ __func__, (!strcmp(part->mtd.name, ROOTFS_SPLIT_NAME) ? "updating" : "creating"), -+ (u32) part->offset, (u32) part->mtd.size); -+ name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL); -+ strcpy(name, ROOTFS_SPLIT_NAME); -+ part->mtd.name = name; -+ } else if ((offset <= 0) && mtd->split) { -+ printk(KERN_INFO "%s: removing partition \"%s\"\n", __func__, mtd->split->name); -+ -+ /* mark existing partition as removed */ -+ part = PART(mtd->split); -+ name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL); -+ strcpy(name, ROOTFS_REMOVED_NAME); -+ part->mtd.name = name; -+ part->offset = 0; -+ part->mtd.size = 0; -+ } -+ -+ return 0; -+} -+#endif /* CONFIG_MTD_ROOTFS_SPLIT */ -+ - /* - * This function, given a master MTD object and a partition table, creates - * and registers slave MTD objects which are bound to the master according to -@@ -633,7 +784,7 @@ int add_mtd_partitions(struct mtd_info * - { - struct mtd_part *slave; - uint64_t cur_offset = 0; -- int i; -+ int i, ret; - - printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); - -@@ -648,6 +799,21 @@ int add_mtd_partitions(struct mtd_info * - - add_mtd_device(&slave->mtd); - -+ if (!strcmp(parts[i].name, "rootfs")) { -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+ if (ROOT_DEV == 0) { -+ printk(KERN_NOTICE "mtd: partition \"rootfs\" " -+ "set to be root filesystem\n"); -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index); -+ } -+#endif -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+ ret = split_rootfs_data(master, &slave->mtd, &parts[i]); -+ /* if (ret == 0) -+ * j++; */ -+#endif -+ } -+ - cur_offset = slave->offset + slave->mtd.size; - } - -@@ -655,6 +821,32 @@ int add_mtd_partitions(struct mtd_info * - } - EXPORT_SYMBOL(add_mtd_partitions); - -+int refresh_mtd_partitions(struct mtd_info *mtd) -+{ -+ int ret = 0; -+ -+ if (IS_PART(mtd)) { -+ struct mtd_part *part; -+ struct mtd_info *master; -+ -+ part = PART(mtd); -+ master = part->master; -+ if (master->refresh_device) -+ ret = master->refresh_device(master); -+ } -+ -+ if (!ret && mtd->refresh_device) -+ ret = mtd->refresh_device(mtd); -+ -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+ if (!ret && IS_PART(mtd) && !strcmp(mtd->name, "rootfs")) -+ refresh_rootfs_split(mtd); -+#endif -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(refresh_mtd_partitions); -+ - static DEFINE_SPINLOCK(part_parser_lock); - static LIST_HEAD(part_parsers); - ---- a/drivers/mtd/mtdchar.c -+++ b/drivers/mtd/mtdchar.c -@@ -956,6 +956,13 @@ static int mtd_ioctl(struct file *file, - break; - } - #endif -+#ifdef CONFIG_MTD_PARTITIONS -+ case MTDREFRESH: -+ { -+ ret = refresh_mtd_partitions(mtd); -+ break; -+ } -+#endif - - default: - ret = -ENOTTY; ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -125,6 +125,7 @@ struct nand_ecclayout { - struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE]; - }; - -+struct mtd_info; - struct mtd_info { - u_char type; - uint32_t flags; -@@ -266,6 +267,9 @@ struct mtd_info { - struct device dev; - int usecount; - -+ int (*refresh_device)(struct mtd_info *mtd); -+ struct mtd_info *split; -+ - /* If the driver is something smart, like UBI, it may need to maintain - * its own reference counting. The below functions are only for driver. - * The driver may register its callbacks. These callbacks are not ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -34,12 +34,14 @@ - * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). - */ - -+struct mtd_partition; - struct mtd_partition { -- char *name; /* identifier string */ -+ const char *name; /* identifier string */ - uint64_t size; /* partition size */ - uint64_t offset; /* offset within the master MTD space */ - uint32_t mask_flags; /* master MTD flags to mask out for this partition */ - struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */ -+ int (*refresh_partition)(struct mtd_info *); - }; - - #define MTDPART_OFS_NXTBLK (-2) -@@ -51,6 +53,7 @@ struct mtd_info; - - int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); - int del_mtd_partitions(struct mtd_info *); -+int refresh_mtd_partitions(struct mtd_info *); - - /* - * Functions dealing with the various ways of partitioning the space ---- a/include/mtd/mtd-abi.h -+++ b/include/mtd/mtd-abi.h -@@ -127,6 +127,7 @@ struct otp_info { - #define MEMWRITEOOB64 _IOWR('M', 21, struct mtd_oob_buf64) - #define MEMREADOOB64 _IOWR('M', 22, struct mtd_oob_buf64) - #define MEMISLOCKED _IOR('M', 23, struct erase_info_user) -+#define MTDREFRESH _IO('M', 50) - - /* - * Obsolete legacy interface. Keep it in order not to break userspace |