OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [hfs/] [mdb.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/fs/hfs/mdb.c
3
 *
4
 * Copyright (C) 1995-1997  Paul H. Hargrove
5
 * This file may be distributed under the terms of the GNU General Public License.
6
 *
7
 * This file contains functions for reading/writing the MDB.
8
 *
9
 * "XXX" in a comment is a note to myself to consider changing something.
10
 *
11
 * In function preconditions the term "valid" applied to a pointer to
12
 * a structure means that the pointer is non-NULL and the structure it
13
 * points to has all fields initialized to consistent values.
14
 *
15
 * The code in this file initializes some structures which contain
16
 * pointers by calling memset(&foo, 0, sizeof(foo)).
17
 * This produces the desired behavior only due to the non-ANSI
18
 * assumption that the machine representation of NULL is all zeros.
19
 */
20
 
21
#include "hfs.h"
22
 
23
/*================ File-local data types ================*/
24
 
25
/*
26
 * The HFS Master Directory Block (MDB).
27
 *
28
 * Also known as the Volume Information Block (VIB), this structure is
29
 * the HFS equivalent of a superblock.
30
 *
31
 * Reference: _Inside Macintosh: Files_ pages 2-59 through 2-62
32
 *
33
 * modified for HFS Extended
34
 */
35
struct raw_mdb {
36
        hfs_word_t      drSigWord;      /* Signature word indicating fs type */
37
        hfs_lword_t     drCrDate;       /* fs creation date/time */
38
        hfs_lword_t     drLsMod;        /* fs modification date/time */
39
        hfs_word_t      drAtrb;         /* fs attributes */
40
        hfs_word_t      drNmFls;        /* number of files in root directory */
41
        hfs_word_t      drVBMSt;        /* location (in 512-byte blocks)
42
                                           of the volume bitmap */
43
        hfs_word_t      drAllocPtr;     /* location (in allocation blocks)
44
                                           to begin next allocation search */
45
        hfs_word_t      drNmAlBlks;     /* number of allocation blocks */
46
        hfs_lword_t     drAlBlkSiz;     /* bytes in an allocation block */
47
        hfs_lword_t     drClpSiz;       /* clumpsize, the number of bytes to
48
                                           allocate when extending a file */
49
        hfs_word_t      drAlBlSt;       /* location (in 512-byte blocks)
50
                                           of the first allocation block */
51
        hfs_lword_t     drNxtCNID;      /* CNID to assign to the next
52
                                           file or directory created */
53
        hfs_word_t      drFreeBks;      /* number of free allocation blocks */
54
        hfs_byte_t      drVN[28];       /* the volume label */
55
        hfs_lword_t     drVolBkUp;      /* fs backup date/time */
56
        hfs_word_t      drVSeqNum;      /* backup sequence number */
57
        hfs_lword_t     drWrCnt;        /* fs write count */
58
        hfs_lword_t     drXTClpSiz;     /* clumpsize for the extents B-tree */
59
        hfs_lword_t     drCTClpSiz;     /* clumpsize for the catalog B-tree */
60
        hfs_word_t      drNmRtDirs;     /* number of directories in
61
                                           the root directory */
62
        hfs_lword_t     drFilCnt;       /* number of files in the fs */
63
        hfs_lword_t     drDirCnt;       /* number of directories in the fs */
64
        hfs_byte_t      drFndrInfo[32]; /* data used by the Finder */
65
        hfs_word_t      drEmbedSigWord; /* embedded volume signature */
66
        hfs_lword_t     drEmbedExtent;  /* starting block number (xdrStABN)
67
                                           and number of allocation blocks
68
                                           (xdrNumABlks) occupied by embedded
69
                                           volume */
70
        hfs_lword_t     drXTFlSize;     /* bytes in the extents B-tree */
71
        hfs_byte_t      drXTExtRec[12]; /* extents B-tree's first 3 extents */
72
        hfs_lword_t     drCTFlSize;     /* bytes in the catalog B-tree */
73
        hfs_byte_t      drCTExtRec[12]; /* catalog B-tree's first 3 extents */
74
} __attribute__((packed));
75
 
76
/*================ Global functions ================*/
77
 
78
/*
79
 * hfs_mdb_get()
80
 *
81
 * Build the in-core MDB for a filesystem, including
82
 * the B-trees and the volume bitmap.
83
 */
84
struct hfs_mdb *hfs_mdb_get(hfs_sysmdb sys_mdb, int readonly,
85
                            hfs_s32 part_start)
86
{
87
        struct hfs_mdb *mdb;
88
        hfs_buffer buf;
89
        struct raw_mdb *raw;
90
        unsigned int bs, block;
91
        int lcv, limit;
92
        hfs_buffer *bmbuf;
93
 
94
        if (!HFS_NEW(mdb)) {
95
                hfs_warn("hfs_fs: out of memory\n");
96
                return NULL;
97
        }
98
 
99
        memset(mdb, 0, sizeof(*mdb));
100
        mdb->magic = HFS_MDB_MAGIC;
101
        mdb->sys_mdb = sys_mdb;
102
        INIT_LIST_HEAD(&mdb->entry_dirty);
103
        hfs_init_waitqueue(&mdb->rename_wait);
104
        hfs_init_waitqueue(&mdb->bitmap_wait);
105
 
106
        /* See if this is an HFS filesystem */
107
        buf = hfs_buffer_get(sys_mdb, part_start + HFS_MDB_BLK, 1);
108
        if (!hfs_buffer_ok(buf)) {
109
                hfs_warn("hfs_fs: Unable to read superblock\n");
110
                HFS_DELETE(mdb);
111
                goto bail2;
112
        }
113
 
114
        raw = (struct raw_mdb *)hfs_buffer_data(buf);
115
        if (hfs_get_ns(raw->drSigWord) != htons(HFS_SUPER_MAGIC)) {
116
                hfs_buffer_put(buf);
117
                HFS_DELETE(mdb);
118
                goto bail2;
119
        }
120
        mdb->buf = buf;
121
 
122
        bs = hfs_get_hl(raw->drAlBlkSiz);
123
        if (!bs || (bs & (HFS_SECTOR_SIZE-1))) {
124
                hfs_warn("hfs_fs: bad allocation block size %d != 512\n", bs);
125
                hfs_buffer_put(buf);
126
                HFS_DELETE(mdb);
127
                goto bail2;
128
        }
129
        mdb->alloc_blksz = bs >> HFS_SECTOR_SIZE_BITS;
130
 
131
        /* These parameters are read from the MDB, and never written */
132
        mdb->create_date = hfs_get_hl(raw->drCrDate);
133
        mdb->fs_ablocks  = hfs_get_hs(raw->drNmAlBlks);
134
        mdb->fs_start    = hfs_get_hs(raw->drAlBlSt) + part_start;
135
        mdb->backup_date = hfs_get_hl(raw->drVolBkUp);
136
        mdb->clumpablks  = (hfs_get_hl(raw->drClpSiz) / mdb->alloc_blksz)
137
                                                 >> HFS_SECTOR_SIZE_BITS;
138
        memcpy(mdb->vname, raw->drVN, sizeof(raw->drVN));
139
 
140
        /* These parameters are read from and written to the MDB */
141
        mdb->modify_date  = hfs_get_nl(raw->drLsMod);
142
        mdb->attrib       = hfs_get_ns(raw->drAtrb);
143
        mdb->free_ablocks = hfs_get_hs(raw->drFreeBks);
144
        mdb->next_id      = hfs_get_hl(raw->drNxtCNID);
145
        mdb->write_count  = hfs_get_hl(raw->drWrCnt);
146
        mdb->root_files   = hfs_get_hs(raw->drNmFls);
147
        mdb->root_dirs    = hfs_get_hs(raw->drNmRtDirs);
148
        mdb->file_count   = hfs_get_hl(raw->drFilCnt);
149
        mdb->dir_count    = hfs_get_hl(raw->drDirCnt);
150
 
151
        /* TRY to get the alternate (backup) MDB. */
152
        lcv = mdb->fs_start + mdb->fs_ablocks * mdb->alloc_blksz;
153
        limit = lcv + mdb->alloc_blksz;
154
        for (; lcv < limit; ++lcv) {
155
                buf = hfs_buffer_get(sys_mdb, lcv, 1);
156
                if (hfs_buffer_ok(buf)) {
157
                        struct raw_mdb *tmp =
158
                                (struct raw_mdb *)hfs_buffer_data(buf);
159
 
160
                        if (hfs_get_ns(tmp->drSigWord) ==
161
                            htons(HFS_SUPER_MAGIC)) {
162
                                mdb->alt_buf = buf;
163
                                break;
164
                        }
165
                }
166
                hfs_buffer_put(buf);
167
        }
168
 
169
        if (mdb->alt_buf == NULL) {
170
                hfs_warn("hfs_fs: unable to locate alternate MDB\n");
171
                hfs_warn("hfs_fs: continuing without an alternate MDB\n");
172
        }
173
 
174
        /* read in the bitmap */
175
        block = hfs_get_hs(raw->drVBMSt) + part_start;
176
        bmbuf = mdb->bitmap;
177
        lcv = (mdb->fs_ablocks + 4095) / 4096;
178
        for ( ; lcv; --lcv, ++bmbuf, ++block) {
179
                if (!hfs_buffer_ok(*bmbuf =
180
                                   hfs_buffer_get(sys_mdb, block, 1))) {
181
                        hfs_warn("hfs_fs: unable to read volume bitmap\n");
182
                        goto bail1;
183
                }
184
        }
185
 
186
        if (!(mdb->ext_tree = hfs_btree_init(mdb, htonl(HFS_EXT_CNID),
187
                                             raw->drXTExtRec,
188
                                             hfs_get_hl(raw->drXTFlSize),
189
                                             hfs_get_hl(raw->drXTClpSiz))) ||
190
            !(mdb->cat_tree = hfs_btree_init(mdb, htonl(HFS_CAT_CNID),
191
                                             raw->drCTExtRec,
192
                                             hfs_get_hl(raw->drCTFlSize),
193
                                             hfs_get_hl(raw->drCTClpSiz)))) {
194
                hfs_warn("hfs_fs: unable to initialize data structures\n");
195
                goto bail1;
196
        }
197
 
198
        if (!(mdb->attrib & htons(HFS_SB_ATTRIB_CLEAN))) {
199
                hfs_warn("hfs_fs: WARNING: mounting unclean filesystem.\n");
200
        } else if (!readonly && !(mdb->attrib & (HFS_SB_ATTRIB_HLOCK | HFS_SB_ATTRIB_SLOCK))) {
201
                /* Mark the volume uncleanly unmounted in case we crash */
202
                hfs_put_ns(mdb->attrib & htons(~HFS_SB_ATTRIB_CLEAN),
203
                           raw->drAtrb);
204
                hfs_buffer_dirty(mdb->buf);
205
                hfs_buffer_sync(mdb->buf);
206
        }
207
 
208
        return mdb;
209
 
210
bail1:
211
        hfs_mdb_put(mdb, readonly);
212
bail2:
213
        return NULL;
214
}
215
 
216
/*
217
 * hfs_mdb_commit()
218
 *
219
 * Description:
220
 *   This updates the MDB on disk (look also at hfs_write_super()).
221
 *   It does not check, if the superblock has been modified, or
222
 *   if the filesystem has been mounted read-only. It is mainly
223
 *   called by hfs_write_super() and hfs_btree_extend().
224
 * Input Variable(s):
225
 *   struct hfs_mdb *mdb: Pointer to the hfs MDB
226
 *   int backup;
227
 * Output Variable(s):
228
 *   NONE
229
 * Returns:
230
 *   void
231
 * Preconditions:
232
 *   'mdb' points to a "valid" (struct hfs_mdb).
233
 * Postconditions:
234
 *   The HFS MDB and on disk will be updated, by copying the possibly
235
 *   modified fields from the in memory MDB (in native byte order) to
236
 *   the disk block buffer.
237
 *   If 'backup' is non-zero then the alternate MDB is also written
238
 *   and the function doesn't return until it is actually on disk.
239
 */
240
void hfs_mdb_commit(struct hfs_mdb *mdb, int backup)
241
{
242
        struct raw_mdb *raw = (struct raw_mdb *)hfs_buffer_data(mdb->buf);
243
 
244
        /* Commit catalog entries to buffers */
245
        hfs_cat_commit(mdb);
246
 
247
        /* Commit B-tree data to buffers */
248
        hfs_btree_commit(mdb->cat_tree, raw->drCTExtRec, raw->drCTFlSize);
249
        hfs_btree_commit(mdb->ext_tree, raw->drXTExtRec, raw->drXTFlSize);
250
 
251
        /* Update write_count and modify_date */
252
        ++mdb->write_count;
253
        mdb->modify_date = hfs_time();
254
 
255
        /* These parameters may have been modified, so write them back */
256
        hfs_put_nl(mdb->modify_date,   raw->drLsMod);
257
        hfs_put_hs(mdb->free_ablocks,  raw->drFreeBks);
258
        hfs_put_hl(mdb->next_id,       raw->drNxtCNID);
259
        hfs_put_hl(mdb->write_count,   raw->drWrCnt);
260
        hfs_put_hs(mdb->root_files,    raw->drNmFls);
261
        hfs_put_hs(mdb->root_dirs,     raw->drNmRtDirs);
262
        hfs_put_hl(mdb->file_count,    raw->drFilCnt);
263
        hfs_put_hl(mdb->dir_count,     raw->drDirCnt);
264
 
265
        /* write MDB to disk */
266
        hfs_buffer_dirty(mdb->buf);
267
 
268
        /* write the backup MDB, not returning until it is written.
269
         * we only do this when either the catalog or extents overflow
270
         * files grow. */
271
        if (backup && hfs_buffer_ok(mdb->alt_buf)) {
272
                struct raw_mdb *tmp = (struct raw_mdb *)
273
                        hfs_buffer_data(mdb->alt_buf);
274
 
275
                if ((hfs_get_hl(tmp->drCTFlSize) <
276
                     hfs_get_hl(raw->drCTFlSize)) ||
277
                    (hfs_get_hl(tmp->drXTFlSize) <
278
                     hfs_get_hl(raw->drXTFlSize))) {
279
                        memcpy(hfs_buffer_data(mdb->alt_buf),
280
                               hfs_buffer_data(mdb->buf), HFS_SECTOR_SIZE);
281
                        hfs_buffer_dirty(mdb->alt_buf);
282
                        hfs_buffer_sync(mdb->alt_buf);
283
                }
284
        }
285
}
286
 
287
/*
288
 * hfs_mdb_put()
289
 *
290
 * Release the resources associated with the in-core MDB.  */
291
void hfs_mdb_put(struct hfs_mdb *mdb, int readonly) {
292
        int lcv;
293
 
294
        /* invalidate cached catalog entries */
295
        hfs_cat_invalidate(mdb);
296
 
297
        /* free the B-trees */
298
        hfs_btree_free(mdb->ext_tree);
299
        hfs_btree_free(mdb->cat_tree);
300
 
301
        /* free the volume bitmap */
302
        for (lcv = 0; lcv < HFS_BM_MAXBLOCKS; ++lcv) {
303
                hfs_buffer_put(mdb->bitmap[lcv]);
304
        }
305
 
306
        /* update volume attributes */
307
        if (!readonly) {
308
                struct raw_mdb *raw =
309
                                (struct raw_mdb *)hfs_buffer_data(mdb->buf);
310
                hfs_put_ns(mdb->attrib, raw->drAtrb);
311
                hfs_buffer_dirty(mdb->buf);
312
        }
313
 
314
        /* free the buffers holding the primary and alternate MDBs */
315
        hfs_buffer_put(mdb->buf);
316
        hfs_buffer_put(mdb->alt_buf);
317
 
318
        /* free the MDB */
319
        HFS_DELETE(mdb);
320
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.