diff options
Diffstat (limited to '')
-rw-r--r-- | libblkid/ext.c | 540 |
1 files changed, 0 insertions, 540 deletions
diff --git a/libblkid/ext.c b/libblkid/ext.c deleted file mode 100644 index eff96a066..000000000 --- a/libblkid/ext.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (C) 1999, 2001 by Andries Brouwer - * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o - * Copyright (C) 2008 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <stdint.h> -#ifdef __linux__ -#include <sys/utsname.h> -#endif -#include <time.h> - -#include "linux_version.h" -#include "superblocks.h" - -struct ext2_super_block { - uint32_t s_inodes_count; - uint32_t s_blocks_count; - uint32_t s_r_blocks_count; - uint32_t s_free_blocks_count; - uint32_t s_free_inodes_count; - uint32_t s_first_data_block; - uint32_t s_log_block_size; - uint32_t s_dummy3[7]; - unsigned char s_magic[2]; - uint16_t s_state; - uint16_t s_errors; - uint16_t s_minor_rev_level; - uint32_t s_lastcheck; - uint32_t s_checkinterval; - uint32_t s_creator_os; - uint32_t s_rev_level; - uint16_t s_def_resuid; - uint16_t s_def_resgid; - uint32_t s_first_ino; - uint16_t s_inode_size; - uint16_t s_block_group_nr; - uint32_t s_feature_compat; - uint32_t s_feature_incompat; - uint32_t s_feature_ro_compat; - unsigned char s_uuid[16]; - char s_volume_name[16]; - char s_last_mounted[64]; - uint32_t s_algorithm_usage_bitmap; - uint8_t s_prealloc_blocks; - uint8_t s_prealloc_dir_blocks; - uint16_t s_reserved_gdt_blocks; - uint8_t s_journal_uuid[16]; - uint32_t s_journal_inum; - uint32_t s_journal_dev; - uint32_t s_last_orphan; - uint32_t s_hash_seed[4]; - uint8_t s_def_hash_version; - uint8_t s_jnl_backup_type; - uint16_t s_reserved_word_pad; - uint32_t s_default_mount_opts; - uint32_t s_first_meta_bg; - uint32_t s_mkfs_time; - uint32_t s_jnl_blocks[17]; - uint32_t s_blocks_count_hi; - uint32_t s_r_blocks_count_hi; - uint32_t s_free_blocks_hi; - uint16_t s_min_extra_isize; - uint16_t s_want_extra_isize; - uint32_t s_flags; - uint16_t s_raid_stride; - uint16_t s_mmp_interval; - uint64_t s_mmp_block; - uint32_t s_raid_stripe_width; - uint32_t s_reserved[163]; -} __attribute__((packed)); - -/* magic string */ -#define EXT_SB_MAGIC "\123\357" -/* supper block offset */ -#define EXT_SB_OFF 0x400 -/* supper block offset in kB */ -#define EXT_SB_KBOFF (EXT_SB_OFF >> 10) -/* magic string offset within super block */ -#define EXT_MAG_OFF 0x38 - - - -/* for s_flags */ -#define EXT2_FLAGS_TEST_FILESYS 0x0004 - -/* for s_feature_compat */ -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 - -/* for s_feature_ro_compat */ -#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 -#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 -#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 -#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 - -/* for s_feature_incompat */ -#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ -#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 - -#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP -#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP - -#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED ~EXT3_FEATURE_INCOMPAT_SUPP -#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP - -/* - * Check to see if a filesystem is in /proc/filesystems. - * Returns 1 if found, 0 if not - */ -static int fs_proc_check(const char *fs_name) -{ - FILE *f; - char buf[80], *cp, *t; - - f = fopen("/proc/filesystems", "r"); - if (!f) - return 0; - while (!feof(f)) { - if (!fgets(buf, sizeof(buf), f)) - break; - cp = buf; - if (!isspace(*cp)) { - while (*cp && !isspace(*cp)) - cp++; - } - while (*cp && isspace(*cp)) - cp++; - if ((t = strchr(cp, '\n')) != NULL) - *t = 0; - if ((t = strchr(cp, '\t')) != NULL) - *t = 0; - if ((t = strchr(cp, ' ')) != NULL) - *t = 0; - if (!strcmp(fs_name, cp)) { - fclose(f); - return 1; - } - } - fclose(f); - return (0); -} - -/* - * Check to see if a filesystem is available as a module - * Returns 1 if found, 0 if not - */ -static int check_for_modules(const char *fs_name) -{ -#ifdef __linux__ - struct utsname uts; - FILE *f; - char buf[1024], *cp; - int namesz; - - if (uname(&uts)) - return 0; - snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release); - - f = fopen(buf, "r"); - if (!f) - return 0; - - namesz = strlen(fs_name); - - while (!feof(f)) { - if (!fgets(buf, sizeof(buf), f)) - break; - if ((cp = strchr(buf, ':')) != NULL) - *cp = 0; - else - continue; - if ((cp = strrchr(buf, '/')) == NULL) - continue; - cp++; - - if (!strncmp(cp, fs_name, namesz) && - (!strcmp(cp + namesz, ".ko") || - !strcmp(cp + namesz, ".ko.gz"))) { - fclose(f); - return 1; - } - } - fclose(f); -#endif /* __linux__ */ - return 0; -} - -/* - * Starting in 2.6.29, ext4 can be used to support filesystems - * without a journal. - */ -#define EXT4_SUPPORTS_EXT2 KERNEL_VERSION(2, 6, 29) - -static int system_supports_ext2(void) -{ - static time_t last_check = 0; - static int ret = -1; - time_t now = time(0); - - if (ret != -1 || (now - last_check) < 5) - return ret; - last_check = now; - ret = (fs_proc_check("ext2") || check_for_modules("ext2")); - return ret; -} - -static int system_supports_ext4(void) -{ - static time_t last_check = 0; - static int ret = -1; - time_t now = time(0); - - if (ret != -1 || (now - last_check) < 5) - return ret; - last_check = now; - ret = (fs_proc_check("ext4") || check_for_modules("ext4")); - return ret; -} - -static int system_supports_ext4dev(void) -{ - static time_t last_check = 0; - static int ret = -1; - time_t now = time(0); - - if (ret != -1 || (now - last_check) < 5) - return ret; - last_check = now; - ret = (fs_proc_check("ext4dev") || check_for_modules("ext4dev")); - return ret; -} - -static int system_supports_ext4_ext2(void) -{ -#ifdef __linux__ - return get_linux_version() >= EXT4_SUPPORTS_EXT2; -#else - return 0; -#endif -} -/* - * reads superblock and returns: - * fc = feature_compat - * fi = feature_incompat - * frc = feature_ro_compat - */ -static struct ext2_super_block *ext_get_super( - blkid_probe pr, uint32_t *fc, uint32_t *fi, uint32_t *frc) -{ - struct ext2_super_block *es; - - es = (struct ext2_super_block *) - blkid_probe_get_buffer(pr, EXT_SB_OFF, 0x200); - if (!es) - return NULL; - if (fc) - *fc = le32_to_cpu(es->s_feature_compat); - if (fi) - *fi = le32_to_cpu(es->s_feature_incompat); - if (frc) - *frc = le32_to_cpu(es->s_feature_ro_compat); - - return es; -} - -static void ext_get_info(blkid_probe pr, int ver, struct ext2_super_block *es) -{ - struct blkid_chain *chn = blkid_probe_get_chain(pr); - - DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n", - le32_to_cpu(es->s_feature_compat), - le32_to_cpu(es->s_feature_incompat), - le32_to_cpu(es->s_feature_ro_compat))); - - if (strlen(es->s_volume_name)) - blkid_probe_set_label(pr, (unsigned char *) es->s_volume_name, - sizeof(es->s_volume_name)); - blkid_probe_set_uuid(pr, es->s_uuid); - - if (le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) - blkid_probe_set_uuid_as(pr, es->s_journal_uuid, "EXT_JOURNAL"); - - if (ver != 2 && (chn->flags & BLKID_SUBLKS_SECTYPE) && - ((le32_to_cpu(es->s_feature_incompat) & EXT2_FEATURE_INCOMPAT_UNSUPPORTED) == 0)) - blkid_probe_set_value(pr, "SEC_TYPE", - (unsigned char *) "ext2", - sizeof("ext2")); - - blkid_probe_sprintf_version(pr, "%u.%u", - le32_to_cpu(es->s_rev_level), - le16_to_cpu(es->s_minor_rev_level)); -} - - -static int probe_jbd(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) -{ - struct ext2_super_block *es; - uint32_t fi; - - es = ext_get_super(pr, NULL, &fi, NULL); - if (!es) - return -BLKID_ERR_PARAM; - if (!(fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) - return -BLKID_ERR_PARAM; - - ext_get_info(pr, 2, es); - return 0; -} - -static int probe_ext2(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -BLKID_ERR_PARAM; - - /* Distinguish between ext3 and ext2 */ - if (fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) - return -BLKID_ERR_PARAM; - - /* Any features which ext2 doesn't understand */ - if ((frc & EXT2_FEATURE_RO_COMPAT_UNSUPPORTED) || - (fi & EXT2_FEATURE_INCOMPAT_UNSUPPORTED)) - return -BLKID_ERR_PARAM; - - /* - * If ext2 is not present, but ext4 or ext4dev are, then - * disclaim we are ext2 - */ - if (!system_supports_ext2() && - (system_supports_ext4() || system_supports_ext4dev()) && - system_supports_ext4_ext2()) - return -BLKID_ERR_PARAM; - - ext_get_info(pr, 2, es); - return 0; -} - -static int probe_ext3(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -BLKID_ERR_PARAM; - - /* ext3 requires journal */ - if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) - return -BLKID_ERR_PARAM; - - /* Any features which ext3 doesn't understand */ - if ((frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) || - (fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) - return -BLKID_ERR_PARAM; - - ext_get_info(pr, 3, es); - return 0; -} - - -static int probe_ext4dev(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -BLKID_ERR_PARAM; - - /* Distinguish from jbd */ - if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) - return -BLKID_ERR_PARAM; - - /* - * If the filesystem does not have a journal and ext2 and ext4 - * is not present, then force this to be detected as an - * ext4dev filesystem. - */ - if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - !system_supports_ext2() && !system_supports_ext4() && - system_supports_ext4dev() && - system_supports_ext4_ext2()) - goto force_ext4dev; - - /* - * If the filesystem is marked as OK for use by in-development - * filesystem code, but ext4dev is not supported, and ext4 is, - * then don't call ourselves ext4dev, since we should be - * detected as ext4 in that case. - * - * If the filesystem is marked as in use by production - * filesystem, then it can only be used by ext4 and NOT by - * ext4dev, so always disclaim we are ext4dev in that case. - */ - if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { - if (!system_supports_ext4dev() && system_supports_ext4()) - return -BLKID_ERR_PARAM; - } else - return -BLKID_ERR_PARAM; - -force_ext4dev: - ext_get_info(pr, 4, es); - return 0; -} - -static int probe_ext4(blkid_probe pr, - const struct blkid_idmag *mag __attribute__((__unused__))) -{ - struct ext2_super_block *es; - uint32_t fc, frc, fi; - - es = ext_get_super(pr, &fc, &fi, &frc); - if (!es) - return -1; - - /* Distinguish from jbd */ - if (fi & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) - return -BLKID_ERR_PARAM; - - /* - * If the filesystem does not have a journal and ext2 is not - * present, then force this to be detected as an ext2 - * filesystem. - */ - if (!(fc & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - !system_supports_ext2() && system_supports_ext4() && - system_supports_ext4_ext2()) - goto force_ext4; - - /* Ext4 has at least one feature which ext3 doesn't understand */ - if (!(frc & EXT3_FEATURE_RO_COMPAT_UNSUPPORTED) && - !(fi & EXT3_FEATURE_INCOMPAT_UNSUPPORTED)) - return -BLKID_ERR_PARAM; - -force_ext4: - /* - * If the filesystem is a OK for use by in-development - * filesystem code, and ext4dev is supported or ext4 is not - * supported, then don't call ourselves ext4, so we can redo - * the detection and mark the filesystem as ext4dev. - * - * If the filesystem is marked as in use by production - * filesystem, then it can only be used by ext4 and NOT by - * ext4dev. - */ - if (le32_to_cpu(es->s_flags) & EXT2_FLAGS_TEST_FILESYS) { - if (system_supports_ext4dev() || !system_supports_ext4()) - return -BLKID_ERR_PARAM; - } - - ext_get_info(pr, 4, es); - return 0; -} - -#define BLKID_EXT_MAGICS \ - { \ - { \ - .magic = EXT_SB_MAGIC, \ - .len = sizeof(EXT_SB_MAGIC) - 1, \ - .kboff = EXT_SB_KBOFF, \ - .sboff = EXT_MAG_OFF \ - }, \ - { NULL } \ - } - -const struct blkid_idinfo jbd_idinfo = -{ - .name = "jbd", - .usage = BLKID_USAGE_OTHER, - .probefunc = probe_jbd, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext2_idinfo = -{ - .name = "ext2", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext2, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext3_idinfo = -{ - .name = "ext3", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext3, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext4_idinfo = -{ - .name = "ext4", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext4, - .magics = BLKID_EXT_MAGICS -}; - -const struct blkid_idinfo ext4dev_idinfo = -{ - .name = "ext4dev", - .usage = BLKID_USAGE_FILESYSTEM, - .probefunc = probe_ext4dev, - .magics = BLKID_EXT_MAGICS -}; - |