summaryrefslogtreecommitdiffstats
path: root/shlibs/blkid
diff options
context:
space:
mode:
authorKarel Zak2010-03-03 13:12:02 +0100
committerKarel Zak2010-03-03 14:00:34 +0100
commit25d1e630f6e32f05454ba38e5c4fdd03b66de589 (patch)
tree06016faf5a6c0240e0da2edf8be7e94cb7a0e645 /shlibs/blkid
parentmount: posix option of vfat is obsolete (diff)
downloadkernel-qcow2-util-linux-25d1e630f6e32f05454ba38e5c4fdd03b66de589.tar.gz
kernel-qcow2-util-linux-25d1e630f6e32f05454ba38e5c4fdd03b66de589.tar.xz
kernel-qcow2-util-linux-25d1e630f6e32f05454ba38e5c4fdd03b66de589.zip
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... 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>
Diffstat (limited to 'shlibs/blkid')
-rw-r--r--shlibs/blkid/src/blkidP.h4
-rw-r--r--shlibs/blkid/src/devno.c20
-rw-r--r--shlibs/blkid/src/partitions/partitions.c4
-rw-r--r--shlibs/blkid/src/topology/ioctl.c15
-rw-r--r--shlibs/blkid/src/topology/sysfs.c86
-rw-r--r--shlibs/blkid/src/topology/topology.c18
-rw-r--r--shlibs/blkid/src/topology/topology.h2
7 files changed, 89 insertions, 60 deletions
diff --git a/shlibs/blkid/src/blkidP.h b/shlibs/blkid/src/blkidP.h
index c9b2bcd18..1de6dd064 100644
--- a/shlibs/blkid/src/blkidP.h
+++ b/shlibs/blkid/src/blkidP.h
@@ -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);
diff --git a/shlibs/blkid/src/devno.c b/shlibs/blkid/src/devno.c
index 1b64ec1e1..a667becf5 100644
--- a/shlibs/blkid/src/devno.c
+++ b/shlibs/blkid/src/devno.c
@@ -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)
{
diff --git a/shlibs/blkid/src/partitions/partitions.c b/shlibs/blkid/src/partitions/partitions.c
index 9c3296e90..0f342fc87 100644
--- a/shlibs/blkid/src/partitions/partitions.c
+++ b/shlibs/blkid/src/partitions/partitions.c
@@ -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++) {
diff --git a/shlibs/blkid/src/topology/ioctl.c b/shlibs/blkid/src/topology/ioctl.c
index 709b2f458..e85ecdf95 100644
--- a/shlibs/blkid/src/topology/ioctl.c
+++ b/shlibs/blkid/src/topology/ioctl.c
@@ -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++;
diff --git a/shlibs/blkid/src/topology/sysfs.c b/shlibs/blkid/src/topology/sysfs.c
index ce870f226..25e2b0aa0 100644
--- a/shlibs/blkid/src/topology/sysfs.c
+++ b/shlibs/blkid/src/topology/sysfs.c
@@ -19,51 +19,20 @@
#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++;
diff --git a/shlibs/blkid/src/topology/topology.c b/shlibs/blkid/src/topology/topology.c
index db97c5fb2..fa49fd092 100644
--- a/shlibs/blkid/src/topology/topology.c
+++ b/shlibs/blkid/src/topology/topology.c
@@ -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)
diff --git a/shlibs/blkid/src/topology/topology.h b/shlibs/blkid/src/topology/topology.h
index d4879204d..b7429d904 100644
--- a/shlibs/blkid/src/topology/topology.h
+++ b/shlibs/blkid/src/topology/topology.h
@@ -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);