From: Karel Zak Date: Fri, 13 Jan 2017 11:44:35 +0000 (+0100) Subject: libfdisk: change the way how apply user device properties X-Git-Tag: v2.30-rc1~306 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=502dd53c864c26124146eb42eb9bbf5bb7b587b9;p=thirdparty%2Futil-linux.git libfdisk: change the way how apply user device properties The current code calls fdisk_apply_user_device_properties() after label probing, because we want to overwrite label geometry by user settings (e.g. -C -H -S fdisk options). Unfortunately, this way does not work if we need to use a different sector size, because label probing depends on sector size... So, the right way is to apply user setting to the fdisk context before we start to read from device, and overwrite geometry again after label is already read. Fortunately, this shit is necessary only rarely and for SUN and SGI disk labels. Addresses: https://github.com/karelzak/util-linux/issues/396 Signed-off-by: Karel Zak --- diff --git a/libfdisk/src/alignment.c b/libfdisk/src/alignment.c index c4496fe9f2..15d6140ed7 100644 --- a/libfdisk/src/alignment.c +++ b/libfdisk/src/alignment.c @@ -321,11 +321,13 @@ int fdisk_save_user_sector_size(struct fdisk_context *cxt, */ int fdisk_has_user_device_properties(struct fdisk_context *cxt) { - return (cxt->user_pyh_sector - || cxt->user_log_sector - || cxt->user_geom.heads - || cxt->user_geom.sectors - || cxt->user_geom.cylinders); + return (cxt->user_pyh_sector || cxt->user_log_sector || + fdisk_has_user_device_geometry(cxt)); +} + +int fdisk_has_user_device_geometry(struct fdisk_context *cxt) +{ + return (cxt->user_geom.heads || cxt->user_geom.sectors || cxt->user_geom.cylinders); } int fdisk_apply_user_device_properties(struct fdisk_context *cxt) diff --git a/libfdisk/src/bsd.c b/libfdisk/src/bsd.c index ad0a54f6f4..62e4634b61 100644 --- a/libfdisk/src/bsd.c +++ b/libfdisk/src/bsd.c @@ -859,6 +859,9 @@ static int bsd_readlabel(struct fdisk_context *cxt) cxt->geom.heads = d->d_ntracks; cxt->geom.cylinders = d->d_ncylinders; + if (fdisk_has_user_device_geometry(cxt)) + fdisk_apply_user_device_properties(cxt); + cxt->label->nparts_cur = d->d_npartitions; cxt->label->nparts_max = BSD_MAXPARTITIONS; DBG(LABEL, ul_debug("read BSD label")); diff --git a/libfdisk/src/context.c b/libfdisk/src/context.c index 947f104fab..25220f0642 100644 --- a/libfdisk/src/context.c +++ b/libfdisk/src/context.c @@ -614,17 +614,13 @@ int fdisk_assign_device(struct fdisk_context *cxt, fdisk_discover_topology(cxt); fdisk_discover_geometry(cxt); + fdisk_apply_user_device_properties(cxt); + if (fdisk_read_firstsector(cxt) < 0) goto fail; - /* detect labels and apply labels specific stuff (e.g geometry) - * to the context */ fdisk_probe_labels(cxt); - /* let's apply user geometry *after* label prober - * to make it possible to override in-label setting */ - fdisk_apply_user_device_properties(cxt); - /* warn about obsolete stuff on the device if we aren't in * list-only mode and there is not PT yet */ if (!fdisk_is_listonly(cxt) && !fdisk_has_label(cxt) && check_collisions(cxt) < 0) diff --git a/libfdisk/src/dos.c b/libfdisk/src/dos.c index b2c6a58ebe..6adcc7230e 100644 --- a/libfdisk/src/dos.c +++ b/libfdisk/src/dos.c @@ -779,6 +779,9 @@ static int dos_probe_label(struct fdisk_context *cxt) if (h && s) { cxt->geom.heads = h; cxt->geom.sectors = s; + + if (fdisk_has_user_device_geometry(cxt)) + fdisk_apply_user_device_properties(cxt); } for (i = 0; i < 4; i++) { diff --git a/libfdisk/src/fdiskP.h b/libfdisk/src/fdiskP.h index b068638ab1..0f37541d8e 100644 --- a/libfdisk/src/fdiskP.h +++ b/libfdisk/src/fdiskP.h @@ -413,6 +413,7 @@ fdisk_sector_t fdisk_cround(struct fdisk_context *cxt, fdisk_sector_t num); extern int fdisk_discover_geometry(struct fdisk_context *cxt); extern int fdisk_discover_topology(struct fdisk_context *cxt); +extern int fdisk_has_user_device_geometry(struct fdisk_context *cxt); extern int fdisk_apply_user_device_properties(struct fdisk_context *cxt); extern void fdisk_zeroize_device_properties(struct fdisk_context *cxt); diff --git a/libfdisk/src/sun.c b/libfdisk/src/sun.c index d6a71b6e6f..ac46d2ae57 100644 --- a/libfdisk/src/sun.c +++ b/libfdisk/src/sun.c @@ -146,6 +146,10 @@ static int sun_probe_label(struct fdisk_context *cxt) cxt->geom.cylinders = be16_to_cpu(sunlabel->ncyl); cxt->geom.sectors = be16_to_cpu(sunlabel->nsect); + /* we have on label geom, but user has to win */ + if (fdisk_has_user_device_geometry(cxt)) + fdisk_apply_user_device_properties(cxt); + if (be32_to_cpu(sunlabel->vtoc.version) != SUN_VTOC_VERSION) { fdisk_warnx(cxt, _("Detected sun disklabel with wrong version [%d]."), be32_to_cpu(sunlabel->vtoc.version));