From: Karel Zak Date: Fri, 22 Feb 2013 21:46:51 +0000 (+0100) Subject: libfdisk: add fdisk_partition_toggle_flag() X-Git-Tag: v2.23-rc1~98 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fb1caca70acca20145cf12b23804443b77c26c1d;p=thirdparty%2Futil-linux.git libfdisk: add fdisk_partition_toggle_flag() Signed-off-by: Karel Zak --- diff --git a/fdisks/fdisk.c b/fdisks/fdisk.c index 3c569d8313..179b905b27 100644 --- a/fdisks/fdisk.c +++ b/fdisks/fdisk.c @@ -1072,15 +1072,17 @@ static void command_prompt(struct fdisk_context *cxt) switch (c) { case 'a': if (fdisk_is_disklabel(cxt, DOS)) - dos_toggle_active(cxt, - get_partition(cxt, 1, cxt->label->nparts_max)); + fdisk_partition_toggle_flag(cxt, + get_partition(cxt, 1, cxt->label->nparts_max), + DOS_FLAG_ACTIVE); else if (fdisk_is_disklabel(cxt, SUN)) - toggle_sunflags(cxt, + fdisk_partition_toggle_flag(cxt, get_partition(cxt, 1, cxt->label->nparts_max), SUN_FLAG_UNMNT); else if (fdisk_is_disklabel(cxt, SGI)) - sgi_set_bootpartition(cxt, - get_partition(cxt, 1, cxt->label->nparts_max)); + fdisk_partition_toggle_flag(cxt, + get_partition(cxt, 1, cxt->label->nparts_max), + SGI_FLAG_BOOT); else unknown_command(c); break; @@ -1101,12 +1103,13 @@ static void command_prompt(struct fdisk_context *cxt) if (fdisk_is_disklabel(cxt, DOS)) toggle_dos_compatibility_flag(cxt); else if (fdisk_is_disklabel(cxt, SUN)) - toggle_sunflags(cxt, + fdisk_partition_toggle_flag(cxt, get_partition(cxt, 1, cxt->label->nparts_max), SUN_FLAG_RONLY); else if (fdisk_is_disklabel(cxt, SGI)) - sgi_set_swappartition(cxt, - get_partition(cxt, 1, cxt->label->nparts_max)); + fdisk_partition_toggle_flag(cxt, + get_partition(cxt, 1, cxt->label->nparts_max), + SGI_FLAG_SWAP); else unknown_command(c); break; diff --git a/fdisks/fdiskdoslabel.c b/fdisks/fdiskdoslabel.c index 1481ca2ff7..464a184759 100644 --- a/fdisks/fdiskdoslabel.c +++ b/fdisks/fdiskdoslabel.c @@ -1402,21 +1402,6 @@ void dos_move_begin(struct fdisk_context *cxt, int i) } } -void dos_toggle_active(struct fdisk_context *cxt, int i) -{ - struct pte *pe = &ptes[i]; - struct partition *p = pe->part_table; - - if (IS_EXTENDED (p->sys_ind) && !p->boot_ind) - fprintf(stderr, - _("WARNING: Partition %d is an extended partition\n"), - i + 1); - p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); - pe->changed = 1; - fdisk_label_set_changed(cxt->label, 1); -} - - static int dos_get_partition_status( struct fdisk_context *cxt, size_t i, @@ -1442,6 +1427,40 @@ static int dos_get_partition_status( return 0; } +static int dos_toggle_partition_flag( + struct fdisk_context *cxt, + size_t i, + unsigned long flag) +{ + struct pte *pe; + struct partition *p; + + assert(cxt); + assert(cxt->label); + assert(fdisk_is_disklabel(cxt, DOS)); + + if (i >= cxt->label->nparts_max) + return -EINVAL; + + pe = &ptes[i]; + p = pe->part_table; + + switch (flag) { + case DOS_FLAG_ACTIVE: + if (IS_EXTENDED(p->sys_ind) && !p->boot_ind) + fdisk_warnx(cxt, _("WARNING: Partition %d is an extended partition"), i + 1); + + p->boot_ind = (p->boot_ind ? 0 : ACTIVE_FLAG); + pe->changed = 1; + fdisk_label_set_changed(cxt->label, 1); + break; + default: + return 1; + } + + return 0; +} + static const struct fdisk_label_operations dos_operations = { .probe = dos_probe_label, @@ -1453,6 +1472,7 @@ static const struct fdisk_label_operations dos_operations = .part_get_type = dos_get_parttype, .part_set_type = dos_set_parttype, + .part_toggle_flag = dos_toggle_partition_flag, .part_get_status = dos_get_partition_status, .reset_alignment = dos_reset_alignment, diff --git a/fdisks/fdiskdoslabel.h b/fdisks/fdiskdoslabel.h index a997be8207..1a11442863 100644 --- a/fdisks/fdiskdoslabel.h +++ b/fdisks/fdiskdoslabel.h @@ -59,4 +59,7 @@ extern int mbr_is_valid_magic(unsigned char *b); (fdisk_is_disklabel(_x, DOS) && \ fdisk_dos_is_compatible(fdisk_context_get_label(_x, NULL))) +/* toggle flags */ +#define DOS_FLAG_ACTIVE 1 + #endif diff --git a/fdisks/fdisksgilabel.c b/fdisks/fdisksgilabel.c index 58f7133b82..9000b3e251 100644 --- a/fdisks/fdisksgilabel.c +++ b/fdisks/fdisksgilabel.c @@ -281,22 +281,11 @@ sgi_get_swappartition(struct fdisk_context *cxt) return (short) SSWAP16(sgilabel->swap_part); } -void -sgi_set_bootpartition(struct fdisk_context *cxt, int i) -{ - sgilabel->boot_part = SSWAP16(((short)i)); -} - static unsigned int sgi_get_lastblock(struct fdisk_context *cxt) { return cxt->geom.heads * cxt->geom.sectors * cxt->geom.cylinders; } -void -sgi_set_swappartition(struct fdisk_context *cxt, int i) { - sgilabel->swap_part = SSWAP16(((short)i)); -} - static int sgi_check_bootfile(struct fdisk_context *cxt, const char* aFile) { @@ -1022,6 +1011,29 @@ static int sgi_get_partition_status( return 0; } +static int sgi_toggle_partition_flag(struct fdisk_context *cxt, size_t i, unsigned long flag) +{ + assert(cxt); + assert(cxt->label); + assert(fdisk_is_disklabel(cxt, SGI)); + + if (i >= cxt->label->nparts_max) + return -EINVAL; + + switch (flag) { + case SGI_FLAG_BOOT: + sgilabel->boot_part = sgilabel->boot_part == SSWAP16(i) ? 0 : SSWAP16(i); + break; + case SGI_FLAG_SWAP: + sgilabel->swap_part = sgilabel->swap_part == SSWAP16(i) ? 0 : SSWAP16(i); + break; + default: + return 1; + } + + return 0; +} + static const struct fdisk_label_operations sgi_operations = { .probe = sgi_probe_label, @@ -1033,7 +1045,8 @@ static const struct fdisk_label_operations sgi_operations = .part_get_type = sgi_get_parttype, .part_set_type = sgi_set_parttype, - .part_get_status = sgi_get_partition_status + .part_get_status = sgi_get_partition_status, + .part_toggle_flag = sgi_toggle_partition_flag }; /* diff --git a/fdisks/fdisksgilabel.h b/fdisks/fdisksgilabel.h index ce53ec151e..b89012d099 100644 --- a/fdisks/fdisksgilabel.h +++ b/fdisks/fdisksgilabel.h @@ -105,6 +105,10 @@ typedef struct { #define SSWAP16(x) (other_endian ? swab16(x) : (uint16_t)(x)) #define SSWAP32(x) (other_endian ? swab32(x) : (uint32_t)(x)) +/* toggle flags */ +#define SGI_FLAG_BOOT 1 +#define SGI_FLAG_SWAP 2 + /* fdisk.c */ #define sgilabel ((sgi_partition *)cxt->firstsector) #define sgiparam (sgilabel->devparam) diff --git a/fdisks/fdisksunlabel.c b/fdisks/fdisksunlabel.c index 5826465d4d..66f459bf53 100644 --- a/fdisks/fdisksunlabel.c +++ b/fdisks/fdisksunlabel.c @@ -305,14 +305,35 @@ static int sun_create_disklabel(struct fdisk_context *cxt) return 0; } -void toggle_sunflags(struct fdisk_context *cxt, size_t i, uint16_t mask) +static int sun_toggle_partition_flag(struct fdisk_context *cxt, size_t i, unsigned long flag) { - struct sun_disklabel *sunlabel = self_disklabel(cxt); - struct sun_info *p = &sunlabel->vtoc.infos[i]; + struct sun_disklabel *sunlabel; + struct sun_info *p; + + assert(cxt); + assert(cxt->label); + assert(fdisk_is_disklabel(cxt, SUN)); - p->flags ^= cpu_to_be16(mask); + if (!i >= cxt->label->nparts_max) + return -EINVAL; - fdisk_label_set_changed(cxt->label, 1); + sunlabel = self_disklabel(cxt); + p = &sunlabel->vtoc.infos[i]; + + switch (flag) { + case SUN_FLAG_UNMNT: + p->flags ^= cpu_to_be16(SUN_FLAG_UNMNT); + fdisk_label_set_changed(cxt->label, 1); + break; + case SUN_FLAG_RONLY: + p->flags ^= cpu_to_be16(SUN_FLAG_RONLY); + fdisk_label_set_changed(cxt->label, 1); + break; + default: + return 1; + } + + return 0; } static void fetch_sun(struct fdisk_context *cxt, @@ -939,6 +960,7 @@ const struct fdisk_label_operations sun_operations = .part_set_type = sun_set_parttype, .part_get_status = sun_get_partition_status, + .part_toggle_flag = sun_toggle_partition_flag, .reset_alignment = sun_reset_alignment, }; diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index 4c66a5a330..7a528eb57b 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -164,6 +164,8 @@ struct fdisk_label_operations { size_t partnum, int *status); + int (*part_toggle_flag)(struct fdisk_context *cxt, size_t i, unsigned long flag); + /* refresh alignment setting */ int (*reset_alignment)(struct fdisk_context *cxt); diff --git a/libfdisk/src/label.c b/libfdisk/src/label.c index f80bf66b12..d8ce279db3 100644 --- a/libfdisk/src/label.c +++ b/libfdisk/src/label.c @@ -263,7 +263,32 @@ int fdisk_partition_get_status(struct fdisk_context *cxt, rc = cxt->label->op->part_get_status(cxt, partnum, status); - /* DBG(LABEL, dbgprint("partition: %zd: status: 0x%04x [rc=%d]", partnum, *status, rc)); */ + DBG(LABEL, dbgprint("partition: %zd: status: 0x%04x [rc=%d]", partnum, *status, rc)); + return rc; +} + +/** + * fdisk_partition_taggle_flag: + * @cxt: fdisk context + * @partnum: partition number + * @status: flags + * + * Returns 0 on success, otherwise, a corresponding error. + */ +int fdisk_partition_toggle_flag(struct fdisk_context *cxt, + size_t partnum, + unsigned long flag) +{ + int rc; + + if (!cxt || !cxt->label) + return -EINVAL; + if (!cxt->label->op->part_toggle_flag) + return -ENOSYS; + + rc = cxt->label->op->part_toggle_flag(cxt, partnum, flag); + + DBG(LABEL, dbgprint("partition: %zd: toggle: 0x%04lx [rc=%d]", partnum, flag, rc)); return rc; } diff --git a/libfdisk/src/libfdisk.h b/libfdisk/src/libfdisk.h index f60b3eb553..87dad95ac2 100644 --- a/libfdisk/src/libfdisk.h +++ b/libfdisk/src/libfdisk.h @@ -62,6 +62,8 @@ enum { FDISK_ASKTYPE_YESNO }; + + /* init.c */ extern void fdisk_init_debug(int mask); @@ -119,6 +121,7 @@ extern void fdisk_label_set_changed(struct fdisk_label *lb, int changed); extern int fdisk_label_is_changed(struct fdisk_label *lb); extern int fdisk_partition_get_status(struct fdisk_context *cxt, size_t partnum, int *status); +extern int fdisk_partition_toggle_flag(struct fdisk_context *cxt, size_t partnum, unsigned long flag); /* alignment.c */ extern int fdisk_reset_alignment(struct fdisk_context *cxt);