52d8e24d0f37a1480c6ee8af47c7e4ba071f432b
[openwrt/staging/ldir.git] / target / linux / generic / hack-5.10 / 410-block-fit-partition-parser.patch
1 From: Daniel Golle <daniel@makrotopia.org>
2 Subject: [PATCH] kernel: fix FIT partition parser compatibility issues
3
4 The uImage.FIT partition parser used to squeeze in FIT partitions in
5 the range where partition editor tools (fdisk and such) expect the
6 regular partition. This is confusing people and tools when adding
7 additional partitions on top of the partition used for OpenWrt's
8 uImage.FIT.
9 Instead of squeezing in the additional partitions, rather start with
10 all uImage.FIT partitions at offset 64.
11
12 Submitted-by: Daniel Golle <daniel@makrotopia.org>
13 ---
14 block/blk.h | 2 ++
15 block/partitions/Kconfig | 7 +++
16 block/partitions/Makefile | 1 +
17 block/partitions/check.h | 3 ++
18 block/partitions/core.c | 15 +++++++
19 drivers/mtd/ubi/block.c | 7 +++
20 block/partitions/efi.c | 8 +++++++
21 block/partitions/efi.h | 3 ++
22 drivers/mtd/mtdblock.c | 4 +++
23 drivers/mtd/mtd_blkdevs.c | 14 +------
24 block/partitions/msdos.c | 10 ++++++
25 include/linux/msdos_partition.h | 1 +
26 12 files changed, 52 insertions(+), 13 deletions(-)
27
28 --- a/block/blk.h
29 +++ b/block/blk.h
30 @@ -361,6 +361,8 @@ char *disk_name(struct gendisk *hd, int
31 #define ADDPART_FLAG_NONE 0
32 #define ADDPART_FLAG_RAID 1
33 #define ADDPART_FLAG_WHOLEDISK 2
34 +#define ADDPART_FLAG_READONLY 4
35 +#define ADDPART_FLAG_ROOTDEV 8
36 void delete_partition(struct hd_struct *part);
37 int bdev_add_partition(struct block_device *bdev, int partno,
38 sector_t start, sector_t length);
39 --- a/block/partitions/Kconfig
40 +++ b/block/partitions/Kconfig
41 @@ -101,6 +101,13 @@ config ATARI_PARTITION
42 Say Y here if you would like to use hard disks under Linux which
43 were partitioned under the Atari OS.
44
45 +config FIT_PARTITION
46 + bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
47 + default n
48 + help
49 + Say Y here if your system needs to mount the filesystem part of
50 + a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
51 +
52 config IBM_PARTITION
53 bool "IBM disk label and partition support"
54 depends on PARTITION_ADVANCED && S390
55 --- a/block/partitions/Makefile
56 +++ b/block/partitions/Makefile
57 @@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
58 obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
59 obj-$(CONFIG_ATARI_PARTITION) += atari.o
60 obj-$(CONFIG_AIX_PARTITION) += aix.o
61 +obj-$(CONFIG_FIT_PARTITION) += fit.o
62 obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
63 obj-$(CONFIG_MAC_PARTITION) += mac.o
64 obj-$(CONFIG_LDM_PARTITION) += ldm.o
65 --- a/block/partitions/check.h
66 +++ b/block/partitions/check.h
67 @@ -58,6 +58,7 @@ int amiga_partition(struct parsed_partit
68 int atari_partition(struct parsed_partitions *state);
69 int cmdline_partition(struct parsed_partitions *state);
70 int efi_partition(struct parsed_partitions *state);
71 +int fit_partition(struct parsed_partitions *state);
72 int ibm_partition(struct parsed_partitions *);
73 int karma_partition(struct parsed_partitions *state);
74 int ldm_partition(struct parsed_partitions *state);
75 @@ -68,3 +69,5 @@ int sgi_partition(struct parsed_partitio
76 int sun_partition(struct parsed_partitions *state);
77 int sysv68_partition(struct parsed_partitions *state);
78 int ultrix_partition(struct parsed_partitions *state);
79 +
80 +int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
81 --- a/block/partitions/core.c
82 +++ b/block/partitions/core.c
83 @@ -10,6 +10,10 @@
84 #include <linux/vmalloc.h>
85 #include <linux/blktrace_api.h>
86 #include <linux/raid/detect.h>
87 +#ifdef CONFIG_FIT_PARTITION
88 +#include <linux/root_dev.h>
89 +#endif
90 +
91 #include "check.h"
92
93 static int (*check_part[])(struct parsed_partitions *) = {
94 @@ -46,6 +50,9 @@ static int (*check_part[])(struct parsed
95 #ifdef CONFIG_EFI_PARTITION
96 efi_partition, /* this must come before msdos */
97 #endif
98 +#ifdef CONFIG_FIT_PARTITION
99 + fit_partition,
100 +#endif
101 #ifdef CONFIG_SGI_PARTITION
102 sgi_partition,
103 #endif
104 @@ -701,6 +708,14 @@ static bool blk_add_partition(struct gen
105 (state->parts[p].flags & ADDPART_FLAG_RAID))
106 md_autodetect_dev(part_to_dev(part)->devt);
107
108 +#ifdef CONFIG_FIT_PARTITION
109 + if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
110 + ROOT_DEV = part_to_dev(part)->devt;
111 +
112 + if (state->parts[p].flags & ADDPART_FLAG_READONLY)
113 + part->policy = true;
114 +#endif
115 +
116 return true;
117 }
118
119 --- a/drivers/mtd/ubi/block.c
120 +++ b/drivers/mtd/ubi/block.c
121 @@ -396,7 +396,11 @@ int ubiblock_create(struct ubi_volume_in
122 dev->leb_size = vi->usable_leb_size;
123
124 /* Initialize the gendisk of this ubiblock device */
125 +#ifdef CONFIG_FIT_PARTITION
126 + gd = alloc_disk(0);
127 +#else
128 gd = alloc_disk(1);
129 +#endif
130 if (!gd) {
131 pr_err("UBI: block: alloc_disk failed\n");
132 ret = -ENODEV;
133 @@ -413,6 +417,9 @@ int ubiblock_create(struct ubi_volume_in
134 goto out_put_disk;
135 }
136 gd->private_data = dev;
137 +#ifdef CONFIG_FIT_PARTITION
138 + gd->flags |= GENHD_FL_EXT_DEVT;
139 +#endif
140 sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
141 set_capacity(gd, disk_capacity);
142 dev->gd = gd;
143 --- a/block/partitions/efi.c
144 +++ b/block/partitions/efi.c
145 @@ -706,6 +706,9 @@ int efi_partition(struct parsed_partitio
146 gpt_entry *ptes = NULL;
147 u32 i;
148 unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
149 +#ifdef CONFIG_FIT_PARTITION
150 + u32 extra_slot = 64;
151 +#endif
152
153 if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
154 kfree(gpt);
155 @@ -739,6 +742,11 @@ int efi_partition(struct parsed_partitio
156 ARRAY_SIZE(ptes[i].partition_name));
157 utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
158 state->parts[i + 1].has_info = true;
159 +#ifdef CONFIG_FIT_PARTITION
160 + /* If this is a U-Boot FIT volume it may have subpartitions */
161 + if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
162 + (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
163 +#endif
164 }
165 kfree(ptes);
166 kfree(gpt);
167 --- a/block/partitions/efi.h
168 +++ b/block/partitions/efi.h
169 @@ -52,6 +52,9 @@
170 #define PARTITION_LINUX_LVM_GUID \
171 EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
172 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
173 +#define PARTITION_LINUX_FIT_GUID \
174 + EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
175 + 0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
176
177 typedef struct _gpt_header {
178 __le64 signature;
179 --- a/drivers/mtd/mtdblock.c
180 +++ b/drivers/mtd/mtdblock.c
181 @@ -338,7 +338,11 @@ static void mtdblock_remove_dev(struct m
182 static struct mtd_blktrans_ops mtdblock_tr = {
183 .name = "mtdblock",
184 .major = MTD_BLOCK_MAJOR,
185 +#ifdef CONFIG_FIT_PARTITION
186 + .part_bits = 2,
187 +#else
188 .part_bits = 0,
189 +#endif
190 .blksize = 512,
191 .open = mtdblock_open,
192 .flush = mtdblock_flush,
193 --- a/drivers/mtd/mtd_blkdevs.c
194 +++ b/drivers/mtd/mtd_blkdevs.c
195 @@ -407,18 +407,8 @@ int add_mtd_blktrans_dev(struct mtd_blkt
196 gd->first_minor = (new->devnum) << tr->part_bits;
197 gd->fops = &mtd_block_ops;
198
199 - if (tr->part_bits)
200 - if (new->devnum < 26)
201 - snprintf(gd->disk_name, sizeof(gd->disk_name),
202 - "%s%c", tr->name, 'a' + new->devnum);
203 - else
204 - snprintf(gd->disk_name, sizeof(gd->disk_name),
205 - "%s%c%c", tr->name,
206 - 'a' - 1 + new->devnum / 26,
207 - 'a' + new->devnum % 26);
208 - else
209 - snprintf(gd->disk_name, sizeof(gd->disk_name),
210 - "%s%d", tr->name, new->devnum);
211 + snprintf(gd->disk_name, sizeof(gd->disk_name),
212 + "%s%d", tr->name, new->devnum);
213
214 set_capacity(gd, ((u64)new->size * tr->blksize) >> 9);
215
216 --- a/block/partitions/msdos.c
217 +++ b/block/partitions/msdos.c
218 @@ -563,6 +563,15 @@ static void parse_minix(struct parsed_pa
219 #endif /* CONFIG_MINIX_SUBPARTITION */
220 }
221
222 +static void parse_fit_mbr(struct parsed_partitions *state,
223 + sector_t offset, sector_t size, int origin)
224 +{
225 +#ifdef CONFIG_FIT_PARTITION
226 + u32 extra_slot = 64;
227 + (void) parse_fit_partitions(state, offset, size, &extra_slot, 1);
228 +#endif /* CONFIG_FIT_PARTITION */
229 +}
230 +
231 static struct {
232 unsigned char id;
233 void (*parse)(struct parsed_partitions *, sector_t, sector_t, int);
234 @@ -574,6 +583,7 @@ static struct {
235 {UNIXWARE_PARTITION, parse_unixware},
236 {SOLARIS_X86_PARTITION, parse_solaris_x86},
237 {NEW_SOLARIS_X86_PARTITION, parse_solaris_x86},
238 + {FIT_PARTITION, parse_fit_mbr},
239 {0, NULL},
240 };
241
242 --- a/include/linux/msdos_partition.h
243 +++ b/include/linux/msdos_partition.h
244 @@ -31,6 +31,7 @@ enum msdos_sys_ind {
245 LINUX_LVM_PARTITION = 0x8e,
246 LINUX_RAID_PARTITION = 0xfd, /* autodetect RAID partition */
247
248 + FIT_PARTITION = 0x2e, /* U-Boot uImage.FIT */
249 SOLARIS_X86_PARTITION = 0x82, /* also Linux swap partitions */
250 NEW_SOLARIS_X86_PARTITION = 0xbf,
251