From: Karel Zak Date: Mon, 19 Apr 2010 21:03:30 +0000 (+0200) Subject: libblkid: add partial support for superblock binary API X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=861902b5c925a16db9846fb810c86efd3c33a93f;p=util-linux libblkid: add partial support for superblock binary API The API is used only internally. Signed-off-by: Karel Zak --- 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)));