chiark / gitweb /
volume_id: add OVFS Version 1
authorKay Sievers <kay@pim>
Sun, 23 Oct 2005 14:08:56 +0000 (16:08 +0200)
committerKay Sievers <kay@pim>
Sun, 23 Oct 2005 14:08:56 +0000 (16:08 +0200)
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
extras/volume_id/volume_id/Makefile.inc
extras/volume_id/volume_id/ocfs.c [new file with mode: 0644]
extras/volume_id/volume_id/ocfs.h [moved from extras/volume_id/volume_id/ocfs2.h with 58% similarity]
extras/volume_id/volume_id/ocfs2.c [deleted file]
extras/volume_id/volume_id/volume_id.c

index 71f4ea2862790b78c86e9f1f6221e06bc79ee986..80f451d58304eee520ca240367d29188e90fac6a 100644 (file)
@@ -27,7 +27,7 @@ VOLUME_ID_OBJS=                                       \
        $(VOLUME_ID_BASE)/sysv.o                \
        $(VOLUME_ID_BASE)/minix.o               \
        $(VOLUME_ID_BASE)/luks.o                \
-       $(VOLUME_ID_BASE)/ocfs2.o               \
+       $(VOLUME_ID_BASE)/ocfs.o                \
        $(VOLUME_ID_BASE)/volume_id.o           \
        $(VOLUME_ID_BASE)/util.o
 
@@ -59,6 +59,6 @@ VOLUME_ID_HEADERS=                            \
        $(VOLUME_ID_BASE)/sysv.h                \
        $(VOLUME_ID_BASE)/minix.h               \
        $(VOLUME_ID_BASE)/luks.h                \
-       $(VOLUME_ID_BASE)/ocfs2.h               \
+       $(VOLUME_ID_BASE)/ocfs.h                \
        $(VOLUME_ID_BASE)/volume_id.h           \
        $(VOLUME_ID_BASE)/util.h
