/*
 * superblocks.c - reads information from filesystem and raid superblocks
 *
 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdint.h>
#include <stdarg.h>

#include "superblocks.h"

/**
 * SECTION:superblocks
 * @title: Superblocks probing
 * @short_description: filesystems and raids superblocks probing.
 *
 * The library API has been originally designed for superblocks probing only.
 * This is reason why some *deprecated* superblock specific functions don't use
 * '_superblocks_' namespace in the function name. Please, don't use these
 * functions in new code.
 *
 * The 'superblocks' probers support NAME=value (tags) interface only. The
 * superblocks probing is enabled by default (and controlled by
 * blkid_probe_enable_superblocks()).
 *
 * Currently supported tags:
 *
 * @TYPE: filesystem type
 *
 * @SEC_TYPE: secondary filesystem type
 *
 * @LABEL: filesystem label
 *
 * @LABEL_RAW: raw label from FS superblock
 *
 * @UUID: filesystem UUID (lower case)
 *
 * @UUID_SUB: subvolume uuid (e.g. btrfs)
 *
 * @UUID_RAW: raw UUID from FS superblock
 *
 * @EXT_JOURNAL: external journal UUID
 *
 * @USAGE:  usage string: "raid", "filesystem", ...
 *
 * @VERSION: filesystem version
 *
 * @MOUNT: cluster mount name (?) -- ocfs only
 *
 * @SBMAGIC: super block magic string
 *
 * @SBMAGIC_OFFSET: offset of SBMAGIC
 *
 * @FSSIZE: size of filessystem [not-implemented yet]
 *
 * @SYSTEM_ID: ISO9660 system identifier
 *
 * @PUBLISHER_ID: ISO9660 publisher identifier
 *
 * @APPLICATION_ID: ISO9660 application identifier
 *
 * @BOOT_SYSTEM_ID: ISO9660 boot system identifier
 */

static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);

static int blkid_probe_set_usage(blkid_probe pr, int usage);


/*
 * Superblocks chains probing functions
 */
static const struct blkid_idinfo *idinfos[] =
{
	/* RAIDs */
	&linuxraid_idinfo,
	&ddfraid_idinfo,
	&iswraid_idinfo,
	&lsiraid_idinfo,
	&viaraid_idinfo,
	&silraid_idinfo,
	&nvraid_idinfo,
	&pdcraid_idinfo,
	&highpoint45x_idinfo,
	&highpoint37x_idinfo,
	&adraid_idinfo,
	&jmraid_idinfo,

	&drbd_idinfo,
	&drbdproxy_datalog_idinfo,
	&lvm2_idinfo,
	&lvm1_idinfo,
	&snapcow_idinfo,
	&verity_hash_idinfo,
	&luks_idinfo,
	&vmfs_volume_idinfo,

	/* Filesystems */
	&vfat_idinfo,
	&swsuspend_idinfo,
	&swap_idinfo,
	&xfs_idinfo,
	&ext4dev_idinfo,
	&ext4_idinfo,
	&ext3_idinfo,
	&ext2_idinfo,
	&jbd_idinfo,
	&reiser_idinfo,
	&reiser4_idinfo,
	&jfs_idinfo,
	&udf_idinfo,
	&iso9660_idinfo,
	&zfs_idinfo,
	&hfsplus_idinfo,
	&hfs_idinfo,
	&ufs_idinfo,
	&hpfs_idinfo,
	&sysv_idinfo,
        &xenix_idinfo,
	&ntfs_idinfo,
	&cramfs_idinfo,
	&romfs_idinfo,
	&minix_idinfo,
	&gfs_idinfo,
	&gfs2_idinfo,
	&ocfs_idinfo,
	&ocfs2_idinfo,
	&oracleasm_idinfo,
	&vxfs_idinfo,
	&squashfs_idinfo,
	&netware_idinfo,
	&btrfs_idinfo,
	&ubifs_idinfo,
	&bfs_idinfo,
	&vmfs_fs_idinfo,
	&befs_idinfo,
	&nilfs2_idinfo,
	&exfat_idinfo,
	&f2fs_idinfo
};

/*
 * Driver definition
 */
