119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * probe.c - identify a block device by its contents, and return a dev
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *           struct with the details
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1999 by Andries Brouwer
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2001 by Andreas Dilger
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header%
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * GNU Lesser General Public License.
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header%
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h>
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h>
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h>
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h>
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SYS_STAT_H
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/stat.h>
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SYS_MKDEV_H
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/mkdev.h>
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef __linux__
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/utsname.h>
313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h>
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "blkidP.h"
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "uuid/uuid.h"
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "probe.h"
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int figure_label_len(const unsigned char *label, int len)
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const unsigned char *end = label + len - 1;
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while ((*end == ' ' || *end == 0) && end >= label)
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		--end;
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (end >= label) {
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = label;
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return end - label + 1;
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic unsigned char *get_buffer(struct blkid_probe *pr,
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  blkid_loff_t off, size_t len)
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ssize_t		ret_read;
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned char	*newbuf;
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (off + len <= SB_BUFFER_SIZE) {
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!pr->sbbuf) {
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			pr->sbbuf = malloc(SB_BUFFER_SIZE);
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!pr->sbbuf)
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				return NULL;
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (lseek(pr->fd, 0, SEEK_SET) < 0)
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				return NULL;
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ret_read = read(pr->fd, pr->sbbuf, SB_BUFFER_SIZE);
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ret_read < 0)
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ret_read = 0;
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			pr->sb_valid = ret_read;
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (off+len > pr->sb_valid)
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return NULL;
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return pr->sbbuf + off;
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (len > pr->buf_max) {
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			newbuf = realloc(pr->buf, len);
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (newbuf == NULL)
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				return NULL;
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			pr->buf = newbuf;
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			pr->buf_max = len;
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (blkid_llseek(pr->fd, off, SEEK_SET) < 0)
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return NULL;
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ret_read = read(pr->fd, pr->buf, len);
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ret_read != (ssize_t) len)
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return NULL;
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return pr->buf;
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This is a special case code to check for an MDRAID device.  We do
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * this special since it requires checking for a superblock at the end
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * of the device.
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_mdraid(int fd, unsigned char *ret_uuid)
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct mdp_superblock_s *md;
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_loff_t		offset;
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char			buf[4096];
1013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fd < 0)
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536;
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_llseek(fd, offset, 0) < 0 ||
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    read(fd, buf, 4096) != 4096)
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_IO;
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Check for magic number */
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (memcmp("\251+N\374", buf, 4) && memcmp("\374N+\251", buf, 4))
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ret_uuid)
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	*ret_uuid = 0;
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* The MD UUID is not contiguous in the superblock, make it so */
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	md = (struct mdp_superblock_s *)buf;
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) {
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		memcpy(ret_uuid, &md->set_uuid0, 4);
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		memcpy(ret_uuid + 4, &md->set_uuid1, 12);
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void set_uuid(blkid_dev dev, uuid_t uuid, const char *tag)
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	str[37];
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!uuid_is_null(uuid)) {
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		uuid_unparse(uuid, str);
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(dev, tag ? tag : "UUID", str, sizeof(str));
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void get_ext2_info(blkid_dev dev, struct blkid_magic *id,
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  unsigned char *buf)
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *es = (struct ext2_super_block *) buf;
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n",
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   blkid_le32(es->s_feature_compat),
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   blkid_le32(es->s_feature_incompat),
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   blkid_le32(es->s_feature_ro_compat)));
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strlen(es->s_volume_name))
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = es->s_volume_name;
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name));
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	set_uuid(dev, es->s_uuid, 0);
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((es->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !uuid_is_null(es->s_journal_uuid))
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		set_uuid(dev, es->s_journal_uuid, "EXT_JOURNAL");
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strcmp(id->bim_type, "ext2") &&
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    ((blkid_le32(es->s_feature_incompat) &
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0))
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(dev, "SEC_TYPE", "ext2", sizeof("ext2"));
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to see if a filesystem is in /proc/filesystems.
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Returns 1 if found, 0 if not
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int fs_proc_check(const char *fs_name)
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	FILE	*f;
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	buf[80], *cp, *t;
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	f = fopen("/proc/filesystems", "r");
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!f)
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return (0);
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (!feof(f)) {
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!fgets(buf, sizeof(buf), f))
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp = buf;
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!isspace(*cp)) {
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			while (*cp && !isspace(*cp))
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				cp++;
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (*cp && isspace(*cp))
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp++;
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((t = strchr(cp, '\n')) != NULL)
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*t = 0;
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((t = strchr(cp, '\t')) != NULL)
19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*t = 0;
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((t = strchr(cp, ' ')) != NULL)
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*t = 0;
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!strcmp(fs_name, cp)) {
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fclose(f);
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return (1);
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fclose(f);
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return (0);
20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Check to see if a filesystem is available as a module
20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Returns 1 if found, 0 if not
20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int check_for_modules(const char *fs_name)
20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
2083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef __linux__
20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct utsname	uts;
21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	FILE		*f;
2113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char		buf[1024], *cp;
2123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int		namesz;
21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (uname(&uts))
21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return (0);
21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release);
21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	f = fopen(buf, "r");
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!f)
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return (0);
2213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	namesz = strlen(fs_name);
2233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (!feof(f)) {
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!fgets(buf, sizeof(buf), f))
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((cp = strchr(buf, ':')) != NULL)
22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*cp = 0;
22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else
23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((cp = strrchr(buf, '/')) != NULL)
23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			cp++;
2333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		else
2343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			cp = buf;
2353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strncmp(cp, fs_name, namesz) &&
2363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		    (!strcmp(cp + namesz, ".ko") ||
2373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		     !strcmp(cp + namesz, ".ko.gz"))) {
2383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fclose(f);
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return (1);
2403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fclose(f);
2433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return (0);
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int linux_version_code()
2483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
2493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef __linux__
2503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct utsname	ut;
2513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static		version_code = -1;
2523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int		major, minor, rev;
2533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char		*endptr;
2543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const char 	*cp;
2553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (version_code > 0)
2573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return version_code;
2583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (uname(&ut))
2603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
2613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	cp = ut.release;
2623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	major = strtol(cp, &endptr, 10);
2643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (cp == endptr || *endptr != '.')
2653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
2663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	cp = endptr + 1;
2673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	minor = strtol(cp, &endptr, 10);
2683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (cp == endptr || *endptr != '.')
2693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
2703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	cp = endptr + 1;
2713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	rev = strtol(cp, &endptr, 10);
2723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (cp == endptr)
2733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
2743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	version_code = (((major * 256) + minor) * 256) + rev;
2753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return version_code;
2763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#else
2773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
2783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
2793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
2803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define EXT4_SUPPORTS_EXT2 (2 * 65536 + 6*256 + 29)
2823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int system_supports_ext2(void)
2843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
2853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static time_t	last_check = 0;
2863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static int	ret = -1;
2873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	time_t		now = time(0);
2883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
2893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ret != -1 || (now - last_check) < 5)
2903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return ret;
2913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	last_check = now;
2923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	ret = (fs_proc_check("ext2") || check_for_modules("ext2"));
2933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return ret;
2943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
2953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int system_supports_ext4(void)
29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static time_t	last_check = 0;
29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static int	ret = -1;
30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	time_t		now = time(0);
30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ret != -1 || (now - last_check) < 5)
30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return ret;
30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	last_check = now;
30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ret = (fs_proc_check("ext4") || check_for_modules("ext4"));
30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ret;
30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int system_supports_ext4dev(void)
31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static time_t	last_check = 0;
31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static int	ret = -1;
31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	time_t		now = time(0);
31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ret != -1 || (now - last_check) < 5)
31619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return ret;
31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	last_check = now;
31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ret = (fs_proc_check("ext4dev") || check_for_modules("ext4dev"));
31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ret;
32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ext4dev(struct blkid_probe *probe,
32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 struct blkid_magic *id,
32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 unsigned char *buf)
32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *es;
32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	es = (struct ext2_super_block *)buf;
32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Distinguish from jbd */
33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_le32(es->s_feature_incompat) &
33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/*
3353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * If the filesystem does not have a journal and ext2 and ext4
3363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * is not present, then force this to be detected as an
3373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * ext4dev filesystem.
3383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 */
33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(blkid_le32(es->s_feature_compat) &
3403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	      EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
3413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    !system_supports_ext2() && !system_supports_ext4() &&
3423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    system_supports_ext4dev() &&
3433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    linux_version_code() >= EXT4_SUPPORTS_EXT2)
3443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		goto force_ext4dev;
34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If the filesystem is marked as OK for use by in-development
34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * filesystem code, but ext4dev is not supported, and ext4 is,
34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * then don't call ourselves ext4dev, since we should be
35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * detected as ext4 in that case.
35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 *
35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If the filesystem is marked as in use by production
35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * filesystem, then it can only be used by ext4 and NOT by
35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * ext4dev, so always disclaim we are ext4dev in that case.
35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_le32(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) {
35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!system_supports_ext4dev() && system_supports_ext4())
35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return -BLKID_ERR_PARAM;
35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else
36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtforce_ext4dev:
36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    	get_ext2_info(probe->dev, id, buf);
36419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ext4(struct blkid_probe *probe, struct blkid_magic *id,
36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned char *buf)
36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *es;
37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	es = (struct ext2_super_block *)buf;
37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Distinguish from jbd */
3743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (blkid_le32(es->s_feature_incompat) &
37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/*
3793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * If the filesystem does not have a journal and ext2 is not
3803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * present, then force this to be detected as an ext2
3813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * filesystem.
3823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 */
38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(blkid_le32(es->s_feature_compat) &
3843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	      EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
3853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    !system_supports_ext2() && system_supports_ext4() &&
3863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    linux_version_code() >= EXT4_SUPPORTS_EXT2)
3873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		goto force_ext4;
38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Ext4 has at least one feature which ext3 doesn't understand */
39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(blkid_le32(es->s_feature_ro_compat) &
39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) &&
39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !(blkid_le32(es->s_feature_incompat) &
39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtforce_ext4:
39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If the filesystem is a OK for use by in-development
39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * filesystem code, and ext4dev is supported or ext4 is not
40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * supported, then don't call ourselves ext4, so we can redo
40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * the detection and mark the filesystem as ext4dev.
40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 *
40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If the filesystem is marked as in use by production
40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * filesystem, then it can only be used by ext4 and NOT by
40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * ext4dev.
40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_le32(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) {
40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (system_supports_ext4dev() || !system_supports_ext4())
40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return -BLKID_ERR_PARAM;
41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    	get_ext2_info(probe->dev, id, buf);
41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ext3(struct blkid_probe *probe, struct blkid_magic *id,
41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned char *buf)
41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *es;
41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	es = (struct ext2_super_block *)buf;
42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* ext3 requires journal */
42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(blkid_le32(es->s_feature_compat) &
42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Any features which ext3 doesn't understand */
42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((blkid_le32(es->s_feature_ro_compat) &
42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) ||
42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (blkid_le32(es->s_feature_incompat) &
43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     EXT3_FEATURE_INCOMPAT_UNSUPPORTED))
43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
43219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    	get_ext2_info(probe->dev, id, buf);
43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ext2(struct blkid_probe *probe, struct blkid_magic *id,
43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned char *buf)
43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *es;
44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	es = (struct ext2_super_block *)buf;
44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Distinguish between ext3 and ext2 */
44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((blkid_le32(es->s_feature_compat) &
44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Any features which ext2 doesn't understand */
45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((blkid_le32(es->s_feature_ro_compat) &
45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) ||
45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (blkid_le32(es->s_feature_incompat) &
45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     EXT2_FEATURE_INCOMPAT_UNSUPPORTED))
45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/*
4573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * If ext2 is not present, but ext4 or ext4dev are, then
4583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * disclaim we are ext2
4593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 */
4603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!system_supports_ext2() &&
4613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (system_supports_ext4() || system_supports_ext4dev()) &&
4623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    linux_version_code() >= EXT4_SUPPORTS_EXT2)
4633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return -BLKID_ERR_PARAM;
4643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
46519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	get_ext2_info(probe->dev, id, buf);
46619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
46719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
46819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
46919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_jbd(struct blkid_probe *probe, struct blkid_magic *id,
47019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     unsigned char *buf)
47119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
47219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *es = (struct ext2_super_block *) buf;
47319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
47419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(blkid_le32(es->s_feature_incompat) &
47519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
47619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
47719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
47819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	get_ext2_info(probe->dev, id, buf);
47919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
48019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
48119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
48219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
48319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define FAT_ATTR_VOLUME_ID		0x08
48419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define FAT_ATTR_DIR			0x10
48519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define FAT_ATTR_LONG_NAME		0x0f
48619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define FAT_ATTR_MASK			0x3f
48719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define FAT_ENTRY_FREE			0xe5
48819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
48919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char *no_name = "NO NAME    ";
49019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
49119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned char *search_fat_label(struct vfat_dir_entry *dir, int count)
49219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
49319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int i;
49419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
49519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (i = 0; i < count; i++) {
49619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (dir[i].name[0] == 0x00)
49719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
4983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
49919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((dir[i].name[0] == FAT_ENTRY_FREE) ||
50019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (dir[i].cluster_high != 0 || dir[i].cluster_low != 0) ||
50119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    ((dir[i].attr & FAT_ATTR_MASK) == FAT_ATTR_LONG_NAME))
50219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
50319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) ==
50519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    FAT_ATTR_VOLUME_ID) {
50619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return dir[i].name;
50719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
50819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
50919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
51019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
51119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
51219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* FAT label extraction from the root directory taken from Kay
51319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Sievers's volume_id library */
51419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_fat(struct blkid_probe *probe,
5153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		      struct blkid_magic *id __BLKID_ATTR((unused)),
51619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned char *buf)
51719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
51819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct vfat_super_block *vs = (struct vfat_super_block *) buf;
51919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct msdos_super_block *ms = (struct msdos_super_block *) buf;
52019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct vfat_dir_entry *dir;
52119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char serno[10];
52219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const unsigned char *label = 0, *vol_label = 0, *tmp;
52319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned char	*vol_serno;
52419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int label_len = 0, maxloop = 100;
52519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	__u16 sector_size, dir_entries, reserved;
52619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	__u32 sect_count, fat_size, dir_size, cluster_count, fat_length;
52719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	__u32 buf_size, start_data_sect, next, root_start, root_dir_entries;
52819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
52919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* sector size check */
53019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp = (unsigned char *)&ms->ms_sector_size;
53119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sector_size = tmp[0] + (tmp[1] << 8);
53219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sector_size != 0x200 && sector_size != 0x400 &&
53319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    sector_size != 0x800 && sector_size != 0x1000)
53419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
53519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
53619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp = (unsigned char *)&ms->ms_dir_entries;
53719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dir_entries = tmp[0] + (tmp[1] << 8);
53819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	reserved =  blkid_le16(ms->ms_reserved);
53919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp = (unsigned char *)&ms->ms_sectors;
54019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sect_count = tmp[0] + (tmp[1] << 8);
54119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sect_count == 0)
54219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sect_count = blkid_le32(ms->ms_total_sect);
54319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
54419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fat_length = blkid_le16(ms->ms_fat_length);
54519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fat_length == 0)
54619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fat_length = blkid_le32(vs->vs_fat32_length);
54719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
54819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fat_size = fat_length * ms->ms_fats;
54919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
55019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			(sector_size-1)) / sector_size;
55119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
55219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	cluster_count = sect_count - (reserved + fat_size + dir_size);
55319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ms->ms_cluster_size == 0)
55419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
55519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	cluster_count /= ms->ms_cluster_size;
55619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
55719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (cluster_count > FAT32_MAX)
55819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
55919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
56019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ms->ms_fat_length) {
56119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* the label may be an attribute in the root directory */
56219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		root_start = (reserved + fat_size) * sector_size;
5633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		root_dir_entries = vs->vs_dir_entries[0] +
56419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			(vs->vs_dir_entries[1] << 8);
56519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
56619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		buf_size = root_dir_entries * sizeof(struct vfat_dir_entry);
5673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		dir = (struct vfat_dir_entry *) get_buffer(probe, root_start,
56819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project							   buf_size);
56919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (dir)
57019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			vol_label = search_fat_label(dir, root_dir_entries);
57119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
57219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!vol_label || !memcmp(vol_label, no_name, 11))
57319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			vol_label = ms->ms_label;
57419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		vol_serno = ms->ms_serno;
57519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		blkid_set_tag(probe->dev, "SEC_TYPE", "msdos",
57719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			      sizeof("msdos"));
57819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
57919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* Search the FAT32 root dir for the label attribute */
58019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		buf_size = vs->vs_cluster_size * sector_size;
58119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		start_data_sect = reserved + fat_size;
58219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
58319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		next = blkid_le32(vs->vs_root_cluster);
58419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (next && --maxloop) {
58519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			__u32 next_sect_off;
58619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			__u64 next_off, fat_entry_off;
58719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			int count;
58819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
58919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			next_sect_off = (next - 2) * vs->vs_cluster_size;
5903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			next_off = (start_data_sect + next_sect_off) *
59119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				sector_size;
59219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			dir = (struct vfat_dir_entry *)
59419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				get_buffer(probe, next_off, buf_size);
59519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (dir == NULL)
59619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
59719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
59819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			count = buf_size / sizeof(struct vfat_dir_entry);
59919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
60019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			vol_label = search_fat_label(dir, count);
60119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (vol_label)
60219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
60319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
60419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			/* get FAT entry */
6053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fat_entry_off = (reserved * sector_size) +
60619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				(next * sizeof(__u32));
60719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			buf = get_buffer(probe, fat_entry_off, buf_size);
60819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (buf == NULL)
60919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
61019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
61119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			/* set next cluster */
61219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			next = blkid_le32(*((__u32 *) buf) & 0x0fffffff);
61319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
61419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
61519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!vol_label || !memcmp(vol_label, no_name, 11))
61619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			vol_label = vs->vs_label;
61719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		vol_serno = vs->vs_serno;
61819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
61919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
62019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (vol_label && memcmp(vol_label, no_name, 11)) {
62119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((label_len = figure_label_len(vol_label, 11)))
62219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			label = vol_label;
62319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
62419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
62519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* We can't just print them as %04X, because they are unaligned */
62619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sprintf(serno, "%02X%02X-%02X%02X", vol_serno[3], vol_serno[2],
62719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		vol_serno[1], vol_serno[0]);
62819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
62919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", (const char *) label, label_len);
63019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "UUID", serno, sizeof(serno)-1);
63119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
63219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
63319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
63419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
63519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
63619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * The FAT filesystem could be without a magic string in superblock
63719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * (e.g. old floppies).  This heuristic for FAT detection is inspired
63819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * by http://vrfy.org/projects/volume_id/ and Linux kernel.
63919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * [7-Jul-2005, Karel Zak <kzak@redhat.com>]
64019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
64119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_fat_nomagic(struct blkid_probe *probe,
6423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			     struct blkid_magic *id __BLKID_ATTR((unused)),
64319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			     unsigned char *buf)
64419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
6453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct msdos_super_block *ms;
64619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	ms = (struct msdos_super_block *)buf;
64819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
64919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* heads check */
6503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ms->ms_heads == 0)
65119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
65219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* cluster size check*/
6543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ms->ms_cluster_size == 0 ||
6553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (ms->ms_cluster_size & (ms->ms_cluster_size-1)))
65619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
65719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
65819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* media check */
6593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ms->ms_media < 0xf8 && ms->ms_media != 0xf0)
66019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
66119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
66219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* fat counts(Linux kernel expects at least 1 FAT table) */
6633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!ms->ms_fats)
6643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
6653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/*
6673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * OS/2 and apparently DFSee will place a FAT12/16-like
6683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * pseudo-superblock in the first 512 bytes of non-FAT
6693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * filesystems --- at least JFS and HPFS, and possibly others.
6703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * So we explicitly check for those filesystems at the
6713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * FAT12/16 filesystem magic field identifier, and if they are
6723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * present, we rule this out as a FAT filesystem, despite the
6733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * FAT-like pseudo-header.
6743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt         */
6753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((memcmp(ms->ms_magic, "JFS     ", 8) == 0) ||
6763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (memcmp(ms->ms_magic, "HPFS    ", 8) == 0))
67719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
67819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
67919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return probe_fat(probe, id, buf);
68019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
68119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
68219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ntfs(struct blkid_probe *probe,
6833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		      struct blkid_magic *id __BLKID_ATTR((unused)),
68419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned char *buf)
68519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
68619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ntfs_super_block *ns;
68719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct master_file_table_record *mft;
68819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct file_attribute *attr;
68919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char		uuid_str[17], label_str[129], *cp;
69019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		bytes_per_sector, sectors_per_cluster;
69119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		mft_record_size, attr_off, attr_len;
69219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int	i, attr_type, val_len;
69319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		val_off;
69419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	__u64		nr_clusters;
69519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_loff_t off;
69619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned char *buf_mft, *val;
69719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
69819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ns = (struct ntfs_super_block *) buf;
69919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
70019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	bytes_per_sector = ns->bios_parameter_block[0] +
70119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		(ns->bios_parameter_block[1]  << 8);
70219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sectors_per_cluster = ns->bios_parameter_block[2];
70319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
70419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((bytes_per_sector < 512) || (sectors_per_cluster == 0))
70519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
70619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
70719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ns->cluster_per_mft_record < 0)
70819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		mft_record_size = 1 << (0-ns->cluster_per_mft_record);
70919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
7103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		mft_record_size = ns->cluster_per_mft_record *
71119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sectors_per_cluster * bytes_per_sector;
71219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	nr_clusters = blkid_le64(ns->number_of_sectors) / sectors_per_cluster;
71319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
71419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((blkid_le64(ns->mft_cluster_location) > nr_clusters) ||
71519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (blkid_le64(ns->mft_mirror_cluster_location) > nr_clusters))
71619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
71719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	off = blkid_le64(ns->mft_mirror_cluster_location) *
71919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		bytes_per_sector * sectors_per_cluster;
72019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
72119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	buf_mft = get_buffer(probe, off, mft_record_size);
72219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!buf_mft)
72319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
72419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
72519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (memcmp(buf_mft, "FILE", 4))
72619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
72719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	off = blkid_le64(ns->mft_cluster_location) * bytes_per_sector *
72919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sectors_per_cluster;
73019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
73119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	buf_mft = get_buffer(probe, off, mft_record_size);
73219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!buf_mft)
73319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
73419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
73519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (memcmp(buf_mft, "FILE", 4))
73619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
73719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
73819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	off += MFT_RECORD_VOLUME * mft_record_size;
73919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
74019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	buf_mft = get_buffer(probe, off, mft_record_size);
74119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!buf_mft)
74219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
74319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
74419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (memcmp(buf_mft, "FILE", 4))
74519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
74619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
74719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	mft = (struct master_file_table_record *) buf_mft;
74819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
74919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	attr_off = blkid_le16(mft->attrs_offset);
75019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	label_str[0] = 0;
7513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
75219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (1) {
75319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		attr = (struct file_attribute *) (buf_mft + attr_off);
75419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		attr_len = blkid_le16(attr->len);
75519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		attr_type = blkid_le32(attr->type);
75619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		val_off = blkid_le16(attr->value_offset);
75719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		val_len = blkid_le32(attr->value_len);
75819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
75919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		attr_off += attr_len;
76019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
76119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((attr_off > mft_record_size) ||
76219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (attr_len == 0))
76319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
76419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
76519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (attr_type == MFT_RECORD_ATTR_END)
76619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
76719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
76819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (attr_type == MFT_RECORD_ATTR_VOLUME_NAME) {
76919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (val_len > sizeof(label_str))
77019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				val_len = sizeof(label_str)-1;
77119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
77219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			for (i=0, cp=label_str; i < val_len; i+=2,cp++) {
77319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				val = ((__u8 *) attr) + val_off + i;
77419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				*cp = val[0];
77519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (val[1])
77619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					*cp = '?';
77719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
77819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*cp = 0;
77919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
78019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
78119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
78219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sprintf(uuid_str, "%016llX", blkid_le64(ns->volume_serial));
78319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "UUID", uuid_str, 0);
78419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (label_str[0])
78519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev, "LABEL", label_str, 0);
78619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
78719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
78819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
78919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
79019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_xfs(struct blkid_probe *probe,
7913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		     struct blkid_magic *id __BLKID_ATTR((unused)),
79219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     unsigned char *buf)
79319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
79419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct xfs_super_block *xs;
79519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
79619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
79719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	xs = (struct xfs_super_block *)buf;
79819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
79919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strlen(xs->xs_fname))
80019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = xs->xs_fname;
80119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", label, sizeof(xs->xs_fname));
80219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	set_uuid(probe->dev, xs->xs_uuid, 0);
80319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
80419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
80519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
80619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_reiserfs(struct blkid_probe *probe,
80719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  struct blkid_magic *id, unsigned char *buf)
80819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
80919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf;
81019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int blocksize;
81119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
81219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
81319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blocksize = blkid_le16(rs->rs_blocksize);
81419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
81519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* The blocksize must be at least 1k */
81619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((blocksize >> 10) == 0)
81719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_PARAM;
81819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
81919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* If the superblock is inside the journal, we have the wrong one */
82019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block))
82119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return -BLKID_ERR_BIG;
82219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
82319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
82419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (id->bim_magic[6] == '2' || id->bim_magic[6] == '3') {
82519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strlen(rs->rs_label))
82619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			label = rs->rs_label;
82719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		set_uuid(probe->dev, rs->rs_uuid, 0);
82819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
82919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", label, sizeof(rs->rs_label));
83019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
83119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
83219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
83319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
83419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_reiserfs4(struct blkid_probe *probe,
8353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			   struct blkid_magic *id __BLKID_ATTR((unused)),
83619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   unsigned char *buf)
83719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
83819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct reiser4_super_block *rs4 = (struct reiser4_super_block *) buf;
83919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const unsigned char *label = 0;
84019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
84119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strlen((char *) rs4->rs4_label))
84219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = rs4->rs4_label;
84319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	set_uuid(probe->dev, rs4->rs4_uuid, 0);
8443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_set_tag(probe->dev, "LABEL", (const char *) label,
84519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      sizeof(rs4->rs4_label));
84619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
84719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
84819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
84919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
85019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_jfs(struct blkid_probe *probe,
8513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		     struct blkid_magic *id __BLKID_ATTR((unused)),
85219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     unsigned char *buf)
85319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
85419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct jfs_super_block *js;
85519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
85619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
85719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	js = (struct jfs_super_block *)buf;
85819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (blkid_le32(js->js_bsize) != (1 << blkid_le16(js->js_l2bsize)))
8603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
8613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
8623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (blkid_le32(js->js_pbsize) != (1 << blkid_le16(js->js_l2pbsize)))
8633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
8643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
8653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((blkid_le16(js->js_l2bsize) - blkid_le16(js->js_l2pbsize)) !=
8663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    blkid_le16(js->js_l2bfactor))
8673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
8683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
86919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strlen((char *) js->js_label))
87019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = (char *) js->js_label;
87119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", label, sizeof(js->js_label));
87219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	set_uuid(probe->dev, js->js_uuid, 0);
87319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
87419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
87519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int probe_zfs(struct blkid_probe *probe, struct blkid_magic *id,
8773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		     unsigned char *buf)
8783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
8793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if 0
8803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char *vdev_label;
8813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const char *pool_name = 0;
8823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
8833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* read nvpair data for pool name, pool GUID (complex) */
8843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_set_tag(probe->dev, "LABEL", pool_name, sizeof(pool_name));
8853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	set_uuid(probe->dev, pool_guid, 0);
8863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
8873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
8883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
8893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
89019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_luks(struct blkid_probe *probe,
89119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       struct blkid_magic *id __BLKID_ATTR((unused)),
89219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       unsigned char *buf)
89319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
89419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char uuid[40];
8953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
89619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* 168 is the offset to the 40 character uuid:
89719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * http://luks.endorphin.org/LUKS-on-disk-format.pdf */
89819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	strncpy(uuid, (char *) buf+168, 40);
89919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "UUID", uuid, sizeof(uuid));
90019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
90119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
90219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
90319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_romfs(struct blkid_probe *probe,
9043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       struct blkid_magic *id __BLKID_ATTR((unused)),
90519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       unsigned char *buf)
90619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
90719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct romfs_super_block *ros;
90819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
90919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
91019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ros = (struct romfs_super_block *)buf;
91119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
91219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strlen((char *) ros->ros_volume))
91319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = (char *) ros->ros_volume;
91419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", label, 0);
91519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
91619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
91719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
91819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_cramfs(struct blkid_probe *probe,
9193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			struct blkid_magic *id __BLKID_ATTR((unused)),
92019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			unsigned char *buf)
92119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
92219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct cramfs_super_block *csb;
92319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
92419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
92519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	csb = (struct cramfs_super_block *)buf;
92619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
92719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (strlen((char *) csb->name))
92819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = (char *) csb->name;
92919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", label, 0);
93019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
93119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
93219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
93319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_swap0(struct blkid_probe *probe,
93419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       struct blkid_magic *id __BLKID_ATTR((unused)),
93519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       unsigned char *buf __BLKID_ATTR((unused)))
93619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
93719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "UUID", 0, 0);
93819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", 0, 0);
93919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
94019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
94119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
94219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_swap1(struct blkid_probe *probe,
9433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       struct blkid_magic *id,
94419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       unsigned char *buf __BLKID_ATTR((unused)))
94519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
94619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct swap_id_block *sws;
94719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
94819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	probe_swap0(probe, id, buf);
94919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
95019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Version 1 swap headers are always located at offset of 1024
95119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * bytes, although the swap signature itself is located at the
95219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * end of the page (which may vary depending on hardware
95319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * pagesize).
95419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
95519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sws = (struct swap_id_block *) get_buffer(probe, 1024, 1024);
95619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!sws)
95719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
95819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* check for wrong version or zeroed pagecount, for sanity */
9603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!memcmp(id->bim_magic, "SWAPSPACE2", id->bim_len) &&
9613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			(sws->sws_version != 1 || sws->sws_lastpage == 0))
9623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
9633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
96419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* arbitrary sanity check.. is there any garbage down there? */
96519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sws->sws_pad[32] == 0 && sws->sws_pad[33] == 0)  {
96619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (sws->sws_volume[0])
9673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			blkid_set_tag(probe->dev, "LABEL", sws->sws_volume,
96819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				      sizeof(sws->sws_volume));
96919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (sws->sws_uuid[0])
97019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			set_uuid(probe->dev, sws->sws_uuid, 0);
97119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
97219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
97319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
97419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
97519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_iso9660(struct blkid_probe *probe,
9763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			 struct blkid_magic *id __BLKID_ATTR((unused)),
97719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 unsigned char *buf)
97819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
97919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct iso_volume_descriptor *iso;
98019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const unsigned char *label;
98119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
98219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	iso = (struct iso_volume_descriptor *) buf;
98319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	label = iso->volume_id;
98419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_set_tag(probe->dev, "LABEL", (const char *) label,
98619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      figure_label_len(label, 32));
98719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
98819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
98919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
99019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
99119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char
99219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
99319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 "NSR03", "TEA01", 0 };
99419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
99519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_udf(struct blkid_probe *probe,
9963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		     struct blkid_magic *id __BLKID_ATTR((unused)),
99719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     unsigned char *buf __BLKID_ATTR((unused)))
99819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
99919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int j, bs;
100019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct iso_volume_descriptor *isosb;
100119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char ** m;
100219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
100319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* determine the block size by scanning in 2K increments
100419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	   (block sizes larger than 2K will be null padded) */
100519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (bs = 1; bs < 16; bs++) {
10063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		isosb = (struct iso_volume_descriptor *)
100719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			get_buffer(probe, bs*2048+32768, sizeof(isosb));
100819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!isosb)
100919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 1;
101019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (isosb->vd_id[0])
101119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
101219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
101319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
101419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Scan up to another 64 blocks looking for additional VSD's */
101519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (j = 1; j < 64; j++) {
101619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (j > 1) {
10173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			isosb = (struct iso_volume_descriptor *)
10183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				get_buffer(probe, j*bs*2048+32768,
101919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					   sizeof(isosb));
102019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!isosb)
102119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				return 1;
102219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
102319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/* If we find NSR0x then call it udf:
102419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   NSR01 for UDF 1.00
102519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   NSR02 for UDF 1.50
102619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   NSR03 for UDF 2.00 */
102719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!memcmp(isosb->vd_id, "NSR0", 4))
102819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return probe_iso9660(probe, id, buf);
102919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (m = udf_magic; *m; m++)
103019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!memcmp(*m, isosb->vd_id, 5))
103119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
103219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (*m == 0)
103319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 1;
103419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
103519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 1;
103619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
103719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
103819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ocfs(struct blkid_probe *probe,
10393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		      struct blkid_magic *id __BLKID_ATTR((unused)),
104019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		      unsigned char *buf)
104119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
104219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ocfs_volume_header ovh;
104319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ocfs_volume_label ovl;
104419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	__u32 major;
104519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
104619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memcpy(&ovh, buf, sizeof(ovh));
104719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memcpy(&ovl, buf+512, sizeof(ovl));
104819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
104919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	major = ocfsmajor(ovh);
105019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (major == 1)
105119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev,"SEC_TYPE","ocfs1",sizeof("ocfs1"));
105219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if (major >= 9)
105319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev,"SEC_TYPE","ntocfs",sizeof("ntocfs"));
10543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
105519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", ovl.label, ocfslabellen(ovl));
105619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "MOUNT", ovh.mount, ocfsmountlen(ovh));
105719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	set_uuid(probe->dev, ovl.vol_id, 0);
105819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
105919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
106019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
106119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_ocfs2(struct blkid_probe *probe,
10623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       struct blkid_magic *id __BLKID_ATTR((unused)),
106319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       unsigned char *buf)
106419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
106519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ocfs2_super_block *osb;
106619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
106719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	osb = (struct ocfs2_super_block *)buf;
106819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
106919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", osb->s_label, sizeof(osb->s_label));
107019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	set_uuid(probe->dev, osb->s_uuid, 0);
107119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
107219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
107319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
107419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_oracleasm(struct blkid_probe *probe,
10753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			   struct blkid_magic *id __BLKID_ATTR((unused)),
107619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   unsigned char *buf)
107719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
107819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct oracle_asm_disk_label *dl;
107919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
108019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dl = (struct oracle_asm_disk_label *)buf;
108119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
108219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "LABEL", dl->dl_id, sizeof(dl->dl_id));
108319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
108419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
108519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
108619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_gfs(struct blkid_probe *probe,
108719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     struct blkid_magic *id __BLKID_ATTR((unused)),
108819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     unsigned char *buf)
108919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
109019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct gfs2_sb *sbd;
109119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
109219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
109319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sbd = (struct gfs2_sb *)buf;
109419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
109519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_be32(sbd->sb_fs_format) == GFS_FORMAT_FS &&
109619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    blkid_be32(sbd->sb_multihost_format) == GFS_FORMAT_MULTI)
10973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	{
109819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev, "UUID", 0, 0);
10993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
110019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strlen(sbd->sb_locktable))
110119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			label = sbd->sb_locktable;
110219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev, "LABEL", label, sizeof(sbd->sb_locktable));
110319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
110419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
110519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 1;
110619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
110719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
110819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_gfs2(struct blkid_probe *probe,
110919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     struct blkid_magic *id __BLKID_ATTR((unused)),
111019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		     unsigned char *buf)
111119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
111219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct gfs2_sb *sbd;
111319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *label = 0;
111419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
111519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sbd = (struct gfs2_sb *)buf;
111619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
111719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_be32(sbd->sb_fs_format) == GFS2_FORMAT_FS &&
111819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    blkid_be32(sbd->sb_multihost_format) == GFS2_FORMAT_MULTI)
11193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	{
112019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev, "UUID", 0, 0);
11213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
112219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strlen(sbd->sb_locktable))
112319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			label = sbd->sb_locktable;
112419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(probe->dev, "LABEL", label, sizeof(sbd->sb_locktable));
112519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
112619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
112719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 1;
112819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
112919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic void unicode_16be_to_utf8(unsigned char *str, int out_len,
11313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				 const unsigned char *buf, int in_len)
11323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
11333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int i, j;
11343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int c;
11353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
11363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (i = j = 0; i + 2 <= in_len; i += 2) {
11373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		c = (buf[i] << 8) | buf[i+1];
11383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (c == 0) {
11393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j] = '\0';
11403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			break;
11413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		} else if (c < 0x80) {
11423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (j+1 >= out_len)
11433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				break;
11443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j++] = (unsigned char) c;
11453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		} else if (c < 0x800) {
11463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (j+2 >= out_len)
11473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				break;
11483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j++] = (unsigned char) (0xc0 | (c >> 6));
11493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j++] = (unsigned char) (0x80 | (c & 0x3f));
11503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		} else {
11513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (j+3 >= out_len)
11523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				break;
11533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j++] = (unsigned char) (0xe0 | (c >> 12));
11543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j++] = (unsigned char) (0x80 | ((c >> 6) & 0x3f));
11553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			str[j++] = (unsigned char) (0x80 | (c & 0x3f));
11563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
11573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
11583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	str[j] = '\0';
11593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
11603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
11613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int probe_hfs(struct blkid_probe *probe __BLKID_ATTR((unused)),
116219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 struct blkid_magic *id __BLKID_ATTR((unused)),
116319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 unsigned char *buf)
116419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
11653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfs_mdb *hfs = (struct hfs_mdb *) buf;
11663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char	uuid_str[17];
11673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	__u64	uuid;
11683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
11693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((memcmp(hfs->embed_sig, "H+", 2) == 0) ||
11703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (memcmp(hfs->embed_sig, "HX", 2) == 0))
11713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;	/* Not hfs, but an embedded HFS+ */
11723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
11733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	uuid = blkid_le64(*((unsigned long long *) hfs->finder_info.id));
11743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (uuid) {
11753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		sprintf(uuid_str, "%016llX", uuid);
11763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		blkid_set_tag(probe->dev, "UUID", uuid_str, 0);
11773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
11783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_set_tag(probe->dev, "LABEL", hfs->label, hfs->label_len);
11793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
11803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
11813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
11823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
11833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int probe_hfsplus(struct blkid_probe *probe,
11843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			 struct blkid_magic *id,
11853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			 unsigned char *buf)
11863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
11873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT];
11883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfsplus_bnode_descriptor *descr;
11893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfsplus_bheader_record *bnode;
11903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfsplus_catalog_key *key;
11913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfsplus_vol_header *hfsplus;
11923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct hfs_mdb *sbd = (struct hfs_mdb *) buf;
11933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int alloc_block_size;
11943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int alloc_first_block;
11953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int embed_first_block;
11963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int off = 0;
11973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int blocksize;
11983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int cat_block;
11993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int ext_block_start;
12003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int ext_block_count;
12013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int record_count;
12023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int leaf_node_head;
12033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int leaf_node_count;
12043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int leaf_node_size;
12053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int leaf_block;
12063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unsigned int label_len;
12073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int ext;
12083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	__u64 leaf_off, uuid;
12093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char	uuid_str[17], label[512];
121019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
121119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Check for a HFS+ volume embedded in a HFS volume */
12123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (memcmp(sbd->signature, "BD", 2) == 0) {
12133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((memcmp(sbd->embed_sig, "H+", 2) != 0) &&
12143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		    (memcmp(sbd->embed_sig, "HX", 2) != 0))
12153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			/* This must be an HFS volume, so fail */
12163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return 1;
12173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		alloc_block_size = blkid_be32(sbd->al_blk_size);
12193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		alloc_first_block = blkid_be16(sbd->al_bl_st);
12203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		embed_first_block = blkid_be16(sbd->embed_startblock);
12213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		off = (alloc_first_block * 512) +
12223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			(embed_first_block * alloc_block_size);
12233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		buf = get_buffer(probe, off + (id->bim_kboff * 1024),
12243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				 sizeof(sbd));
12253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!buf)
12263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return 1;
12273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		hfsplus = (struct hfsplus_vol_header *) buf;
12293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
12303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	hfsplus = (struct hfsplus_vol_header *) buf;
12323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((memcmp(hfsplus->signature, "H+", 2) != 0) &&
12343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (memcmp(hfsplus->signature, "HX", 2) != 0))
12353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 1;
12363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	uuid = blkid_le64(*((unsigned long long *) hfsplus->finder_info.id));
12383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (uuid) {
12393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		sprintf(uuid_str, "%016llX", uuid);
12403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		blkid_set_tag(probe->dev, "UUID", uuid_str, 0);
12413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
12423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blocksize = blkid_be32(hfsplus->blocksize);
12443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
12453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	cat_block = blkid_be32(extents[0].start_block);
12463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	buf = get_buffer(probe, off + (cat_block * blocksize), 0x2000);
12483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!buf)
124919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
125019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	bnode = (struct hfsplus_bheader_record *)
12523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		&buf[sizeof(struct hfsplus_bnode_descriptor)];
12533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	leaf_node_head = blkid_be32(bnode->leaf_head);
12553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	leaf_node_size = blkid_be16(bnode->node_size);
12563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	leaf_node_count = blkid_be32(bnode->leaf_count);
12573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (leaf_node_count == 0)
12583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
12593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	leaf_block = (leaf_node_head * leaf_node_size) / blocksize;
12613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* get physical location */
12633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (ext = 0; ext < HFSPLUS_EXTENT_COUNT; ext++) {
12643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ext_block_start = blkid_be32(extents[ext].start_block);
12653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ext_block_count = blkid_be32(extents[ext].block_count);
12663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (ext_block_count == 0)
12673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return 0;
12683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		/* this is our extent */
12703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (leaf_block < ext_block_count)
12713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			break;
12723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		leaf_block -= ext_block_count;
12743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
12753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ext == HFSPLUS_EXTENT_COUNT)
12763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
12773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	leaf_off = (ext_block_start + leaf_block) * blocksize;
12793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	buf = get_buffer(probe, off + leaf_off, leaf_node_size);
12813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!buf)
12823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
12833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	descr = (struct hfsplus_bnode_descriptor *) buf;
12853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	record_count = blkid_be16(descr->num_recs);
12863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (record_count == 0)
12873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
12883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (descr->type != HFS_NODE_LEAF)
12903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
12913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	key = (struct hfsplus_catalog_key *)
12933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		&buf[sizeof(struct hfsplus_bnode_descriptor)];
12943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (blkid_be32(key->parent_id) != HFSPLUS_POR_CNID)
12963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
12973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	label_len = blkid_be16(key->unicode_len) * 2;
12993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	unicode_16be_to_utf8(label, sizeof(label), key->unicode, label_len);
13003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_set_tag(probe->dev, "LABEL", label, 0);
13013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
130219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
130319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
130419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LVM2_LABEL_SIZE 512
130519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned int lvm2_calc_crc(const void *buf, unsigned int size)
130619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
130719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static const unsigned int crctab[] = {
130819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
130919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
131019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
131119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
131219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	};
131319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int i, crc = 0xf597a6cf;
131419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const __u8 *data = (const __u8 *) buf;
131519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
131619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (i = 0; i < size; i++) {
131719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		crc ^= *data++;
131819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		crc = (crc >> 4) ^ crctab[crc & 0xf];
131919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		crc = (crc >> 4) ^ crctab[crc & 0xf];
132019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
132119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return crc;
132219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
132319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
132419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int probe_lvm2(struct blkid_probe *probe,
13253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			struct blkid_magic *id,
132619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			unsigned char *buf)
132719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
13283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int sector = (id->bim_kboff) << 1;
13293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct lvm2_pv_label_header *label= (struct lvm2_pv_label_header *)buf;
133019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char *p, *q, uuid[40];
133119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int i, b;
133219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
133319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* buf is at 0k or 1k offset; find label inside */
133419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (memcmp(buf, "LABELONE", 8) == 0) {
133519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = (struct lvm2_pv_label_header *)buf;
133619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else if (memcmp(buf + 512, "LABELONE", 8) == 0) {
133719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		label = (struct lvm2_pv_label_header *)(buf + 512);
133819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sector++;
133919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
134019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
134119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
134219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
134319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (blkid_le64(label->sector_xl) != (unsigned) sector) {
134419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		DBG(DEBUG_PROBE,
134519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    printf("LVM2: label for sector %llu found at sector %d\n",
134619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   blkid_le64(label->sector_xl), sector));
134719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
134819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
134919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
135019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (lvm2_calc_crc(&label->offset_xl, LVM2_LABEL_SIZE -
135119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  ((char *)&label->offset_xl - (char *)label)) !=
135219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			blkid_le32(label->crc_xl)) {
135319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		DBG(DEBUG_PROBE,
135419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    printf("LVM2: label checksum incorrect at sector %d\n",
135519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   sector));
135619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
135719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
135819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
135919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (i=0, b=1, p=uuid, q= (char *) label->pv_uuid; i <= 32;
136019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     i++, b <<= 1) {
136119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (b & 0x4444440)
136219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*p++ = '-';
136319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*p++ = *q++;
136419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
136519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
136619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_set_tag(probe->dev, "UUID", uuid, LVM2_ID_LEN+6);
136719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
136819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
136919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
137019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic int probe_btrfs(struct blkid_probe *probe,
13723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			struct blkid_magic *id,
13733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			unsigned char *buf)
13743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
13753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct btrfs_super_block *bs;
13763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const char *label = 0;
13773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
13783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	bs = (struct btrfs_super_block *)buf;
13793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
13803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (strlen(bs->label))
13813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		label = bs->label;
13823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blkid_set_tag(probe->dev, "LABEL", label, sizeof(bs->label));
13833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	set_uuid(probe->dev, bs->fsid, 0);
13843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
13853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
138619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
138719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Various filesystem magics that we can check for.  Note that kboff and
138819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * sboff are in kilobytes and bytes respectively.  All magics are in
138919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * byte strings so we don't worry about endian issues.
139019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
139119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic struct blkid_magic type_array[] = {
139219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*  type     kboff   sboff len  magic			probe */
139319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "oracleasm", 0,	32,  8, "ORCLDISK",		probe_oracleasm },
139419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ntfs",	 0,	 3,  8, "NTFS    ",		probe_ntfs },
139519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "jbd",	 1,   0x38,  2, "\123\357",		probe_jbd },
139619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ext4dev",	 1,   0x38,  2, "\123\357",		probe_ext4dev },
139719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ext4",	 1,   0x38,  2, "\123\357",		probe_ext4 },
139819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ext3",	 1,   0x38,  2, "\123\357",		probe_ext3 },
139919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ext2",	 1,   0x38,  2, "\123\357",		probe_ext2 },
140019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "reiserfs",	 8,   0x34,  8, "ReIsErFs",		probe_reiserfs },
140119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "reiserfs", 64,   0x34,  9, "ReIsEr2Fs",		probe_reiserfs },
140219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "reiserfs", 64,   0x34,  9, "ReIsEr3Fs",		probe_reiserfs },
140319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "reiserfs", 64,   0x34,  8, "ReIsErFs",		probe_reiserfs },
140419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "reiserfs",	 8,	20,  8, "ReIsErFs",		probe_reiserfs },
140519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "reiser4",  64,	 0,  7, "ReIsEr4",		probe_reiserfs4 },
140619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "gfs2",     64,      0,  4, "\x01\x16\x19\x70",     probe_gfs2 },
140719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "gfs",      64,      0,  4, "\x01\x16\x19\x70",     probe_gfs },
140819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,   0x52,  5, "MSWIN",                probe_fat },
140919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,   0x52,  8, "FAT32   ",             probe_fat },
141019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,   0x36,  5, "MSDOS",                probe_fat },
141119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,   0x36,  8, "FAT16   ",             probe_fat },
141219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,   0x36,  8, "FAT12   ",             probe_fat },
141319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,      0,  1, "\353",                 probe_fat_nomagic },
141419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,      0,  1, "\351",                 probe_fat_nomagic },
141519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vfat",      0,  0x1fe,  2, "\125\252",             probe_fat_nomagic },
141619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "minix",     1,   0x10,  2, "\177\023",             0 },
141719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "minix",     1,   0x10,  2, "\217\023",             0 },
141819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "minix",	 1,   0x10,  2, "\150\044",		0 },
141919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "minix",	 1,   0x10,  2, "\170\044",		0 },
142019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "vxfs",	 1,	 0,  4, "\365\374\001\245",	0 },
142119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "xfs",	 0,	 0,  4, "XFSB",			probe_xfs },
142219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "romfs",	 0,	 0,  8, "-rom1fs-",		probe_romfs },
142319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "bfs",	 0,	 0,  4, "\316\372\173\033",	0 },
142419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "cramfs",	 0,	 0,  4, "E=\315\050",		probe_cramfs },
142519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "qnx4",	 0,	 4,  6, "QNX4FS",		0 },
142619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "BEA01",		probe_udf },
142719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "BOOT2",		probe_udf },
142819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "CD001",		probe_udf },
142919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "CDW02",		probe_udf },
143019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "NSR02",		probe_udf },
143119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "NSR03",		probe_udf },
143219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "udf",	32,	 1,  5, "TEA01",		probe_udf },
143319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "iso9660",	32,	 1,  5, "CD001",		probe_iso9660 },
143419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "iso9660",	32,	 9,  5, "CDROM",		probe_iso9660 },
143519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "jfs",	32,	 0,  4, "JFS1",			probe_jfs },
14363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "zfs",       8,	 0,  8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", probe_zfs },
14373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "zfs",       8,	 0,  8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", probe_zfs },
14383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "zfs",     264,	 0,  8, "\0\0\x02\xf5\xb0\x07\xb1\x0c", probe_zfs },
14393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "zfs",     264,	 0,  8, "\x0c\xb1\x07\xb0\xf5\x02\0\0", probe_zfs },
144019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "hfsplus",	 1,	 0,  2, "BD",			probe_hfsplus },
14413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "hfsplus",	 1,	 0,  2, "H+",			probe_hfsplus },
14423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "hfsplus",	 1,	 0,  2, "HX",			probe_hfsplus },
14433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "hfs",	 1,	 0,  2, "BD",			probe_hfs },
144419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ufs",	 8,  0x55c,  4, "T\031\001\000",	0 },
144519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "hpfs",	 8,	 0,  4, "I\350\225\371",	0 },
144619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "sysv",	 0,  0x3f8,  4, "\020~\030\375",	0 },
144719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0,  0xff6, 10, "SWAP-SPACE",		probe_swap0 },
144819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0,  0xff6, 10, "SWAPSPACE2",		probe_swap1 },
144919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0,  0xff6,  9, "S1SUSPEND",		probe_swap1 },
145019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0,  0xff6,  9, "S2SUSPEND",		probe_swap1 },
14513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "swsuspend", 0,  0xff6,  9, "ULSUSPEND",		probe_swap1 },
145219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0x1ff6, 10, "SWAP-SPACE",		probe_swap0 },
145319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0x1ff6, 10, "SWAPSPACE2",		probe_swap1 },
145419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0x1ff6,  9, "S1SUSPEND",		probe_swap1 },
145519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0x1ff6,  9, "S2SUSPEND",		probe_swap1 },
14563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "swsuspend", 0, 0x1ff6,  9, "ULSUSPEND",		probe_swap1 },
145719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0x3ff6, 10, "SWAP-SPACE",		probe_swap0 },
145819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0x3ff6, 10, "SWAPSPACE2",		probe_swap1 },
145919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0x3ff6,  9, "S1SUSPEND",		probe_swap1 },
146019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0x3ff6,  9, "S2SUSPEND",		probe_swap1 },
14613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "swsuspend", 0, 0x3ff6,  9, "ULSUSPEND",		probe_swap1 },
146219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0x7ff6, 10, "SWAP-SPACE",		probe_swap0 },
146319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0x7ff6, 10, "SWAPSPACE2",		probe_swap1 },
146419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0x7ff6,  9, "S1SUSPEND",		probe_swap1 },
146519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0x7ff6,  9, "S2SUSPEND",		probe_swap1 },
14663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "swsuspend", 0, 0x7ff6,  9, "ULSUSPEND",		probe_swap1 },
146719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0xfff6, 10, "SWAP-SPACE",		probe_swap0 },
146819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swap",	 0, 0xfff6, 10, "SWAPSPACE2",		probe_swap1 },
146919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0xfff6,  9, "S1SUSPEND",		probe_swap1 },
147019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "swsuspend", 0, 0xfff6,  9, "S2SUSPEND",		probe_swap1 },
14713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "swsuspend", 0, 0xfff6,  9, "ULSUSPEND",		probe_swap1 },
147219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ocfs",	 0,	 8,  9,	"OracleCFS",		probe_ocfs },
147319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ocfs2",	 1,	 0,  6,	"OCFSV2",		probe_ocfs2 },
147419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ocfs2",	 2,	 0,  6,	"OCFSV2",		probe_ocfs2 },
147519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ocfs2",	 4,	 0,  6,	"OCFSV2",		probe_ocfs2 },
147619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "ocfs2",	 8,	 0,  6,	"OCFSV2",		probe_ocfs2 },
147719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "crypt_LUKS", 0,	 0,  6,	"LUKS\xba\xbe",		probe_luks },
147819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "squashfs",	 0,	 0,  4,	"sqsh",			0 },
147919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "squashfs",	 0,	 0,  4,	"hsqs",			0 },
148019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "lvm2pv",	 0,  0x218,  8, "LVM2 001",		probe_lvm2 },
148119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "lvm2pv",	 0,  0x018,  8, "LVM2 001",		probe_lvm2 },
148219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "lvm2pv",	 1,  0x018,  8, "LVM2 001",		probe_lvm2 },
148319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  { "lvm2pv",	 1,  0x218,  8, "LVM2 001",		probe_lvm2 },
14843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt  { "btrfs",	 64,  0x40,  8, "_BHRfS_M",		probe_btrfs },
148519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {   NULL,	 0,	 0,  0, NULL,			NULL }
148619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
148719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
148819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
148919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Verify that the data in dev is consistent with what is on the actual
149019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * block device (using the devname field only).  Normally this will be
149119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * called when finding items in the cache, but for long running processes
149219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * is also desirable to revalidate an item before use.
149319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
149419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * If we are unable to revalidate the data, we return the old data and
149519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * do not set the BLKID_BID_FL_VERIFIED flag on it.
149619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
149719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectblkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
149819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
149919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct blkid_magic *id;
150019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct blkid_probe probe;
150119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_tag_iterate iter;
150219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned char *buf;
150319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *type, *value;
150419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct stat st;
150519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	time_t diff, now;
150619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int idx;
150719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
150819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!dev)
150919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return NULL;
151019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
151119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	now = time(0);
151219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	diff = now - dev->bid_time;
151319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (stat(dev->bid_name, &st) < 0) {
15153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		DBG(DEBUG_PROBE,
15163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		    printf("blkid_verify: error %s (%d) while "
15173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			   "trying to stat %s\n", strerror(errno), errno,
15183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			   dev->bid_name));
15193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	open_err:
15203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((errno == EPERM) || (errno == EACCES) || (errno == ENOENT)) {
15213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			/* We don't have read permission, just return cache data. */
15223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			DBG(DEBUG_PROBE, printf("returning unverified data for %s\n",
15233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt						dev->bid_name));
15243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return dev;
15253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
15263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		blkid_free_dev(dev);
15273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return NULL;
15283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
15293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
15303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((now >= dev->bid_time) &&
15313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (st.st_mtime <= dev->bid_time) &&
15323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    ((diff < BLKID_PROBE_MIN) ||
153319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
153419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	      diff < BLKID_PROBE_INTERVAL)))
153519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return dev;
153619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
153719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	DBG(DEBUG_PROBE,
15383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    printf("need to revalidate %s (cache time %lu, stat time %lu,\n\t"
15393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   "time since last check %lu)\n",
15403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   dev->bid_name, (unsigned long)dev->bid_time,
15413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   (unsigned long)st.st_mtime, (unsigned long)diff));
15423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
15433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((probe.fd = open(dev->bid_name, O_RDONLY)) < 0) {
15443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		DBG(DEBUG_PROBE, printf("blkid_verify: error %s (%d) while "
15453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					"opening %s\n", strerror(errno), errno,
15463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					dev->bid_name));
15473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		goto open_err;
154819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
154919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
155019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	probe.cache = cache;
155119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	probe.dev = dev;
155219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	probe.sbbuf = 0;
155319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	probe.buf = 0;
155419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	probe.buf_max = 0;
15553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
155619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
155719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Iterate over the type array.  If we already know the type,
155819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * then try that first.  If it doesn't work, then blow away
155919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * the type information, and try again.
15603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 *
156119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
156219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecttry_again:
156319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	type = 0;
156419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) {
156519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		uuid_t	uuid;
156619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
156719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (check_mdraid(probe.fd, uuid) == 0) {
156819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			set_uuid(dev, uuid, 0);
156919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			type = "mdraid";
157019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto found_type;
157119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
157219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
157319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (id = type_array; id->bim_type; id++) {
157419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (dev->bid_type &&
157519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    strcmp(id->bim_type, dev->bid_type))
157619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
157719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
157819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		idx = id->bim_kboff + (id->bim_sboff >> 10);
157919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		buf = get_buffer(&probe, idx << 10, 1024);
158019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!buf)
158119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
158219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (memcmp(id->bim_magic, buf + (id->bim_sboff & 0x3ff),
158419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   id->bim_len))
158519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
158619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
158719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((id->bim_probe == NULL) ||
158819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (id->bim_probe(&probe, id, buf) == 0)) {
158919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			type = id->bim_type;
159019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto found_type;
159119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
159219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
159319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
159419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!id->bim_type && dev->bid_type) {
159519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/*
159619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * Zap the device filesystem information and try again
159719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 */
159819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		DBG(DEBUG_PROBE,
159919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    printf("previous fs type %s not valid, "
160019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   "trying full probe\n", dev->bid_type));
160119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		iter = blkid_tag_iterate_begin(dev);
160219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while (blkid_tag_next(iter, &type, &value) == 0)
160319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			blkid_set_tag(dev, type, 0, 0);
160419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_tag_iterate_end(iter);
160519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto try_again;
160619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
160719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
160819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!dev->bid_type) {
160919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_free_dev(dev);
161019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dev = 0;
161119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto found_type;
161219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
16133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
161419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectfound_type:
161519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (dev && type) {
161619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dev->bid_devno = st.st_rdev;
161719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dev->bid_time = time(0);
161819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dev->bid_flags |= BLKID_BID_FL_VERIFIED;
161919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cache->bic_flags |= BLKID_BIC_FL_CHANGED;
162019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
162119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		blkid_set_tag(dev, "TYPE", type, 0);
16223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
162319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
162419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   dev->bid_name, (long long)st.st_rdev, type));
162519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
162619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
16273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	free(probe.sbbuf);
16283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	free(probe.buf);
16293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (probe.fd >= 0)
163019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		close(probe.fd);
163119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
163219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return dev;
163319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
163419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
163519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint blkid_known_fstype(const char *fstype)
163619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
163719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct blkid_magic *id;
163819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
163919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (id = type_array; id->bim_type; id++) {
164019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strcmp(fstype, id->bim_type) == 0)
164119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 1;
164219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
164319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
164419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
164519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
164619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef TEST_PROGRAM
164719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main(int argc, char **argv)
164819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
164919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_dev dev;
165019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_cache cache;
165119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int ret;
165219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
165319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (argc != 2) {
165419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf(stderr, "Usage: %s device\n"
165519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"Probe a single device to determine type\n", argv[0]);
165619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(1);
165719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
165819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
165919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf(stderr, "%s: error creating cache (%d)\n",
166019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			argv[0], ret);
166119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(1);
166219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
166319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
166419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!dev) {
166519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
166619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return (1);
166719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
166819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)");
166919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (dev->bid_label)
167019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("LABEL='%s'\n", dev->bid_label);
167119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (dev->bid_uuid)
167219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("UUID='%s'\n", dev->bid_uuid);
16733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
167419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_free_dev(dev);
167519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return (0);
167619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
167719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
1678