/* * 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; }
/* * 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; }