From: Karel Zak Date: Wed, 10 Mar 2010 11:49:56 +0000 (+0100) Subject: libblkid: support alignment_offset=-1 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0386fe0cd49f6ac4efbf839c1dd2b2b7f517978b;p=util-linux libblkid: support alignment_offset=-1 Unfortunately, Linux kernel uses "signed int" for alignment_offset and the offset could be -1 for devices with undefined alignment (if no compatible sizes and alignments exist for stacked devices). There is no way how libblkid caller can respond to the value -1, so we are going to hide this corner case... This patch also cleanups usage of empty topology values (e.g. MINIMUM_IO_SIZE=0 value should not be returned by NAME=value API. The binary blkid_topology_get_* is not affected by this change.) Signed-off-by: Karel Zak --- diff --git a/shlibs/blkid/src/topology/ioctl.c b/shlibs/blkid/src/topology/ioctl.c index 709b2f45..094da5b7 100644 --- a/shlibs/blkid/src/topology/ioctl.c +++ b/shlibs/blkid/src/topology/ioctl.c @@ -44,11 +44,18 @@ static int probe_ioctl_tp(blkid_probe pr, const struct blkid_idmag *mag) for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { struct topology_val *val = &topology_vals[i]; - unsigned int data; + unsigned int data = 0; int rc; - if (ioctl(pr->fd, val->ioc, &data) == -1) + if (val->ioc == BLKALIGNOFF) { + int sdata = 0; + if (ioctl(pr->fd, val->ioc, &sdata) == -1) + goto nothing; + data = sdata < 0 ? 0 : sdata; + + } else if (ioctl(pr->fd, val->ioc, &data) == -1) goto nothing; + rc = val->set_result(pr, (unsigned long) data); if (rc) goto err; diff --git a/shlibs/blkid/src/topology/sysfs.c b/shlibs/blkid/src/topology/sysfs.c index 20c507f1..00f342b8 100644 --- a/shlibs/blkid/src/topology/sysfs.c +++ b/shlibs/blkid/src/topology/sysfs.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,15 +20,14 @@ #include "topology.h" -static unsigned long dev_topology_attribute(const char *attribute, - dev_t dev, dev_t *primary) +static int dev_topology_attribute(const char *attribute, + dev_t dev, dev_t *primary, int64_t *result) { const char *sysfs_fmt_str = "/sys/dev/block/%d:%d/%s"; char path[PATH_MAX]; int len; FILE *fp = NULL; struct stat info; - unsigned long result = 0UL; len = snprintf(path, sizeof(path), sysfs_fmt_str, major(dev), minor(dev), attribute); @@ -58,7 +58,7 @@ static unsigned long dev_topology_attribute(const char *attribute, goto err; } - if (fscanf(fp, "%lu", &result) != 1) { + if (fscanf(fp, "%" SCNd64, result) != 1) { DBG(DEBUG_LOWPROBE, printf( "topology: %s: unexpected file format\n", path)); goto err; @@ -67,15 +67,15 @@ static unsigned long dev_topology_attribute(const char *attribute, fclose(fp); DBG(DEBUG_LOWPROBE, - printf("topology: attribute %s = %lu\n", attribute, result)); + printf("topology: attribute %s = %"PRId64"\n", attribute, *result)); - return result; + return 0; err: if (fp) fclose(fp); DBG(DEBUG_LOWPROBE, printf("topology: failed to read %s attribute\n", attribute)); - return 0; + return -1; } /* @@ -107,17 +107,16 @@ static int probe_sysfs_tp(blkid_probe pr, const struct blkid_idmag *mag) for (i = 0; i < ARRAY_SIZE(topology_vals); i++) { struct topology_val *val = &topology_vals[i]; - unsigned long data; - - /* - * Don't bother reporting any of the topology information - * if it's zero. - */ - data = dev_topology_attribute(val->sysfs_name, dev, &pri_dev); - if (!data) + int64_t data = 0; + + if (dev_topology_attribute(val->sysfs_name, dev, + &pri_dev, &data)) continue; - rc = val->set_result(pr, data); + if (!strcmp(val->sysfs_name, "alignment_offset") && data < 0) + data = 0; + + rc = val->set_result(pr, (unsigned long) data); if (rc) goto err; count++; diff --git a/shlibs/blkid/src/topology/topology.c b/shlibs/blkid/src/topology/topology.c index db97c5fb..42812ac4 100644 --- a/shlibs/blkid/src/topology/topology.c +++ b/shlibs/blkid/src/topology/topology.c @@ -43,6 +43,10 @@ * @ALIGNMENT_OFFSET: indicates how many bytes the beginning o the device is * offset from the disk's natural alignment. * + * The NAME=value tags are not defined when the corresponding topology value + * is zero. The MINIMUM_IO_SIZE should be always defined if kernel provides + * topology information. + * * Binary interface: * * blkid_probe_get_tolology() @@ -214,6 +218,8 @@ static int topology_set_value(blkid_probe pr, const char *name, if (!chn) return -1; + if (!data) + return 0; /* ignore zeros */ if (chn->binary) { unsigned long *v =