~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to libblkid/src/superblocks/ufs.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
 
3
 *
 
4
 * Inspired by libvolume_id by
 
5
 *     Kay Sievers <kay.sievers@vrfy.org>
 
6
 *
 
7
 * This file may be redistributed under the terms of the
 
8
 * GNU Lesser General Public License.
 
9
 */
 
10
 
 
11
#include <stdio.h>
 
12
#include <stdlib.h>
 
13
#include <unistd.h>
 
14
#include <string.h>
 
15
#include <errno.h>
 
16
#include <ctype.h>
 
17
#include <stdint.h>
 
18
#include <stddef.h>
 
19
 
 
20
#include "superblocks.h"
 
21
 
 
22
struct ufs_super_block {
 
23
        uint32_t        fs_link;
 
24
        uint32_t        fs_rlink;
 
25
        uint32_t        fs_sblkno;
 
26
        uint32_t        fs_cblkno;
 
27
        uint32_t        fs_iblkno;
 
28
        uint32_t        fs_dblkno;
 
29
        uint32_t        fs_cgoffset;
 
30
        uint32_t        fs_cgmask;
 
31
        uint32_t        fs_time;
 
32
        uint32_t        fs_size;
 
33
        uint32_t        fs_dsize;
 
34
        uint32_t        fs_ncg;
 
35
        uint32_t        fs_bsize;
 
36
        uint32_t        fs_fsize;
 
37
        uint32_t        fs_frag;
 
38
        uint32_t        fs_minfree;
 
39
        uint32_t        fs_rotdelay;
 
40
        uint32_t        fs_rps;
 
41
        uint32_t        fs_bmask;
 
42
        uint32_t        fs_fmask;
 
43
        uint32_t        fs_bshift;
 
44
        uint32_t        fs_fshift;
 
45
        uint32_t        fs_maxcontig;
 
46
        uint32_t        fs_maxbpg;
 
47
        uint32_t        fs_fragshift;
 
48
        uint32_t        fs_fsbtodb;
 
49
        uint32_t        fs_sbsize;
 
50
        uint32_t        fs_csmask;
 
51
        uint32_t        fs_csshift;
 
52
        uint32_t        fs_nindir;
 
53
        uint32_t        fs_inopb;
 
54
        uint32_t        fs_nspf;
 
55
        uint32_t        fs_optim;
 
56
        uint32_t        fs_npsect_state;
 
57
        uint32_t        fs_interleave;
 
58
        uint32_t        fs_trackskew;
 
59
        uint32_t        fs_id[2];
 
60
        uint32_t        fs_csaddr;
 
61
        uint32_t        fs_cssize;
 
62
        uint32_t        fs_cgsize;
 
63
        uint32_t        fs_ntrak;
 
64
        uint32_t        fs_nsect;
 
65
        uint32_t        fs_spc;
 
66
        uint32_t        fs_ncyl;
 
67
        uint32_t        fs_cpg;
 
68
        uint32_t        fs_ipg;
 
69
        uint32_t        fs_fpg;
 
70
        struct ufs_csum {
 
71
                uint32_t        cs_ndir;
 
72
                uint32_t        cs_nbfree;
 
73
                uint32_t        cs_nifree;
 
74
                uint32_t        cs_nffree;
 
75
        } fs_cstotal;
 
76
        int8_t          fs_fmod;
 
77
        int8_t          fs_clean;
 
78
        int8_t          fs_ronly;
 
79
        int8_t          fs_flags;
 
80
        union {
 
81
                struct {
 
82
                        int8_t  fs_fsmnt[512];
 
83
                        uint32_t        fs_cgrotor;
 
84
                        uint32_t        fs_csp[31];
 
85
                        uint32_t        fs_maxcluster;
 
86
                        uint32_t        fs_cpc;
 
87
                        uint16_t        fs_opostbl[16][8];
 
88
                } fs_u1;
 
89
                struct {
 
90
                        int8_t          fs_fsmnt[468];
 
91
                        uint8_t         fs_volname[32];
 
92
                        uint64_t        fs_swuid;
 
93
                        int32_t         fs_pad;
 
94
                        uint32_t        fs_cgrotor;
 
95
                        uint32_t        fs_ocsp[28];
 
96
                        uint32_t        fs_contigdirs;
 
97
                        uint32_t        fs_csp;
 
98
                        uint32_t        fs_maxcluster;
 
99
                        uint32_t        fs_active;
 
100
                        int32_t         fs_old_cpc;
 
101
                        int32_t         fs_maxbsize;
 
102
                        int64_t         fs_sparecon64[17];
 
103
                        int64_t         fs_sblockloc;
 
104
                        struct ufs2_csum_total {
 
105
                                uint64_t        cs_ndir;
 
106
                                uint64_t        cs_nbfree;
 
107
                                uint64_t        cs_nifree;
 
108
                                uint64_t        cs_nffree;
 
109
                                uint64_t        cs_numclusters;
 
110
                                uint64_t        cs_spare[3];
 
111
                        } fs_cstotal;
 
112
                        struct ufs_timeval {
 
113
                                int32_t         tv_sec;
 
114
                                int32_t         tv_usec;
 
115
                        } fs_time;
 
116
                        int64_t         fs_size;
 
117
                        int64_t         fs_dsize;
 
118
                        uint64_t        fs_csaddr;
 
119
                        int64_t         fs_pendingblocks;
 
120
                        int32_t         fs_pendinginodes;
 
121
                } __attribute__((packed)) fs_u2;
 
122
        }  fs_u11;
 
123
        union {
 
124
                struct {
 
125
                        int32_t         fs_sparecon[53];
 
126
                        int32_t         fs_reclaim;
 
127
                        int32_t         fs_sparecon2[1];
 
128
                        int32_t         fs_state;
 
129
                        uint32_t        fs_qbmask[2];
 
130
                        uint32_t        fs_qfmask[2];
 
131
                } fs_sun;
 
132
                struct {
 
133
                        int32_t         fs_sparecon[53];
 
134
                        int32_t         fs_reclaim;
 
135
                        int32_t         fs_sparecon2[1];
 
136
                        uint32_t        fs_npsect;
 
137
                        uint32_t        fs_qbmask[2];
 
138
                        uint32_t        fs_qfmask[2];
 
139
                } fs_sunx86;
 
140
                struct {
 
141
                        int32_t         fs_sparecon[50];
 
142
                        int32_t         fs_contigsumsize;
 
143
                        int32_t         fs_maxsymlinklen;
 
144
                        int32_t         fs_inodefmt;
 
145
                        uint32_t        fs_maxfilesize[2];
 
146
                        uint32_t        fs_qbmask[2];
 
147
                        uint32_t        fs_qfmask[2];
 
148
                        int32_t         fs_state;
 
149
                } fs_44;
 
150
        } fs_u2;
 
151
        int32_t         fs_postblformat;
 
152
        int32_t         fs_nrpos;
 
153
        int32_t         fs_postbloff;
 
154
        int32_t         fs_rotbloff;
 
155
        uint32_t        fs_magic;
 
156
        uint8_t         fs_space[1];
 
157
} __attribute__((packed));
 
