From 6a5aac78f4d04490fc1d0178b1d7c0cb415c2944 Mon Sep 17 00:00:00 2001 From: Andre Masella Date: Sun, 17 Jul 2005 09:54:40 -0400 Subject: volume_id: add OCFS (Oracle Cluster File System) support --- extras/volume_id/Makefile | 3 +- extras/volume_id/volume_id/Makefile.inc | 2 + extras/volume_id/volume_id/ocfs2.c | 125 ++++++++++++++++++++++++++++++++ extras/volume_id/volume_id/ocfs2.h | 26 +++++++ extras/volume_id/volume_id/volume_id.c | 4 + extras/volume_id/volume_id/volume_id.h | 2 +- 6 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 extras/volume_id/volume_id/ocfs2.c create mode 100644 extras/volume_id/volume_id/ocfs2.h (limited to 'extras') diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index eca9cfdbd4..014bf8713d 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -33,7 +33,8 @@ override CFLAGS+=-D_FILE_OFFSET_BITS=64 VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc -OBJS = vol_id.o $(VOLUME_ID_OBJS) ../../udev.a +OBJS = vol_id.o $(VOLUME_ID_OBJS) +LIB_OBJS=../../udev.a HEADERS = $(VOLUME_ID_HEADERS) $(OBJS): $(HEADERS) diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 266d1e4872..71f4ea2862 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -27,6 +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)/volume_id.o \ $(VOLUME_ID_BASE)/util.o @@ -58,5 +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)/volume_id.h \ $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c new file mode 100644 index 0000000000..1f2819c0cc --- /dev/null +++ b/extras/volume_id/volume_id/ocfs2.c @@ -0,0 +1,125 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) Andre Masella + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#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 { + __u8 i_signature[8]; /* Signature for validation */ + __u32 i_generation; /* Generation number */ + __s16 i_suballoc_slot; /* Slot suballocator this inode belongs to */ + __u16 i_suballoc_bit; /* Bit offset in suballocator block group */ + __u32 i_reserved0; + __u32 i_clusters; /* Cluster count */ + __u32 i_uid; /* Owner UID */ + __u32 i_gid; /* Owning GID */ + __u64 i_size; /* Size in bytes */ + __u16 i_mode; /* File mode */ + __u16 i_links_count; /* Links count */ + __u32 i_flags; /* File flags */ + __u64 i_atime; /* Access time */ + __u64 i_ctime; /* Creation time */ + __u64 i_mtime; /* Modification time */ + __u64 i_dtime; /* Deletion time */ + __u64 i_blkno; /* Offset on disk, in blocks */ + __u64 i_last_eb_blk; /* Pointer to last extent block */ + __u32 i_fs_generation; /* Generation per fs-instance */ + __u32 i_atime_nsec; + __u32 i_ctime_nsec; + __u32 i_mtime_nsec; + __u64 i_reserved1[9]; + __u64 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. */ + __u16 s_major_rev_level; + __u16 s_minor_rev_level; + __u16 s_mnt_count; + __s16 s_max_mnt_count; + __u16 s_state; /* File system state */ + __u16 s_errors; /* Behaviour when detecting errors */ + __u32 s_checkinterval; /* Max time between checks */ + __u64 s_lastcheck; /* Time of last check */ + __u32 s_creator_os; /* OS */ + __u32 s_feature_compat; /* Compatible feature set */ + __u32 s_feature_incompat; /* Incompatible feature set */ + __u32 s_feature_ro_compat; /* Readonly-compatible feature set */ + __u64 s_root_blkno; /* Offset, in blocks, of root directory dinode */ + __u64 s_system_dir_blkno; /* Offset, in blocks, of system directory dinode */ + __u32 s_blocksize_bits; /* Blocksize for this fs */ + __u32 s_clustersize_bits; /* Clustersize for this fs */ + __u16 s_max_slots; /* Max number of simultaneous mounts before tunefs required */ + __u16 s_reserved1; + __u32 s_reserved2; + __u64 s_first_cluster_group; /* Block offset of 1st cluster group header */ + __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ + __u8 s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */ +} __attribute__((__packed__)); + +int volume_id_probe_ocfs2(struct volume_id *id, __u64 off) +{ + struct ocfs2_super_block *os; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + os = (struct ocsf2_super_block *) volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200); + if (os == NULL) + return -1; + + if (strcmp(os->i_signature, "OCFSV2") != 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; +} diff --git a/extras/volume_id/volume_id/ocfs2.h b/extras/volume_id/volume_id/ocfs2.h new file mode 100644 index 0000000000..128348133c --- /dev/null +++ b/extras/volume_id/volume_id/ocfs2.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) Andre Masella + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_OCFS2_ +#define _VOLUME_ID_OCFS2_ + +extern int volume_id_probe_ocfs2(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 3fe8562e33..8e944be0b1 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -69,6 +69,7 @@ #include "minix.h" #include "mac.h" #include "msdos.h" +#include "ocfs2.h" int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size) { @@ -169,6 +170,9 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_minix(id, off) == 0) goto exit; + if (volume_id_probe_ocfs2(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index c6aef50876..4e0defdadd 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 45 +#define VOLUME_ID_VERSION 46 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 -- cgit v1.2.3-54-g00ecf