const struct blkid_chaindrv superblocks_drv = {
	.id           = BLKID_CHAIN_SUBLKS,
	.name         = "superblocks",
	.dflt_enabled = TRUE,
	.dflt_flags   = BLKID_SUBLKS_DEFAULT,
	.idinfos      = idinfos,
	.nidinfos     = ARRAY_SIZE(idinfos),
	.has_fltr     = TRUE,
	.probe        = superblocks_probe,
	.safeprobe    = superblocks_safeprobe,
};

/**
 * blkid_probe_enable_superblocks:
 * @pr: probe
 * @enable: TRUE/FALSE
 *
 * Enables/disables the superblocks probing for non-binary interface.
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
{
	if (!pr)
		return -1;
	pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
	return 0;
}

/**
 * blkid_probe_set_superblocks_flags:
 * @pr: prober
 * @flags: BLKID_SUBLKS_* flags
 *
 * Sets probing flags to the superblocks prober. This function is optional, the
 * default are BLKID_SUBLKS_DEFAULTS flags.
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
{
	if (!pr)
		return -1;

	pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
	return 0;
}

/**
 * blkid_probe_reset_superblocks_filter:
 * @pr: prober
 *
 * Resets superblocks probing filter
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_reset_superblocks_filter(blkid_probe pr)
{
	return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
}

/**
 * blkid_probe_invert_superblocks_filter:
 * @pr: prober
 *
 * Inverts superblocks probing filter
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_invert_superblocks_filter(blkid_probe pr)
{
	return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
}

/**
 * blkid_probe_filter_superblocks_type:
 * @pr: prober
 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
 * @names: NULL terminated array of probing function names (e.g. "vfat").
 *
 *  %BLKID_FLTR_NOTIN  - probe for all items which are NOT IN @names;
 *
 *  %BLKID_FLTR_ONLYIN - probe for items which are IN @names
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
{
	return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
}

/**
 * blkid_probe_filter_superblocks_usage:
 * @pr: prober
 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
 * @usage: BLKID_USAGE_* flags
 *
 *  %BLKID_FLTR_NOTIN  - probe for all items which are NOT IN @usage;
 *
 *  %BLKID_FLTR_ONLYIN - probe for items which are IN @usage
 *
 * Returns: 0 on success, or -1 in case of error.
 */
int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
{
	unsigned long *fltr;
	struct blkid_chain *chn;
	size_t i;

	fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
	if (!fltr)
		return -1;

	chn = &pr->chains[BLKID_CHAIN_SUBLKS];

	for (i = 0; i < chn->driver->nidinfos; i++) {
		const struct blkid_idinfo *id = chn->driver->idinfos[i];

		if (id->usage & usage) {
			if (flag & BLKID_FLTR_NOTIN)
				blkid_bmp_set_item(chn->fltr, i);
		} else if (flag & BLKID_FLTR_ONLYIN)
			blkid_bmp_set_item(chn->fltr, i);
	}
	DBG(DEBUG_LOWPROBE, printf("a new probing usage-filter initialized\n"));
	return 0;
}

/**
 * blkid_known_fstype:
 * @fstype: filesystem name
 *
 * Returns: 1 for known filesytems, or 0 for unknown filesystem.
 */
int blkid_known_fstype(const char *fstype)
{
	size_t i;

	if (!fstype)
		return 0;

	for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
		const struct blkid_idinfo *id = idinfos[i];
		if (strcmp(id->name, fstype) == 0)
			return 1;
	}
	return 0;
}

/**
 * blkid_superblocks_get_name:
 * @idx: number >= 0
 * @name: returns name of supported filesystem/raid (optional)
 * @usage: returns BLKID_USAGE_* flags, (optional)
 *
 * Returns: -1 if @idx is out of range, or 0 on success.
 */
int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
{
	if (idx < ARRAY_SIZE(idinfos)) {
		if (name)
			*name = idinfos[idx]->name;
		if (usage)
			*usage = idinfos[idx]->usage;
		return 0;
	}
	return -1;
}

/*
 * The blkid_do_probe() backend.
 */
