예제 #1
0
/*
 * 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 list_head vals;
	int idx = -1;
	int count = 0;
	int intol = 0;
	int rc;

	INIT_LIST_HEAD(&vals);

	if (pr->flags & BLKID_FL_NOSCAN_DEV)
		return BLKID_PROBE_NONE;

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

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

		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 */
			blkid_probe_chain_save_values(pr, chn, &vals);
			idx = chn->idx;
		}
	}

	if (rc < 0)
		goto done;		/* error */

	if (count > 1 && intol) {
		DBG(LOWPROBE, ul_debug("ERROR: superblocks chain: "
			       "ambivalent result detected (%d filesystems)!",
			       count));
		rc = -2;		/* error, ambivalent result (more FS) */
		goto done;
	}
	if (!count) {
		rc = BLKID_PROBE_NONE;
		goto done;
	}

	if (idx != -1) {
		/* restore the first result */
		blkid_probe_chain_reset_values(pr, chn);
		blkid_probe_append_values_list(pr, &vals);
		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;

	rc = BLKID_PROBE_OK;
done:
	blkid_probe_free_values_list(&vals);
	return rc;
}
예제 #2
0
/*
 * 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(LOWPROBE, ul_debug("ERROR: superblocks chain: "
			       "ambivalent result detected (%d filesystems)!",
			       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;
}