From df82f6f305af908419791945e1eec6d6ffd86312 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Fri, 19 Feb 2010 14:54:25 +0100 Subject: [PATCH] libblkid: improve Sun VTOC It seems that for example GNU Parted is able to generate Sun VTOC with empty sanity, version and nparts fields. But there is still useful info about partition flags in such VTOC. This change makes libblkid Sun PT parser compatible with Sun PT parser in Linux kernel. Signed-off-by: Karel Zak --- shlibs/blkid/src/partitions/sun.c | 48 +++++++++++++++++++------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/shlibs/blkid/src/partitions/sun.c b/shlibs/blkid/src/partitions/sun.c index 10c555ab..d70200c8 100644 --- a/shlibs/blkid/src/partitions/sun.c +++ b/shlibs/blkid/src/partitions/sun.c @@ -32,7 +32,7 @@ struct sun_disklabel { uint16_t nparts; /* num of partitions */ struct sun_info { /* partition information */ - uint16_t id; + uint16_t id; /* tag */ uint16_t flags; } __attribute__ ((packed)) infos[8]; @@ -84,12 +84,11 @@ static int probe_sun_pt(blkid_probe pr, const struct blkid_idmag *mag) { struct sun_disklabel *l; struct sun_partition *p; - struct sun_info *infos = NULL; blkid_parttable tab = NULL; blkid_partlist ls; uint16_t nparts; blkid_loff_t spc; - int i; + int i, use_vtoc; l = (struct sun_disklabel *) blkid_probe_get_sector(pr, 0); if (!l) @@ -113,30 +112,41 @@ static int probe_sun_pt(blkid_probe pr, const struct blkid_idmag *mag) if (!tab) goto err; - /* default number of partitions */ - nparts = SUN_MAXPARTITIONS; - /* sectors per cylinder (partition offset is in cylinders...) */ spc = be16_to_cpu(l->ntrks) * be16_to_cpu(l->nsect); - if ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) && - (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) && - (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS)) { + DBG(DEBUG_LOWPROBE, + printf("Sun VTOC sanity=%u version=%u nparts=%u\n", + be32_to_cpu(l->vtoc.sanity), + be32_to_cpu(l->vtoc.version), + be16_to_cpu(l->vtoc.nparts))); - nparts = be16_to_cpu(l->vtoc.nparts); - infos = l->vtoc.infos; /* for partition type */ - } + /* Check to see if we can use the VTOC table */ + use_vtoc = ((be32_to_cpu(l->vtoc.sanity) == SUN_VTOC_SANITY) && + (be32_to_cpu(l->vtoc.version) == SUN_VTOC_VERSION) && + (be16_to_cpu(l->vtoc.nparts) <= SUN_MAXPARTITIONS)); + + /* Use 8 partition entries if not specified in validated VTOC */ + nparts = use_vtoc ? be16_to_cpu(l->vtoc.nparts) : SUN_MAXPARTITIONS; + + /* + * So that old Linux-Sun partitions continue to work, + * alow the VTOC to be used under the additional condition ... + */ + use_vtoc = use_vtoc || !(l->vtoc.sanity || l->vtoc.version || l->vtoc.nparts); for (i = 0, p = l->partitions; i < nparts; i++, p++) { - blkid_loff_t start; - blkid_loff_t size; - uint16_t type = infos ? be16_to_cpu(infos[i].id) : 0; - uint16_t flags = infos ? be16_to_cpu(infos[i].flags) : 0; + blkid_loff_t start, size; + uint16_t type = 0, flags = 0; blkid_partition par; start = be32_to_cpu(p->start_cylinder) * spc; size = be32_to_cpu(p->num_sectors); + if (use_vtoc) { + type = be16_to_cpu(l->vtoc.infos[i].id); + flags = be16_to_cpu(l->vtoc.infos[i].flags); + } if (type == SUN_TAG_WHOLEDISK || !size) continue; @@ -145,8 +155,10 @@ static int probe_sun_pt(blkid_probe pr, const struct blkid_idmag *mag) if (!par) goto err; - blkid_partition_set_type(par, type); - blkid_partition_set_flags(par, flags); + if (type) + blkid_partition_set_type(par, type); + if (flags) + blkid_partition_set_flags(par, flags); } return 0; -- 2.39.5