1 /*
2 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
3 *
4 * This is written from sratch according to Linux kernel fs/sysv/super.c file.
5 * It seems that sysv probing code in libvolume_id and also in the original
6 * blkid is useless.
7 *
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
10 */
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdint.h>
15 #include <stddef.h>
16
17 #include "superblocks.h"
18
19 #define XENIX_NICINOD 100
20 #define XENIX_NICFREE 100
21
22 struct xenix_super_block {
23 uint16_t s_isize;
24 uint32_t s_fsize;
25 uint16_t s_nfree;
26 uint32_t s_free[XENIX_NICFREE];
27 uint16_t s_ninode;
28 uint16_t s_inode[XENIX_NICINOD];
29 uint8_t s_flock;
30 uint8_t s_ilock;
31 uint8_t s_fmod;
32 uint8_t s_ronly;
33 uint32_t s_time;
34 uint32_t s_tfree;
35 uint16_t s_tinode;
36 uint16_t s_dinfo[4];
37 uint8_t s_fname[6];
38 uint8_t s_fpack[6];
39 uint8_t s_clean;
40 uint8_t s_fill[371];
41 uint32_t s_magic;
42 uint32_t s_type;
43 } __attribute__((packed));
44
45
46 #define SYSV_NICINOD 100
47 #define SYSV_NICFREE 50
48
49 struct sysv_super_block
50 {
51 uint16_t s_isize;
52 uint16_t s_pad0;
53 uint32_t s_fsize;
54 uint16_t s_nfree;
55 uint16_t s_pad1;
56 uint32_t s_free[SYSV_NICFREE];
57 uint16_t s_ninode;
58 uint16_t s_pad2;
59 uint16_t s_inode[SYSV_NICINOD];
60 uint8_t s_flock;
61 uint8_t s_ilock;
62 uint8_t s_fmod;
63 uint8_t s_ronly;
64 uint32_t s_time;
65 uint16_t s_dinfo[4];
66 uint32_t s_tfree;
67 uint16_t s_tinode;
68 uint16_t s_pad3;
69 uint8_t s_fname[6];
70 uint8_t s_fpack[6];
71 uint32_t s_fill[12];
72 uint32_t s_state;
73 uint32_t s_magic;
74 uint32_t s_type;
75 };
76
probe_xenix(blkid_probe pr,const struct blkid_idmag * mag)77 static int probe_xenix(blkid_probe pr, const struct blkid_idmag *mag)
78 {
79 struct xenix_super_block *sb;
80
81 sb = blkid_probe_get_sb(pr, mag, struct xenix_super_block);
82 if (!sb)
83 return errno ? -errno : 1;
84 blkid_probe_set_label(pr, sb->s_fname, sizeof(sb->s_fname));
85 return 0;
86 }
87
88 #define SYSV_BLOCK_SIZE 1024
89
90 /* Note that we don't probe for Coherent FS, this FS does not have
91 * magic string. (It requires to probe fname/fpack field..)
92 */
probe_sysv(blkid_probe pr,const struct blkid_idmag * mag)93 static int probe_sysv(blkid_probe pr,
94 const struct blkid_idmag *mag __attribute__((__unused__)))
95 {
96 struct sysv_super_block *sb;
97 int blocks[] = {0, 9, 15, 18};
98 size_t i;
99
100 for (i = 0; i < ARRAY_SIZE(blocks); i++) {
101 int off = blocks[i] * SYSV_BLOCK_SIZE + SYSV_BLOCK_SIZE/2;
102
103 sb = (struct sysv_super_block *)
104 blkid_probe_get_buffer(pr,
105 off,
106 sizeof(struct sysv_super_block));
107 if (!sb)
108 return errno ? -errno : 1;
109
110 if (sb->s_magic == cpu_to_le32(0xfd187e20) ||
111 sb->s_magic == cpu_to_be32(0xfd187e20)) {
112
113 if (blkid_probe_set_label(pr, sb->s_fname,
114 sizeof(sb->s_fname)))
115 return 1;
116
117 if (blkid_probe_set_magic(pr,
118 off + offsetof(struct sysv_super_block,
119 s_magic),
120 sizeof(sb->s_magic),
121 (unsigned char *) &sb->s_magic))
122 return 1;
123
124 return 0;
125 }
126 }
127 return 1;
128 }
129
130 const struct blkid_idinfo xenix_idinfo =
131 {
132 .name = "xenix",
133 .usage = BLKID_USAGE_FILESYSTEM,
134 .probefunc = probe_xenix,
135 .magics =
136 {
137 { .magic = "\x2b\x55\x44", .len = 3, .kboff = 1, .sboff = 0x400 },
138 { .magic = "\x44\x55\x2b", .len = 3, .kboff = 1, .sboff = 0x400 },
139 { NULL }
140 }
141 };
142
143 const struct blkid_idinfo sysv_idinfo =
144 {
145 .name = "sysv",
146 .usage = BLKID_USAGE_FILESYSTEM,
147 .probefunc = probe_sysv,
148
149 /* SYSV is BE and LE and superblock could be on four positions. It's
150 * simpler to probe for the magic string by .probefunc().
151 */
152 .magics = BLKID_NONE_MAGIC
153 };
154
155