probe.c revision 1e5630abab066035602437ed047e0988064687f0
1e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
2e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * probe.c - identify a block device by its contents, and return a dev
3e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o *           struct with the details
4e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o *
5e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Copyright (C) 1999 by Andries Brouwer
650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
7e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Copyright (C) 2001 by Andreas Dilger
8e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o *
9e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * %Begin-Header%
10e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * This file may be redistributed under the terms of the
11e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * GNU Lesser General Public License.
12e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * %End-Header%
13e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
14e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
15e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <stdio.h>
16e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <string.h>
17e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <stdlib.h>
18e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <unistd.h>
19e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <fcntl.h>
20e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <sys/types.h>
21e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef HAVE_SYS_STAT_H
22e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <sys/stat.h>
23e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
24e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef HAVE_SYS_MKDEV_H
25e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <sys/mkdev.h>
26e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
27e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef HAVE_ERRNO_H
28e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include <errno.h>
29e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
307a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o#include "blkidP.h"
31e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include "uuid/uuid.h"
32e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#include "probe.h"
33e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
3445a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'ostatic int figure_label_len(const unsigned char *label, int len)
3545a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o{
3645a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	const unsigned char *end = label + len - 1;
3745a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
3845a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	while ((*end == ' ' || *end == 0) && end >= label)
3945a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		--end;
4045a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	if (end >= label) {
4145a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		label = label;
4245a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		return end - label + 1;
4345a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	}
4445a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	return 0;
4545a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o}
4645a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
47e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
4850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * This is a special case code to check for an MDRAID device.  We do
4950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * this special since it requires checking for a superblock at the end
5050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * of the device.
51e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
5250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'ostatic int check_mdraid(int fd, unsigned char *ret_uuid)
53e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
5450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	struct mdp_superblock_s *md;
5550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	blkid_loff_t		offset;
5650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	char			buf[4096];
5750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
5850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (fd < 0)
59e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_PARAM;
60e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
6150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536;
62e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
63e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (blkid_llseek(fd, offset, 0) < 0 ||
6450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	    read(fd, buf, 4096) != 4096)
65e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_IO;
66e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
6750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	/* Check for magic number */
6850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (memcmp("\251+N\374", buf, 4))
69e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_PARAM;
70e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
7150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!ret_uuid)
7250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		return 0;
7350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	*ret_uuid = 0;
74e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
7550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	/* The MD UUID is not contiguous in the superblock, make it so */
7650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	md = (struct mdp_superblock_s *)buf;
7750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) {
7850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		memcpy(ret_uuid, &md->set_uuid0, 4);
7950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		memcpy(ret_uuid, &md->set_uuid1, 12);
80e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
8150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	return 0;
8250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o}
83e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
8450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'ostatic void set_uuid(blkid_dev dev, uuid_t uuid)
8550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o{
8650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	char	str[37];
87e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
8850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!uuid_is_null(uuid)) {
8950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		uuid_unparse(uuid, str);
9079dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		blkid_set_tag(dev, "UUID", str, sizeof(str));
9150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
92e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
93e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
942e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'ostatic void get_ext2_info(blkid_dev dev, unsigned char *buf)
952e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o{
962e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	struct ext2_super_block *es = (struct ext2_super_block *) buf;
972e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	const char *label = 0;
982e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
992e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n",
1002e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		   blkid_le32(es->s_feature_compat),
1012e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		   blkid_le32(es->s_feature_incompat),
1022e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		   blkid_le32(es->s_feature_ro_compat)));
1032e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1047369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	if (strlen(es->s_volume_name))
1052e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		label = es->s_volume_name;
1067369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name));
1072e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1082e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	set_uuid(dev, es->s_uuid);
1092e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o}
1102e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1112e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'ostatic int probe_ext3(int fd __BLKID_ATTR((unused)),
112544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      blkid_cache cache __BLKID_ATTR((unused)),
113544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      blkid_dev dev,
11412b3c8ec1d314b8775fc7d9cefd6bfff551f1de0Theodore Ts'o		      struct blkid_magic *id __BLKID_ATTR((unused)),
11512b3c8ec1d314b8775fc7d9cefd6bfff551f1de0Theodore Ts'o		      unsigned char *buf)
116e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
117e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	struct ext2_super_block *es;
118e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
119e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	es = (struct ext2_super_block *)buf;
120e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
12179dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	/* Distinguish between jbd and ext2/3 fs */
1222e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	if (blkid_le32(es->s_feature_incompat) &
1232e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
124e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_PARAM;
125e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
1262e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	/* Distinguish between ext3 and ext2 */
1272e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	if (!(blkid_le32(es->s_feature_compat) &
1282e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
1292e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		return -BLKID_ERR_PARAM;
130e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
1312e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	get_ext2_info(dev, buf);
132e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
1332e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	blkid_set_tag(dev, "SEC_TYPE", "ext2", sizeof("ext2"));
1342e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1352e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	return 0;
1362e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o}
1372e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1382e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'ostatic int probe_ext2(int fd __BLKID_ATTR((unused)),
1392e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		      blkid_cache cache __BLKID_ATTR((unused)),
1402e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		      blkid_dev dev,
14112b3c8ec1d314b8775fc7d9cefd6bfff551f1de0Theodore Ts'o		      struct blkid_magic *id __BLKID_ATTR((unused)),
14212b3c8ec1d314b8775fc7d9cefd6bfff551f1de0Theodore Ts'o		      unsigned char *buf)
1432e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o{
1442e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	struct ext2_super_block *es;
1452e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1462e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	es = (struct ext2_super_block *)buf;
1472e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1482e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	/* Distinguish between jbd and ext2/3 fs */
1492e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	if (blkid_le32(es->s_feature_incompat) &
1502e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	    EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
1512e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o		return -BLKID_ERR_PARAM;
15205a6edf4fdf3beb93d22116cf4ec39d161ab2790Karel Zak
15305a6edf4fdf3beb93d22116cf4ec39d161ab2790Karel Zak	/* Distinguish between ext3 and ext2 */
15405a6edf4fdf3beb93d22116cf4ec39d161ab2790Karel Zak	if ((blkid_le32(es->s_feature_compat) &
15505a6edf4fdf3beb93d22116cf4ec39d161ab2790Karel Zak	      EXT3_FEATURE_COMPAT_HAS_JOURNAL))
15605a6edf4fdf3beb93d22116cf4ec39d161ab2790Karel Zak		return -BLKID_ERR_PARAM;
1572e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1582e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	get_ext2_info(dev, buf);
15979dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o
160e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return 0;
161e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
162e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
163544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int probe_jbd(int fd __BLKID_ATTR((unused)),
164544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_cache cache __BLKID_ATTR((unused)),
165544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_dev dev,
166544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     struct blkid_magic *id __BLKID_ATTR((unused)),
167544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     unsigned char *buf)
168e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
16950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	struct ext2_super_block *es = (struct ext2_super_block *) buf;
170e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
17176b07bb1bc9cbcb70a94cb235954eaac993920adTheodore Ts'o	if (!(blkid_le32(es->s_feature_incompat) &
17250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	      EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
173e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_PARAM;
174e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
1752e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	get_ext2_info(dev, buf);
1762e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o
1772e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	return 0;
178e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
179e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
180038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'ostatic int probe_fat(int fd __BLKID_ATTR((unused)),
181544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      blkid_cache cache __BLKID_ATTR((unused)),
182544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      blkid_dev dev,
183544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      struct blkid_magic *id __BLKID_ATTR((unused)),
184544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      unsigned char *buf)
185e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
186038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	struct vfat_super_block *vs = (struct vfat_super_block *) buf;
187038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	struct msdos_super_block *ms = (struct msdos_super_block *) buf;
188e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	char serno[10];
189038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	const char *label = 0, *vol_label = 0;
190038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	unsigned char	*vol_serno;
1917369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	int label_len = 0;
192038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u16 sector_size;
193038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u16 dir_entries;
194038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u32 sect_count;
195038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u16 reserved;
196038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u32 fat_size;
197038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u32 dir_size;
198038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u32 cluster_count;
199038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	__u32 fat_length;
200e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
201038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	/* sector size check */
202038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	sector_size = blkid_le16(*((__u16 *) &ms->ms_sector_size));
203038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	if (sector_size != 0x200 && sector_size != 0x400 &&
204038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	    sector_size != 0x800 && sector_size != 0x1000)
205038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		return 1;
206e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
207038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	dir_entries = blkid_le16(*((__u16 *) &ms->ms_dir_entries));
208038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	reserved =  blkid_le16(ms->ms_reserved);
209038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	sect_count = blkid_le16(*((__u16 *) &ms->ms_sectors));
210038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	if (sect_count == 0)
211038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		sect_count = blkid_le32(ms->ms_total_sect);
212e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
213038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	fat_length = blkid_le16(ms->ms_fat_length);
214038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	if (fat_length == 0)
215038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		fat_length = blkid_le32(vs->vs_fat32_length);
216e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
217038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	fat_size = fat_length * ms->ms_fats;
218038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) +
219038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o			(sector_size-1)) / sector_size;
220e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
221038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	cluster_count = sect_count - (reserved + fat_size + dir_size);
222038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	cluster_count /= ms->ms_cluster_size;
223e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
224038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	if (cluster_count > FAT32_MAX)
225038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		return 1;
226038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o
227038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	if (ms->ms_fat_length) {
228038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		vol_label = ms->ms_label;
229038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		vol_serno = ms->ms_serno;
230038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o
231038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		blkid_set_tag(dev, "SEC_TYPE", "msdos", sizeof("msdos"));
232038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	} else {
233038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		vol_label = vs->vs_label;
234038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		vol_serno = vs->vs_serno;
235038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	}
236e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
237038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	if (vol_label && memcmp(vol_label, "NO NAME    ", 11)) {
23845a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		label = vol_label;
23945a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		label_len = figure_label_len(vol_label, 11);
240e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
241e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
242e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	/* We can't just print them as %04X, because they are unaligned */
243038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	sprintf(serno, "%02X%02X-%02X%02X", vol_serno[3], vol_serno[2],
244038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o		vol_serno[1], vol_serno[0]);
245038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o
2467369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, label_len);
247038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	blkid_set_tag(dev, "UUID", serno, sizeof(serno)-1);
248e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
249e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return 0;
250e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
251e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
252c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak/*
253c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak * The FAT filesystem could be without a magic string in superblock
254c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak * (e.g. old floppies).  This heuristic for FAT detection is inspired
255c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak * by http://vrfy.org/projects/volume_id/ and Linux kernel.
256c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak * [7-Jul-2005, Karel Zak <kzak@redhat.com>]
257c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak */
258038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'ostatic int probe_fat_nomagic(int fd __BLKID_ATTR((unused)),
259038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o			     blkid_cache cache __BLKID_ATTR((unused)),
260038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o			     blkid_dev dev,
261038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o			     struct blkid_magic *id __BLKID_ATTR((unused)),
262038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o			     unsigned char *buf)
263c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak{
264c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	struct vfat_super_block *vs;
265c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
266c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	vs = (struct vfat_super_block *)buf;
267c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
268c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	/* heads check */
269c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	if (vs->vs_heads == 0)
270c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak		return 1;
271c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
272c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	/* cluster size check*/
273c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	if (vs->vs_cluster_size == 0 ||
274c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	    (vs->vs_cluster_size & (vs->vs_cluster_size-1)))
275c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak		return 1;
276c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
277c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	/* media check */
278c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	if (vs->vs_media < 0xf8 && vs->vs_media != 0xf0)
279c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak		return 1;
280c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
281c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	/* fat counts(Linux kernel expects at least 1 FAT table) */
282c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak	if (!vs->vs_fats)
283c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak		return 1;
284c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
285038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o	return probe_fat(fd, cache, dev, id, buf);
286c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak}
287c4c740ff488dae232dd3a64fccd26ec7265165a4Karel Zak
288544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int probe_xfs(int fd __BLKID_ATTR((unused)),
289544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_cache cache __BLKID_ATTR((unused)),
290544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_dev dev,
291544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     struct blkid_magic *id __BLKID_ATTR((unused)),
292544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     unsigned char *buf)
293e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
294e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	struct xfs_super_block *xs;
295a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	const char *label = 0;
296e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
297e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	xs = (struct xfs_super_block *)buf;
298e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
299e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (strlen(xs->xs_fname))
300a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o		label = xs->xs_fname;
301a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	blkid_set_tag(dev, "LABEL", label, sizeof(xs->xs_fname));
30250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	set_uuid(dev, xs->xs_uuid);
303e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return 0;
304e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
305e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
306544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int probe_reiserfs(int fd __BLKID_ATTR((unused)),
307544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			  blkid_cache cache __BLKID_ATTR((unused)),
308544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o			  blkid_dev dev,
30979dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o			  struct blkid_magic *id, unsigned char *buf)
310e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
31150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf;
312e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	unsigned int blocksize;
313a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	const char *label = 0;
314e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
31576b07bb1bc9cbcb70a94cb235954eaac993920adTheodore Ts'o	blocksize = blkid_le16(rs->rs_blocksize);
316e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
317e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	/* If the superblock is inside the journal, we have the wrong one */
31850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block))
319e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return -BLKID_ERR_BIG;
320e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
321e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	/* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
322e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (!strcmp(id->bim_magic, "ReIsEr2Fs") ||
323e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	    !strcmp(id->bim_magic, "ReIsEr3Fs")) {
324a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o		if (strlen(rs->rs_label))
325a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o			label = rs->rs_label;
32650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		set_uuid(dev, rs->rs_uuid);
327e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
3287369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, sizeof(rs->rs_label));
329e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
330e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return 0;
331e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
332e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
333bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'ostatic int probe_reiserfs4(int fd __BLKID_ATTR((unused)),
334bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o			   blkid_cache cache __BLKID_ATTR((unused)),
335bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o			   blkid_dev dev,
336bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o			   struct blkid_magic *id, unsigned char *buf)
337bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o{
338bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	struct reiser4_super_block *rs4 = (struct reiser4_super_block *) buf;
339bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	unsigned int blocksize;
340bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	const char *label = 0;
341bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o
342bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	if (strlen(rs4->rs4_label))
343bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o		label = rs4->rs4_label;
344bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	set_uuid(dev, rs4->rs4_uuid);
345bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, sizeof(rs4->rs4_label));
346bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o
347bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o	return 0;
348bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o}
349bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o
350544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int probe_jfs(int fd __BLKID_ATTR((unused)),
351544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_cache cache __BLKID_ATTR((unused)),
352544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_dev dev,
353544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     struct blkid_magic *id __BLKID_ATTR((unused)),
354544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     unsigned char *buf)
35509a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o{
35609a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	struct jfs_super_block *js;
357a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	const char *label = 0;
35809a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o
35909a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	js = (struct jfs_super_block *)buf;
36009a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o
36148e6e81362f264aee4f3945c14928efaf71a06c9Theodore Ts'o	if (strlen((char *) js->js_label))
362a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o		label = (char *) js->js_label;
363a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	blkid_set_tag(dev, "LABEL", label, sizeof(js->js_label));
36409a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	set_uuid(dev, js->js_uuid);
36509a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	return 0;
36609a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o}
36709a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o
368544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int probe_romfs(int fd __BLKID_ATTR((unused)),
369544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		       blkid_cache cache __BLKID_ATTR((unused)),
370544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		       blkid_dev dev,
371544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		       struct blkid_magic *id __BLKID_ATTR((unused)),
372544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		       unsigned char *buf)
37309a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o{
37409a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	struct romfs_super_block *ros;
375a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	const char *label = 0;
37609a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o
37709a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	ros = (struct romfs_super_block *)buf;
37809a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o
379a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o	if (strlen((char *) ros->ros_volume))
380a30b9446d1899260159968826428722f2dcbbc64Theodore Ts'o		label = (char *) ros->ros_volume;
3817369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, 0);
3827369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	return 0;
3837369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o}
3847369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o
3854c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'ostatic int probe_cramfs(int fd __BLKID_ATTR((unused)),
3864c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o		       blkid_cache cache __BLKID_ATTR((unused)),
3874c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o		       blkid_dev dev,
3884c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o		       struct blkid_magic *id __BLKID_ATTR((unused)),
3894c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o		       unsigned char *buf)
3904c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o{
3914c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o	struct cramfs_super_block *csb;
3924c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o	const char *label = 0;
3934c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o
3944c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o	csb = (struct cramfs_super_block *)buf;
3954c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o
3964c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o	if (strlen((char *) csb->name))
3974c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o		label = (char *) csb->name;
3984c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, 0);
3994c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o	return 0;
4004c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o}
4014c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o
4027369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'ostatic int probe_swap0(int fd __BLKID_ATTR((unused)),
4037369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       blkid_cache cache __BLKID_ATTR((unused)),
4047369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       blkid_dev dev,
4057369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       struct blkid_magic *id __BLKID_ATTR((unused)),
4067369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       unsigned char *buf __BLKID_ATTR((unused)))
4077369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o{
4087369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	blkid_set_tag(dev, "UUID", 0, 0);
4097369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	blkid_set_tag(dev, "LABEL", 0, 0);
4107369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	return 0;
4117369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o}
4127369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o
4137369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'ostatic int probe_swap1(int fd,
4147369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       blkid_cache cache __BLKID_ATTR((unused)),
4157369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       blkid_dev dev,
4167369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       struct blkid_magic *id __BLKID_ATTR((unused)),
4177369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		       unsigned char *buf __BLKID_ATTR((unused)))
4187369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o{
4197369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	struct swap_id_block *sws;
4207369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o
4217369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	probe_swap0(fd, cache, dev, id, buf);
4227369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	/*
4237369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	 * Version 1 swap headers are always located at offset of 1024
4247369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	 * bytes, although the swap signature itself is located at the
4257369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	 * end of the page (which may vary depending on hardware
4267369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	 * pagesize).
4277369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	 */
4287369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	if (lseek(fd, 1024, SEEK_SET) < 0) return 1;
4297369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	if (!(sws = (struct swap_id_block *)malloc(1024))) return 1;
4307369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	if (read(fd, sws, 1024) != 1024) {
4317369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		free(sws);
4327369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		return 1;
4337369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	}
4347369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o
4357369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	/* arbitrary sanity check.. is there any garbage down there? */
4367369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	if (sws->sws_pad[32] == 0 && sws->sws_pad[33] == 0)  {
4377369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		if (sws->sws_volume[0])
4387369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o			blkid_set_tag(dev, "LABEL", sws->sws_volume,
4397369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o				      sizeof(sws->sws_volume));
4407369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o		if (sws->sws_uuid[0])
4417369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o			set_uuid(dev, sws->sws_uuid);
4427369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	}
4437369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o	free(sws);
4447369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o
44509a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o	return 0;
44609a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o}
44709a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o
44845a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'ostatic int probe_iso9660(int fd, blkid_cache cache __BLKID_ATTR((unused)),
44945a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o			 blkid_dev dev __BLKID_ATTR((unused)),
45045a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o			 struct blkid_magic *id __BLKID_ATTR((unused)),
45145a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o			 unsigned char *buf)
45245a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o{
45345a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	struct iso_volume_descriptor *iso;
45445a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	const unsigned char *label;
45545a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
45645a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	iso = (struct iso_volume_descriptor *) buf;
45745a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
45845a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	label = iso->volume_id;
45945a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
46045a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	blkid_set_tag(dev, "LABEL", label, figure_label_len(label, 32));
46145a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o	return 0;
46245a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o}
46345a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
46445a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o
465544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic const char
4663de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
4673de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		 "NSR03", "TEA01", 0 };
4683de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o
469544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'ostatic int probe_udf(int fd, blkid_cache cache __BLKID_ATTR((unused)),
470544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     blkid_dev dev __BLKID_ATTR((unused)),
471544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		       struct blkid_magic *id __BLKID_ATTR((unused)),
472544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		     unsigned char *buf __BLKID_ATTR((unused)))
4733de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o{
4743de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	int j, bs;
4753de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	struct iso_volume_descriptor isosb;
476544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o	const char ** m;
4773de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o
4783de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	/* determine the block size by scanning in 2K increments
4793de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	   (block sizes larger than 2K will be null padded) */
4803de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	for (bs = 1; bs < 16; bs++) {
4813de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		lseek(fd, bs*2048+32768, SEEK_SET);
4823de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb))
4833de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			return 1;
48445a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		if (isosb.vd_id[0])
4853de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			break;
4863de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	}
4873de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o
4883de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	/* Scan up to another 64 blocks looking for additional VSD's */
4893de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	for (j = 1; j < 64; j++) {
4903de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		if (j > 1) {
4913de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			lseek(fd, j*bs*2048+32768, SEEK_SET);
4923de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			if (read(fd, (char *)&isosb, sizeof(isosb))
4933de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			    != sizeof(isosb))
4943de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o				return 1;
4953de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		}
4963de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		/* If we find NSR0x then call it udf:
4973de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		   NSR01 for UDF 1.00
4983de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		   NSR02 for UDF 1.50
4993de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		   NSR03 for UDF 2.00 */
50045a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o		if (!strncmp(isosb.vd_id, "NSR0", 4))
5013de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			return 0;
5023de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		for (m = udf_magic; *m; m++)
50345a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o			if (!strncmp(*m, isosb.vd_id, 5))
5043de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o				break;
5053de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o		if (*m == 0)
5063de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o			return 1;
5073de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	}
5083de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o	return 1;
5093de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o}
5103de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o
5119387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'ostatic int probe_ocfs(int fd __BLKID_ATTR((unused)),
5129387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o		      blkid_cache cache __BLKID_ATTR((unused)),
5139387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o		      blkid_dev dev,
5149387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o		      struct blkid_magic *id __BLKID_ATTR((unused)),
5159387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o		      unsigned char *buf)
5169387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o{
5179387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	struct ocfs_volume_header ovh;
5189387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	struct ocfs_volume_label ovl;
5193838f7df134035089e8e8df317112e4fd645602dTheodore Ts'o	__u32 major;
5209387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o
5219387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	memcpy(&ovh, buf, sizeof(ovh));
5229387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	memcpy(&ovl, buf+512, sizeof(ovl));
5239387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o
5249387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	major = ocfsmajor(ovh);
5259387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	if (major == 1)
5264b8f81aace86dd308d5af4669eab116d1a8c8418Theodore Ts'o		blkid_set_tag(dev,"SEC_TYPE","ocfs1",sizeof("ocfs1"));
5279387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	else if (major >= 9)
5289387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o		blkid_set_tag(dev,"SEC_TYPE","ntocfs",sizeof("ntocfs"));
5299387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o
5309387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	blkid_set_tag(dev, "LABEL", ovl.label, ocfslabellen(ovl));
5319387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	blkid_set_tag(dev, "MOUNT", ovh.mount, ocfsmountlen(ovh));
5329387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	set_uuid(dev, ovl.vol_id);
5339387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o	return 0;
5349387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o}
5359387c281ef88cd1fba7cb1c9336b5ab00a2d82b4Theodore Ts'o
536414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'ostatic int probe_ocfs2(int fd __BLKID_ATTR((unused)),
5372c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o		       blkid_cache cache __BLKID_ATTR((unused)),
5382c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o		       blkid_dev dev,
5392c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o		       struct blkid_magic *id __BLKID_ATTR((unused)),
5402c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o		       unsigned char *buf)
541414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o{
542414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o	struct ocfs2_super_block *osb;
543414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o
544414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o	osb = (struct ocfs2_super_block *)buf;
545414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o
546414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o	blkid_set_tag(dev, "LABEL", osb->s_label, sizeof(osb->s_label));
547414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o	set_uuid(dev, osb->s_uuid);
548414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o	return 0;
549414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o}
550414846b126d4d751bd6b36df0a39dcb030e0feb3Theodore Ts'o
5512c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'ostatic int probe_oracleasm(int fd __BLKID_ATTR((unused)),
5522c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o			   blkid_cache cache __BLKID_ATTR((unused)),
5532c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o			   blkid_dev dev,
5542c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o			   struct blkid_magic *id __BLKID_ATTR((unused)),
5552c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o			   unsigned char *buf)
5562c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o{
5572c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o	struct oracle_asm_disk_label *dl;
5582c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o
5592c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o	dl = (struct oracle_asm_disk_label *)buf;
5602c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o
5612c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o	blkid_set_tag(dev, "LABEL", dl->dl_id, sizeof(dl->dl_id));
5622c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o	return 0;
5632c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o}
5642c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o
565e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
566e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
56750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * in the type_array table below + bim_kbalign.
56850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o *
56950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * When probing for a lot of magics, we handle everything in 1kB buffers so
57050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o * that we don't have to worry about reading each combination of block sizes.
571e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
57250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o#define BLKID_BLK_OFFS	64	/* currently reiserfs */
573e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
574e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
575e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Various filesystem magics that we can check for.  Note that kboff and
576e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * sboff are in kilobytes and bytes respectively.  All magics are in
577e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * byte strings so we don't worry about endian issues.
578e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
57950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'ostatic struct blkid_magic type_array[] = {
58050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o/*  type     kboff   sboff len  magic			probe */
5812c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o  { "oracleasm", 0,	32,  8, "ORCLDISK",		probe_oracleasm },
5829d0f46169f8c3df2e07b262b1f1b3f3c75aba2c6Theodore Ts'o  { "ntfs",      0,      3,  8, "NTFS    ",             0 },
58350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "jbd",	 1,   0x38,  2, "\123\357",		probe_jbd },
5842e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o  { "ext3",	 1,   0x38,  2, "\123\357",		probe_ext3 },
58550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "ext2",	 1,   0x38,  2, "\123\357",		probe_ext2 },
58650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "reiserfs",	 8,   0x34,  8, "ReIsErFs",		probe_reiserfs },
58750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "reiserfs", 64,   0x34,  9, "ReIsEr2Fs",		probe_reiserfs },
58850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "reiserfs", 64,   0x34,  9, "ReIsEr3Fs",		probe_reiserfs },
58950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "reiserfs", 64,   0x34,  8, "ReIsErFs",		probe_reiserfs },
59050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "reiserfs",	 8,	20,  8, "ReIsErFs",		probe_reiserfs },
591bb626bcd546a039b39b9f25e65881b36b2abe24fTheodore Ts'o  { "reiser4",  64,	 0,  7, "ReIsEr4",		probe_reiserfs4 },
592038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,   0x52,  5, "MSWIN",                probe_fat },
593038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,   0x52,  8, "FAT32   ",             probe_fat },
594038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,   0x36,  5, "MSDOS",                probe_fat },
595038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,   0x36,  8, "FAT16   ",             probe_fat },
596038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,   0x36,  8, "FAT12   ",             probe_fat },
597038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,      0,  2, "\353\220",             probe_fat_nomagic },
598038d2bedaad526f91c9e4f55184bcaa59e245e27Theodore Ts'o  { "vfat",      0,      0,  1, "\351",                 probe_fat_nomagic },
59950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "minix",     1,   0x10,  2, "\177\023",             0 },
60050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "minix",     1,   0x10,  2, "\217\023",             0 },
60150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "minix",	 1,   0x10,  2, "\150\044",		0 },
60250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "minix",	 1,   0x10,  2, "\170\044",		0 },
60350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "vxfs",	 1,	 0,  4, "\365\374\001\245",	0 },
60450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "xfs",	 0,	 0,  4, "XFSB",			probe_xfs },
60509a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o  { "romfs",	 0,	 0,  8, "-rom1fs-",		probe_romfs },
60650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "bfs",	 0,	 0,  4, "\316\372\173\033",	0 },
6074c4e3f784330978fa127edaa3936957d38c7e93aTheodore Ts'o  { "cramfs",	 0,	 0,  4, "E=\315\050",		probe_cramfs },
60850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "qnx4",	 0,	 4,  6, "QNX4FS",		0 },
6093de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "BEA01",		probe_udf },
6103de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "BOOT2",		probe_udf },
6113de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "CD001",		probe_udf },
6123de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "CDW02",		probe_udf },
6133de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "NSR02",		probe_udf },
6143de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "NSR03",		probe_udf },
6153de5bf61060634c5c8c3a0d231e8a7246094a2c2Theodore Ts'o  { "udf",	32,	 1,  5, "TEA01",		probe_udf },
61645a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o  { "iso9660",	32,	 1,  5, "CD001",		probe_iso9660 },
61745a3fa873852ce407b5eda0f764c63bab04e4c0cTheodore Ts'o  { "iso9660",	32,	 9,  5, "CDROM",		probe_iso9660 },
61809a2ef8ddab7fed91b9ec8314e0a10e11d3c0323Theodore Ts'o  { "jfs",	32,	 0,  4, "JFS1",			probe_jfs },
61950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "hfs",	 1,	 0,  2, "BD",			0 },
62050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "ufs",	 8,  0x55c,  4, "T\031\001\000",	0 },
62150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "hpfs",	 8,	 0,  4, "I\350\225\371",	0 },
62250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  { "sysv",	 0,  0x3f8,  4, "\020~\030\375",	0 },
6237369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0,  0xff6, 10, "SWAP-SPACE",		probe_swap0 },
6247369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0,  0xff6, 10, "SWAPSPACE2",		probe_swap1 },
625abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0,  0xff6,  9, "S1SUSPEND",		probe_swap1 },
626abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0,  0xff6,  9, "S2SUSPEND",		probe_swap1 },
6277369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0x1ff6, 10, "SWAP-SPACE",		probe_swap0 },
6287369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0x1ff6, 10, "SWAPSPACE2",		probe_swap1 },
629abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0x1ff6,  9, "S1SUSPEND",		probe_swap1 },
630abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0x1ff6,  9, "S2SUSPEND",		probe_swap1 },
6317369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0x3ff6, 10, "SWAP-SPACE",		probe_swap0 },
6327369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0x3ff6, 10, "SWAPSPACE2",		probe_swap1 },
633abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0x3ff6,  9, "S1SUSPEND",		probe_swap1 },
634abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0x3ff6,  9, "S2SUSPEND",		probe_swap1 },
6357369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0x7ff6, 10, "SWAP-SPACE",		probe_swap0 },
6367369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0x7ff6, 10, "SWAPSPACE2",		probe_swap1 },
637abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0x7ff6,  9, "S1SUSPEND",		probe_swap1 },
638abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0x7ff6,  9, "S2SUSPEND",		probe_swap1 },
6397369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0xfff6, 10, "SWAP-SPACE",		probe_swap0 },
6407369f0ce5fdde7f8a1cc6e49211469b905c2c58fTheodore Ts'o  { "swap",	 0, 0xfff6, 10, "SWAPSPACE2",		probe_swap1 },
641abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0xfff6,  9, "S1SUSPEND",		probe_swap1 },
642abaa11240a742bcfc4783e2cbebb7dd0cdf17e96Karel Zak  { "swsuspend", 0, 0xfff6,  9, "S2SUSPEND",		probe_swap1 },
6432c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o  { "ocfs",	 0,	 8,  9,	"OracleCFS",		probe_ocfs },
6442c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o  { "ocfs2",	 1,	 0,  6,	"OCFSV2",		probe_ocfs2 },
6452c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o  { "ocfs2",	 2,	 0,  6,	"OCFSV2",		probe_ocfs2 },
6462c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o  { "ocfs2",	 4,	 0,  6,	"OCFSV2",		probe_ocfs2 },
6472c92375ea426768a6e37faf876b2b06f0bf781a6Theodore Ts'o  { "ocfs2",	 8,	 0,  6,	"OCFSV2",		probe_ocfs2 },
64850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o  {   NULL,	 0,	 0,  0, NULL,			NULL }
649e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o};
650e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
651e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o/*
652e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * Verify that the data in dev is consistent with what is on the actual
653e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * block device (using the devname field only).  Normally this will be
654e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * called when finding items in the cache, but for long running processes
655e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * is also desirable to revalidate an item before use.
656e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o *
657e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * If we are unable to revalidate the data, we return the old data and
658e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o * do not set the BLKID_BID_FL_VERIFIED flag on it.
659e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o */
66018d12963335b04a402d097af1d714e8708805adaTheodore Ts'oblkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
661e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
662e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	struct blkid_magic *id;
66350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	unsigned char *bufs[BLKID_BLK_OFFS + 1], *buf;
66479dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	const char *type;
66550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	struct stat st;
6667ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	time_t diff, now;
66750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	int fd, idx;
668e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
669e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (!dev)
670e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return NULL;
671e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
6727ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	now = time(0);
6737ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	diff = now - dev->bid_time;
674e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
6757ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	if ((now < dev->bid_time) ||
6767ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	    (diff < BLKID_PROBE_MIN) ||
6777ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	    (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
6787ce08064061ed66647fa2c152c65f2f28eac9a0aTheodore Ts'o	     diff < BLKID_PROBE_INTERVAL))
679e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return dev;
680e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
681f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o	DBG(DEBUG_PROBE,
682f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o	    printf("need to revalidate %s (time since last check %lu)\n",
683ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		   dev->bid_name, diff));
684e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
68550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (((fd = open(dev->bid_name, O_RDONLY)) < 0) ||
6862e6a9febb48ea0e57d32cacb5e67220443c0e059Theodore Ts'o	    (fstat(fd, &st) < 0)) {
687ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		if (errno == ENXIO || errno == ENODEV || errno == ENOENT) {
688e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			blkid_free_dev(dev);
689e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			return NULL;
690e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		}
691e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		/* We don't have read permission, just return cache data. */
692f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o		DBG(DEBUG_PROBE,
693f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o		    printf("returning unverified data for %s\n",
694f0a22d0fd3ec3f45b562af5afba8811f72b94a28Theodore Ts'o			   dev->bid_name));
695e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		return dev;
696e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
697e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
69850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	memset(bufs, 0, sizeof(bufs));
69950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
70050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	/*
70150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	 * Iterate over the type array.  If we already know the type,
70250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	 * then try that first.  If it doesn't work, then blow away
70350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	 * the type information, and try again.
70450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	 *
70550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	 */
70650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'otry_again:
70750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	type = 0;
70850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) {
70950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		uuid_t	uuid;
71050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
71150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (check_mdraid(fd, uuid) == 0) {
71250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			set_uuid(dev, uuid);
71350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			type = "mdraid";
71450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			goto found_type;
71550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		}
71650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
717e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	for (id = type_array; id->bim_type; id++) {
71850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (dev->bid_type &&
71950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		    strcmp(id->bim_type, dev->bid_type))
72050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			continue;
72150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
72250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		idx = id->bim_kboff + (id->bim_sboff >> 10);
72350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (idx > BLKID_BLK_OFFS || idx < 0)
72450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			continue;
72550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		buf = bufs[idx];
72650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (!buf) {
72750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			if (lseek(fd, idx << 10, SEEK_SET) < 0)
72850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o				continue;
72950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
73050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			if (!(buf = (unsigned char *)malloc(1024)))
73150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o				continue;
73250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
73350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			if (read(fd, buf, 1024) != 1024) {
73450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o				free(buf);
73550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o				continue;
736e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			}
73750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			bufs[idx] = buf;
73850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		}
739e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
74050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if (memcmp(id->bim_magic, buf + (id->bim_sboff&0x3ff),
74150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			   id->bim_len))
74250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			continue;
74350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
74450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		if ((id->bim_probe == NULL) ||
74579dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		    (id->bim_probe(fd, cache, dev, id, buf) == 0)) {
74650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			type = id->bim_type;
74750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			goto found_type;
748e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		}
749e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
750e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
75150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!id->bim_type && dev->bid_type) {
75250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		/*
75350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		 * Zap the device filesystem type and try again
75450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		 */
75579dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		blkid_set_tag(dev, "TYPE", 0, 0);
75679dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		blkid_set_tag(dev, "SEC_TYPE", 0, 0);
75779dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		blkid_set_tag(dev, "LABEL", 0, 0);
75879dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		blkid_set_tag(dev, "UUID", 0, 0);
75950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		goto try_again;
76050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
761e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
76250b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!dev->bid_type) {
763e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		blkid_free_dev(dev);
76450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		return NULL;
76550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
76650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
76750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'ofound_type:
76850b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (dev && type) {
76950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev->bid_devno = st.st_rdev;
77050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev->bid_time = time(0);
77150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		dev->bid_flags |= BLKID_BID_FL_VERIFIED;
772ce72b862c59da24ba16b354d687549276a24f908Theodore Ts'o		cache->bic_flags |= BLKID_BIC_FL_CHANGED;
77350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
77479dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		blkid_set_tag(dev, "TYPE", type, 0);
77550b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
77612b3c8ec1d314b8775fc7d9cefd6bfff551f1de0Theodore Ts'o		DBG(DEBUG_PROBE, printf("%s: devno 0x%04llx, type %s\n",
77750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o			   dev->bid_name, st.st_rdev, type));
778e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
779e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
780e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	close(fd);
781e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
782e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return dev;
783e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
784e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
78578e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'oint blkid_known_fstype(const char *fstype)
78678e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o{
78778e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o	struct blkid_magic *id;
78878e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o
78978e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o	for (id = type_array; id->bim_type; id++) {
79078e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o		if (strcmp(fstype, id->bim_type) == 0)
79178e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o			return 1;
79278e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o	}
79378e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o	return 0;
79478e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o}
79578e2edf796e7902b8ce615ca8388840ef1387194Theodore Ts'o
796e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#ifdef TEST_PROGRAM
797e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'oint main(int argc, char **argv)
798e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o{
7997a603aa89fcffb8798eca34ca3858db6f0393046Theodore Ts'o	blkid_dev dev;
80050b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	blkid_cache cache;
80179dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	int ret;
802e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o
803e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	if (argc != 2) {
804e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		fprintf(stderr, "Usage: %s device\n"
805e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o			"Probe a single device to determine type\n", argv[0]);
806e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		exit(1);
807e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	}
80879dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
80979dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		fprintf(stderr, "%s: error creating cache (%d)\n",
81079dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o			argv[0], ret);
81179dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o		exit(1);
81279dd234a799434b6dc8365c49e743f00eb09d2fdTheodore Ts'o	}
81398999c399d563c248728bf217467a788cb0c1aadTheodore Ts'o	dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
81450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (!dev) {
815e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o		printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
81650b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o		return (1);
81750b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	}
8181e5630abab066035602437ed047e0988064687f0Theodore Ts'o	printf("TYPE='%s'\n", dev->bid_type ? dev->bid_type : "(null)");
81950b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (dev->bid_label)
8201e5630abab066035602437ed047e0988064687f0Theodore Ts'o		printf("LABEL='%s'\n", dev->bid_label);
82150b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	if (dev->bid_uuid)
8221e5630abab066035602437ed047e0988064687f0Theodore Ts'o		printf("UUID='%s'\n", dev->bid_uuid);
82350b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o
82450b380b4d4ab668bad45033e3a8aaf93c7f42844Theodore Ts'o	blkid_free_dev(dev);
825e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o	return (0);
826e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o}
827e12f2ae74c2eb8997bf13adf8fdd7e7313971eaeTheodore Ts'o#endif
828