]> err.no Git - util-linux/commitdiff
libblkid: support alignment_offset=-1
authorKarel Zak <kzak@redhat.com>
Wed, 10 Mar 2010 11:49:56 +0000 (12:49 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 10 Mar 2010 11:49:56 +0000 (12:49 +0100)
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 <kzak@redhat.com>
shlibs/blkid/src/topology/ioctl.c
shlibs/blkid/src/topology/sysfs.c
shlibs/blkid/src/topology/topology.c

index 709b2f458a4505b701fb61d90344fcf1e591d19c..094da5b7a9df98075ae9393d17ac6cadd05b7021 100644 (file)
@@ -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;
index 20c507f13aeeb56486095aa6dd38129cb5d896a7..00f342b8380e84f3acfb23282fd8c88707bcc18a 100644 (file)
@@ -12,6 +12,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdint.h>
+#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
 #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++;
index db97c5fb2ac8b37009ca15325a5d1fe118a81da1..42812ac49f6aa60c4d40e974428fae4ca0f6ddcf 100644 (file)
  * @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 =