From 02460b8aae3f44cb56d7a23bff2a420e2241c4be Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 26 Sep 2012 13:30:44 +0200 Subject: [PATCH] fdisk: add fdisk_set_partition_type() - remove all label specific partition type stuff from fdisk.c to label files - add new fdisk_set_partition_type() to API Signed-off-by: Karel Zak --- fdisks/fdisk.c | 83 +++++++----------------------------------- fdisks/fdisk.h | 5 ++- fdisks/fdiskbsdlabel.c | 18 +++++++++ fdisks/fdiskdoslabel.c | 31 +++++++++++++++- fdisks/fdiskdoslabel.h | 1 - fdisks/fdisksgilabel.c | 53 ++++++++++++++++----------- fdisks/fdisksunlabel.c | 75 +++++++++++++++++++++++--------------- fdisks/utils.c | 17 +++++++++ 8 files changed, 160 insertions(+), 123 deletions(-) diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index 151790262b..814183108c 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -128,7 +128,6 @@ char *line_ptr, /* interactive input */ int nowarn = 0, /* no warnings for fdisk -l/-s */ dos_compatible_flag = 0, /* disabled by default */ - dos_changed = 0, partitions = 4; /* maximum partition + 1 */ unsigned int user_cylinders, user_heads, user_sectors; @@ -846,7 +845,7 @@ static void delete_partition(struct fdisk_context *cxt, int partnum) printf(_("Partition %d is deleted\n"), partnum + 1); } -static void change_sysid(struct fdisk_context *cxt) +static void change_partition_type(struct fdisk_context *cxt) { int i; struct fdisk_parttype *t, *org_t; @@ -859,71 +858,23 @@ static void change_sysid(struct fdisk_context *cxt) if (!t) printf(_("Partition %d does not exist yet!\n"), i + 1); - else while (1) { + else do { t = read_partition_type(cxt); - - if (!t && disklabel != SGI_LABEL && disklabel != SUN_LABEL) { - printf(_("Type 0 means free space to many systems\n" - "(but not to Linux). Having partitions of\n" - "type 0 is probably unwise. You can delete\n" - "a partition using the `d' command.\n")); - /* break; */ - } - if (!t) continue; - if (disklabel != SGI_LABEL && disklabel != SUN_LABEL) { - if (IS_EXTENDED (t->type) != IS_EXTENDED (t->type)) { - printf(_("You cannot change a partition into" - " an extended one or vice versa\n" - "Delete it first.\n")); - break; - } + if (fdisk_set_partition_type(cxt, i, t) == 0) { + ptes[i].changed = 1; + printf (_("Changed type of partition '%s' to '%s'\n"), + org_t ? org_t->name : _("Unknown"), + t ? t->name : _("Unknown")); + } else { + printf (_("Type of partition %d is unchanged: %s\n"), + i + 1, + org_t ? org_t->name : _("Unknown")); } - - /* TODO: add set_partition_type(cxt, npart, type) API */ - if (t->type < 256) { - if (disklabel == SUN_LABEL && i == 2 && t->type != SUN_TAG_BACKUP) - printf(_("Consider leaving partition 3 " - "as Whole disk (5),\n" - "as SunOS/Solaris expects it and " - "even Linux likes it.\n\n")); - if (disklabel == SGI_LABEL && ((i == 10 && t->type != ENTIRE_DISK) - || (i == 8 && t->type != 0))) - printf(_("Consider leaving partition 9 " - "as volume header (0),\nand " - "partition 11 as entire volume (6), " - "as IRIX expects it.\n\n")); - if (t == org_t) - goto nochange; - - if (disklabel == SUN_LABEL) { - ptes[i].changed = sun_change_sysid(cxt, i, t->type); - } else - if (disklabel == SGI_LABEL) { - ptes[i].changed = sgi_change_sysid(cxt, i, t->type); - } else { - ptes[i].part_table->sys_ind = t->type; - ptes[i].changed = 1; - } - - if (ptes[i].changed) - printf (_("Changed type of partition '%s' to '%s'\n"), - org_t ? org_t->name : _("Unknown"), - t ? t->name : _("Unknown")); - else { -nochange: - printf (_("Type of partition %d is unchanged: %s\n"), - i + 1, - org_t ? org_t->name : _("Unknown")); - } - - if (is_dos_partition(t->type) || is_dos_partition(t->type)) - dos_changed = 1; - break; - } - } + break; + } while (1); fdisk_free_parttype(t); fdisk_free_parttype(org_t); @@ -1398,12 +1349,6 @@ reread_partition_table(struct fdisk_context *cxt, int leave) { errno); } - if (dos_changed) - printf( - _("\nWARNING: If you have created or modified any DOS 6.x\n" - "partitions, please see the fdisk manual page for additional\n" - "information.\n")); - if (leave) { if (fsync(cxt->dev_fd) || close(cxt->dev_fd)) { fprintf(stderr, _("\nError closing file\n")); @@ -1780,7 +1725,7 @@ static void command_prompt(struct fdisk_context *cxt) fdisk_create_disklabel(cxt, "sun"); break; case 't': - change_sysid(cxt); + change_partition_type(cxt); break; case 'u': change_units(cxt); diff --git a/fdisks/fdisk.h b/fdisks/fdisk.h index 879f3d640d..5af172fcf2 100644 --- a/fdisks/fdisk.h +++ b/fdisks/fdisk.h @@ -176,7 +176,8 @@ struct fdisk_label { void (*part_delete)(struct fdisk_context *cxt, int partnum); /* get partition type */ struct fdisk_parttype *(*part_get_type)(struct fdisk_context *cxt, int partnum); - + /* set partition type */ + int (*part_set_type)(struct fdisk_context *cxt, int partnum, struct fdisk_parttype *t); }; /* @@ -205,6 +206,8 @@ extern int fdisk_write_disklabel(struct fdisk_context *cxt); extern int fdisk_verify_disklabel(struct fdisk_context *cxt); extern int fdisk_create_disklabel(struct fdisk_context *cxt, const char *name); extern struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int partnum); +extern int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum, + struct fdisk_parttype *t); extern size_t fdisk_get_nparttypes(struct fdisk_context *cxt); extern struct fdisk_parttype *fdisk_get_parttype_from_code(struct fdisk_context *cxt, diff --git a/fdisks/fdiskbsdlabel.c b/fdisks/fdiskbsdlabel.c index 3a23c02f09..b11bcf1cb7 100644 --- a/fdisks/fdiskbsdlabel.c +++ b/fdisks/fdiskbsdlabel.c @@ -558,6 +558,7 @@ xbsd_write_bootstrap (struct fdisk_context *cxt) sync_disks (); } +/* TODO: remove this, use regular change_partition_type() in fdisk.c */ static void xbsd_change_fstype (struct fdisk_context *cxt) { @@ -856,6 +857,22 @@ static struct fdisk_parttype *xbsd_get_parttype(struct fdisk_context *cxt, int n return t; } +static int xbsd_set_parttype(struct fdisk_context *cxt, int partnum, + struct fdisk_parttype *t) +{ + struct xbsd_partition *p; + + if (partnum >= xbsd_dlabel.d_npartitions || !t || t->type > UINT8_MAX) + return -EINVAL; + + p = &xbsd_dlabel.d_partitions[partnum]; + if (t->type == p->p_fstype) + return 0; + + p->p_fstype = t->type; + return 0; +} + const struct fdisk_label bsd_label = { .name = "bsd", @@ -869,4 +886,5 @@ const struct fdisk_label bsd_label = .part_add = xbsd_add_part, .part_delete = xbsd_delete_part, .part_get_type = xbsd_get_parttype, + .part_set_type = xbsd_set_parttype, }; diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index 3b2f9d5bfd..d391126ecc 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -414,7 +414,7 @@ static int dos_probe_label(struct fdisk_context *cxt) * We might also do the opposite and warn in all cases except * for "is probably nondos partition". */ -int is_dos_partition(int t) +static int is_dos_partition(int t) { return (t == 1 || t == 4 || t == 6 || t == 0x0b || t == 0x0c || t == 0x0e || @@ -840,6 +840,34 @@ static struct fdisk_parttype *dos_get_parttype(struct fdisk_context *cxt, int pa return t; } +static int dos_set_parttype(struct fdisk_context *cxt, int partnum, + struct fdisk_parttype *t) +{ + struct partition *p; + + if (partnum >= partitions || !t || t->type > UINT8_MAX) + return -EINVAL; + + p = ptes[partnum].part_table; + if (t->type == p->sys_ind) + return 0; + + if (IS_EXTENDED(p->sys_ind) || IS_EXTENDED(t->type)) { + printf(_("\nYou cannot change a partition into an extended one " + "or vice versa.\nDelete it first.\n\n")); + return -EINVAL; + } + + if (is_dos_partition(t->type) || is_dos_partition(p->sys_ind)) + printf( + _("\nWARNING: If you have created or modified any DOS 6.x" + "partitions, please see the fdisk manual page for additional" + "information.\n\n")); + + p->sys_ind = t->type; + return 0; +} + const struct fdisk_label dos_label = { .name = "dos", @@ -853,4 +881,5 @@ const struct fdisk_label dos_label = .part_add = dos_add_partition, .part_delete = dos_delete_partition, .part_get_type = dos_get_parttype, + .part_set_type = dos_set_parttype, }; diff --git a/fdisks/fdiskdoslabel.h b/fdisks/fdiskdoslabel.h index 0754b17141..3b6d64478d 100644 --- a/fdisks/fdiskdoslabel.h +++ b/fdisks/fdiskdoslabel.h @@ -39,7 +39,6 @@ static inline sector_t get_partition_start(struct pte *pe) extern void dos_print_mbr_id(struct fdisk_context *cxt); extern void dos_set_mbr_id(struct fdisk_context *cxt); -extern int is_dos_partition(int t); extern void dos_init(struct fdisk_context *cxt); extern int mbr_is_valid_magic(unsigned char *b); diff --git a/fdisks/fdisksgilabel.c b/fdisks/fdisksgilabel.c index a181a77091..6cef145e4d 100644 --- a/fdisks/fdisksgilabel.c +++ b/fdisks/fdisksgilabel.c @@ -575,27 +575,6 @@ sgi_gaps(struct fdisk_context *cxt) { return sgi_verify_disklabel(cxt); } -int -sgi_change_sysid(struct fdisk_context *cxt, int i, int sys) -{ - if (sgi_get_num_sectors(cxt, i) == 0) /* caught already before, ... */ { - printf(_("Sorry, only for non-empty partitions you can change the tag.\n")); - return 0; - } - if (((sys != ENTIRE_DISK) && (sys != SGI_VOLHDR)) - && (sgi_get_start_sector(cxt, i)<1)) { - read_chars( - _("It is highly recommended that the partition at offset 0\n" - "is of type \"SGI volhdr\", the IRIX system will rely on it to\n" - "retrieve from its directory standalone tools like sash and fx.\n" - "Only the \"SGI volume\" entire disk section may violate this.\n" - "Type YES if you are sure about tagging this partition differently.\n")); - if (strcmp (line_ptr, _("YES\n"))) - return 0; - } - sgilabel->partitions[i].id = SSWAP32(sys); - return 1; -} /* returns partition index of first entry marked as entire disk */ static int @@ -910,6 +889,37 @@ static struct fdisk_parttype *sgi_get_parttype(struct fdisk_context *cxt, int n) return t; } +static int sgi_set_parttype(struct fdisk_context *cxt, int i, + struct fdisk_parttype *t) +{ + if (i >= partitions || !t || t->type > UINT32_MAX) + return -EINVAL; + + if (sgi_get_num_sectors(cxt, i) == 0) /* caught already before, ... */ { + printf(_("Sorry, only for non-empty partitions you can change the tag.\n")); + return -EINVAL; + } + + if ((i == 10 && t->type != ENTIRE_DISK) || (i == 8 && t->type != 0)) + printf(_("Consider leaving partition 9 as volume header (0), " + "and partition 11 as entire volume (6), as IRIX " + "expects it.\n\n")); + + if (((t->type != ENTIRE_DISK) && (t->type != SGI_VOLHDR)) + && (sgi_get_start_sector(cxt, i) < 1)) { + read_chars( + _("It is highly recommended that the partition at offset 0\n" + "is of type \"SGI volhdr\", the IRIX system will rely on it to\n" + "retrieve from its directory standalone tools like sash and fx.\n" + "Only the \"SGI volume\" entire disk section may violate this.\n" + "Type YES if you are sure about tagging this partition differently.\n")); + if (strcmp (line_ptr, _("YES\n"))) + return 1; + } + sgilabel->partitions[i].id = SSWAP32(t->type); + return 0; +} + const struct fdisk_label sgi_label = { .name = "sgi", @@ -923,4 +933,5 @@ const struct fdisk_label sgi_label = .part_add = sgi_add_partition, .part_delete = sgi_delete_partition, .part_get_type = sgi_get_parttype, + .part_set_type = sgi_set_parttype, }; diff --git a/fdisks/fdisksunlabel.c b/fdisks/fdisksunlabel.c index 521c43a174..43d3cdfd94 100644 --- a/fdisks/fdisksunlabel.c +++ b/fdisks/fdisksunlabel.c @@ -504,36 +504,6 @@ static void sun_delete_partition(struct fdisk_context *cxt, int partnum) part->num_sectors = 0; } -int sun_change_sysid(struct fdisk_context *cxt, int i, uint16_t sys) -{ - struct sun_partition *part = &sunlabel->partitions[i]; - struct sun_tag_flag *tag = &sunlabel->part_tags[i]; - - if (sys == SUN_TAG_LINUX_SWAP && !part->start_cylinder) { - read_chars( - _("It is highly recommended that the partition at offset 0\n" - "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n" - "there may destroy your partition table and bootblock.\n" - "Type YES if you're very sure you would like that partition\n" - "tagged with 82 (Linux swap): ")); - if (strcmp (line_ptr, _("YES\n"))) - return 0; - } - switch (sys) { - case SUN_TAG_SWAP: - case SUN_TAG_LINUX_SWAP: - /* swaps are not mountable by default */ - tag->flag |= SSWAP16(SUN_FLAG_UNMNT); - break; - default: - /* assume other types are mountable; - user can change it anyway */ - tag->flag &= ~SSWAP16(SUN_FLAG_UNMNT); - break; - } - tag->tag = SSWAP16(sys); - return 1; -} void sun_list_table(struct fdisk_context *cxt, int xtra) { @@ -659,6 +629,49 @@ static struct fdisk_parttype *sun_get_parttype(struct fdisk_context *cxt, int n) return t; } +static int sun_set_parttype(struct fdisk_context *cxt, int i, + struct fdisk_parttype *t) +{ + struct sun_partition *part; + struct sun_tag_flag *tag; + + if (i >= partitions || !t || t->type > UINT16_MAX) + return -EINVAL; + + if (i == 2 && t->type != SUN_TAG_BACKUP) + printf(_("Consider leaving partition 3 as Whole disk (5),\n" + "as SunOS/Solaris expects it and even Linux likes it.\n\n")); + + part = &sunlabel->partitions[i]; + tag = &sunlabel->part_tags[i]; + + if (t->type == SUN_TAG_LINUX_SWAP && !part->start_cylinder) { + read_chars( + _("It is highly recommended that the partition at offset 0\n" + "is UFS, EXT2FS filesystem or SunOS swap. Putting Linux swap\n" + "there may destroy your partition table and bootblock.\n" + "Type YES if you're very sure you would like that partition\n" + "tagged with 82 (Linux swap): ")); + if (strcmp (line_ptr, _("YES\n"))) + return 1; + } + + switch (t->type) { + case SUN_TAG_SWAP: + case SUN_TAG_LINUX_SWAP: + /* swaps are not mountable by default */ + tag->flag |= SSWAP16(SUN_FLAG_UNMNT); + break; + default: + /* assume other types are mountable; + user can change it anyway */ + tag->flag &= ~SSWAP16(SUN_FLAG_UNMNT); + break; + } + tag->tag = SSWAP16(t->type); + return 0; +} + const struct fdisk_label sun_label = { .name = "sun", @@ -672,4 +685,6 @@ const struct fdisk_label sun_label = .part_add = sun_add_partition, .part_delete = sun_delete_partition, .part_get_type = sun_get_parttype, + .part_set_type = sun_set_parttype, + }; diff --git a/fdisks/utils.c b/fdisks/utils.c index fd69fb72ca..e9bc0182c2 100644 --- a/fdisks/utils.c +++ b/fdisks/utils.c @@ -668,3 +668,20 @@ struct fdisk_parttype *fdisk_get_partition_type(struct fdisk_context *cxt, int p return cxt->label->part_get_type(cxt, partnum); } + +/** + * fdisk_set_partition_type: + * @cxt: fdisk context + * @partnum: partition number + * @t: new type + * + * Returns partition type + */ +int fdisk_set_partition_type(struct fdisk_context *cxt, int partnum, + struct fdisk_parttype *t) +{ + if (!cxt || !cxt->label || !cxt->label->part_set_type) + return -EINVAL; + + return cxt->label->part_set_type(cxt, partnum, t); +} -- 2.47.2