]> err.no Git - util-linux/commitdiff
libblkid: support alignment_offset=-1
authorKarel Zak <kzak@redhat.com>
Wed, 3 Mar 2010 12:12:02 +0000 (13:12 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 3 Mar 2010 13:00:34 +0000 (14:00 +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...

TODO: maybe we can export an extra boolean value 'misaligned' rather
      then complete hide this problem. We will see...

Signed-off-by: Karel Zak <kzak@redhat.com>
shlibs/blkid/src/blkidP.h
shlibs/blkid/src/devno.c
shlibs/blkid/src/partitions/partitions.c
shlibs/blkid/src/topology/ioctl.c
shlibs/blkid/src/topology/sysfs.c
shlibs/blkid/src/topology/topology.c
shlibs/blkid/src/topology/topology.h

index c9b2bcd18c06718491f75de9c6b30263c68e239d..1de6dd064396a039356af5002b88510320f2a7d9 100644 (file)
@@ -333,8 +333,10 @@ struct dir_list {
 extern void blkid__scan_dir(char *, dev_t, struct dir_list **, char **);
 extern int blkid_driver_has_major(const char *drvname, int major);
 extern int blkid_devno_has_attribute(dev_t devno, const char *attribute);
-extern int blkid_devno_get_attribute(dev_t devno, const char *attribute,
+extern int blkid_devno_get_u64_attribute(dev_t devno, const char *attribute,
                                                        uint64_t *result);
+extern int blkid_devno_get_s64_attribute(dev_t devno, const char *attribute,
+                                                       int64_t *result);
 
 /* lseek.c */
 extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
index 1b64ec1e1c00bf0015d2d98bb13843cd220011cd..a667becf5260c5bfb0014ee6bed4561f83cbc3de 100644 (file)
@@ -478,7 +478,7 @@ int blkid_devno_has_attribute(dev_t devno, const char *attribute)
        return 0;
 }
 
-int blkid_devno_get_attribute(dev_t devno, const char *attribute, uint64_t *result)
+int blkid_devno_get_u64_attribute(dev_t devno, const char *attribute, uint64_t *result)
 {
        FILE *f;
        char path[PATH_MAX];
@@ -496,6 +496,24 @@ int blkid_devno_get_attribute(dev_t devno, const char *attribute, uint64_t *resu
        return rc == 1 ? 0 : -1;
 }
 
+int blkid_devno_get_s64_attribute(dev_t devno, const char *attribute, int64_t *result)
+{
+       FILE *f;
+       char path[PATH_MAX];
+       int rc = 0;
+
+       if (!mk_devno_attribute_path(path, sizeof(path), devno, attribute))
+               return -1;
+
+       f = fopen(path, "r");
+       if (f) {
+               rc = fscanf(f, "%" SCNd64, result);
+               fclose(f);
+       }
+
+       return rc == 1 ? 0 : -1;
+}
+
 #ifdef TEST_PROGRAM
 int main(int argc, char** argv)
 {
index 9c3296e902c1334baddd7698456d89d952870faf..0f342fc87b724dd4b7ed0de85500a9822331465e 100644 (file)
@@ -828,9 +828,9 @@ blkid_partition blkid_partlist_devno_to_partition(blkid_partlist ls, dev_t devno
        uint64_t start, size;
        int i;
 
-       if (blkid_devno_get_attribute(devno, "start", &start))
+       if (blkid_devno_get_u64_attribute(devno, "start", &start))
                return NULL;
-       if (blkid_devno_get_attribute(devno, "size", &size))
+       if (blkid_devno_get_u64_attribute(devno, "size", &size))
                return NULL;
 
        for (i = 0; i < ls->nparts; i++) {
index 709b2f458a4505b701fb61d90344fcf1e591d19c..e85ecdf957822139cc67c3b3f1cd5fbad3c8de65 100644 (file)
@@ -26,11 +26,12 @@ static struct topology_val {
 
        long  ioc;
 
-       /* function to set probing resut */
-       int (*set_result)(blkid_probe, unsigned long);
+       /* functions to set probing resut */
+       int (*set_ulong)(blkid_probe, unsigned long);
+       int (*set_int)(blkid_probe, int);
 
 } topology_vals[] = {
-       { BLKALIGNOFF, blkid_topology_set_alignment_offset },
+       { BLKALIGNOFF, NULL, blkid_topology_set_alignment_offset },
        { BLKIOMIN, blkid_topology_set_minimum_io_size },
        { BLKIOOPT, blkid_topology_set_optimal_io_size },
        { BLKPBSZGET, blkid_topology_set_physical_sector_size }
@@ -44,12 +45,16 @@ 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];
+               int rc = 1;
                unsigned int data;
-               int rc;
 
                if (ioctl(pr->fd, val->ioc, &data) == -1)
                        goto nothing;
-               rc = val->set_result(pr, (unsigned long) data);
+
+               if (val->set_int)
+                       rc = val->set_int(pr, (int) data);
+               else
+                       rc = val->set_ulong(pr, (unsigned long) data);
                if (rc)
                        goto err;
                count++;
index ce870f226e6778ce53cfe47d8f65661301343aea..25e2b0aa047c42b022f8f590ec7e62e046536a3f 100644 (file)
 
 #include "topology.h"
 
-static unsigned long dev_topology_attribute(const char *attribute,
-                               dev_t dev, dev_t *primary)
-{
-       uint64_t result;
-
-       /*
-        * check if the desired sysfs attribute exists
-        * - if not: either the kernel doesn't have topology support or the
-        *   device could be a partition
-        */
-       if (!blkid_devno_has_attribute(dev, attribute)) {
-               if (!*primary &&
-                   blkid_devno_to_wholedisk(dev, NULL, 0, primary))
-                       goto err;
-
-               /* get attribute from partition's primary device */
-               dev = *primary;
-       }
-
-       if (blkid_devno_get_attribute(dev, attribute, &result))
-               goto err;
-
-       DBG(DEBUG_LOWPROBE,
-               printf("topology: attribute %s = %" PRIu64 "\n", attribute, result));
-
-       return result;
-err:
-       DBG(DEBUG_LOWPROBE,
-               printf("topology: failed to read %s attribute\n", attribute));
-       return 0;
-}
-
 /*
  * Sysfs topology values (since 2.6.31, May 2009).
  */
 static struct topology_val {
 
-       /* /sys/dev/block/<maj>:<min>/NAME */
-       const char *sysfs_name;
+       /* /sys/dev/block/<maj>:<min>/<ATTR> */
+       const char *attr;
 
-       /* function to set probing resut */
-       int (*set_result)(blkid_probe, unsigned long);
+       /* functions to set probing resut */
+       int (*set_ulong)(blkid_probe, unsigned long);
+       int (*set_int)(blkid_probe, int);
 
 } topology_vals[] = {
-       { "alignment_offset", blkid_topology_set_alignment_offset },
+       { "alignment_offset", NULL, blkid_topology_set_alignment_offset },
        { "queue/minimum_io_size", blkid_topology_set_minimum_io_size },
        { "queue/optimal_io_size", blkid_topology_set_optimal_io_size },
        { "queue/physical_block_size", blkid_topology_set_physical_sector_size },
@@ -72,7 +41,7 @@ static struct topology_val {
 static int probe_sysfs_tp(blkid_probe pr, const struct blkid_idmag *mag)
 {
        dev_t dev, pri_dev = 0;
-       int i, rc = 0, count = 0;
+       int i, count = 0;
 
        dev = blkid_probe_get_devno(pr);
        if (!dev)
@@ -80,17 +49,38 @@ 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)
-                       continue;
+               dev_t attr_dev = dev;
+               int rc = 1;
+
+               if (!blkid_devno_has_attribute(dev, val->attr)) {
+                       /* get attribute from partition's primary device */
+                       if (!pri_dev &&
+                           blkid_devno_to_wholedisk(dev, NULL, 0, &pri_dev))
+                               continue;
+                       attr_dev = pri_dev;
+               }
+
+               if (val->set_ulong) {
+                       uint64_t data = 0;
+
+                       if (blkid_devno_get_u64_attribute(attr_dev,
+                                                       val->attr, &data))
+                               continue;
+                       if (!data)
+                               continue;
+                       rc = val->set_ulong(pr, (unsigned long) data);
+
+               } else if (val->set_int) {
+                       int64_t data = 0;
+
+                       if (blkid_devno_get_s64_attribute(attr_dev,
+                                                       val->attr, &data))
+                               continue;
+                       if (!data)
+                               continue;
+                       rc = val->set_int(pr, (int) data);
+               }
 
-               rc = val->set_result(pr, data);
                if (rc)
                        goto err;
                count++;
index db97c5fb2ac8b37009ca15325a5d1fe118a81da1..fa49fd092e1bad229ced09be7ba9b32ef39dd316 100644 (file)
@@ -242,12 +242,26 @@ static int topology_is_complete(blkid_probe pr)
        return __blkid_probe_lookup_value(pr, "MINIMUM_IO_SIZE") ? TRUE : FALSE;
 }
 
-int blkid_topology_set_alignment_offset(blkid_probe pr, unsigned long val)
+int blkid_topology_set_alignment_offset(blkid_probe pr, int val)
 {
+       unsigned long xval;
+
+       /* Welcome to Hell. The kernel is able to returns -1 as an
+        * alignment_offset 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 will hide this corner case...
+        *
+        * (TODO: maybe we can export an extra boolean value 'misaligned' rather
+        *  then complete hide this problem.)
+        */
+       xval = val < 0 ? 0 : val;
+
        return topology_set_value(pr,
                        "ALIGNMENT_OFFSET",
                        offsetof(struct blkid_struct_topology, alignment_offset),
-                       val);
+                       xval);
 }
 
 int blkid_topology_set_minimum_io_size(blkid_probe pr, unsigned long val)
index d4879204d722b9ebaf1de6ddc68916c2d26bce6e..b7429d904c5a5d8de778f428cc085e781155edb9 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "blkidP.h"
 
-extern int blkid_topology_set_alignment_offset(blkid_probe pr, unsigned long val);
+extern int blkid_topology_set_alignment_offset(blkid_probe pr, int val);
 extern int blkid_topology_set_minimum_io_size(blkid_probe pr, unsigned long val);
 extern int blkid_topology_set_optimal_io_size(blkid_probe pr, unsigned long val);
 extern int blkid_topology_set_physical_sector_size(blkid_probe pr, unsigned long val);