diff options
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch')
-rw-r--r-- | target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch | 488 |
1 files changed, 0 insertions, 488 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch b/target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch deleted file mode 100644 index 3a773847fc..0000000000 --- a/target/linux/generic-2.6/patches-2.6.21/060-rootfs_split.patch +++ /dev/null @@ -1,488 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -49,6 +49,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 -@@ -20,6 +20,8 @@ - #include <linux/mtd/mtd.h> - #include <linux/mtd/partitions.h> - #include <linux/mtd/compatmac.h> -+#include <linux/squashfs_fs.h> -+#include <linux/root_dev.h> - - /* Our partition linked list */ - static LIST_HEAD(mtd_partitions); -@@ -308,6 +310,266 @@ int del_mtd_partitions(struct mtd_info * - return 0; - } - -+static u_int32_t cur_offset = 0; -+static int add_one_partition(struct mtd_info *master, const struct mtd_partition *part, -+ int i, struct mtd_part **slp) -+{ -+ struct mtd_part *slave; -+ -+ /* allocate the partition structure */ -+ slave = kzalloc (sizeof(*slave), GFP_KERNEL); -+ if (!slave) { -+ printk ("memory allocation error while creating partitions for \"%s\"\n", -+ master->name); -+ del_mtd_partitions(master); -+ return -ENOMEM; -+ } -+ list_add(&slave->list, &mtd_partitions); -+ -+ /* set up the MTD object for this partition */ -+ slave->mtd.type = master->type; -+ slave->mtd.flags = master->flags & ~part->mask_flags; -+ slave->mtd.size = part->size; -+ slave->mtd.writesize = master->writesize; -+ slave->mtd.oobsize = master->oobsize; -+ slave->mtd.oobavail = master->oobavail; -+ slave->mtd.subpage_sft = master->subpage_sft; -+ -+ slave->mtd.name = part->name; -+ slave->mtd.bank_size = master->bank_size; -+ slave->mtd.owner = master->owner; -+ -+ slave->mtd.read = part_read; -+ slave->mtd.write = part_write; -+ -+ if(master->point && master->unpoint){ -+ slave->mtd.point = part_point; -+ slave->mtd.unpoint = part_unpoint; -+ } -+ -+ if (master->read_oob) -+ slave->mtd.read_oob = part_read_oob; -+ if (master->write_oob) -+ slave->mtd.write_oob = part_write_oob; -+ if(master->read_user_prot_reg) -+ slave->mtd.read_user_prot_reg = part_read_user_prot_reg; -+ if(master->read_fact_prot_reg) -+ slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; -+ if(master->write_user_prot_reg) -+ slave->mtd.write_user_prot_reg = part_write_user_prot_reg; -+ if(master->lock_user_prot_reg) -+ slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; -+ if(master->get_user_prot_info) -+ slave->mtd.get_user_prot_info = part_get_user_prot_info; -+ if(master->get_fact_prot_info) -+ slave->mtd.get_fact_prot_info = part_get_fact_prot_info; -+ if (master->sync) -+ slave->mtd.sync = part_sync; -+ if (!i && master->suspend && master->resume) { -+ slave->mtd.suspend = part_suspend; -+ slave->mtd.resume = part_resume; -+ } -+ if (master->writev) -+ slave->mtd.writev = part_writev; -+ if (master->lock) -+ slave->mtd.lock = part_lock; -+ if (master->unlock) -+ slave->mtd.unlock = part_unlock; -+ if (master->block_isbad) -+ slave->mtd.block_isbad = part_block_isbad; -+ if (master->block_markbad) -+ slave->mtd.block_markbad = part_block_markbad; -+ slave->mtd.erase = part_erase; -+ slave->master = master; -+ slave->offset = part->offset; -+ slave->index = i; -+ -+ if (slave->offset == MTDPART_OFS_APPEND) -+ slave->offset = cur_offset; -+ if (slave->offset == MTDPART_OFS_NXTBLK) { -+ slave->offset = cur_offset; -+ if ((cur_offset % master->erasesize) != 0) { -+ /* Round up to next erasesize */ -+ slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; -+ printk(KERN_NOTICE "Moving partition %d: " -+ "0x%08x -> 0x%08x\n", i, -+ cur_offset, slave->offset); -+ } -+ } -+ if (slave->mtd.size == MTDPART_SIZ_FULL) -+ slave->mtd.size = master->size - slave->offset; -+ cur_offset = slave->offset + slave->mtd.size; -+ -+ printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, -+ slave->offset + slave->mtd.size, slave->mtd.name); -+ -+ /* let's do some sanity checks */ -+ if (slave->offset >= master->size) { -+ /* let's register it anyway to preserve ordering */ -+ slave->offset = 0; -+ slave->mtd.size = 0; -+ printk ("mtd: partition \"%s\" is out of reach -- disabled\n", -+ part->name); -+ } -+ if (slave->offset + slave->mtd.size > master->size) { -+ slave->mtd.size = master->size - slave->offset; -+ printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", -+ part->name, master->name, slave->mtd.size); -+ } -+ if (master->numeraseregions>1) { -+ /* Deal with variable erase size stuff */ -+ int i; -+ struct mtd_erase_region_info *regions = master->eraseregions; -+ -+ /* Find the first erase regions which is part of this partition. */ -+ for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) -+ ; -+ -+ for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { -+ if (slave->mtd.erasesize < regions[i].erasesize) { -+ slave->mtd.erasesize = regions[i].erasesize; -+ } -+ } -+ } else { -+ /* Single erase size */ -+ slave->mtd.erasesize = master->erasesize; -+ } -+ -+ if ((slave->mtd.flags & MTD_WRITEABLE) && -+ (slave->offset % slave->mtd.erasesize)) { -+ /* Doesn't start on a boundary of major erase size */ -+ /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ -+ slave->mtd.flags &= ~MTD_WRITEABLE; -+ printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", -+ part->name); -+ } -+ if ((slave->mtd.flags & MTD_WRITEABLE) && -+ (slave->mtd.size % slave->mtd.erasesize)) { -+ slave->mtd.flags &= ~MTD_WRITEABLE; -+ printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", -+ part->name); -+ } -+ -+ slave->mtd.ecclayout = master->ecclayout; -+ if (master->block_isbad) { -+ uint32_t offs = 0; -+ -+ while(offs < slave->mtd.size) { -+ if (master->block_isbad(master, -+ offs + slave->offset)) -+ slave->mtd.ecc_stats.badblocks++; -+ offs += slave->mtd.erasesize; -+ } -+ } -+ -+ if(part->mtdp) -+ { /* store the object pointer (caller may or may not register it */ -+ *part->mtdp = &slave->mtd; -+ slave->registered = 0; -+ } -+ else -+ { -+ /* register our partition */ -+ add_mtd_device(&slave->mtd); -+ slave->registered = 1; -+ } -+ -+ if (slp) -+ *slp = slave; -+ -+ return 0; -+} -+ -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+#define ROOTFS_SPLIT_NAME "rootfs_data" -+static int split_squashfs(struct mtd_info *master, struct mtd_partition *old, -+ struct mtd_partition **new) -+{ -+ struct mtd_partition *part = NULL; -+ int len; -+ char buf[512]; -+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf; -+ int ret; -+ -+ ret = master->read(master, old->offset, sizeof(*sb), &len, buf); -+ if (ret) { -+ printk(KERN_ALERT "split_squashfs: error occured while reading " -+ "from \"%s\"\n", master->name); -+ goto out; -+ } -+ -+ if (len != sizeof(*sb)) { -+ printk(KERN_ALERT "split_squashfs: unable to read superblock " -+ "from \"%s\"\n", master->name); -+ ret=-1; -+ goto out; -+ } -+ -+ if (*((u32 *) buf) != SQUASHFS_MAGIC) { -+ printk(KERN_ALERT "split_squasfs: no squashfs found in \"%s\"\n", -+ master->name); -+ ret=0; -+ goto out; -+ } -+ -+ if (sb->bytes_used <= 0) { -+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n", -+ master->name); -+ ret=0; -+ goto out; -+ } -+ -+ part = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL); -+ if (part == NULL) { -+ printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n", -+ ROOTFS_SPLIT_NAME); -+ ret = -ENOMEM; -+ goto out; -+ } -+ -+ memcpy(part, old, sizeof(*part)); -+ part->name = (unsigned char *)&part[1]; -+ strcpy(part->name, ROOTFS_SPLIT_NAME); -+ -+ len = (u32) sb->bytes_used; -+ len += (part->offset & 0x000fffff); -+ len += (master->erasesize - 1); -+ len &= ~(master->erasesize - 1); -+ len -= (part->offset & 0x000fffff); -+ part->offset += len; -+ part->size -= len; -+ -+ ret = 0; -+ -+out: -+ *new = part; -+ return ret; -+} -+ -+static int split_rootfs_data(struct mtd_info *master, struct mtd_partition *part, -+ int index) -+{ -+ struct mtd_partition *dpart; -+ int ret; -+ -+ ret = split_squashfs(master, part, &dpart); -+ if (ret) -+ return ret; -+ -+ if (dpart == NULL) -+ return 1; -+ -+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%X, len=%X \n", -+ ROOTFS_SPLIT_NAME, dpart->offset, dpart->size); -+ -+ ret = add_one_partition(master, dpart, index, NULL); -+ if (ret) -+ kfree(dpart); -+ -+ return ret; -+} -+#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 -@@ -320,169 +582,31 @@ int add_mtd_partitions(struct mtd_info * - int nbparts) - { - struct mtd_part *slave; -- u_int32_t cur_offset = 0; -- int i; -+ struct mtd_partition *part; -+ int i, j, ret = 0; - - printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); - -- for (i = 0; i < nbparts; i++) { -- -- /* allocate the partition structure */ -- slave = kzalloc (sizeof(*slave), GFP_KERNEL); -- if (!slave) { -- printk ("memory allocation error while creating partitions for \"%s\"\n", -- master->name); -- del_mtd_partitions(master); -- return -ENOMEM; -- } -- list_add(&slave->list, &mtd_partitions); -- -- /* set up the MTD object for this partition */ -- slave->mtd.type = master->type; -- slave->mtd.flags = master->flags & ~parts[i].mask_flags; -- slave->mtd.size = parts[i].size; -- slave->mtd.writesize = master->writesize; -- slave->mtd.oobsize = master->oobsize; -- slave->mtd.oobavail = master->oobavail; -- slave->mtd.subpage_sft = master->subpage_sft; -- -- slave->mtd.name = parts[i].name; -- slave->mtd.bank_size = master->bank_size; -- slave->mtd.owner = master->owner; -- -- slave->mtd.read = part_read; -- slave->mtd.write = part_write; -- -- if(master->point && master->unpoint){ -- slave->mtd.point = part_point; -- slave->mtd.unpoint = part_unpoint; -- } -- -- if (master->read_oob) -- slave->mtd.read_oob = part_read_oob; -- if (master->write_oob) -- slave->mtd.write_oob = part_write_oob; -- if(master->read_user_prot_reg) -- slave->mtd.read_user_prot_reg = part_read_user_prot_reg; -- if(master->read_fact_prot_reg) -- slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; -- if(master->write_user_prot_reg) -- slave->mtd.write_user_prot_reg = part_write_user_prot_reg; -- if(master->lock_user_prot_reg) -- slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; -- if(master->get_user_prot_info) -- slave->mtd.get_user_prot_info = part_get_user_prot_info; -- if(master->get_fact_prot_info) -- slave->mtd.get_fact_prot_info = part_get_fact_prot_info; -- if (master->sync) -- slave->mtd.sync = part_sync; -- if (!i && master->suspend && master->resume) { -- slave->mtd.suspend = part_suspend; -- slave->mtd.resume = part_resume; -- } -- if (master->writev) -- slave->mtd.writev = part_writev; -- if (master->lock) -- slave->mtd.lock = part_lock; -- if (master->unlock) -- slave->mtd.unlock = part_unlock; -- if (master->block_isbad) -- slave->mtd.block_isbad = part_block_isbad; -- if (master->block_markbad) -- slave->mtd.block_markbad = part_block_markbad; -- slave->mtd.erase = part_erase; -- slave->master = master; -- slave->offset = parts[i].offset; -- slave->index = i; -- -- if (slave->offset == MTDPART_OFS_APPEND) -- slave->offset = cur_offset; -- if (slave->offset == MTDPART_OFS_NXTBLK) { -- slave->offset = cur_offset; -- if ((cur_offset % master->erasesize) != 0) { -- /* Round up to next erasesize */ -- slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; -- printk(KERN_NOTICE "Moving partition %d: " -- "0x%08x -> 0x%08x\n", i, -- cur_offset, slave->offset); -- } -- } -- if (slave->mtd.size == MTDPART_SIZ_FULL) -- slave->mtd.size = master->size - slave->offset; -- cur_offset = slave->offset + slave->mtd.size; -- -- printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, -- slave->offset + slave->mtd.size, slave->mtd.name); -- -- /* let's do some sanity checks */ -- if (slave->offset >= master->size) { -- /* let's register it anyway to preserve ordering */ -- slave->offset = 0; -- slave->mtd.size = 0; -- printk ("mtd: partition \"%s\" is out of reach -- disabled\n", -- parts[i].name); -- } -- if (slave->offset + slave->mtd.size > master->size) { -- slave->mtd.size = master->size - slave->offset; -- printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", -- parts[i].name, master->name, slave->mtd.size); -- } -- if (master->numeraseregions>1) { -- /* Deal with variable erase size stuff */ -- int i; -- struct mtd_erase_region_info *regions = master->eraseregions; -- -- /* Find the first erase regions which is part of this partition. */ -- for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) -- ; -- -- for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { -- if (slave->mtd.erasesize < regions[i].erasesize) { -- slave->mtd.erasesize = regions[i].erasesize; -- } -- } -- } else { -- /* Single erase size */ -- slave->mtd.erasesize = master->erasesize; -- } -- -- if ((slave->mtd.flags & MTD_WRITEABLE) && -- (slave->offset % slave->mtd.erasesize)) { -- /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ -- slave->mtd.flags &= ~MTD_WRITEABLE; -- printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", -- parts[i].name); -- } -- if ((slave->mtd.flags & MTD_WRITEABLE) && -- (slave->mtd.size % slave->mtd.erasesize)) { -- slave->mtd.flags &= ~MTD_WRITEABLE; -- printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", -- parts[i].name); -- } -- -- slave->mtd.ecclayout = master->ecclayout; -- if (master->block_isbad) { -- uint32_t offs = 0; -- -- while(offs < slave->mtd.size) { -- if (master->block_isbad(master, -- offs + slave->offset)) -- slave->mtd.ecc_stats.badblocks++; -- offs += slave->mtd.erasesize; -+ for (i = 0, j = 0; i < nbparts; i++) { -+ part = (struct mtd_partition *) &parts[i]; -+ ret = add_one_partition(master, part, j, &slave); -+ if (ret) -+ return ret; -+ j++; -+ -+ if (strcmp(part->name, "rootfs") == 0 && slave->registered) { -+#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); - } -- } -- -- if(parts[i].mtdp) -- { /* store the object pointer (caller may or may not register it */ -- *parts[i].mtdp = &slave->mtd; -- slave->registered = 0; -- } -- else -- { -- /* register our partition */ -- add_mtd_device(&slave->mtd); -- slave->registered = 1; -+#endif -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+ ret = split_rootfs_data(master, part, j); -+ if (ret == 0) -+ j++; -+#endif - } - } - |