static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
{
	size_t i;

	if (!pr || chn->idx < -1)
		return -1;
	blkid_probe_chain_reset_vals(pr, chn);

	DBG(DEBUG_LOWPROBE,
		printf("--> starting probing loop [SUBLKS idx=%d]\n",
		chn->idx));

	if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode)))
		/* Ignore very very small block devices or regular files (e.g.
		 * extended partitions). Note that size of the UBI char devices
		 * is 1 byte */
		goto nothing;

	i = chn->idx < 0 ? 0 : chn->idx + 1U;

	for ( ; i < ARRAY_SIZE(idinfos); i++) {
		const struct blkid_idinfo *id;
		const struct blkid_idmag *mag = NULL;
		blkid_loff_t off = 0;
		int rc = 0;

		chn->idx = i;
		id = idinfos[i];

		if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
			DBG(DEBUG_LOWPROBE, printf("filter out: %s\n", id->name));
			continue;
		}

		if (id->minsz && id->minsz > pr->size)
			continue;	/* the device is too small */

		/* don't probe for RAIDs, swap or journal on CD/DVDs */
		if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
		    blkid_probe_is_cdrom(pr))
			continue;

		/* don't probe for RAIDs on floppies */
		if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr))
			continue;

		DBG(DEBUG_LOWPROBE, printf("[%zd] %s:\n", i, id->name));

		if (blkid_probe_get_idmag(pr, id, &off, &mag))
			continue;

		/* final check by probing function */
		if (id->probefunc) {
			DBG(DEBUG_LOWPROBE, printf("\tcall probefunc()\n"));
			if (id->probefunc(pr, mag) != 0) {
				blkid_probe_chain_reset_vals(pr, chn);
				continue;
			}
		}

		/* all cheks passed */
		if (chn->flags & BLKID_SUBLKS_TYPE)
			rc = blkid_probe_set_value(pr, "TYPE",
				(unsigned char *) id->name,
				strlen(id->name) + 1);

		if (!rc)
			rc = blkid_probe_set_usage(pr, id->usage);

		if (!rc && mag)
			rc = blkid_probe_set_magic(pr, off, mag->len,
					(unsigned char *) mag->magic);
		if (rc) {
			blkid_probe_chain_reset_vals(pr, chn);
			DBG(DEBUG_LOWPROBE, printf("failed to set result -- ingnore\n"));
			continue;
		}

		DBG(DEBUG_LOWPROBE,
			printf("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]\n",
			id->name, chn->idx));
		return 0;
	}

nothing:
	DBG(DEBUG_LOWPROBE,
		printf("<-- leaving probing loop (failed) [SUBLKS idx=%d]\n",
		chn->idx));
	return 1;
}

/*
 * This is the same function as blkid_do_probe(), but returns only one result
 * (cannot be used in while()) and checks for ambivalen results (more
 * filesystems on the device) -- in such case returns -2.
 *
 * The function does not check for filesystems when a RAID or crypto signature
 * is detected.  The function also does not check for collision between RAIDs
 * and crypto devices. The first detected RAID or crypto device is returned.
 *
 * The function does not probe for ambivalent results on very small devices
 * (e.g. floppies), on small devices the first detected filesystem is returned.
 */
static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
{
	struct blkid_prval vals[BLKID_NVALS_SUBLKS];
	int nvals = BLKID_NVALS_SUBLKS;
	int idx = -1;
	int count = 0;
	int intol = 0;
	int rc;

	while ((rc = superblocks_probe(pr, chn)) == 0) {

		if (blkid_probe_is_tiny(pr) && !count)
			/* floppy or so -- returns the first result. */
			return 0;

		count++;

		if (chn->idx >= 0 &&
		    idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
			break;

		if (chn->idx >= 0 &&
		    !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
			intol++;

		if (count == 1) {
			/* save the first result */
			nvals = blkid_probe_chain_copy_vals(pr, chn, vals, nvals);
			idx = chn->idx;
		}
	}

	if (rc < 0)
		return rc;		/* error */

	if (count > 1 && intol) {
		DBG(DEBUG_LOWPROBE,
			printf("ERROR: superblocks chain: "
			       "ambivalent result detected (%d filesystems)!\n",
			       count));
		return -2;		/* error, ambivalent result (more FS) */
	}
	if (!count)
		return 1;		/* nothing detected */

	if (idx != -1) {
		/* restore the first result */
		blkid_probe_chain_reset_vals(pr, chn);
		blkid_probe_append_vals(pr, vals, nvals);
		chn->idx = idx;
	}

	/*
	 * The RAID device could be partitioned. The problem are RAID1 devices
	 * where the partition table is visible from underlaying devices. We
	 * have to ignore such partition tables.
	 */
	if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
		pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;

	return 0;
}

int blkid_probe_set_version(blkid_probe pr, const char *version)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);

	if (chn->flags & BLKID_SUBLKS_VERSION)
		return blkid_probe_set_value(pr, "VERSION",
			   (unsigned char *) version, strlen(version) + 1);
	return 0;
}


