blob: 9ea49fee878587cdffe872aa4cc4d2e44027a2b5 [file] [log] [blame]
bigbiff7b4c7a62015-01-01 19:44:14 -05001/*
2 * Copyright (C) 1999 by Andries Brouwer
3 * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
4 * Copyright (C) 2001 by Andreas Dilger
5 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
6 * Copyright (C) 2008-2013 Karel Zak <kzak@redhat.com>
7 *
8 * This file may be redistributed under the terms of the
9 * GNU Lesser General Public License.
10 */
11
12#include <string.h>
13#include "superblocks.h"
14#include "minix.h"
15
16#define minix_swab16(doit, num) ((uint16_t) (doit ? swab16(num) : num))
17#define minix_swab32(doit, num) ((uint32_t) (doit ? swab32(num) : num))
18
19static int get_minix_version(const unsigned char *data, int *other_endian)
20{
21 struct minix_super_block *sb = (struct minix_super_block *) data;
22 struct minix3_super_block *sb3 = (struct minix3_super_block *) data;
23 int version = 0;
24
25 *other_endian = 0;
26
27 switch (sb->s_magic) {
28 case MINIX_SUPER_MAGIC:
29 case MINIX_SUPER_MAGIC2:
30 version = 1;
31 break;
32 case MINIX2_SUPER_MAGIC:
33 case MINIX2_SUPER_MAGIC2:
34 version = 2;
35 break;
36 default:
37 if (sb3->s_magic == MINIX3_SUPER_MAGIC)
38 version = 3;
39 break;
40 }
41
42 if (!version) {
43 *other_endian = 1;
44
45 switch (swab16(sb->s_magic)) {
46 case MINIX_SUPER_MAGIC:
47 case MINIX_SUPER_MAGIC2:
48 version = 1;
49 break;
50 case MINIX2_SUPER_MAGIC:
51 case MINIX2_SUPER_MAGIC2:
52 version = 2;
53 break;
54 default:
55 if (sb3->s_magic == MINIX3_SUPER_MAGIC)
56 version = 3;
57 break;
58 }
59 }
60 if (!version)
61 return -1;
62
63 DBG(LOWPROBE, ul_debug("minix version %d detected [%s]", version,
64#if defined(WORDS_BIGENDIAN)
65 *other_endian ? "LE" : "BE"
66#else
67 *other_endian ? "BE" : "LE"
68#endif
69 ));
70 return version;
71}
72
73static int probe_minix(blkid_probe pr, const struct blkid_idmag *mag)
74{
75 unsigned char *ext;
76 const unsigned char *data;
77 int version = 0, swabme = 0;
78
79 data = blkid_probe_get_buffer(pr, 1024,
80 max(sizeof(struct minix_super_block),
81 sizeof(struct minix3_super_block)));
82 if (!data)
83 return errno ? -errno : 1;
84 version = get_minix_version(data, &swabme);
85 if (version < 1)
86 return 1;
87
88 if (version <= 2) {
89 struct minix_super_block *sb = (struct minix_super_block *) data;
90 int zones, ninodes, imaps, zmaps, firstz;
91
92 if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0)
93 return 1;
94
95 zones = version == 2 ? minix_swab32(swabme, sb->s_zones) :
96 minix_swab16(swabme, sb->s_nzones);
97 ninodes = minix_swab16(swabme, sb->s_ninodes);
98 imaps = minix_swab16(swabme, sb->s_imap_blocks);
99 zmaps = minix_swab16(swabme, sb->s_zmap_blocks);
100 firstz = minix_swab16(swabme, sb->s_firstdatazone);
101
102 /* sanity checks to be sure that the FS is really minix */
103 if (imaps * MINIX_BLOCK_SIZE * 8 < ninodes + 1)
104 return 1;
105 if (zmaps * MINIX_BLOCK_SIZE * 8 < zones - firstz + 1)
106 return 1;
107
108 } else if (version == 3) {
109 struct minix3_super_block *sb = (struct minix3_super_block *) data;
110
111 if (sb->s_imap_blocks == 0 || sb->s_zmap_blocks == 0)
112 return 1;
113 }
114
115 /* unfortunately, some parts of ext3 is sometimes possible to
116 * interpreted as minix superblock. So check for extN magic
117 * string. (For extN magic string and offsets see ext.c.)
118 */
119 ext = blkid_probe_get_buffer(pr, 0x400 + 0x38, 2);
120 if (!ext)
121 return errno ? -errno : 1;
122 else if (memcmp(ext, "\123\357", 2) == 0)
123 return 1;
124
125 blkid_probe_sprintf_version(pr, "%d", version);
126 return 0;
127}
128
129const struct blkid_idinfo minix_idinfo =
130{
131 .name = "minix",
132 .usage = BLKID_USAGE_FILESYSTEM,
133 .probefunc = probe_minix,
134 .magics =
135 {
136 /* version 1 - LE */
137 { .magic = "\177\023", .len = 2, .kboff = 1, .sboff = 0x10 },
138 { .magic = "\217\023", .len = 2, .kboff = 1, .sboff = 0x10 },
139
140 /* version 1 - BE */
141 { .magic = "\023\177", .len = 2, .kboff = 1, .sboff = 0x10 },
142 { .magic = "\023\217", .len = 2, .kboff = 1, .sboff = 0x10 },
143
144 /* version 2 - LE */
145 { .magic = "\150\044", .len = 2, .kboff = 1, .sboff = 0x10 },
146 { .magic = "\170\044", .len = 2, .kboff = 1, .sboff = 0x10 },
147
148 /* version 2 - BE */
149 { .magic = "\044\150", .len = 2, .kboff = 1, .sboff = 0x10 },
150 { .magic = "\044\170", .len = 2, .kboff = 1, .sboff = 0x10 },
151
152 /* version 3 - LE */
153 { .magic = "\132\115", .len = 2, .kboff = 1, .sboff = 0x18 },
154
155 /* version 3 - BE */
156 { .magic = "\115\132", .len = 2, .kboff = 1, .sboff = 0x18 },
157
158 { NULL }
159 }
160};
161