aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-04-18 17:04:16 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-04-18 17:04:16 +0000
commitbe37a62e6d6e328c936beadd12a8059764fa6e12 (patch)
treecde758e42a625ac3fbcd4004200df28f03d2c8e2 /target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch
parent05d8459bb9f96b9e0a19b8735d3bee05484eca22 (diff)
downloadupstream-be37a62e6d6e328c936beadd12a8059764fa6e12.tar.gz
upstream-be37a62e6d6e328c936beadd12a8059764fa6e12.tar.bz2
upstream-be37a62e6d6e328c936beadd12a8059764fa6e12.zip
add generic 2.6.29 patches and config (squashfs still untested, user space mkfs still missing)
SVN-Revision: 15251
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch')
-rw-r--r--target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch616
1 files changed, 312 insertions, 304 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch b/target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch
index bae9621933..172eb0f19b 100644
--- a/target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch
+++ b/target/linux/generic-2.6/patches-2.6.29/065-rootfs_split.patch
@@ -1,7 +1,268 @@
-diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3/drivers/mtd/devices/block2mtd.c
---- linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c 2009-03-09 05:13:51.000000000 +0100
-+++ linux-2.6.29-rc3/drivers/mtd/devices/block2mtd.c 2009-03-09 18:18:49.000000000 +0100
-@@ -28,6 +28,8 @@
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -53,6 +53,16 @@ config MTD_TESTS
+ should normally be compiled as kernel modules. The modules perform
+ various checks and verifications when loaded.
+
++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
+@@ -18,6 +18,8 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/mtd/compatmac.h>
++#include <linux/root_dev.h>
++#include <linux/magic.h>
+
+ /* Our partition linked list */
+ static LIST_HEAD(mtd_partitions);
+@@ -37,7 +39,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
+@@ -489,6 +491,156 @@ out_register:
+ return slave;
+ }
+
++#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)
++{
++ char buf[512];
++ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
++ int len, ret;
++
++ ret = master->read(master, offset, sizeof(*sb), &len, buf);
++ if (ret || (len != sizeof(*sb))) {
++ printk(KERN_ALERT "split_squashfs: error occured while reading "
++ "from \"%s\"\n", master->name);
++ return -EINVAL;
++ }
++
++ if (*((u32 *) buf) != SQUASHFS_MAGIC) {
++ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n",
++ master->name);
++ *split_offset = 0;
++ return 0;
++ }
++
++ if (sb->bytes_used <= 0) {
++ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
++ master->name);
++ *split_offset = 0;
++ return 0;
++ }
++
++ len = (u32) 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,
++ int index)
++{
++ struct mtd_partition *dpart;
++ struct mtd_part *slave = NULL;
++ int split_offset = 0;
++ int ret;
++
++ ret = split_squashfs(master, part->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));
++ dpart->name = (unsigned char *)&dpart[1];
++ strcpy(dpart->name, ROOTFS_SPLIT_NAME);
++
++ dpart->size -= split_offset - dpart->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 = add_one_partition(master, dpart, index, split_offset);
++ if (!slave) {
++ kfree(dpart);
++ return -ENOMEM;
++ }
++ 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;
++
++ /* find the index of the last partition */
++ if (!list_empty(&mtd_partitions))
++ index = list_first_entry(&mtd_partitions, struct mtd_part, list)->index + 1;
++
++ return split_rootfs_data(part->master, &part->mtd, &tpart, index);
++ } 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
+@@ -502,14 +654,29 @@ int add_mtd_partitions(struct mtd_info *
+ {
+ struct mtd_part *slave;
+ uint64_t cur_offset = 0;
+- int i;
++ int i, j, ret;
+
+ printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
+
+- for (i = 0; i < nbparts; i++) {
+- slave = add_one_partition(master, parts + i, i, cur_offset);
++ for (i = 0, j = 0; i < nbparts; i++) {
++ slave = add_one_partition(master, parts + i, j++, cur_offset);
+ if (!slave)
+ return -ENOMEM;
++
++ if (!strcmp(parts[i].name, "rootfs") && 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);
++ }
++#endif
++#ifdef CONFIG_MTD_ROOTFS_SPLIT
++ ret = split_rootfs_data(master, &slave->mtd, &parts[i], j);
++ if (ret == 0)
++ j++;
++#endif
++ }
+ cur_offset = slave->offset + slave->mtd.size;
+ }
+
+@@ -517,6 +684,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/devices/block2mtd.c
++++ b/drivers/mtd/devices/block2mtd.c
+@@ -29,6 +29,8 @@ struct block2mtd_dev {
struct block_device *blkdev;
struct mtd_info mtd;
struct mutex write_mutex;
@@ -10,7 +271,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
};
-@@ -80,6 +82,12 @@
+@@ -81,6 +83,12 @@ static int block2mtd_erase(struct mtd_in
size_t len = instr->len;
int err;
@@ -23,7 +284,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
instr->state = MTD_ERASING;
mutex_lock(&dev->write_mutex);
err = _block2mtd_erase(dev, from, len);
-@@ -92,6 +100,10 @@
+@@ -93,6 +101,10 @@ static int block2mtd_erase(struct mtd_in
instr->state = MTD_ERASE_DONE;
mtd_erase_callback(instr);
@@ -34,7 +295,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
return err;
}
-@@ -103,10 +115,14 @@
+@@ -104,10 +116,14 @@ static int block2mtd_read(struct mtd_inf
struct page *page;
int index = from >> PAGE_SHIFT;
int offset = from & (PAGE_SIZE-1);
@@ -52,7 +313,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
if (from + len > mtd->size)
len = mtd->size - from;
-@@ -121,10 +137,14 @@
+@@ -122,10 +138,14 @@ static int block2mtd_read(struct mtd_inf
len = len - cpylen;
page = page_read(dev->blkdev->bd_inode->i_mapping, index);
@@ -71,7 +332,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
memcpy(buf, page_address(page) + offset, cpylen);
page_cache_release(page);
-@@ -135,7 +155,10 @@
+@@ -136,7 +156,10 @@ static int block2mtd_read(struct mtd_inf
offset = 0;
index++;
}
@@ -83,7 +344,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
}
-@@ -187,12 +210,22 @@
+@@ -188,12 +211,22 @@ static int block2mtd_write(struct mtd_in
size_t *retlen, const u_char *buf)
{
struct block2mtd_dev *dev = mtd->priv;
@@ -110,7 +371,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
if (to + len > mtd->size)
len = mtd->size - to;
-@@ -201,6 +234,9 @@
+@@ -202,6 +235,9 @@ static int block2mtd_write(struct mtd_in
mutex_unlock(&dev->write_mutex);
if (err > 0)
err = 0;
@@ -120,7 +381,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
return err;
}
-@@ -209,30 +245,15 @@
+@@ -210,52 +246,29 @@ static int block2mtd_write(struct mtd_in
static void block2mtd_sync(struct mtd_info *mtd)
{
struct block2mtd_dev *dev = mtd->priv;
@@ -128,37 +389,44 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
- return;
-}
-
-+ read_lock(&dev->bdev_mutex);
-+ if (dev->blkdev)
-+ sync_blockdev(dev->blkdev);
-+ read_unlock(&dev->bdev_mutex);
-
+-
-static void block2mtd_free_device(struct block2mtd_dev *dev)
-{
- if (!dev)
- return;
-
- kfree(dev->mtd.name);
--
+
- if (dev->blkdev) {
- invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
- 0, -1);
- close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
- }
--
++ read_lock(&dev->bdev_mutex);
++ if (dev->blkdev)
++ sync_blockdev(dev->blkdev);
++ read_unlock(&dev->bdev_mutex);
+
- kfree(dev);
+ return;
}
--
+
-/* FIXME: ensure that mtd->size % erase_size == 0 */
--static struct block2mtd_dev *add_device(char *devname, int erase_size)
+-static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
+static int _open_bdev(struct block2mtd_dev *dev)
{
struct block_device *bdev;
- struct block2mtd_dev *dev;
-@@ -246,14 +267,14 @@
- return NULL;
+- struct block2mtd_dev *dev;
+- struct mtd_partition *part;
+- char *name;
+-
+- if (!devname)
+- return NULL;
+-
+- dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
+- if (!dev)
+- return NULL;
/* Get a handle on the device */
- bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL);
@@ -174,7 +442,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
if (devt) {
bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
}
-@@ -261,17 +282,97 @@
+@@ -263,17 +276,97 @@ static struct block2mtd_dev *add_device(
#endif
if (IS_ERR(bdev)) {
@@ -273,39 +541,18 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/devices/block2mtd.c linux-2.6.29-rc3
mutex_init(&dev->write_mutex);
+ rwlock_init(&dev->bdev_mutex);
- /* Setup the MTD structure */
- /* make the name contain the block device in */
-@@ -295,6 +396,7 @@
+ if (!mtdname)
+ mtdname = devname;
+@@ -297,6 +390,7 @@ static struct block2mtd_dev *add_device(
dev->mtd.read = block2mtd_read;
dev->mtd.priv = dev;
dev->mtd.owner = THIS_MODULE;
+ dev->mtd.refresh_device = block2mtd_refresh;
- if (add_mtd_device(&dev->mtd)) {
- /* Device didnt get added, so free the entry */
-diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/Kconfig linux-2.6.29-rc3/drivers/mtd/Kconfig
---- linux-2.6.29-rc3.orig/drivers/mtd/Kconfig 2009-03-09 05:13:51.000000000 +0100
-+++ linux-2.6.29-rc3/drivers/mtd/Kconfig 2009-03-09 18:10:48.000000000 +0100
-@@ -53,6 +53,16 @@
- should normally be compiled as kernel modules. The modules perform
- various checks and verifications when loaded.
-
-+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
-diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/mtdchar.c linux-2.6.29-rc3/drivers/mtd/mtdchar.c
---- linux-2.6.29-rc3.orig/drivers/mtd/mtdchar.c 2009-03-09 05:13:51.000000000 +0100
-+++ linux-2.6.29-rc3/drivers/mtd/mtdchar.c 2009-03-09 18:10:48.000000000 +0100
+ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
+ part->name = dev->mtd.name;
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
@@ -16,6 +16,7 @@
#include <linux/mtd/mtd.h>
@@ -314,7 +561,7 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/mtdchar.c linux-2.6.29-rc3/drivers/m
#include <asm/uaccess.h>
-@@ -773,6 +774,13 @@
+@@ -773,6 +774,13 @@ static int mtd_ioctl(struct inode *inode
file->f_pos = 0;
break;
}
@@ -328,246 +575,9 @@ diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/mtdchar.c linux-2.6.29-rc3/drivers/m
default:
ret = -ENOTTY;
-diff -ruN linux-2.6.29-rc3.orig/drivers/mtd/mtdpart.c linux-2.6.29-rc3/drivers/mtd/mtdpart.c
---- linux-2.6.29-rc3.orig/drivers/mtd/mtdpart.c 2009-03-09 05:13:51.000000000 +0100
-+++ linux-2.6.29-rc3/drivers/mtd/mtdpart.c 2009-03-09 18:29:58.000000000 +0100
-@@ -18,6 +18,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);
-@@ -37,7 +39,7 @@
- * 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
-@@ -489,6 +491,148 @@
- return slave;
- }
-
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+#define ROOTFS_SPLIT_NAME "rootfs_data"
-+#define ROOTFS_REMOVED_NAME "<removed>"
-+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset)
-+{
-+ char buf[512];
-+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
-+ int len, ret;
-+
-+ ret = master->read(master, offset, sizeof(*sb), &len, buf);
-+ if (ret || (len != sizeof(*sb))) {
-+ printk(KERN_ALERT "split_squashfs: error occured while reading "
-+ "from \"%s\"\n", master->name);
-+ return -EINVAL;
-+ }
-+
-+ if (*((u32 *) buf) != SQUASHFS_MAGIC) {
-+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n",
-+ master->name);
-+ *split_offset = 0;
-+ return 0;
-+ }
-+
-+ if (sb->bytes_used <= 0) {
-+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
-+ master->name);
-+ *split_offset = 0;
-+ return 0;
-+ }
-+
-+ len = (u32) 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,
-+ int index)
-+{
-+ struct mtd_partition *dpart;
-+ struct mtd_part *slave = NULL;
-+ int split_offset = 0;
-+ int ret;
-+
-+ ret = split_squashfs(master, part->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));
-+ dpart->name = (unsigned char *)&dpart[1];
-+ strcpy(dpart->name, ROOTFS_SPLIT_NAME);
-+
-+ dpart->size -= split_offset - dpart->offset;
-+ dpart->offset = split_offset;
-+
-+ 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);
-+
-+ slave = add_one_partition(master, dpart, index, split_offset);
-+ if (!slave) {
-+ kfree(dpart);
-+ return -ENOMEM;
-+ }
-+ 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;
-+
-+ /* find the index of the last partition */
-+ if (!list_empty(&mtd_partitions))
-+ index = list_first_entry(&mtd_partitions, struct mtd_part, list)->index + 1;
-+
-+ return split_rootfs_data(part->master, &part->mtd, &tpart, index);
-+ } 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"),
-+ part->offset, 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
-@@ -502,14 +646,29 @@
- {
- struct mtd_part *slave;
- uint64_t cur_offset = 0;
-- int i;
-+ int i, j, ret;
-
- printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
-
-- for (i = 0; i < nbparts; i++) {
-- slave = add_one_partition(master, parts + i, i, cur_offset);
-+ for (i = 0, j = 0; i < nbparts; i++) {
-+ slave = add_one_partition(master, parts + i, j++, cur_offset);
- if (!slave)
- return -ENOMEM;
-+
-+ if (!strcmp(parts[i].name, "rootfs") && 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);
-+ }
-+#endif
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+ ret = split_rootfs_data(master, &slave->mtd, &parts[i], j);
-+ if (ret == 0)
-+ j++;
-+#endif
-+ }
- cur_offset = slave->offset + slave->mtd.size;
- }
-
-@@ -517,6 +676,32 @@
- }
- 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);
-
-diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/mtd.h linux-2.6.29-rc3/include/linux/mtd/mtd.h
---- linux-2.6.29-rc3.orig/include/linux/mtd/mtd.h 2009-03-09 05:13:58.000000000 +0100
-+++ linux-2.6.29-rc3/include/linux/mtd/mtd.h 2009-03-09 18:10:48.000000000 +0100
-@@ -100,6 +100,7 @@
+--- a/include/linux/mtd/mtd.h
++++ b/include/linux/mtd/mtd.h
+@@ -100,6 +100,7 @@ struct mtd_oob_ops {
uint8_t *oobbuf;
};
@@ -575,7 +585,7 @@ diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/mtd.h linux-2.6.29-rc3/include
struct mtd_info {
u_char type;
uint32_t flags;
-@@ -225,6 +226,9 @@
+@@ -225,6 +226,9 @@ struct mtd_info {
struct module *owner;
int usecount;
@@ -585,9 +595,8 @@ diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/mtd.h linux-2.6.29-rc3/include
/* 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
-diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/partitions.h linux-2.6.29-rc3/include/linux/mtd/partitions.h
---- linux-2.6.29-rc3.orig/include/linux/mtd/partitions.h 2009-03-09 05:13:58.000000000 +0100
-+++ linux-2.6.29-rc3/include/linux/mtd/partitions.h 2009-03-09 18:10:48.000000000 +0100
+--- a/include/linux/mtd/partitions.h
++++ b/include/linux/mtd/partitions.h
@@ -34,6 +34,7 @@
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
*/
@@ -596,7 +605,7 @@ diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/partitions.h linux-2.6.29-rc3/
struct mtd_partition {
char *name; /* identifier string */
uint64_t size; /* partition size */
-@@ -41,6 +42,7 @@
+@@ -41,6 +42,7 @@ struct mtd_partition {
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)*/
struct mtd_info **mtdp; /* pointer to store the MTD object */
@@ -604,7 +613,7 @@ diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/partitions.h linux-2.6.29-rc3/
};
#define MTDPART_OFS_NXTBLK (-2)
-@@ -50,6 +52,7 @@
+@@ -50,6 +52,7 @@ struct mtd_partition {
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
@@ -612,10 +621,9 @@ diff -ruN linux-2.6.29-rc3.orig/include/linux/mtd/partitions.h linux-2.6.29-rc3/
/*
* Functions dealing with the various ways of partitioning the space
-diff -ruN linux-2.6.29-rc3.orig/include/mtd/mtd-abi.h linux-2.6.29-rc3/include/mtd/mtd-abi.h
---- linux-2.6.29-rc3.orig/include/mtd/mtd-abi.h 2009-03-09 05:13:57.000000000 +0100
-+++ linux-2.6.29-rc3/include/mtd/mtd-abi.h 2009-03-09 18:10:48.000000000 +0100
-@@ -93,6 +93,7 @@
+--- a/include/mtd/mtd-abi.h
++++ b/include/mtd/mtd-abi.h
+@@ -93,6 +93,7 @@ struct otp_info {
#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout)
#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats)
#define MTDFILEMODE _IO('M', 19)