diff --git a/extras/volume_id/volume_id/ocfs.c b/extras/volume_id/volume_id/ocfs.c
new file mode 100644 (file)
index 0000000..81b4e2d
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2004 Andre Masella <andre@masella.no-ip.org>
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the
+ *     Free Software Foundation version 2 of the License.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include "volume_id.h"
+#include "logging.h"
+#include "util.h"
+#include "ocfs.h"
+
+
+struct ocfs1_super_block_header {
+       uint32_t        minor_version;
+       uint32_t        major_version;
+       uint8_t         signature[128];
+       uint8_t         mount_point[128];
+       uint64_t        serial_num;
+       uint64_t        device_size;
+       uint64_t        start_off;
+       uint64_t        bitmap_off;
+       uint64_t        publ_off;
+       uint64_t        vote_off;
+       uint64_t        root_bitmap_off;
+       uint64_t        data_start_off;
+       uint64_t        root_bitmap_size;
+       uint64_t        root_off;
+       uint64_t        root_size;
+       uint64_t        cluster_size;
+       uint64_t        num_nodes;
+       uint64_t        num_clusters;
+       uint64_t        dir_node_size;
+       uint64_t        file_node_size;
+       uint64_t        internal_off;
+       uint64_t        node_cfg_off;
+       uint64_t        node_cfg_size;
+       uint64_t        new_cfg_off;
+       uint32_t        prot_bits;
+       int32_t         excl_mount;
+} __attribute__((__packed__));
+
+struct ocfs1_super_block_label {
+       struct ocfs1_disk_lock {
+               uint32_t        curr_master;
+               uint8_t         file_lock;
+               uint8_t         compat_pad[3];
+               uint64_t        last_write_time;
+               uint64_t        last_read_time;
+               uint32_t        writer_node_num;
+               uint32_t        reader_node_num;
+               uint64_t        oin_node_map;
+               uint64_t        dlock_seq_num;
+       } disk_lock __attribute__((__packed__));
+       uint8_t         label[64];
+       uint16_t        label_len;
+       uint8_t         vol_id[16];
+       uint16_t        vol_id_len;
+       uint8_t         cluster_name[64];
+       uint16_t        cluster_name_len;
+} __attribute__((__packed__));
+
+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__));
+
+int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off)
+{
+       const uint8_t *buf;
+       struct ocfs1_super_block_header *osh;
+       struct ocfs1_super_block_label *osl;
+
+       buf = volume_id_get_buffer(id, off, 0x200);
+       if (buf == NULL)
+               return -1;
+
+       osh = (struct ocfs1_super_block_header *) buf;
+       if (memcmp(osh->signature, "OracleCFS", 9) != 0)
+               return -1;
+       snprintf(id->type_version, sizeof(id->type_version)-1,
+                "%u.%u", osh->major_version, osh->minor_version);
+
+       dbg("found OracleCFS signature, now reading label");
+       buf = volume_id_get_buffer(id, off + 0x200, 0x200);
+       if (buf == NULL)
+               return -1;
+
+       osl = (struct ocfs1_super_block_label *) buf;
+       volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
+       if (osl->label_len <= 64) {
+               volume_id_set_label_raw(id, osl->label, 64);
+               volume_id_set_label_string(id, osl->label, 64);
+       }
+       if (osl->vol_id_len == 16)
+               volume_id_set_uuid(id, osl->vol_id, UUID_DCE);
+       id->type = "ocfs";
+       return 0;
+}
+
+#define OCFS2_MAX_BLOCKSIZE            0x1000
+#define OCFS2_SUPER_BLOCK_BLKNO                2
+
+int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off)
+{
+       const uint8_t *buf;
+       struct ocfs2_super_block *os;
+       size_t blksize;
+
+       dbg("probing at offset 0x%llx", (unsigned long long) off);
+
+       for (blksize = 0x200; blksize <= OCFS2_MAX_BLOCKSIZE; blksize >>= 1) {
+               buf = volume_id_get_buffer(id, off + OCFS2_SUPER_BLOCK_BLKNO * blksize, 0x200);
+               if (buf == NULL)
+                       return -1;
+
+               os = (struct ocfs2_super_block *) buf;
+               if (memcmp(os->i_signature, "OCFSV2", 6) != 0)
+                       continue;
+
+               volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
+               volume_id_set_label_raw(id, os->s_label, 64);
+               volume_id_set_label_string(id, os->s_label, 64);
+               volume_id_set_uuid(id, os->s_uuid, UUID_DCE);
+               snprintf(id->type_version, sizeof(id->type_version)-1,
+                        "%u.%u", os->s_major_rev_level, os->s_minor_rev_level);
+               id->type = "ocfs2";
+               return 0;
+       }
+       return -1;
+}
similarity index 58%
rename from extras/volume_id/volume_id/ocfs2.h
rename to extras/volume_id/volume_id/ocfs.h
index 24b43b18752db5304687936a6c593985546cc65c..9d46b28dcd2586be40ed73f6060af4fb24627570 100644 (file)
@@ -1,16 +1,18 @@
 /*
  * volume_id - reads filesystem label and uuid
  *
- * Copyright (C) Andre Masella <andre@masella.no-ip.org>
+ * Copyright (C) 2004 Andre Masella <andre@masella.no-ip.org>
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the
  *     Free Software Foundation version 2 of the License.
  */
 
-#ifndef _VOLUME_ID_OCFS2_
-#define _VOLUME_ID_OCFS2_
+#ifndef _VOLUME_ID_OCFS1_
+#define _VOLUME_ID_OCFS1_
 
+extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off);
 extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off);
 
 #endif
diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c
deleted file mode 100644 (file)
index 3a77112..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * volume_id - reads filesystem label and uuid
- *
- * Copyright (C) Andre Masella <andre@masella.no-ip.org>
- *
- *     This program is free software; you can redistribute it and/or modify it
- *     under the terms of the GNU General Public License as published by the
- *     Free Software Foundation version 2 of the License.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE 1
-#endif
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "volume_id.h"
-#include "logging.h"
-#include "util.h"
-#include "ocfs2.h"
-
-
-/* All these values are taken from ocfs2-tools's ocfs2_fs.h */
-#define OCFS2_VOL_UUID_LEN                     16
-#define OCFS2_MAX_VOL_LABEL_LEN                        64
-#define OCFS2_SUPERBLOCK_OFFSET                        0x2000
-
-
-/* This is the superblock. The OCFS2 header files have structs in structs.
-This is one has been simplified since we only care about the superblock.
-*/
-
-struct ocfs2_super_block {
-       uint8_t         i_signature[8];                 /* Signature for validation */
-       uint32_t        i_generation;                   /* Generation number */
-       int16_t         i_suballoc_slot;                        /* Slot suballocator this inode belongs to */
-       uint16_t        i_suballoc_bit;                 /* Bit offset in suballocator block group */
-       uint32_t        i_reserved0;
-       uint32_t        i_clusters;                     /* Cluster count */
-       uint32_t        i_uid;                          /* Owner UID */
-       uint32_t        i_gid;                          /* Owning GID */
-       uint64_t        i_size;                         /* Size in bytes */
-       uint16_t        i_mode;                         /* File mode */
-       uint16_t        i_links_count;                  /* Links count */
-       uint32_t        i_flags;                                /* File flags */
-       uint64_t        i_atime;                                /* Access time */
-       uint64_t        i_ctime;                                /* Creation time */
-       uint64_t        i_mtime;                                /* Modification time */
-       uint64_t        i_dtime;                                /* Deletion time */
-       uint64_t        i_blkno;                                /* Offset on disk, in blocks */
-       uint64_t        i_last_eb_blk;                  /* Pointer to last extent block */
-       uint32_t        i_fs_generation;                        /* Generation per fs-instance */
-       uint32_t        i_atime_nsec;
-       uint32_t        i_ctime_nsec;
-       uint32_t        i_mtime_nsec;
-       uint64_t        i_reserved1[9];
-       uint64_t        i_pad1;                         /* Generic way to refer to this 64bit union */
-       /* Normally there is a union of the different block types, but we only care about the superblock. */
-       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;                                /* File system state */
-       uint16_t        s_errors;                               /* Behaviour when detecting errors */
-       uint32_t        s_checkinterval;                        /* Max time between checks */
-       uint64_t        s_lastcheck;                    /* Time of last check */
-       uint32_t        s_creator_os;                   /* OS */
-       uint32_t        s_feature_compat;                       /* Compatible feature set */
-       uint32_t        s_feature_incompat;             /* Incompatible feature set */
-       uint32_t        s_feature_ro_compat;            /* Readonly-compatible feature set */
-       uint64_t        s_root_blkno;                   /* Offset, in blocks, of root directory dinode */
-       uint64_t        s_system_dir_blkno;             /* Offset, in blocks, of system directory dinode */
-       uint32_t        s_blocksize_bits;                       /* Blocksize for this fs */
-       uint32_t        s_clustersize_bits;             /* Clustersize for this fs */
-       uint16_t        s_max_slots;                    /* Max number of simultaneous mounts before tunefs required */
-       uint16_t        s_reserved1;
-       uint32_t        s_reserved2;
-       uint64_t        s_first_cluster_group;          /* Block offset of 1st cluster group header */
-       uint8_t         s_label[OCFS2_MAX_VOL_LABEL_LEN];       /* Label for mounting, etc. */
-       uint8_t         s_uuid[OCFS2_VOL_UUID_LEN];     /* 128-bit uuid */
-} __attribute__((__packed__));
-
-int volume_id_probe_ocfs2(struct volume_id *id, uint64_t               off)
-{
-       struct ocfs2_super_block *os;
-
-       dbg("probing at offset 0x%llx", (unsigned long long) off);
-
-       os = (struct ocfs2_super_block *) volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200);
-       if (os == NULL)
-               return -1;
-
-       if (memcmp(os->i_signature, "OCFSV2", 6) != 0) {
-               return -1;
-       }
-
-       volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
-       volume_id_set_label_raw(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ?
-                                       OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE);
-       volume_id_set_label_string(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ?
-                                       OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE);
-       volume_id_set_uuid(id, os->s_uuid, UUID_DCE);
-       id->type = "ocfs2";
-       return 0;
-}
index d1a6a5f0f51a50480760be6ecaf4ce136ba5b149..25bcd953584ac781da73a29a8bfc51c98e451b0e 100644 (file)
@@ -58,7 +58,7 @@
 #include "minix.h"
 #include "mac.h"
 #include "msdos.h"
-#include "ocfs2.h"
+#include "ocfs.h"
 
 int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
 {
@@ -156,6 +156,9 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size)
        if (volume_id_probe_minix(id, off) == 0)
                goto exit;
 
+       if (volume_id_probe_ocfs1(id, off) == 0)
+               goto exit;
+
        if (volume_id_probe_ocfs2(id, off) == 0)
                goto exit;