chiark / gitweb /
volume_id: better DDF raid detection
[elogind.git] / extras / volume_id / lib / reiserfs.c
1 /*
2  * volume_id - reads filesystem label and uuid
3  *
4  * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
5  * Copyright (C) 2005 Tobias Klauser <tklauser@access.unizh.ch>
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifndef _GNU_SOURCE
22 #define _GNU_SOURCE 1
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <ctype.h>
31
32 #include "libvolume_id.h"
33 #include "libvolume_id-private.h"
34
35 struct reiserfs_super_block {
36         uint32_t        blocks_count;
37         uint32_t        free_blocks;
38         uint32_t        root_block;
39         uint32_t        journal_block;
40         uint32_t        journal_dev;
41         uint32_t        orig_journal_size;
42         uint32_t        dummy2[5];
43         uint16_t        blocksize;
44         uint16_t        dummy3[3];
45         uint8_t         magic[12];
46         uint32_t        dummy4[5];
47         uint8_t         uuid[16];
48         uint8_t         label[16];
49 } PACKED;
50
51 struct reiser4_super_block {
52         uint8_t         magic[16];
53         uint16_t        dummy[2];
54         uint8_t         uuid[16];
55         uint8_t         label[16];
56         uint64_t        dummy2;
57 } PACKED;
58
59 #define REISERFS1_SUPERBLOCK_OFFSET             0x2000
60 #define REISERFS_SUPERBLOCK_OFFSET              0x10000
61
62 int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off, uint64_t size)
63 {
64         struct reiserfs_super_block *rs;
65         struct reiser4_super_block *rs4;
66         uint8_t  *buf;
67
68         info("probing at offset 0x%llx\n", (unsigned long long) off);
69
70         buf = volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200);
71         if (buf == NULL)
72                 return -1;
73
74         rs = (struct reiserfs_super_block *) buf;
75         if (memcmp(rs->magic, "ReIsErFs", 8) == 0) {
76                 strcpy(id->type_version, "3.5");
77                 id->type = "reiserfs";
78                 goto found;
79         }
80         if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) {
81                 strcpy(id->type_version, "3.6");
82                 id->type = "reiserfs";
83                 goto found_label;
84         }
85         if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) {
86                 strcpy(id->type_version, "JR");
87                 id->type = "reiserfs";
88                 goto found_label;
89         }
90
91         rs4 = (struct reiser4_super_block *) buf;
92         if (memcmp(rs4->magic, "ReIsEr4", 7) == 0) {
93                 strcpy(id->type_version, "4");
94                 volume_id_set_label_raw(id, rs4->label, 16);
95                 volume_id_set_label_string(id, rs4->label, 16);
96                 volume_id_set_uuid(id, rs4->uuid, 0, UUID_DCE);
97                 id->type = "reiser4";
98                 goto found;
99         }
100
101         buf = volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200);
102         if (buf == NULL)
103                 return -1;
104
105         rs = (struct reiserfs_super_block *) buf;
106         if (memcmp(rs->magic, "ReIsErFs", 8) == 0) {
107                 strcpy(id->type_version, "3.5");
108                 id->type = "reiserfs";
109                 goto found;
110         }
111
112         return -1;
113
114 found_label:
115         volume_id_set_label_raw(id, rs->label, 16);
116         volume_id_set_label_string(id, rs->label, 16);
117         volume_id_set_uuid(id, rs->uuid, 0, UUID_DCE);
118
119 found:
120         volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
121
122         return 0;
123 }