blob: b2c016304430728f41dba69fe07ca949f7a4415c [file] [log] [blame]
bigbiff bigbiffe60683a2013-02-22 20:55:50 -05001/*
2 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
3 *
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
6 */
7#include <stdio.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <string.h>
11#include <stdint.h>
12
13#include "superblocks.h"
14
15/* Common gfs/gfs2 constants: */
16#define GFS_LOCKNAME_LEN 64
17
18/* gfs1 constants: */
19#define GFS_FORMAT_FS 1309
20#define GFS_FORMAT_MULTI 1401
21/* gfs2 constants: */
22#define GFS2_FORMAT_FS 1801
23#define GFS2_FORMAT_MULTI 1900
24
25struct gfs2_meta_header {
26 uint32_t mh_magic;
27 uint32_t mh_type;
28 uint64_t __pad0; /* Was generation number in gfs1 */
29 uint32_t mh_format;
30 uint32_t __pad1; /* Was incarnation number in gfs1 */
31};
32
33struct gfs2_inum {
34 uint64_t no_formal_ino;
35 uint64_t no_addr;
36};
37
38struct gfs2_sb {
39 struct gfs2_meta_header sb_header;
40
41 uint32_t sb_fs_format;
42 uint32_t sb_multihost_format;
43 uint32_t __pad0; /* Was superblock flags in gfs1 */
44
45 uint32_t sb_bsize;
46 uint32_t sb_bsize_shift;
47 uint32_t __pad1; /* Was journal segment size in gfs1 */
48
49 struct gfs2_inum sb_master_dir; /* Was jindex dinode in gfs1 */
50 struct gfs2_inum __pad2; /* Was rindex dinode in gfs1 */
51 struct gfs2_inum sb_root_dir;
52
53 char sb_lockproto[GFS_LOCKNAME_LEN];
54 char sb_locktable[GFS_LOCKNAME_LEN];
55
56 struct gfs2_inum __pad3; /* Was quota inode in gfs1 */
57 struct gfs2_inum __pad4; /* Was licence inode in gfs1 */
58 uint8_t sb_uuid[16]; /* The UUID maybe 0 for backwards compat */
59} __attribute__((packed));
60
61static int probe_gfs(blkid_probe pr, const struct blkid_idmag *mag)
62{
63 struct gfs2_sb *sbd;
64
65 sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
66 if (!sbd)
67 return -1;
68
69 if (be32_to_cpu(sbd->sb_fs_format) == GFS_FORMAT_FS &&
70 be32_to_cpu(sbd->sb_multihost_format) == GFS_FORMAT_MULTI)
71 {
72 if (*sbd->sb_locktable)
73 blkid_probe_set_label(pr,
74 (unsigned char *) sbd->sb_locktable,
75 sizeof(sbd->sb_locktable));
76
77 blkid_probe_set_uuid(pr, sbd->sb_uuid);
78 return 0;
79 }
80
81 return -1;
82}
83
84static int probe_gfs2(blkid_probe pr, const struct blkid_idmag *mag)
85{
86 struct gfs2_sb *sbd;
87
88 sbd = blkid_probe_get_sb(pr, mag, struct gfs2_sb);
89 if (!sbd)
90 return -1;
91
92 if (be32_to_cpu(sbd->sb_fs_format) == GFS2_FORMAT_FS &&
93 be32_to_cpu(sbd->sb_multihost_format) == GFS2_FORMAT_MULTI)
94 {
95 if (*sbd->sb_locktable)
96 blkid_probe_set_label(pr,
97 (unsigned char *) sbd->sb_locktable,
98 sizeof(sbd->sb_locktable));
99 blkid_probe_set_uuid(pr, sbd->sb_uuid);
100 blkid_probe_set_version(pr, "1");
101 return 0;
102 }
103 return -1;
104}
105
106const struct blkid_idinfo gfs_idinfo =
107{
108 .name = "gfs",
109 .usage = BLKID_USAGE_FILESYSTEM,
110 .probefunc = probe_gfs,
111 .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */
112 .magics =
113 {
114 { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
115 { NULL }
116 }
117};
118
119const struct blkid_idinfo gfs2_idinfo =
120{
121 .name = "gfs2",
122 .usage = BLKID_USAGE_FILESYSTEM,
123 .probefunc = probe_gfs2,
124 .minsz = 32 * 1024 * 1024, /* minimal size of GFS journal */
125 .magics =
126 {
127 { .magic = "\x01\x16\x19\x70", .len = 4, .kboff = 64 },
128 { NULL }
129 }
130};
131