158
 
 
159
#define UFS_MAGIC                       0x00011954
 
160
#define UFS2_MAGIC                      0x19540119
 
161
#define UFS_MAGIC_FEA                   0x00195612
 
162
#define UFS_MAGIC_LFN                   0x00095014
 
163
#define UFS_MAGIC_SEC                   0x00612195
 
164
#define UFS_MAGIC_4GB                   0x05231994
 
165
 
 
166
static int probe_ufs(blkid_probe pr,
 
167
                const struct blkid_idmag *mag __attribute__((__unused__)))
 
168
{
 
169
        int offsets[] = { 0, 8, 64, 256 };
 
170
        uint32_t mags[] = {
 
171
                UFS2_MAGIC, UFS_MAGIC, UFS_MAGIC_FEA, UFS_MAGIC_LFN,
 
172
                UFS_MAGIC_SEC, UFS_MAGIC_4GB
 
173
        };
 
174
        size_t i;
 
175
        uint32_t magic;
 
176
        struct ufs_super_block *ufs;
 
177
 
 
178
        for (i = 0; i < ARRAY_SIZE(offsets); i++) {
 
179
                uint32_t magLE, magBE;
 
180
                size_t y;
 
181
 
 
182
                ufs = (struct ufs_super_block *)
 
183
                                blkid_probe_get_buffer(pr,
 
184
                                        offsets[i] * 1024,
 
185
                                        sizeof(struct ufs_super_block));
 
186
                if (!ufs)
 
187
                        return -1;
 
188
 
 
189
                magBE = be32_to_cpu(ufs->fs_magic);
 
190
                magLE = le32_to_cpu(ufs->fs_magic);
 
191
 
 
192
                for (y = 0; y < ARRAY_SIZE(mags); y++) {
 
193
                        if (magLE == mags[y] || magBE == mags[y]) {
 
194
                                magic = mags[y];
 
195
                                goto found;
 
196
                        }
 
197
                }
 
198
        }
 
199
 
 
200
        return 1;
 
201
 
 
202
found:
 
203
        if (magic == UFS2_MAGIC) {
 
204
                blkid_probe_set_version(pr, "2");
 
205
                blkid_probe_set_label(pr, ufs->fs_u11.fs_u2.fs_volname,
 
206
                                sizeof(ufs->fs_u11.fs_u2.fs_volname));
 
207
        } else
 
208
                blkid_probe_set_version(pr, "1");
 
209
 
 
210
        if (blkid_probe_set_magic(pr,
 
211
                        (offsets[i] * 1024) +
 
212
                                offsetof(struct ufs_super_block, fs_magic),
 
213
                        sizeof(ufs->fs_magic),
 
214
                        (unsigned char *) &ufs->fs_magic))
 
215
                return -1;
 
216
 
 
217
        return 0;
 
218
}
 
219
 
 
220
/*
 
221
 * According to libvolume_id the UFS superblock could be on four positions.
 
222
 * The original libblkid has checked one position (.kboff=8) only.
 
223
 *
 
224
 * We know four UFS magic strings and UFS could be both little-endian and
 
225
 * big-endian. ... so we have:
 
226
 *
 
227
 *      4 position * 4 string * 2 version = 32 magic strings
 
228
 *
 
229
 * It seems simpler to check for these string in probing function that hardcode
 
230
 * all in the .magic array.
 
231
 */
 
232
const struct blkid_idinfo ufs_idinfo =
 
233
{
 
234
        .name           = "ufs",
 
235
        .usage          = BLKID_USAGE_FILESYSTEM,
 
236
        .probefunc      = probe_ufs,
 
237
        .magics         = BLKID_NONE_MAGIC
 
238
};
 
239