diff options
Diffstat (limited to 'libblkid/ocfs.c')
-rw-r--r-- | libblkid/ocfs.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/libblkid/ocfs.c b/libblkid/ocfs.c new file mode 100644 index 000000000..82170ace1 --- /dev/null +++ b/libblkid/ocfs.c @@ -0,0 +1,213 @@ +/* + * 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 <stdint.h> + +#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 -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 -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 -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 -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 } + } +}; + |