~pr0gg3d/ubuntu/oneiric/util-linux/bug-805886

« back to all changes in this revision

Viewing changes to shlibs/blkid/src/superblocks/befs.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant
  • Date: 2010-03-22 17:35:40 UTC
  • mfrom: (1.6.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100322173540-sm083tdtvne1wa5w
Tags: 2.17.2-0ubuntu1
* Merge from Debian experimental, remaining changes:
  - Since udev is required in Ubuntu, the hwclock.sh init script is
    not called on startup and the hwclockfirst.sh init script is
    removed.
  - Use wildcards for symbols file, since they use versioned symbols
    properly.
  - Remove /etc/adjtime on upgrade if it was not used.
  - Install custom blkid.conf to use /dev/.blkid.tab since we don't
    expect device names to survive a reboot
  - No lsb_release call in mount.preinst since we'd need Pre-Depends
    (LP: #383697).
  - Do not install initramfs hook, since our initramfs already handles
    including blkid.
  - Mention mountall(8) in fstab(5) manpages, along with its special
    options.

* For the case where mount is called with a directory to mount, look
  that directory up in mountall's /lib/init/fstab if we couldn't find
  it mentioned anywhere else.  This means "mount /proc", "mount /sys",
  etc. work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2010 Jeroen Oortwijn <oortwijn@gmail.com>
3
 
 *
4
 
 * This file may be redistributed under the terms of the
5
 
 * GNU Lesser General Public License.
6
 
 */
7
 
#include <stdio.h>
8
 
#include <stdlib.h>
9
 
#include <unistd.h>
10
 
#include <string.h>
11
 
#include <inttypes.h>
12
 
 
13
 
#include "superblocks.h"
14
 
 
15
 
#define B_OS_NAME_LENGTH        0x20
16
 
#define SUPER_BLOCK_MAGIC1      0x42465331      /* BFS1 */
17
 
#define SUPER_BLOCK_MAGIC2      0xdd121031
18
 
#define SUPER_BLOCK_MAGIC3      0x15b6830e
19
 
#define SUPER_BLOCK_FS_ENDIAN   0x42494745      /* BIGE */
20
 
#define INODE_MAGIC1            0x3bbe0ad9
21
 
#define B_UINT64_TYPE           0x554C4C47      /* ULLG */
22
 
 
23
 
#define FS16_TO_CPU(value, fs_is_le) (fs_is_le ? le16_to_cpu(value) \
24
 
                                                        : be16_to_cpu(value))
25
 
#define FS32_TO_CPU(value, fs_is_le) (fs_is_le ? le32_to_cpu(value) \
26
 
                                                        : be32_to_cpu(value))
27
 
#define FS64_TO_CPU(value, fs_is_le) (fs_is_le ? le64_to_cpu(value) \
28
 
                                                        : be64_to_cpu(value))
29
 
 
30
 
typedef struct block_run {
31
 
        int32_t         allocation_group;
32
 
        uint16_t        start;
33
 
        uint16_t        len;
34
 
} __attribute__((packed)) block_run, inode_addr;
35
 
 
36
 
struct befs_super_block {
37
 
        char            name[B_OS_NAME_LENGTH];
38
 
        int32_t         magic1;
39
 
        int32_t         fs_byte_order;
40
 
        uint32_t        block_size;
41
 
        uint32_t        block_shift;
42
 
        int64_t         num_blocks;
43
 
        int64_t         used_blocks;
44
 
        int32_t         inode_size;
45
 
        int32_t         magic2;
46
 
        int32_t         blocks_per_ag;
47
 
        int32_t         ag_shift;
48
 
        int32_t         num_ags;
49
 
        int32_t         flags;
50
 
        block_run       log_blocks;
51
 
        int64_t         log_start;
52
 
        int64_t         log_end;
53
 
        int32_t         magic3;
54
 
        inode_addr      root_dir;
55
 
        inode_addr      indices;
56
 
        int32_t         pad[8];
57
 
} __attribute__((packed));
58
 
 
59
 
typedef struct data_stream {
60
 
        block_run       direct[12];
61
 
        int64_t         max_direct_range;
62
 
        block_run       indirect;
63
 
        int64_t         max_indirect_range;
64
 
        block_run       double_indirect;
65
 
        int64_t         max_double_indirect_range;
66
 
        int64_t         size;
67
 
} __attribute__((packed)) data_stream;
68
 
 
69
 
struct befs_inode {
70
 
        int32_t         magic1;
71
 
        inode_addr      inode_num;
72
 
        int32_t         uid;
73
 
        int32_t         gid;
74
 
        int32_t         mode;
75
 
        int32_t         flags;
76
 
        int64_t         create_time;
77
 
        int64_t         last_modified_time;
78
 
        inode_addr      parent;
79
 
        inode_addr      attributes;
80
 
        uint32_t        type;
81
 
        int32_t         inode_size;
82
 
        uint32_t        etc;
83
 
        data_stream     data;
84
 
        int32_t         pad[4];
85
 
        int32_t         small_data[1];
86
 
} __attribute__((packed));
87
 
 
88
 
struct small_data {
89
 
        uint32_t        type;
90
 
        uint16_t        name_size;
91
 
        uint16_t        data_size;
92
 
        char            name[0];
93
 
} __attribute__((packed));
94
 
 
95
 
static int probe_befs(blkid_probe pr, const struct blkid_idmag *mag)
96
 
