/* * Copyright (C) 1999, 2001 by Andries Brouwer * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o * Copyright (C) 2008 Karel Zak * * This file may be redistributed under the terms of the * GNU Lesser General Public License. */ #include #include #include #include #include #include "superblocks.h" struct ocfs_volume_header { unsigned char minor_version[4]; unsigned char major_version[4]; unsigned char signature[128]; char mount[128]; unsigned char mount_len[2]; } __attribute__((packed)); struct ocfs_volume_label { unsigned char disk_lock[48]; char label[64]; unsigned char label_len[2]; unsigned char vol_id[16]; unsigned char vol_id_len[2]; } __attribute__((packed)); #define ocfsmajor(o) ( (uint32_t) o.major_version[0] \ + (((uint32_t) o.major_version[1]) << 8) \ + (((uint32_t) o.major_version[2]) << 16) \ + (((uint32_t) o.major_version[3]) << 24)) #define ocfsminor(o) ( (uint32_t) o.minor_version[0] \ + (((uint32_t) o.minor_version[1]) << 8) \ + (((uint32_t) o.minor_version[2]) << 16) \ + (((uint32_t) o.minor_version[3]) << 24)) #define ocfslabellen(o) ((uint32_t)o.label_len[0] + (((uint32_t) o.label_len[1]) << 8)) #define ocfsmountlen(o) ((uint32_t)o.mount_len[0] + (((uint32_t) o.mount_len[1]) << 8)) struct ocfs2_super_block { uint8_t i_signature[8]; uint32_t i_generation; int16_t i_suballoc_slot; uint16_t i_suballoc_bit; uint32_t i_reserved0; uint32_t i_clusters; uint32_t i_uid; uint32_t i_gid; uint64_t i_size; uint16_t i_mode; uint16_t i_links_count; uint32_t i_flags; uint64_t i_atime; uint64_t i_ctime; uint64_t i_mtime; uint64_t i_dtime; uint64_t i_blkno; uint64_t i_last_eb_blk; uint32_t i_fs_generation; uint32_t i_atime_nsec; uint32_t i_ctime_nsec; uint32_t i_mtime_nsec; uint64_t i_reserved1[9]; uint64_t i_pad1; uint16_t s_major_rev_level; uint16_t s_minor_rev_level; uint16_t s_mnt_count; int16_t s_max_mnt_count; uint16_t s_state; uint16_t s_errors; uint32_t s_checkinterval; uint64_t s_lastcheck; uint32_t s_creator_os; uint32_t s_feature_compat; uint32_t s_feature_incompat; uint32_t s_feature_ro_compat; uint64_t s_root_blkno; uint64_t s_system_dir_blkno; uint32_t s_blocksize_bits; uint32_t s_clustersize_bits; uint16_t s_max_slots; uint16_t s_reserved1; uint32_t s_reserved2; uint64_t s_first_cluster_group; uint8_t s_label[64]; uint8_t s_uuid[16]; } __attribute__((packed)); struct oracle_asm_disk_label { char dummy[32]; char dl_tag[8]; char dl_id[24]; } __attribute__((packed)); static int probe_ocfs(blkid_probe pr, const struct blkid_idmag *mag) { unsigned char *buf; struct ocfs_volume_header ovh; struct ocfs_volume_label ovl; uint32_t maj, min; /* header */ buf = blkid_probe_get_buffer(pr, mag->kboff << 10, sizeof(struct ocfs_volume_header)); if (!buf) return errno ? -errno : 1; memcpy(&ovh, buf, sizeof(ovh)); /* label */ buf = blkid_probe_get_buffer(pr, (mag->kboff << 10) + 512, sizeof(struct ocfs_volume_label)); if (!buf) return errno ? -errno : 1; memcpy(&ovl, buf, sizeof(ovl)); maj = ocfsmajor(ovh); min = ocfsminor(ovh); if (maj == 1) blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "ocfs1", sizeof("ocfs1")); else if (maj >= 9) blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "ntocfs", sizeof("ntocfs")); blkid_probe_set_label(pr, (unsigned char *) ovl.label, ocfslabellen(ovl)); blkid_probe_set_value(pr, "MOUNT", (unsigned char *) ovh.mount, ocfsmountlen(ovh)); blkid_probe_set_uuid(pr, ovl.vol_id); blkid_probe_sprintf_version(pr, "%u.%u", maj, min); return 0; } static int probe_ocfs2(blkid_probe pr, const struct blkid_idmag *mag) { struct ocfs2_super_block *osb; osb = blkid_probe_get_sb(pr, mag, struct ocfs2_super_block); if (!osb) return errno ? -errno : 1; blkid_probe_set_label(pr, (unsigned char *) osb->s_label, sizeof(osb->s_label)); blkid_probe_set_uuid(pr, osb->s_uuid); blkid_probe_sprintf_version(pr, "%u.%u", le16_to_cpu(osb->s_major_rev_level), le16_to_cpu(osb->s_minor_rev_level)); return 0; } static int probe_oracleasm(blkid_probe pr, const struct blkid_idmag *mag) { struct oracle_asm_disk_label *dl; dl = blkid_probe_get_sb(pr, mag, struct oracle_asm_disk_label); if (!dl) return errno ? -errno : 1; blkid_probe_set_label(pr, (unsigned char *) dl->dl_id, sizeof(dl->dl_id)); return 0; } const struct blkid_idinfo ocfs_idinfo = { .name = "ocfs", .usage = BLKID_USAGE_FILESYSTEM, .probefunc = probe_ocfs, .minsz = 14000 * 1024, .magics = { { .magic = "OracleCFS", .len = 9, .kboff = 8 }, { NULL } } }; const struct blkid_idinfo ocfs2_idinfo = { .name = "ocfs2", .usage = BLKID_USAGE_FILESYSTEM, .probefunc = probe_ocfs2, .minsz = 14000 * 1024, .magics = { { .magic = "OCFSV2", .len = 6, .kboff = 1 }, { .magic = "OCFSV2", .len = 6, .kboff = 2 }, { .magic = "OCFSV2", .len = 6, .kboff = 4 }, { .magic = "OCFSV2", .len = 6, .kboff = 8 }, { NULL } } }; /* Oracle ASM (Automatic Storage Management) */ const struct blkid_idinfo oracleasm_idinfo = { .name = "oracleasm", .usage = BLKID_USAGE_FILESYSTEM, .probefunc = probe_oracleasm, .magics = { { .magic = "ORCLDISK", .len = 8, .sboff = 32 }, { NULL } } };