int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	int rc = 0;

	if (chn->flags & BLKID_SUBLKS_VERSION) {
		va_list ap;

		va_start(ap, fmt);
		rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
		va_end(ap);
	}
	return rc;
}

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->flags & BLKID_SUBLKS_USAGE))
		return 0;

	if (usage & BLKID_USAGE_FILESYSTEM)
		u = "filesystem";
	else if (usage & BLKID_USAGE_RAID)
		u = "raid";
	else if (usage & BLKID_USAGE_CRYPTO)
		u = "crypto";
	else if (usage & BLKID_USAGE_OTHER)
		u = "other";
	else
		u = "unknown";

	return blkid_probe_set_value(pr, "USAGE", (unsigned char *) u, strlen(u) + 1);
}

int blkid_probe_set_id_label(blkid_probe pr, const char *name,
			     unsigned char *data, size_t len)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	struct blkid_prval *v;

	if (!(chn->flags & BLKID_SUBLKS_LABEL))
		return 0;

	v = blkid_probe_assign_value(pr, name);
	if (!v)
		return -1;

	if (len >= BLKID_PROBVAL_BUFSIZ)
		len = BLKID_PROBVAL_BUFSIZ - 1;			/* make a space for \0 */

	memcpy(v->data, data, len);
	v->data[len] = '\0';

	/* remove white spaces */
	v->len = blkid_rtrim_whitespace(v->data) + 1;
	if (v->len > 1)
		v->len = blkid_ltrim_whitespace(v->data) + 1;

	if (v->len <= 1)
		blkid_probe_reset_last_value(pr);		/* ignore empty */
	return 0;
}

int blkid_probe_set_label(blkid_probe pr, unsigned char *label, size_t len)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	struct blkid_prval *v;
	if (len > BLKID_PROBVAL_BUFSIZ)
		len = BLKID_PROBVAL_BUFSIZ;

	if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
	    blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
		return -1;
	if (!(chn->flags & BLKID_SUBLKS_LABEL))
		return 0;
	v = blkid_probe_assign_value(pr, "LABEL");
	if (!v)
		return -1;

	if (len == BLKID_PROBVAL_BUFSIZ)
		len--;				/* make a space for \0 */

	memcpy(v->data, label, len);
	v->data[len] = '\0';

	v->len = blkid_rtrim_whitespace(v->data) + 1;
	if (v->len == 1)
		blkid_probe_reset_last_value(pr);
	return 0;
}

int blkid_probe_set_utf8label(blkid_probe pr, unsigned char *label,
				size_t len, int enc)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	struct blkid_prval *v;

	if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
	    blkid_probe_set_value(pr, "LABEL_RAW", label, len) < 0)
		return -1;
	if (!(chn->flags & BLKID_SUBLKS_LABEL))
		return 0;
	v = blkid_probe_assign_value(pr, "LABEL");
	if (!v)
		return -1;

	blkid_encode_to_utf8(enc, v->data, sizeof(v->data), label, len);
	v->len = blkid_rtrim_whitespace(v->data) + 1;
	if (v->len == 1)
		blkid_probe_reset_last_value(pr);
	return 0;
}

/* like uuid_is_null() from libuuid, but works with arbitrary size of UUID */
static int uuid_is_empty(const unsigned char *buf, size_t len)
{
	size_t i;

	for (i = 0; i < len; i++)
		if (buf[i])
			return 0;
	return 1;
}

