summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2010-04-19 23:03:30 +0200
committerKarel Zak <kzak@redhat.com>2010-04-21 10:56:46 +0200
commit861902b5c925a16db9846fb810c86efd3c33a93f (patch)
tree44dcf70b2fca189a906eafd8b443a07553877a37
parent90ec8d9cbf4ee44668e93de8278a5cad881131d7 (diff)
downloadutil-linux-old-861902b5c925a16db9846fb810c86efd3c33a93f.tar.gz
libblkid: add partial support for superblock binary API
The API is used only internally. Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--shlibs/blkid/src/superblocks/superblocks.c101
-rw-r--r--shlibs/blkid/src/superblocks/superblocks.h2
2 files changed, 94 insertions, 9 deletions
diff --git a/shlibs/blkid/src/superblocks/superblocks.c b/shlibs/blkid/src/superblocks/superblocks.c
index 9c71597e..6ed0de6e 100644
--- a/shlibs/blkid/src/superblocks/superblocks.c
+++ b/shlibs/blkid/src/superblocks/superblocks.c
@@ -71,6 +71,7 @@
static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);
+static void superblocks_free(blkid_probe pr, void *data);
static int blkid_probe_set_usage(blkid_probe pr, int usage);
@@ -154,9 +155,23 @@ const struct blkid_chaindrv superblocks_drv = {
.nidinfos = ARRAY_SIZE(idinfos),
.has_fltr = TRUE,
.probe = superblocks_probe,
- .safeprobe = superblocks_safeprobe
+ .safeprobe = superblocks_safeprobe,
+ .free_data = superblocks_free
};
+/*
+ * Private chain data
+ *
+ * TODO: export this data by binary interface (see topology.c or partitions.c
+ * for more details) by blkid_probe_get_superblock() or so.
+ */
+struct blkid_struct_superblock {
+ blkid_loff_t magic_off; /* offset of the magic string */
+ int usage;
+};
+
+/* TODO: move to blkid.h */
+typedef struct blkid_struct_superblock *blkid_superblock;
/**
* blkid_probe_enable_superblocks:
@@ -296,6 +311,39 @@ int blkid_known_fstype(const char *fstype)
return 0;
}
+/* init and returns private data */
+static blkid_superblock superblocks_init_data(blkid_probe pr,
+ struct blkid_chain *chn)
+{
+ DBG(DEBUG_LOWPROBE, printf("initialize superblocks binary data\n"));
+
+ if (chn->data)
+ memset(chn->data, 0,
+ sizeof(struct blkid_struct_superblock));
+ else {
+ chn->data = calloc(1,
+ sizeof(struct blkid_struct_superblock));
+ if (!chn->data)
+ return NULL;
+ }
+ return chn->data;
+}
+
+static void superblocks_free(blkid_probe pr, void *data)
+{
+ free(data);
+}
+
+static blkid_superblock superblocks_copy_data(blkid_superblock dest,
+ blkid_superblock src)
+{
+ if (!src || !dest)
+ return NULL;
+
+ memcpy(dest, src, sizeof(struct blkid_struct_superblock));
+ return dest;
+}
+
/*
* The blkid_do_probe() backend.
*/
@@ -317,6 +365,9 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
* is 1 byte */
goto nothing;
+ if (chn->binary)
+ superblocks_init_data(pr, chn);
+
i = chn->idx + 1;
for ( ; i < ARRAY_SIZE(idinfos); i++) {
@@ -386,15 +437,11 @@ static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
(unsigned char *) id->name,
strlen(id->name) + 1);
- if (chn->flags & BLKID_SUBLKS_USAGE)
- blkid_probe_set_usage(pr, id->usage);
+ blkid_probe_set_usage(pr, id->usage);
- if (hasmag && (chn->flags & BLKID_SUBLKS_MAGIC)) {
- blkid_probe_set_value(pr, "SBMAGIC",
- (unsigned char *) mag->magic, mag->len);
- blkid_probe_sprintf_value(pr, "SBMAGIC_OFFSET",
- "%llu", off);
- }
+ if (hasmag)
+ blkid_probe_set_magic(pr, off, mag->len,
+ (unsigned char *) mag->magic);
DBG(DEBUG_LOWPROBE,
printf("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]\n",
@@ -423,6 +470,9 @@ nothing:
*/
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
{
+ blkid_superblock sb = NULL;
+ struct blkid_struct_superblock sb_buff;
+
struct blkid_prval vals[BLKID_NVALS_SUBLKS];
int nvals = BLKID_NVALS_SUBLKS;
int idx = -1;
@@ -440,6 +490,8 @@ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
/* save the first result */
nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals);
idx = chn->idx;
+ if (chn->data)
+ sb = superblocks_copy_data(&sb_buff, chn->data);
}
count++;
@@ -463,11 +515,33 @@ static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
/* restore the first result */
blkid_probe_chain_reset_vals(pr, chn);
blkid_probe_append_vals(pr, vals, nvals);
+ if (sb && chn->data)
+ superblocks_copy_data(chn->data, sb);
chn->idx = idx;
return 0;
}
+int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
+ size_t len, unsigned char *magic)
+{
+ int rc = 0;
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
+
+ if (chn->flags & BLKID_SUBLKS_MAGIC) {
+ if (magic && len)
+ rc = blkid_probe_set_value(pr, "SBMAGIC", magic, len);
+ if (!rc && offset)
+ rc = blkid_probe_sprintf_value(pr, "SBMAGIC_OFFSET",
+ "%llu", offset);
+ }
+ if (!rc && chn->data) {
+ blkid_superblock sb = (blkid_superblock) chn->data;
+ sb->magic_off = offset;
+ }
+ return rc;
+}
+
int blkid_probe_set_version(blkid_probe pr, const char *version)
{
struct blkid_chain *chn = blkid_probe_get_chain(pr);
@@ -495,8 +569,17 @@ int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
static int blkid_probe_set_usage(blkid_probe pr, int usage)
{
+ struct blkid_chain *chn = blkid_probe_get_chain(pr);
char *u = NULL;
+ if (chn->data) {
+ blkid_superblock sb = (blkid_superblock) chn->data;
+ sb->usage = usage;
+ }
+
+ if (!(chn->flags & BLKID_SUBLKS_USAGE))
+ return 0;
+
if (usage & BLKID_USAGE_FILESYSTEM)
u = "filesystem";
else if (usage & BLKID_USAGE_RAID)
diff --git a/shlibs/blkid/src/superblocks/superblocks.h b/shlibs/blkid/src/superblocks/superblocks.h
index 12f197e5..b1fa49d5 100644
--- a/shlibs/blkid/src/superblocks/superblocks.h
+++ b/shlibs/blkid/src/superblocks/superblocks.h
@@ -69,6 +69,8 @@ extern const struct blkid_idinfo befs_idinfo;
/*
* superblock functions
*/
+extern int blkid_probe_set_magic(blkid_probe pr, blkid_loff_t offset,
+ size_t len, unsigned char *magic);
extern int blkid_probe_set_version(blkid_probe pr, const char *version);
extern int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));