summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2010-03-10 12:49:56 +0100
committerKarel Zak <kzak@redhat.com>2010-03-10 12:49:56 +0100
commit0386fe0cd49f6ac4efbf839c1dd2b2b7f517978b (patch)
treebba64fb79b4f494cd298a7320f7e9c7f83ff835d
parent030c9badbdffe5d580c7c86b45474e040d34d315 (diff)
downloadutil-linux-0386fe0cd49f6ac4efbf839c1dd2b2b7f517978b.tar.gz
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 <kzak@redhat.com>
-rw-r--r--shlibs/blkid/src/topology/ioctl.c11
-rw-r--r--shlibs/blkid/src/topology/sysfs.c31
-rw-r--r--shlibs/blkid/src/topology/topology.c6
3 files changed, 30 insertions, 18 deletions
diff --git a/shlibs/blkid/src/topology/ioctl.c b/shlibs/blkid/src/topology/ioctl.c
index 709b2f458..094da5b7a 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 20c507f13..00f342b83 100644
--- a/shlibs/blkid/src/topology/sysfs.c
+++ b/shlibs/blkid/src/topology/sysfs.c
@@ -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>
@@ -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 db97c5fb2..42812ac49 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 =