int blkid_probe_sprintf_uuid(blkid_probe pr, unsigned char *uuid,
				size_t len, const char *fmt, ...)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	int rc = -1;
	va_list ap;

	if (len > BLKID_PROBVAL_BUFSIZ)
		len = BLKID_PROBVAL_BUFSIZ;

	if (uuid_is_empty(uuid, len))
		return 0;

	if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
	    blkid_probe_set_value(pr, "UUID_RAW", uuid, len) < 0)
		return -1;
	if (!(chn->flags & BLKID_SUBLKS_UUID))
		return 0;

	va_start(ap, fmt);
	rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
	va_end(ap);

	/* convert to lower case (..be paranoid) */
	if (!rc) {
		size_t i;
		struct blkid_prval *v = __blkid_probe_get_value(pr,
						blkid_probe_numof_values(pr));
		if (v) {
			for (i = 0; i < v->len; i++)
				if (v->data[i] >= 'A' && v->data[i] <= 'F')
					v->data[i] = (v->data[i] - 'A') + 'a';
		}
	}
	return rc;
}

/* function to set UUIDs that are in suberblocks stored as strings */
int blkid_probe_strncpy_uuid(blkid_probe pr, unsigned char *str, size_t len)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	struct blkid_prval *v;

	if (str == NULL || *str == '\0')
		return -1;
	if (!len)
		len = strlen((char *) str);
	if (len > BLKID_PROBVAL_BUFSIZ)
		len = BLKID_PROBVAL_BUFSIZ;

	if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
	    blkid_probe_set_value(pr, "UUID_RAW", str, len) < 0)
		return -1;
	if (!(chn->flags & BLKID_SUBLKS_UUID))
		return 0;

	v = blkid_probe_assign_value(pr, "UUID");
	if (v) {
		if (len == BLKID_PROBVAL_BUFSIZ)
			len--;		/* make a space for \0 */

		memcpy((char *) v->data, str, len);
		v->data[len] = '\0';
		v->len = len + 1;
		return 0;
	}
	return -1;
}

/* default _set_uuid function to set DCE UUIDs */
int blkid_probe_set_uuid_as(blkid_probe pr, unsigned char *uuid, const char *name)
{
	struct blkid_chain *chn = blkid_probe_get_chain(pr);
	struct blkid_prval *v;

	if (uuid_is_empty(uuid, 16))
		return 0;

	if (!name) {
		if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
		    blkid_probe_set_value(pr, "UUID_RAW", uuid, 16) < 0)
			return -1;
		if (!(chn->flags & BLKID_SUBLKS_UUID))
			return 0;

		v = blkid_probe_assign_value(pr, "UUID");
	} else
		v = blkid_probe_assign_value(pr, name);

	blkid_unparse_uuid(uuid, (char *) v->data, sizeof(v->data));
	v->len = 37;

	return 0;
}

int blkid_probe_set_uuid(blkid_probe pr, unsigned char *uuid)
{
	return blkid_probe_set_uuid_as(pr, uuid, NULL);
}

/**
 * blkid_probe_set_request:
 * @pr: probe
 * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags
 *
 * Returns: 0 on success, or -1 in case of error.
 *
 * Deprecated: Use blkid_probe_set_superblocks_flags().
 */
int blkid_probe_set_request(blkid_probe pr, int flags)
{
	return blkid_probe_set_superblocks_flags(pr, flags);
}

/**
 * blkid_probe_reset_filter:
 * @pr: prober
 *
 * Returns: 0 on success, or -1 in case of error.
 *
 * Deprecated: Use blkid_probe_reset_superblocks_filter().
 */
int blkid_probe_reset_filter(blkid_probe pr)
{
	return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
}

/**
 * blkid_probe_invert_filter:
 * @pr: prober
 *
 * Returns: 0 on success, or -1 in case of error.
 *
 * Deprecated: Use blkid_probe_invert_superblocks_filter().
 */
int blkid_probe_invert_filter(blkid_probe pr)
{
	return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
}

/**
 * blkid_probe_filter_types
 * @pr: prober
 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
 * @names: NULL terminated array of probing function names (e.g. "vfat").
 *
 * Returns: 0 on success, or -1 in case of error.
 *
 * Deprecated: Use blkid_probe_filter_superblocks_types().
 */
int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
{
	return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
}

/**
 * blkid_probe_filter_usage
 * @pr: prober
 * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
 * @usage: BLKID_USAGE_* flags
 *
 * Returns: 0 on success, or -1 in case of error.
 *
 * Deprecated: Use blkid_probe_filter_superblocks_usage().
 */
int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
{
	return blkid_probe_filter_superblocks_usage(pr, flag, usage);
}


