chiark / gitweb /
[PATCH] add "serio" to bus list
[elogind.git] / extras / volume_id / volume_id / ufs.c
1 /*
2  * volume_id - reads filesystem label and uuid
3  *
4  * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  *      This library is free software; you can redistribute it and/or
7  *      modify it under the terms of the GNU Lesser General Public
8  *      License as published by the Free Software Foundation; either
9  *      version 2.1 of the License, or (at your option) any later version.
10  *
11  *      This library is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  *      Lesser General Public License for more details.
15  *
16  *      You should have received a copy of the GNU Lesser General Public
17  *      License along with this library; if not, write to the Free Software
18  *      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20
21 #ifndef _GNU_SOURCE
22 #define _GNU_SOURCE 1
23 #endif
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <ctype.h>
35 #include <asm/types.h>
36
37 #include "volume_id.h"
38 #include "logging.h"
39 #include "util.h"
40 #include "ufs.h"
41
42 struct ufs_super_block {
43         __u32   fs_link;
44         __u32   fs_rlink;
45         __u32   fs_sblkno;
46         __u32   fs_cblkno;
47         __u32   fs_iblkno;
48         __u32   fs_dblkno;
49         __u32   fs_cgoffset;
50         __u32   fs_cgmask;
51         __u32   fs_time;
52         __u32   fs_size;
53         __u32   fs_dsize;
54         __u32   fs_ncg; 
55         __u32   fs_bsize;
56         __u32   fs_fsize;
57         __u32   fs_frag;
58         __u32   fs_minfree;
59         __u32   fs_rotdelay;
60         __u32   fs_rps; 
61         __u32   fs_bmask;
62         __u32   fs_fmask;
63         __u32   fs_bshift;
64         __u32   fs_fshift;
65         __u32   fs_maxcontig;
66         __u32   fs_maxbpg;
67         __u32   fs_fragshift;
68         __u32   fs_fsbtodb;
69         __u32   fs_sbsize;
70         __u32   fs_csmask;
71         __u32   fs_csshift;
72         __u32   fs_nindir;
73         __u32   fs_inopb;
74         __u32   fs_nspf;
75         __u32   fs_optim;
76         __u32   fs_npsect_state;
77         __u32   fs_interleave;
78         __u32   fs_trackskew;
79         __u32   fs_id[2];
80         __u32   fs_csaddr;
81         __u32   fs_cssize;
82         __u32   fs_cgsize;
83         __u32   fs_ntrak;
84         __u32   fs_nsect;
85         __u32   fs_spc; 
86         __u32   fs_ncyl;
87         __u32   fs_cpg;
88         __u32   fs_ipg;
89         __u32   fs_fpg;
90         struct ufs_csum {
91                 __u32   cs_ndir;
92                 __u32   cs_nbfree;
93                 __u32   cs_nifree;
94                 __u32   cs_nffree;
95         } __attribute__((__packed__)) fs_cstotal;
96         __s8    fs_fmod;
97         __s8    fs_clean;
98         __s8    fs_ronly;
99         __s8    fs_flags;
100         union {
101                 struct {
102                         __s8    fs_fsmnt[512];
103                         __u32   fs_cgrotor;
104                         __u32   fs_csp[31];
105                         __u32   fs_maxcluster;
106                         __u32   fs_cpc;
107                         __u16   fs_opostbl[16][8];
108                 } __attribute__((__packed__)) fs_u1;
109                 struct {
110                         __s8    fs_fsmnt[468];
111                         __u8    fs_volname[32];
112                         __u64   fs_swuid;
113                         __s32   fs_pad;
114                         __u32   fs_cgrotor;
115                         __u32   fs_ocsp[28];
116                         __u32   fs_contigdirs;
117                         __u32   fs_csp; 
118                         __u32   fs_maxcluster;
119                         __u32   fs_active;
120                         __s32   fs_old_cpc;
121                         __s32   fs_maxbsize;
122                         __s64   fs_sparecon64[17];
123                         __s64   fs_sblockloc;
124                         struct ufs2_csum_total {
125                                 __u64   cs_ndir;
126                                 __u64   cs_nbfree;
127                                 __u64   cs_nifree;
128                                 __u64   cs_nffree;
129                                 __u64   cs_numclusters;
130                                 __u64   cs_spare[3];
131                         } __attribute__((__packed__)) fs_cstotal;
132                         struct ufs_timeval {
133                                 __s32   tv_sec;
134                                 __s32   tv_usec;
135                         } __attribute__((__packed__)) fs_time;
136                         __s64   fs_size;
137                         __s64   fs_dsize;
138                         __u64   fs_csaddr;
139                         __s64   fs_pendingblocks;
140                         __s32   fs_pendinginodes;
141                 } __attribute__((__packed__)) fs_u2;
142         }  fs_u11;
143         union {
144                 struct {
145                         __s32   fs_sparecon[53];
146                         __s32   fs_reclaim;
147                         __s32   fs_sparecon2[1];
148                         __s32   fs_state;
149                         __u32   fs_qbmask[2];
150                         __u32   fs_qfmask[2];
151                 } __attribute__((__packed__)) fs_sun;
152                 struct {
153                         __s32   fs_sparecon[53];
154                         __s32   fs_reclaim;
155                         __s32   fs_sparecon2[1];
156                         __u32   fs_npsect;
157                         __u32   fs_qbmask[2];
158                         __u32   fs_qfmask[2];
159                 } __attribute__((__packed__)) fs_sunx86;
160                 struct {
161                         __s32   fs_sparecon[50];
162                         __s32   fs_contigsumsize;
163                         __s32   fs_maxsymlinklen;
164                         __s32   fs_inodefmt;
165                         __u32   fs_maxfilesize[2];
166                         __u32   fs_qbmask[2];
167                         __u32   fs_qfmask[2];
168                         __s32   fs_state;
169                 } __attribute__((__packed__)) fs_44;
170         } fs_u2;
171         __s32   fs_postblformat;
172         __s32   fs_nrpos;
173         __s32   fs_postbloff;
174         __s32   fs_rotbloff;
175         __u32   fs_magic;
176         __u8    fs_space[1];
177 } __attribute__((__packed__));
178
179 #define UFS_MAGIC                       0x00011954
180 #define UFS2_MAGIC                      0x19540119
181 #define UFS_MAGIC_FEA                   0x00195612
182 #define UFS_MAGIC_LFN                   0x00095014
183
184 int volume_id_probe_ufs(struct volume_id *id, __u64 off)
185 {
186         __u32   magic;
187         int     i;
188         struct ufs_super_block *ufs;
189         int     offsets[] = {0, 8, 64, 256, -1};
190
191         dbg("probing at offset %llu", off);
192
193         for (i = 0; offsets[i] >= 0; i++) {     
194                 ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800);
195                 if (ufs == NULL)
196                         return -1;
197
198                 dbg("offset 0x%x", offsets[i] * 0x400);
199                 magic = be32_to_cpu(ufs->fs_magic);
200                 if ((magic == UFS_MAGIC) ||
201                     (magic == UFS2_MAGIC) ||
202                     (magic == UFS_MAGIC_FEA) ||
203                     (magic == UFS_MAGIC_LFN)) {
204                         dbg("magic 0x%08x(be)", magic);
205                         goto found;
206                 }
207                 magic = le32_to_cpu(ufs->fs_magic);
208                 if ((magic == UFS_MAGIC) ||
209                     (magic == UFS2_MAGIC) ||
210                     (magic == UFS_MAGIC_FEA) ||
211                     (magic == UFS_MAGIC_LFN)) {
212                         dbg("magic 0x%08x(le)", magic);
213                         goto found;
214                 }
215         }
216         return -1;
217
218 found:
219         volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
220         id->type = "ufs";
221
222         return 0;
223 }