{
97
 
        struct befs_super_block *bs;
98
 
        struct befs_inode *bi;
99
 
        struct small_data *sd;
100
 
        int fs_le;
101
 
        uint64_t volume_id = 0;
102
 
        const char *version = NULL;
103
 
 
104
 
        bs = (struct befs_super_block *) blkid_probe_get_buffer(pr,
105
 
                                        mag->sboff - B_OS_NAME_LENGTH,
106
 
                                        sizeof(struct befs_super_block));
107
 
        if (!bs)
108
 
                return -1;
109
 
 
110
 
        if (le32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
111
 
                && le32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
112
 
                && le32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
113
 
                && le32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
114
 
                fs_le = 1;
115
 
                version = "little-endian";
116
 
        } else if (be32_to_cpu(bs->magic1) == SUPER_BLOCK_MAGIC1
117
 
                && be32_to_cpu(bs->magic2) == SUPER_BLOCK_MAGIC2
118
 
                && be32_to_cpu(bs->magic3) == SUPER_BLOCK_MAGIC3
119
 
                && be32_to_cpu(bs->fs_byte_order) == SUPER_BLOCK_FS_ENDIAN) {
120
 
                fs_le = 0;
121
 
                version = "big-endian";
122
 
        } else
123
 
                return -1;
124
 
 
125
 
        bi = (struct befs_inode *) blkid_probe_get_buffer(pr,
126
 
                        (FS32_TO_CPU(bs->root_dir.allocation_group, fs_le)
127
 
                                << FS32_TO_CPU(bs->ag_shift, fs_le)
128
 
                                << FS32_TO_CPU(bs->block_shift, fs_le))
129
 
                        + (FS16_TO_CPU(bs->root_dir.start, fs_le)
130
 
                                << FS32_TO_CPU(bs->block_shift, fs_le)),
131
 
                        FS16_TO_CPU(bs->root_dir.len, fs_le)
132
 
                                << FS32_TO_CPU(bs->block_shift, fs_le));
133
 
        if (!bi)
134
 
                return -1;
135
 
 
136
 
        if (FS32_TO_CPU(bi->magic1, fs_le) != INODE_MAGIC1)
137
 
                return -1;
138
 
 
139
 
        /*
140
 
         * all checks pass, set LABEL and VERSION
141
 
         */
142
 
        if (strlen(bs->name))
143
 
                blkid_probe_set_label(pr, (unsigned char *) bs->name,
144
 
                                                        sizeof(bs->name));
145
 
        if (version)
146
 
                blkid_probe_set_version(pr, version);
147
 
 
148
 
        /*
149
 
         * search for UUID
150
 
         */
151
 
        sd = (struct small_data *) bi->small_data;
152
 
 
153
 
        do {
154
 
                if (FS32_TO_CPU(sd->type, fs_le) == B_UINT64_TYPE
155
 
                                && FS16_TO_CPU(sd->name_size, fs_le) == 12
156
 
                                && FS16_TO_CPU(sd->data_size, fs_le) == 8
157
 
                                && strcmp(sd->name, "be:volume_id") == 0) {
158
 
                        volume_id = *(uint64_t *) ((uint8_t *) sd->name
159
 
                                        + FS16_TO_CPU(sd->name_size, fs_le)
160
 
                                        + 3);
161
 
                        blkid_probe_sprintf_uuid(pr,
162
 
                                        (unsigned char *) &volume_id,
163
 
                                        sizeof(volume_id),
164
 
                                        "%016" PRIx64,
165
 
                                        FS64_TO_CPU(volume_id, fs_le));
166
 
                        break;
167
 
                } else if (FS32_TO_CPU(sd->type, fs_le) == 0
168
 
                                && FS16_TO_CPU(sd->name_size, fs_le) == 0
169
 
                                && FS16_TO_CPU(sd->data_size, fs_le) == 0) {
170
 
                        break;
171
 
                }
172
 
 
173
 
                sd = (struct small_data *) ((uint8_t *) sd
174
 
                                + sizeof(struct small_data)
175
 
                                + FS16_TO_CPU(sd->name_size, fs_le) + 3
176
 
                                + FS16_TO_CPU(sd->data_size, fs_le) + 1);
177
 
 
178
 
        } while ((intptr_t) sd < (intptr_t) bi
179
 
                                        + FS32_TO_CPU(bi->inode_size, fs_le)
180
 
                                        - sizeof(struct small_data));
181
 
 
182
 
        if (volume_id == 0) {
183
 
                /*
184
 
                 * TODO: Search for the be:volume_id attribute in the
185
 
                 *       attributes directory of the root directory.
186
 
                 */
187
 
        }
188
 
 
189
 
        return 0;
190
 
}
191
 
 
192
 
const struct blkid_idinfo befs_idinfo =
193
 
{
194
 
        .name           = "befs",
195
 
        .usage          = BLKID_USAGE_FILESYSTEM,
196
 
        .probefunc      = probe_befs,
197
 
        .minsz          = 1024 * 1440,
198
 
        .magics         = {
199
 
                { .magic = "BFS1", .len = 4, .sboff = B_OS_NAME_LENGTH },
200
 
                { .magic = "1SFB", .len = 4, .sboff = B_OS_NAME_LENGTH },
201
 
                { .magic = "BFS1", .len = 4, .sboff = 0x200 +
202
 
                                                        B_OS_NAME_LENGTH },
203
 
                { .magic = "1SFB", .len = 4, .sboff = 0x200 +
204
 
                                                        B_OS_NAME_LENGTH },
205
 
                { NULL }
206
 
        }
207
 
};