(root)/
util-linux-2.39/
libblkid/
src/
superblocks/
superblocks.c
       1  /*
       2   * superblocks.c - reads information from filesystem and raid superblocks
       3   *
       4   * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
       5   *
       6   * This file may be redistributed under the terms of the
       7   * GNU Lesser General Public License.
       8   */
       9  
      10  #include <inttypes.h>
      11  #include <stdio.h>
      12  #include <string.h>
      13  #include <stdlib.h>
      14  #include <unistd.h>
      15  #include <fcntl.h>
      16  #include <ctype.h>
      17  #include <sys/types.h>
      18  #include <sys/stat.h>
      19  #include <errno.h>
      20  #include <stdint.h>
      21  #include <stdarg.h>
      22  
      23  #include "superblocks.h"
      24  
      25  /**
      26   * SECTION:superblocks
      27   * @title: Superblocks probing
      28   * @short_description: filesystems and raids superblocks probing.
      29   *
      30   * The library API has been originally designed for superblocks probing only.
      31   * This is reason why some *deprecated* superblock specific functions don't use
      32   * '_superblocks_' namespace in the function name. Please, don't use these
      33   * functions in new code.
      34   *
      35   * The 'superblocks' probers support NAME=value (tags) interface only. The
      36   * superblocks probing is enabled by default (and controlled by
      37   * blkid_probe_enable_superblocks()).
      38   *
      39   * Currently supported tags:
      40   *
      41   * @TYPE: filesystem type
      42   *
      43   * @SEC_TYPE: secondary filesystem type
      44   *
      45   * @LABEL: filesystem label
      46   *
      47   * @LABEL_RAW: raw label from FS superblock
      48   *
      49   * @UUID: filesystem UUID (lower case)
      50   *
      51   * @UUID_SUB: subvolume uuid (e.g. btrfs)
      52   *
      53   * @LOGUUID: external log UUID (e.g. xfs)
      54   *
      55   * @UUID_RAW: raw UUID from FS superblock
      56   *
      57   * @EXT_JOURNAL: external journal UUID
      58   *
      59   * @USAGE:  usage string: "raid", "filesystem", ...
      60   *
      61   * @VERSION: filesystem version
      62   *
      63   * @MOUNT: cluster mount name (?) -- ocfs only
      64   *
      65   * @SBMAGIC: super block magic string
      66   *
      67   * @SBMAGIC_OFFSET: offset of SBMAGIC
      68   *
      69   * @FSSIZE: size of filesystem (implemented for XFS/BTRFS/Ext only)
      70   *
      71   * @FSLASTBLOCK: last fsblock/total number of fsblocks
      72   *
      73   * @FSBLOCKSIZE: file system block size
      74   *
      75   * @SYSTEM_ID: ISO9660 system identifier
      76   *
      77   * @PUBLISHER_ID: ISO9660 publisher identifier
      78   *
      79   * @APPLICATION_ID: ISO9660 application identifier
      80   *
      81   * @BOOT_SYSTEM_ID: ISO9660 boot system identifier
      82   *
      83   * @BLOCK_SIZE: minimal block size accessible by file system
      84   */
      85  
      86  static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn);
      87  static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn);
      88  
      89  static int blkid_probe_set_usage(blkid_probe pr, int usage);
      90  
      91  
      92  /*
      93   * Superblocks chains probing functions
      94   */
      95  static const struct blkid_idinfo *idinfos[] =
      96  {
      97  	/* In case the volume is locked with OPAL we are going to get
      98  	 * an I/O error when reading past the LUKS header, so try it
      99  	 * first. */
     100  	&luks_idinfo,
     101  
     102  	/* RAIDs */
     103  	&linuxraid_idinfo,
     104  	&ddfraid_idinfo,
     105  	&iswraid_idinfo,
     106  	&lsiraid_idinfo,
     107  	&viaraid_idinfo,
     108  	&silraid_idinfo,
     109  	&nvraid_idinfo,
     110  	&pdcraid_idinfo,
     111  	&highpoint45x_idinfo,
     112  	&highpoint37x_idinfo,
     113  	&adraid_idinfo,
     114  	&jmraid_idinfo,
     115  
     116  	&bcache_idinfo,
     117  	&bcachefs_idinfo,
     118  	&bluestore_idinfo,
     119  	&drbd_idinfo,
     120  	&drbdmanage_idinfo,
     121  	&drbdproxy_datalog_idinfo,
     122  	&lvm2_idinfo,
     123  	&lvm1_idinfo,
     124  	&snapcow_idinfo,
     125  	&verity_hash_idinfo,
     126  	&integrity_idinfo,
     127  	&vmfs_volume_idinfo,
     128  	&ubi_idinfo,
     129  	&vdo_idinfo,
     130  	&stratis_idinfo,
     131  	&bitlocker_idinfo,
     132  	&cs_fvault2_idinfo,
     133  
     134  	/* Filesystems */
     135  	&vfat_idinfo,
     136  	&swsuspend_idinfo,
     137  	&swap_idinfo,
     138  	&xfs_idinfo,
     139  	&xfs_log_idinfo,
     140  	&exfs_idinfo,
     141  	&ext4dev_idinfo,
     142  	&ext4_idinfo,
     143  	&ext3_idinfo,
     144  	&ext2_idinfo,
     145  	&jbd_idinfo,
     146  	&reiser_idinfo,
     147  	&reiser4_idinfo,
     148  	&jfs_idinfo,
     149  	&udf_idinfo,
     150  	&iso9660_idinfo,
     151  	&zfs_idinfo,
     152  	&hfsplus_idinfo,
     153  	&hfs_idinfo,
     154  	&ufs_idinfo,
     155  	&hpfs_idinfo,
     156  	&sysv_idinfo,
     157          &xenix_idinfo,
     158  	&ntfs_idinfo,
     159  	&refs_idinfo,
     160  	&cramfs_idinfo,
     161  	&romfs_idinfo,
     162  	&minix_idinfo,
     163  	&gfs_idinfo,
     164  	&gfs2_idinfo,
     165  	&ocfs_idinfo,
     166  	&ocfs2_idinfo,
     167  	&oracleasm_idinfo,
     168  	&vxfs_idinfo,
     169  	&squashfs_idinfo,
     170  	&squashfs3_idinfo,
     171  	&netware_idinfo,
     172  	&btrfs_idinfo,
     173  	&ubifs_idinfo,
     174  	&bfs_idinfo,
     175  	&vmfs_fs_idinfo,
     176  	&befs_idinfo,
     177  	&nilfs2_idinfo,
     178  	&exfat_idinfo,
     179  	&f2fs_idinfo,
     180  	&mpool_idinfo,
     181  	&apfs_idinfo,
     182  	&zonefs_idinfo,
     183  	&erofs_idinfo,
     184  };
     185  
     186  /*
     187   * Driver definition
     188   */
     189  const struct blkid_chaindrv superblocks_drv = {
     190  	.id           = BLKID_CHAIN_SUBLKS,
     191  	.name         = "superblocks",
     192  	.dflt_enabled = TRUE,
     193  	.dflt_flags   = BLKID_SUBLKS_DEFAULT,
     194  	.idinfos      = idinfos,
     195  	.nidinfos     = ARRAY_SIZE(idinfos),
     196  	.has_fltr     = TRUE,
     197  	.probe        = superblocks_probe,
     198  	.safeprobe    = superblocks_safeprobe,
     199  };
     200  
     201  /**
     202   * blkid_probe_enable_superblocks:
     203   * @pr: probe
     204   * @enable: TRUE/FALSE
     205   *
     206   * Enables/disables the superblocks probing for non-binary interface.
     207   *
     208   * Returns: 0 on success, or -1 in case of error.
     209   */
     210  int blkid_probe_enable_superblocks(blkid_probe pr, int enable)
     211  {
     212  	pr->chains[BLKID_CHAIN_SUBLKS].enabled = enable;
     213  	return 0;
     214  }
     215  
     216  /**
     217   * blkid_probe_set_superblocks_flags:
     218   * @pr: prober
     219   * @flags: BLKID_SUBLKS_* flags
     220   *
     221   * Sets probing flags to the superblocks prober. This function is optional, the
     222   * default are BLKID_SUBLKS_DEFAULTS flags.
     223   *
     224   * Returns: 0 on success, or -1 in case of error.
     225   */
     226  int blkid_probe_set_superblocks_flags(blkid_probe pr, int flags)
     227  {
     228  	pr->chains[BLKID_CHAIN_SUBLKS].flags = flags;
     229  	return 0;
     230  }
     231  
     232  /**
     233   * blkid_probe_reset_superblocks_filter:
     234   * @pr: prober
     235   *
     236   * Resets superblocks probing filter
     237   *
     238   * Returns: 0 on success, or -1 in case of error.
     239   */
     240  int blkid_probe_reset_superblocks_filter(blkid_probe pr)
     241  {
     242  	return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
     243  }
     244  
     245  /**
     246   * blkid_probe_invert_superblocks_filter:
     247   * @pr: prober
     248   *
     249   * Inverts superblocks probing filter
     250   *
     251   * Returns: 0 on success, or -1 in case of error.
     252   */
     253  int blkid_probe_invert_superblocks_filter(blkid_probe pr)
     254  {
     255  	return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
     256  }
     257  
     258  /**
     259   * blkid_probe_filter_superblocks_type:
     260   * @pr: prober
     261   * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
     262   * @names: NULL terminated array of probing function names (e.g. "vfat").
     263   *
     264   *  %BLKID_FLTR_NOTIN  - probe for all items which are NOT IN @names;
     265   *
     266   *  %BLKID_FLTR_ONLYIN - probe for items which are IN @names
     267   *
     268   * Returns: 0 on success, or -1 in case of error.
     269   */
     270  int blkid_probe_filter_superblocks_type(blkid_probe pr, int flag, char *names[])
     271  {
     272  	return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
     273  }
     274  
     275  /**
     276   * blkid_probe_filter_superblocks_usage:
     277   * @pr: prober
     278   * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
     279   * @usage: BLKID_USAGE_* flags
     280   *
     281   *  %BLKID_FLTR_NOTIN  - probe for all items which are NOT IN @usage;
     282   *
     283   *  %BLKID_FLTR_ONLYIN - probe for items which are IN @usage
     284   *
     285   * Returns: 0 on success, or -1 in case of error.
     286   */
     287  int blkid_probe_filter_superblocks_usage(blkid_probe pr, int flag, int usage)
     288  {
     289  	unsigned long *fltr;
     290  	struct blkid_chain *chn;
     291  	size_t i;
     292  
     293  	fltr = blkid_probe_get_filter(pr, BLKID_CHAIN_SUBLKS, TRUE);
     294  	if (!fltr)
     295  		return -1;
     296  
     297  	chn = &pr->chains[BLKID_CHAIN_SUBLKS];
     298  
     299  	for (i = 0; i < chn->driver->nidinfos; i++) {
     300  		const struct blkid_idinfo *id = chn->driver->idinfos[i];
     301  
     302  		if (id->usage & usage) {
     303  			if (flag & BLKID_FLTR_NOTIN)
     304  				blkid_bmp_set_item(chn->fltr, i);
     305  		} else if (flag & BLKID_FLTR_ONLYIN)
     306  			blkid_bmp_set_item(chn->fltr, i);
     307  	}
     308  	DBG(LOWPROBE, ul_debug("a new probing usage-filter initialized"));
     309  	return 0;
     310  }
     311  
     312  /**
     313   * blkid_known_fstype:
     314   * @fstype: filesystem name
     315   *
     316   * Returns: 1 for known filesystems, or 0 for unknown filesystem.
     317   */
     318  int blkid_known_fstype(const char *fstype)
     319  {
     320  	size_t i;
     321  
     322  	for (i = 0; i < ARRAY_SIZE(idinfos); i++) {
     323  		const struct blkid_idinfo *id = idinfos[i];
     324  		if (strcmp(id->name, fstype) == 0)
     325  			return 1;
     326  	}
     327  	return 0;
     328  }
     329  
     330  /**
     331   * blkid_superblocks_get_name:
     332   * @idx: number >= 0
     333   * @name: returns name of supported filesystem/raid (optional)
     334   * @usage: returns BLKID_USAGE_* flags, (optional)
     335   *
     336   * Returns: -1 if @idx is out of range, or 0 on success.
     337   */
     338  int blkid_superblocks_get_name(size_t idx, const char **name, int *usage)
     339  {
     340  	if (idx < ARRAY_SIZE(idinfos)) {
     341  		if (name)
     342  			*name = idinfos[idx]->name;
     343  		if (usage)
     344  			*usage = idinfos[idx]->usage;
     345  		return 0;
     346  	}
     347  	return -1;
     348  }
     349  
     350  /*
     351   * The blkid_do_probe() backend.
     352   */
     353  static int superblocks_probe(blkid_probe pr, struct blkid_chain *chn)
     354  {
     355  	size_t i;
     356  	int rc = BLKID_PROBE_NONE;
     357  
     358  	if (chn->idx < -1)
     359  		return -EINVAL;
     360  
     361  	blkid_probe_chain_reset_values(pr, chn);
     362  
     363  	if (pr->flags & BLKID_FL_NOSCAN_DEV) {
     364  		DBG(LOWPROBE, ul_debug("*** ignore (noscan flag)"));
     365  		return BLKID_PROBE_NONE;
     366  	}
     367  
     368  	if (pr->size <= 0 || (pr->size <= 1024 && !S_ISCHR(pr->mode))) {
     369  		/* Ignore very very small block devices or regular files (e.g.
     370  		 * extended partitions). Note that size of the UBI char devices
     371  		 * is 1 byte */
     372  		DBG(LOWPROBE, ul_debug("*** ignore (size <= 1024)"));
     373  		return BLKID_PROBE_NONE;
     374  	}
     375  
     376  	DBG(LOWPROBE, ul_debug("--> starting probing loop [SUBLKS idx=%d]",
     377  		chn->idx));
     378  
     379  	i = chn->idx < 0 ? 0 : chn->idx + 1U;
     380  
     381  	for ( ; i < ARRAY_SIZE(idinfos); i++) {
     382  		const struct blkid_idinfo *id;
     383  		const struct blkid_idmag *mag = NULL;
     384  		uint64_t off = 0;
     385  
     386  		chn->idx = i;
     387  		id = idinfos[i];
     388  
     389  		if (chn->fltr && blkid_bmp_get_item(chn->fltr, i)) {
     390  			DBG(LOWPROBE, ul_debug("filter out: %s", id->name));
     391  			rc = BLKID_PROBE_NONE;
     392  			continue;
     393  		}
     394  
     395  		if (id->minsz && (unsigned)id->minsz > pr->size) {
     396  			rc = BLKID_PROBE_NONE;
     397  			continue;	/* the device is too small */
     398  		}
     399  
     400  		/* don't probe for RAIDs, swap or journal on CD/DVDs */
     401  		if ((id->usage & (BLKID_USAGE_RAID | BLKID_USAGE_OTHER)) &&
     402  		    blkid_probe_is_cdrom(pr)) {
     403  			rc = BLKID_PROBE_NONE;
     404  			continue;
     405  		}
     406  
     407  		/* don't probe for RAIDs on floppies */
     408  		if ((id->usage & BLKID_USAGE_RAID) && blkid_probe_is_tiny(pr)) {
     409  			rc = BLKID_PROBE_NONE;
     410  			continue;
     411  		}
     412  
     413  		DBG(LOWPROBE, ul_debug("[%zd] %s:", i, id->name));
     414  
     415  		rc = blkid_probe_get_idmag(pr, id, &off, &mag);
     416  		if (rc < 0)
     417  			break;
     418  		if (rc != BLKID_PROBE_OK)
     419  			continue;
     420  
     421  		/* final check by probing function */
     422  		if (id->probefunc) {
     423  			DBG(LOWPROBE, ul_debug("\tcall probefunc()"));
     424  			rc = id->probefunc(pr, mag);
     425  			if (rc != BLKID_PROBE_OK) {
     426  				blkid_probe_chain_reset_values(pr, chn);
     427  				if (rc < 0)
     428  					break;
     429  				continue;
     430  			}
     431  		}
     432  
     433  		/* all checks passed */
     434  		if (chn->flags & BLKID_SUBLKS_TYPE)
     435  			rc = blkid_probe_set_value(pr, "TYPE",
     436  				(const unsigned char *) id->name,
     437  				strlen(id->name) + 1);
     438  
     439  		if (!rc)
     440  			rc = blkid_probe_set_usage(pr, id->usage);
     441  
     442  		if (!rc && mag)
     443  			rc = blkid_probe_set_magic(pr, off, mag->len,
     444  					(const unsigned char *) mag->magic);
     445  		if (rc) {
     446  			blkid_probe_chain_reset_values(pr, chn);
     447  			DBG(LOWPROBE, ul_debug("failed to set result -- ignore"));
     448  			continue;
     449  		}
     450  
     451  		DBG(LOWPROBE, ul_debug("<-- leaving probing loop (type=%s) [SUBLKS idx=%d]",
     452  			id->name, chn->idx));
     453  		return BLKID_PROBE_OK;
     454  	}
     455  
     456  	DBG(LOWPROBE, ul_debug("<-- leaving probing loop (failed=%d) [SUBLKS idx=%d]",
     457  			rc, chn->idx));
     458  	return rc;
     459  }
     460  
     461  /*
     462   * This is the same function as blkid_do_probe(), but returns only one result
     463   * (cannot be used in while()) and checks for ambivalent results (more
     464   * filesystems on the device) -- in such case returns -2.
     465   *
     466   * The function does not check for filesystems when a RAID or crypto signature
     467   * is detected.  The function also does not check for collision between RAIDs
     468   * and crypto devices. The first detected RAID or crypto device is returned.
     469   *
     470   * The function does not probe for ambivalent results on very small devices
     471   * (e.g. floppies), on small devices the first detected filesystem is returned.
     472   */
     473  static int superblocks_safeprobe(blkid_probe pr, struct blkid_chain *chn)
     474  {
     475  	struct list_head vals;
     476  	int idx = -1;
     477  	int count = 0;
     478  	int intol = 0;
     479  	int rc;
     480  
     481  	INIT_LIST_HEAD(&vals);
     482  
     483  	if (pr->flags & BLKID_FL_NOSCAN_DEV)
     484  		return BLKID_PROBE_NONE;
     485  
     486  	while ((rc = superblocks_probe(pr, chn)) == 0) {
     487  
     488  		if (blkid_probe_is_tiny(pr) && !count)
     489  			return BLKID_PROBE_OK;	/* floppy or so -- returns the first result. */
     490  
     491  		count++;
     492  
     493  		if (chn->idx >= 0 &&
     494  		    idinfos[chn->idx]->usage & (BLKID_USAGE_RAID | BLKID_USAGE_CRYPTO))
     495  			break;
     496  
     497  		if (chn->idx >= 0 &&
     498  		    !(idinfos[chn->idx]->flags & BLKID_IDINFO_TOLERANT))
     499  			intol++;
     500  
     501  		if (count == 1) {
     502  			/* save the first result */
     503  			blkid_probe_chain_save_values(pr, chn, &vals);
     504  			idx = chn->idx;
     505  		}
     506  	}
     507  
     508  	if (rc < 0)
     509  		goto done;		/* error */
     510  
     511  	if (count > 1 && intol) {
     512  		DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
     513  			       "ambivalent result detected (%d filesystems)!",
     514  			       count));
     515  		rc = BLKID_PROBE_AMBIGUOUS;	/* error, ambivalent result (more FS) */
     516  		goto done;
     517  	}
     518  	if (!count) {
     519  		rc = BLKID_PROBE_NONE;
     520  		goto done;
     521  	}
     522  
     523  	if (idx != -1) {
     524  		/* restore the first result */
     525  		blkid_probe_chain_reset_values(pr, chn);
     526  		blkid_probe_append_values_list(pr, &vals);
     527  		chn->idx = idx;
     528  	}
     529  
     530  	/*
     531  	 * The RAID device could be partitioned. The problem are RAID1 devices
     532  	 * where the partition table is visible from underlying devices. We
     533  	 * have to ignore such partition tables.
     534  	 */
     535  	if (chn->idx >= 0 && idinfos[chn->idx]->usage & BLKID_USAGE_RAID)
     536  		pr->prob_flags |= BLKID_PROBE_FL_IGNORE_PT;
     537  
     538  	rc = BLKID_PROBE_OK;
     539  done:
     540  	blkid_probe_free_values_list(&vals);
     541  	return rc;
     542  }
     543  
     544  int blkid_probe_set_version(blkid_probe pr, const char *version)
     545  {
     546  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     547  
     548  	if (chn->flags & BLKID_SUBLKS_VERSION)
     549  		return blkid_probe_set_value(pr, "VERSION",
     550  				(const unsigned char *) version,
     551  				strlen(version) + 1);
     552  	return 0;
     553  }
     554  
     555  
     556  int blkid_probe_sprintf_version(blkid_probe pr, const char *fmt, ...)
     557  {
     558  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     559  	int rc = 0;
     560  
     561  	if (chn->flags & BLKID_SUBLKS_VERSION) {
     562  		va_list ap;
     563  
     564  		va_start(ap, fmt);
     565  		rc = blkid_probe_vsprintf_value(pr, "VERSION", fmt, ap);
     566  		va_end(ap);
     567  	}
     568  	return rc;
     569  }
     570  
     571  int blkid_probe_set_block_size(blkid_probe pr, unsigned block_size)
     572  {
     573  	return blkid_probe_sprintf_value(pr, "BLOCK_SIZE", "%u", block_size);
     574  }
     575  
     576  static int blkid_probe_set_usage(blkid_probe pr, int usage)
     577  {
     578  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     579  	const char *u = NULL;
     580  
     581  	if (!(chn->flags & BLKID_SUBLKS_USAGE))
     582  		return 0;
     583  
     584  	if (usage & BLKID_USAGE_FILESYSTEM)
     585  		u = "filesystem";
     586  	else if (usage & BLKID_USAGE_RAID)
     587  		u = "raid";
     588  	else if (usage & BLKID_USAGE_CRYPTO)
     589  		u = "crypto";
     590  	else if (usage & BLKID_USAGE_OTHER)
     591  		u = "other";
     592  	else
     593  		u = "unknown";
     594  
     595  	return blkid_probe_set_value(pr, "USAGE",
     596  			(const unsigned char *) u, strlen(u) + 1);
     597  }
     598  
     599  int blkid_probe_set_fssize(blkid_probe pr, uint64_t size)
     600  {
     601  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     602  
     603  	if (!(chn->flags & BLKID_SUBLKS_FSINFO))
     604  		return 0;
     605  
     606  	return blkid_probe_sprintf_value(pr, "FSSIZE", "%" PRIu64, size);
     607  }
     608  
     609  int blkid_probe_set_fslastblock(blkid_probe pr, uint64_t lastblock)
     610  {
     611  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     612  
     613  	if (!(chn->flags & BLKID_SUBLKS_FSINFO))
     614  		return 0;
     615  
     616  	return blkid_probe_sprintf_value(pr, "FSLASTBLOCK", "%" PRIu64,
     617  			lastblock);
     618  }
     619  
     620  int blkid_probe_set_fsblocksize(blkid_probe pr, uint32_t block_size)
     621  {
     622  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     623  
     624  	if (!(chn->flags & BLKID_SUBLKS_FSINFO))
     625  		return 0;
     626  
     627  	return blkid_probe_sprintf_value(pr, "FSBLOCKSIZE", "%" PRIu32,
     628  			block_size);
     629  }
     630  
     631  int blkid_probe_set_fsendianness(blkid_probe pr, enum BLKID_ENDIANNESS endianness)
     632  {
     633  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     634  	const char *value;
     635  
     636  	if (!(chn->flags & BLKID_SUBLKS_FSINFO))
     637  		return 0;
     638  
     639  	switch (endianness) {
     640  		case BLKID_ENDIANNESS_LITTLE:
     641  			value = "LITTLE";
     642  			break;
     643  		case BLKID_ENDIANNESS_BIG:
     644  			value = "BIG";
     645  			break;
     646  		default:
     647  			return -EINVAL;
     648  	}
     649  
     650  	return blkid_probe_set_value(pr, "ENDIANNESS",
     651  			(const unsigned char *) value, strlen(value) + 1);
     652  
     653  }
     654  
     655  int blkid_probe_set_id_label(blkid_probe pr, const char *name,
     656  			     const unsigned char *data, size_t len)
     657  {
     658  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     659  	struct blkid_prval *v;
     660  	int rc = 0;
     661  
     662  	if (!(chn->flags & BLKID_SUBLKS_LABEL))
     663  		return 0;
     664  
     665  	v = blkid_probe_assign_value(pr, name);
     666  	if (!v)
     667  		return -ENOMEM;
     668  
     669  	rc = blkid_probe_value_set_data(v, data, len);
     670  	if (!rc) {
     671  		/* remove white spaces */
     672  		v->len = blkid_rtrim_whitespace(v->data) + 1;
     673  		if (v->len > 1)
     674  			v->len = blkid_ltrim_whitespace(v->data) + 1;
     675  		if (v->len > 1)
     676  			return 0;
     677  	}
     678  
     679  	blkid_probe_free_value(v);
     680  	return rc;
     681  
     682  }
     683  
     684  int blkid_probe_set_utf8_id_label(blkid_probe pr, const char *name,
     685  			     const unsigned char *data, size_t len, int enc)
     686  {
     687  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     688  	struct blkid_prval *v;
     689  	int rc = 0;
     690  
     691  	if (!(chn->flags & BLKID_SUBLKS_LABEL))
     692  		return 0;
     693  
     694  	v = blkid_probe_assign_value(pr, name);
     695  	if (!v)
     696  		return -ENOMEM;
     697  
     698  	v->len = (len * 3) + 1;
     699  	v->data = calloc(1, v->len);
     700  	if (!v->data)
     701  		rc = -ENOMEM;
     702  
     703  	if (!rc) {
     704  		ul_encode_to_utf8(enc, v->data, v->len, data, len);
     705  		v->len = blkid_rtrim_whitespace(v->data) + 1;
     706  		if (v->len > 1)
     707  			v->len = blkid_ltrim_whitespace(v->data) + 1;
     708  		if (v->len > 1)
     709  			return 0;
     710  	}
     711  
     712  	blkid_probe_free_value(v);
     713  	return rc;
     714  }
     715  
     716  int blkid_probe_set_label(blkid_probe pr, const unsigned char *label, size_t len)
     717  {
     718  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     719  	struct blkid_prval *v;
     720  	int rc = 0;
     721  
     722  	if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
     723  	    (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
     724  		return rc;
     725  
     726  	if (!(chn->flags & BLKID_SUBLKS_LABEL))
     727  		return 0;
     728  
     729  	v = blkid_probe_assign_value(pr, "LABEL");
     730  	if (!v)
     731  		return -ENOMEM;
     732  
     733  	rc = blkid_probe_value_set_data(v, label, len);
     734  	if (!rc) {
     735  		v->len = blkid_rtrim_whitespace(v->data) + 1;
     736  		if (v->len > 1)
     737  			return 0;
     738  	}
     739  
     740  	blkid_probe_free_value(v);
     741  	return rc;
     742  }
     743  
     744  int blkid_probe_set_utf8label(blkid_probe pr, const unsigned char *label,
     745  				size_t len, int enc)
     746  {
     747  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     748  	struct blkid_prval *v;
     749  	int rc = 0;
     750  
     751  	if ((chn->flags & BLKID_SUBLKS_LABELRAW) &&
     752  	    (rc = blkid_probe_set_value(pr, "LABEL_RAW", label, len)) < 0)
     753  		return rc;
     754  
     755  	if (!(chn->flags & BLKID_SUBLKS_LABEL))
     756  		return 0;
     757  
     758  	v = blkid_probe_assign_value(pr, "LABEL");
     759  	if (!v)
     760  		return -ENOMEM;
     761  
     762  	v->len = (len * 3) + 1;
     763  	v->data = calloc(1, v->len);
     764  	if (!v->data)
     765  		rc = -ENOMEM;
     766  	if (!rc) {
     767  		ul_encode_to_utf8(enc, v->data, v->len, label, len);
     768  		v->len = blkid_rtrim_whitespace(v->data) + 1;
     769  		if (v->len > 1)
     770  			return 0;
     771  	}
     772  
     773  	blkid_probe_free_value(v);
     774  	return rc;
     775  }
     776  
     777  int blkid_probe_sprintf_uuid(blkid_probe pr, const unsigned char *uuid,
     778  				size_t len, const char *fmt, ...)
     779  {
     780  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     781  	va_list ap;
     782  	int rc = 0;
     783  
     784  	if (blkid_uuid_is_empty(uuid, len))
     785  		return 0;
     786  
     787  	if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
     788  	    (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, len)) < 0)
     789  		return rc;
     790  
     791  	if (!(chn->flags & BLKID_SUBLKS_UUID))
     792  		return 0;
     793  
     794  	va_start(ap, fmt);
     795  	rc = blkid_probe_vsprintf_value(pr, "UUID", fmt, ap);
     796  	va_end(ap);
     797  
     798  	return rc;
     799  }
     800  
     801  /* function to set UUIDs that are in superblocks stored as strings */
     802  int blkid_probe_strncpy_uuid(blkid_probe pr, const unsigned char *str, size_t len)
     803  {
     804  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     805  	struct blkid_prval *v;
     806  	int rc = 0;
     807  
     808  	if (str == NULL || *str == '\0')
     809  		return -EINVAL;
     810  
     811  	if (!len)
     812  		len = strlen((const char *) str);
     813  
     814  	if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
     815  	    (rc = blkid_probe_set_value(pr, "UUID_RAW", str, len)) < 0)
     816  		return rc;
     817  
     818  	if (!(chn->flags & BLKID_SUBLKS_UUID))
     819  		return 0;
     820  
     821  	v = blkid_probe_assign_value(pr, "UUID");
     822  	if (!v)
     823  		rc= -ENOMEM;
     824  	if (!rc)
     825  		rc = blkid_probe_value_set_data(v, str, len);
     826  	if (!rc) {
     827  		v->len = blkid_rtrim_whitespace(v->data) + 1;
     828  		if (v->len > 1)
     829  			return 0;
     830  	}
     831  
     832  	blkid_probe_free_value(v);
     833  	return rc;
     834  }
     835  
     836  /* default _set_uuid function to set DCE UUIDs */
     837  int blkid_probe_set_uuid_as(blkid_probe pr, const unsigned char *uuid, const char *name)
     838  {
     839  	struct blkid_chain *chn = blkid_probe_get_chain(pr);
     840  	struct blkid_prval *v;
     841  	int rc = 0;
     842  
     843  	if (blkid_uuid_is_empty(uuid, 16))
     844  		return 0;
     845  
     846  	if (!name) {
     847  		if ((chn->flags & BLKID_SUBLKS_UUIDRAW) &&
     848  		    (rc = blkid_probe_set_value(pr, "UUID_RAW", uuid, 16)) < 0)
     849  			return rc;
     850  
     851  		if (!(chn->flags & BLKID_SUBLKS_UUID))
     852  			return 0;
     853  
     854  		v = blkid_probe_assign_value(pr, "UUID");
     855  	} else
     856  		v = blkid_probe_assign_value(pr, name);
     857  
     858  	if (!v)
     859  		return -ENOMEM;
     860  
     861  	v->len = UUID_STR_LEN;
     862  	v->data = calloc(1, v->len);
     863  	if (!v->data)
     864  		rc = -ENOMEM;
     865  
     866  	if (!rc) {
     867  		blkid_unparse_uuid(uuid, (char *) v->data, v->len);
     868  		return 0;
     869  	}
     870  
     871  	blkid_probe_free_value(v);
     872  	return rc;
     873  }
     874  
     875  int blkid_probe_set_uuid(blkid_probe pr, const unsigned char *uuid)
     876  {
     877  	return blkid_probe_set_uuid_as(pr, uuid, NULL);
     878  }
     879  
     880  /**
     881   * blkid_probe_set_request:
     882   * @pr: probe
     883   * @flags: BLKID_PROBREQ_* (deprecated) or BLKID_SUBLKS_* flags
     884   *
     885   * Returns: 0 on success, or -1 in case of error.
     886   *
     887   * Deprecated: Use blkid_probe_set_superblocks_flags().
     888   */
     889  int blkid_probe_set_request(blkid_probe pr, int flags)
     890  {
     891  	return blkid_probe_set_superblocks_flags(pr, flags);
     892  }
     893  
     894  /**
     895   * blkid_probe_reset_filter:
     896   * @pr: prober
     897   *
     898   * Returns: 0 on success, or -1 in case of error.
     899   *
     900   * Deprecated: Use blkid_probe_reset_superblocks_filter().
     901   */
     902  int blkid_probe_reset_filter(blkid_probe pr)
     903  {
     904  	return __blkid_probe_reset_filter(pr, BLKID_CHAIN_SUBLKS);
     905  }
     906  
     907  /**
     908   * blkid_probe_invert_filter:
     909   * @pr: prober
     910   *
     911   * Returns: 0 on success, or -1 in case of error.
     912   *
     913   * Deprecated: Use blkid_probe_invert_superblocks_filter().
     914   */
     915  int blkid_probe_invert_filter(blkid_probe pr)
     916  {
     917  	return __blkid_probe_invert_filter(pr, BLKID_CHAIN_SUBLKS);
     918  }
     919  
     920  /**
     921   * blkid_probe_filter_types
     922   * @pr: prober
     923   * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
     924   * @names: NULL terminated array of probing function names (e.g. "vfat").
     925   *
     926   * Returns: 0 on success, or -1 in case of error.
     927   *
     928   * Deprecated: Use blkid_probe_filter_superblocks_type().
     929   */
     930  int blkid_probe_filter_types(blkid_probe pr, int flag, char *names[])
     931  {
     932  	return __blkid_probe_filter_types(pr, BLKID_CHAIN_SUBLKS, flag, names);
     933  }
     934  
     935  /**
     936   * blkid_probe_filter_usage
     937   * @pr: prober
     938   * @flag: filter BLKID_FLTR_{NOTIN,ONLYIN} flag
     939   * @usage: BLKID_USAGE_* flags
     940   *
     941   * Returns: 0 on success, or -1 in case of error.
     942   *
     943   * Deprecated: Use blkid_probe_filter_superblocks_usage().
     944   */
     945  int blkid_probe_filter_usage(blkid_probe pr, int flag, int usage)
     946  {
     947  	return blkid_probe_filter_superblocks_usage(pr, flag, usage);
     948  }
     949  
     950