chiark / gitweb /
bab1d4cfadc1e25710824696d7b64c6416a3248e
[elogind.git] / extras / volume_id / volume_id / ufs / 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 #define UFS_MAGIC                       0x00011954
43 #define UFS2_MAGIC                      0x19540119
44 #define UFS_MAGIC_FEA                   0x00195612
45 #define UFS_MAGIC_LFN                   0x00095014
46
47 int volume_id_probe_ufs(struct volume_id *id, __u64 off)
48 {
49         struct ufs_super_block {
50                 __u32   fs_link;
51                 __u32   fs_rlink;
52                 __u32   fs_sblkno;
53                 __u32   fs_cblkno;
54                 __u32   fs_iblkno;
55                 __u32   fs_dblkno;
56                 __u32   fs_cgoffset;
57                 __u32   fs_cgmask;
58                 __u32   fs_time;
59                 __u32   fs_size;
60                 __u32   fs_dsize;
61                 __u32   fs_ncg; 
62                 __u32   fs_bsize;
63                 __u32   fs_fsize;
64                 __u32   fs_frag;
65                 __u32   fs_minfree;
66                 __u32   fs_rotdelay;
67                 __u32   fs_rps; 
68                 __u32   fs_bmask;
69                 __u32   fs_fmask;
70                 __u32   fs_bshift;
71                 __u32   fs_fshift;
72                 __u32   fs_maxcontig;
73                 __u32   fs_maxbpg;
74                 __u32   fs_fragshift;
75                 __u32   fs_fsbtodb;
76                 __u32   fs_sbsize;
77                 __u32   fs_csmask;
78                 __u32   fs_csshift;
79                 __u32   fs_nindir;
80                 __u32   fs_inopb;
81                 __u32   fs_nspf;
82                 __u32   fs_optim;
83                 __u32   fs_npsect_state;
84                 __u32   fs_interleave;
85                 __u32   fs_trackskew;
86                 __u32   fs_id[2];
87                 __u32   fs_csaddr;
88                 __u32   fs_cssize;
89                 __u32   fs_cgsize;
90                 __u32   fs_ntrak;
91                 __u32   fs_nsect;
92                 __u32   fs_spc; 
93                 __u32   fs_ncyl;
94                 __u32   fs_cpg;
95                 __u32   fs_ipg;
96                 __u32   fs_fpg;
97                 struct ufs_csum {
98                         __u32   cs_ndir;
99                         __u32   cs_nbfree;
100                         __u32   cs_nifree;
101                         __u32   cs_nffree;
102                 } __attribute__((__packed__)) fs_cstotal;
103                 __s8    fs_fmod;
104                 __s8    fs_clean;
105                 __s8    fs_ronly;
106                 __s8    fs_flags;
107                 union {
108                         struct {
109                                 __s8    fs_fsmnt[512];
110                                 __u32   fs_cgrotor;
111                                 __u32   fs_csp[31];
112                                 __u32   fs_maxcluster;
113                                 __u32   fs_cpc;
114                                 __u16   fs_opostbl[16][8];
115                         } __attribute__((__packed__)) fs_u1;
116                         struct {
117                                 __s8  fs_fsmnt[468];
118                                 __u8   fs_volname[32];
119                                 __u64  fs_swuid;
120                                 __s32  fs_pad;
121                                 __u32   fs_cgrotor;
122                                 __u32   fs_ocsp[28];
123                                 __u32   fs_contigdirs;
124                                 __u32   fs_csp; 
125                                 __u32   fs_maxcluster;
126                                 __u32   fs_active;
127                                 __s32   fs_old_cpc;
128                                 __s32   fs_maxbsize;
129                                 __s64   fs_sparecon64[17];
130                                 __s64   fs_sblockloc;
131                                 struct  ufs2_csum_total {
132                                         __u64   cs_ndir;
133                                         __u64   cs_nbfree;
134                                         __u64   cs_nifree;
135                                         __u64   cs_nffree;
136                                         __u64   cs_numclusters;
137                                         __u64   cs_spare[3];
138                                 } __attribute__((__packed__)) fs_cstotal;
139                                 struct  ufs_timeval {
140                                         __s32   tv_sec;
141                                         __s32   tv_usec;
142                                 } __attribute__((__packed__)) fs_time;
143                                 __s64    fs_size;
144                                 __s64    fs_dsize;
145                                 __u64    fs_csaddr;
146                                 __s64    fs_pendingblocks;
147                                 __s32    fs_pendinginodes;
148                         } __attribute__((__packed__)) fs_u2;
149                 }  fs_u11;
150                 union {
151                         struct {
152                                 __s32   fs_sparecon[53];
153                                 __s32   fs_reclaim;
154                                 __s32   fs_sparecon2[1];
155                                 __s32   fs_state;
156                                 __u32   fs_qbmask[2];
157                                 __u32   fs_qfmask[2];
158                         } __attribute__((__packed__)) fs_sun;
159                         struct {
160                                 __s32   fs_sparecon[53];
161                                 __s32   fs_reclaim;
162                                 __s32   fs_sparecon2[1];
163                                 __u32   fs_npsect;
164                                 __u32   fs_qbmask[2];
165                                 __u32   fs_qfmask[2];
166                         } __attribute__((__packed__)) fs_sunx86;
167                         struct {
168                                 __s32   fs_sparecon[50];
169                                 __s32   fs_contigsumsize;
170                                 __s32   fs_maxsymlinklen;
171                                 __s32   fs_inodefmt;
172                                 __u32   fs_maxfilesize[2];
173                                 __u32   fs_qbmask[2];
174                                 __u32   fs_qfmask[2];
175                                 __s32   fs_state;
176                         } __attribute__((__packed__)) fs_44;
177                 } fs_u2;
178                 __s32   fs_postblformat;
179                 __s32   fs_nrpos;
180                 __s32   fs_postbloff;
181                 __s32   fs_rotbloff;
182                 __u32   fs_magic;
183                 __u8    fs_space[1];
184         } __attribute__((__packed__)) *ufs;
185
186         __u32   magic;
187         int     i;
188         int     offsets[] = {0, 8, 64, 256, -1};
189
190         for (i = 0; offsets[i] >= 0; i++) {     
191                 ufs = (struct ufs_super_block *) volume_id_get_buffer(id, off + (offsets[i] * 0x400), 0x800);
192                 if (ufs == NULL)
193                         return -1;
194
195                 dbg("offset 0x%x", offsets[i] * 0x400);
196                 magic = be32_to_cpu(ufs->fs_magic);
197                 if ((magic == UFS_MAGIC) ||
198                     (magic == UFS2_MAGIC) ||
199                     (magic == UFS_MAGIC_FEA) ||
200                     (magic == UFS_MAGIC_LFN)) {
201                         dbg("magic 0x%08x(be)", magic);
202                         goto found;
203                 }
204                 magic = le32_to_cpu(ufs->fs_magic);
205                 if ((magic == UFS_MAGIC) ||
206                     (magic == UFS2_MAGIC) ||
207                     (magic == UFS_MAGIC_FEA) ||
208                     (magic == UFS_MAGIC_LFN)) {
209                         dbg("magic 0x%08x(le)", magic);
210                         goto found;
211                 }
212         }
213         return -1;
214
215 found:
216         volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
217         id->type = "ufs";
218
219         return 0;
220 }