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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/fs/hfs/bitmap.c
3
 *
4
 * Copyright (C) 1996-1997  Paul H. Hargrove
5
 * This file may be distributed under the terms of the GNU General Public License.
6
 *
7
 * Based on GPLed code Copyright (C) 1995  Michael Dreher
8
 *
9
 * This file contains the code to modify the volume bitmap:
10
 * search/set/clear bits.
11
 *
12
 * "XXX" in a comment is a note to myself to consider changing something.
13
 *
14
 * In function preconditions the term "valid" applied to a pointer to
15
 * a structure means that the pointer is non-NULL and the structure it
16
 * points to has all fields initialized to consistent values.
17
 */
18
 
19
#include "hfs.h"
20
 
21
/*================ Global functions ================*/
22
 
23
/*
24
 * hfs_vbm_count_free()
25
 *
26
 * Description:
27
 *   Count the number of consecutive cleared bits in the bitmap blocks of
28
 *   the hfs MDB starting at bit number 'start'.  'mdb' had better
29
 *   be locked or the indicated number of blocks may be no longer free,
30
 *   when this functions returns!
31
 * Input Variable(s):
32
 *   struct hfs_mdb *mdb: Pointer to the hfs MDB
33
 *   hfs_u16 start: bit number to start at
34
 * Output Variable(s):
35
 *   NONE
36
 * Returns:
37
 *   The number of consecutive cleared bits starting at bit 'start'
38
 * Preconditions:
39
 *   'mdb' points to a "valid" (struct hfs_mdb).
40
 * Postconditions:
41
 *   NONE
42
 */
43
hfs_u16 hfs_vbm_count_free(const struct hfs_mdb *mdb, hfs_u16 start)
44
{
45
        hfs_u16 block_nr;       /* index of the current bitmap block */
46
        hfs_u16 bit_nr;         /* index of the current bit in block */
47
        hfs_u16 count;          /* number of bits found so far */
48
        hfs_u16 len;            /* number of bits found in this block */
49
        hfs_u16 max_block;      /* index of last bitmap block */
50
        hfs_u16 max_bits;       /* index of last bit in block */
51
 
52
        /* is this a valid HFS MDB? */
53
        if (!mdb) {
54
                return 0;
55
        }
56
 
57
        block_nr = start / HFS_BM_BPB;
58
        bit_nr   = start % HFS_BM_BPB;
59
        max_block = (mdb->fs_ablocks + HFS_BM_BPB - 1) / HFS_BM_BPB - 1;
60
 
61
        count = 0;
62
        while (block_nr <= max_block) {
63
                if (block_nr != max_block) {
64
                        max_bits = HFS_BM_BPB;
65
                } else {
66
                        max_bits = mdb->fs_ablocks % HFS_BM_BPB;
67
                }
68
 
69
                len=hfs_count_zero_bits(hfs_buffer_data(mdb->bitmap[block_nr]),
70
                                        max_bits, bit_nr);
71
                count += len;
72
 
73
                /* see if we fell short of the end of this block */
74
                if ((len + bit_nr) < max_bits) {
75
                        break;
76
                }
77
 
78
                ++block_nr;
79
                bit_nr = 0;
80
        }
81
        return count;
82
}
83
 
84
/*
85
 * hfs_vbm_search_free()
86
 *
87
 * Description:
88
 *   Search for 'num_bits' consecutive cleared bits in the bitmap blocks of
89
 *   the hfs MDB. 'mdb' had better be locked or the returned range
90
 *   may be no longer free, when this functions returns!
91
 *   XXX Currently the search starts from bit 0, but it should start with
92
 *   the bit number stored in 's_alloc_ptr' of the MDB.
93
 * Input Variable(s):
94
 *   struct hfs_mdb *mdb: Pointer to the hfs MDB
95
 *   hfs_u16 *num_bits: Pointer to the number of cleared bits
96
 *     to search for
97
 * Output Variable(s):
98
 *   hfs_u16 *num_bits: The number of consecutive clear bits of the
99
 *     returned range. If the bitmap is fragmented, this will be less than
100
 *     requested and it will be zero, when the disk is full.
101
 * Returns:
102
 *   The number of the first bit of the range of cleared bits which has been
103
 *   found. When 'num_bits' is zero, this is invalid!
104
 * Preconditions:
105
 *   'mdb' points to a "valid" (struct hfs_mdb).
106
 *   'num_bits' points to a variable of type (hfs_u16), which contains
107
 *      the number of cleared bits to find.
108
 * Postconditions:
109
 *   'num_bits' is set to the length of the found sequence.
110
 */
111
hfs_u16 hfs_vbm_search_free(const struct hfs_mdb *mdb, hfs_u16 *num_bits)
112
{
113
        hfs_u16 block_nr; /* index of the current bitmap block */
114
 
115
        /* position and length of current portion of a run */
116
        hfs_u16 cur_pos, cur_len;
117
 
118
        /* position and length of current complete run */
119
        hfs_u16 pos=0, len=0;
120
 
121
        /* position and length of longest complete run */
122
        hfs_u16 longest_pos=0, longest_len=0;
123
 
124
        void *bitmap; /* contents of the current bitmap block */
125
        hfs_u16 max_block; /* upper limit of outer loop */
126
        hfs_u16 max_bits; /* upper limit of inner loop */
127
 
128
        /* is this a valid HFS MDB? */
129
        if (!mdb) {
130
                *num_bits = 0;
131
                hfs_warn("hfs_vbm_search_free: not a valid MDB\n");
132
                return 0;
133
        }
134
 
135
        /* make sure we have actual work to perform */
136
        if (!(*num_bits)) {
137
                return 0;
138
        }
139
 
140
        max_block = (mdb->fs_ablocks+HFS_BM_BPB-1) / HFS_BM_BPB - 1;
141
 
142
        /* search all bitmap blocks */
143
        for (block_nr = 0; block_nr <= max_block; block_nr++) {
144
                bitmap = hfs_buffer_data(mdb->bitmap[block_nr]);
145
 
146
                if (block_nr != max_block) {
147
                        max_bits = HFS_BM_BPB;
148
                } else {
149
                        max_bits = mdb->fs_ablocks % HFS_BM_BPB;
150
                }
151
 
152
                cur_pos = 0;
153
                do {
154
                        cur_len = hfs_count_zero_bits(bitmap, max_bits,
155
                                                      cur_pos);
156
                        len += cur_len;
157
                        if (len > longest_len) {
158
                                longest_pos = pos;
159
                                longest_len = len;
160
                                if (len >= *num_bits) {
161
                                        goto search_end;
162
                                }
163
                        }
164
                        if ((cur_pos + cur_len) == max_bits) {
165
                                break; /* zeros may continue into next block */
166
                        }
167
 
168
                        /* find start of next run of zeros */
169
                        cur_pos = hfs_find_zero_bit(bitmap, max_bits,
170
                                                    cur_pos + cur_len);
171
                        pos = cur_pos + HFS_BM_BPB*block_nr;
172
                        len = 0;
173
                } while (cur_pos < max_bits);
174
        }
175
 
176
search_end:
177
        *num_bits = longest_len;
178
        return longest_pos;
179
}
180
 
181
 
182
/*
183
 * hfs_set_vbm_bits()
184
 *
185
 * Description:
186
 *   Set the requested bits in the volume bitmap of the hfs filesystem
187
 * Input Variable(s):
188
 *   struct hfs_mdb *mdb: Pointer to the hfs MDB
189
 *   hfs_u16 start: The offset of the first bit
190
 *   hfs_u16 count: The number of bits
191
 * Output Variable(s):
192
 *   None
193
 * Returns:
194
 *    0: no error
195
 *   -1: One of the bits was already set.  This is a strange
196
 *       error and when it happens, the filesystem must be repaired!
197
 *   -2: One or more of the bits are out of range of the bitmap.
198
 *   -3: The 's_magic' field of the MDB does not match
199
 * Preconditions:
200
 *   'mdb' points to a "valid" (struct hfs_mdb).
201
 * Postconditions:
202
 *   Starting with bit number 'start', 'count' bits in the volume bitmap
203
 *   are set. The affected bitmap blocks are marked "dirty", the free
204
 *   block count of the MDB is updated and the MDB is marked dirty.
205
 */
206
int hfs_set_vbm_bits(struct hfs_mdb *mdb, hfs_u16 start, hfs_u16 count)
207
{
208
        hfs_u16 block_nr;       /* index of the current bitmap block */
209
        hfs_u16 u32_nr;         /* index of the current hfs_u32 in block */
210
        hfs_u16 bit_nr;         /* index of the current bit in hfs_u32 */
211
        hfs_u16 left = count;   /* number of bits left to be set */
212
        hfs_u32 *bitmap;        /* the current bitmap block's contents */
213
 
214
        /* is this a valid HFS MDB? */
215
        if (!mdb) {
216
                return -3;
217
        }
218
 
219
        /* is there any actual work to be done? */
220
        if (!count) {
221
                return 0;
222
        }
223
 
224
        /* are all of the bits in range? */
225
        if ((start + count) > mdb->fs_ablocks) {
226
                return -2;
227
        }
228
 
229
        block_nr = start / HFS_BM_BPB;
230
        u32_nr = (start % HFS_BM_BPB) / 32;
231
        bit_nr = start % 32;
232
 
233
        /* bitmap is always on a 32-bit boundary */
234
        bitmap = (hfs_u32 *)hfs_buffer_data(mdb->bitmap[block_nr]);
235
 
236
        /* do any partial hfs_u32 at the start */
237
        if (bit_nr != 0) {
238
                while ((bit_nr < 32) && left) {
239
                        if (hfs_set_bit(bit_nr, bitmap + u32_nr)) {
240
                                hfs_buffer_dirty(mdb->bitmap[block_nr]);
241
                                return -1;
242
                        }
243
                        ++bit_nr;
244
                        --left;
245
                }
246
                bit_nr=0;
247
 
248
                /* advance u32_nr and check for end of this block */
249
                if (++u32_nr > 127) {
250
                        u32_nr = 0;
251
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
252
                        ++block_nr;
253
                        /* bitmap is always on a 32-bit boundary */
254
                        bitmap = (hfs_u32 *)
255
                                        hfs_buffer_data(mdb->bitmap[block_nr]);
256
                }
257
        }
258
 
259
        /* do full hfs_u32s */
260
        while (left > 31) {
261
                if (bitmap[u32_nr] != ((hfs_u32)0)) {
262
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
263
                        return -1;
264
                }
265
                bitmap[u32_nr] = ~((hfs_u32)0);
266
                left -= 32;
267
 
268
                /* advance u32_nr and check for end of this block */
269
                if (++u32_nr > 127) {
270
                        u32_nr = 0;
271
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
272
                        ++block_nr;
273
                        /* bitmap is always on a 32-bit boundary */
274
                        bitmap = (hfs_u32 *)
275
                                        hfs_buffer_data(mdb->bitmap[block_nr]);
276
                }
277
        }
278
 
279
 
280
        /* do any partial hfs_u32 at end */
281
        while (left) {
282
                if (hfs_set_bit(bit_nr, bitmap + u32_nr)) {
283
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
284
                        return -1;
285
                }
286
                ++bit_nr;
287
                --left;
288
        }
289
 
290
        hfs_buffer_dirty(mdb->bitmap[block_nr]);
291
        mdb->free_ablocks -= count;
292
 
293
        /* successful completion */
294
        hfs_mdb_dirty(mdb->sys_mdb);
295
        return 0;
296
}
297
 
298
/*
299
 * hfs_clear_vbm_bits()
300
 *
301
 * Description:
302
 *   Clear the requested bits in the volume bitmap of the hfs filesystem
303
 * Input Variable(s):
304
 *   struct hfs_mdb *mdb: Pointer to the hfs MDB
305
 *   hfs_u16 start: The offset of the first bit
306
 *   hfs_u16 count: The number of bits
307
 * Output Variable(s):
308
 *   None
309
 * Returns:
310
 *    0: no error
311
 *   -1: One of the bits was already clear.  This is a strange
312
 *       error and when it happens, the filesystem must be repaired!
313
 *   -2: One or more of the bits are out of range of the bitmap.
314
 *   -3: The 's_magic' field of the MDB does not match
315
 * Preconditions:
316
 *   'mdb' points to a "valid" (struct hfs_mdb).
317
 * Postconditions:
318
 *   Starting with bit number 'start', 'count' bits in the volume bitmap
319
 *   are cleared. The affected bitmap blocks are marked "dirty", the free
320
 *   block count of the MDB is updated and the MDB is marked dirty.
321
 */
322
int hfs_clear_vbm_bits(struct hfs_mdb *mdb, hfs_u16 start, hfs_u16 count)
323
{
324
        hfs_u16 block_nr;       /* index of the current bitmap block */
325
        hfs_u16 u32_nr;         /* index of the current hfs_u32 in block */
326
        hfs_u16 bit_nr;         /* index of the current bit in hfs_u32 */
327
        hfs_u16 left = count;   /* number of bits left to be set */
328
        hfs_u32 *bitmap;        /* the current bitmap block's contents */
329
 
330
        /* is this a valid HFS MDB? */
331
        if (!mdb) {
332
                return -3;
333
        }
334
 
335
        /* is there any actual work to be done? */
336
        if (!count) {
337
                return 0;
338
        }
339
 
340
        /* are all of the bits in range? */
341
        if ((start + count) > mdb->fs_ablocks) {
342
                return -2;
343
        }
344
 
345
        block_nr = start / HFS_BM_BPB;
346
        u32_nr = (start % HFS_BM_BPB) / 32;
347
        bit_nr = start % 32;
348
 
349
        /* bitmap is always on a 32-bit boundary */
350
        bitmap = (hfs_u32 *)hfs_buffer_data(mdb->bitmap[block_nr]);
351
 
352
        /* do any partial hfs_u32 at the start */
353
        if (bit_nr != 0) {
354
                while ((bit_nr < 32) && left) {
355
                        if (!hfs_clear_bit(bit_nr, bitmap + u32_nr)) {
356
                                hfs_buffer_dirty(mdb->bitmap[block_nr]);
357
                                return -1;
358
                        }
359
                        ++bit_nr;
360
                        --left;
361
                }
362
                bit_nr=0;
363
 
364
                /* advance u32_nr and check for end of this block */
365
                if (++u32_nr > 127) {
366
                        u32_nr = 0;
367
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
368
                        ++block_nr;
369
                        /* bitmap is always on a 32-bit boundary */
370
                        bitmap = (hfs_u32 *)
371
                                        hfs_buffer_data(mdb->bitmap[block_nr]);
372
                }
373
        }
374
 
375
        /* do full hfs_u32s */
376
        while (left > 31) {
377
                if (bitmap[u32_nr] != ~((hfs_u32)0)) {
378
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
379
                        return -1;
380
                }
381
                bitmap[u32_nr] = ((hfs_u32)0);
382
                left -= 32;
383
 
384
                /* advance u32_nr and check for end of this block */
385
                if (++u32_nr > 127) {
386
                        u32_nr = 0;
387
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
388
                        ++block_nr;
389
                        /* bitmap is always on a 32-bit boundary */
390
                        bitmap = (hfs_u32 *)
391
                                        hfs_buffer_data(mdb->bitmap[block_nr]);
392
                }
393
        }
394
 
395
 
396
        /* do any partial hfs_u32 at end */
397
        while (left) {
398
                if (!hfs_clear_bit(bit_nr, bitmap + u32_nr)) {
399
                        hfs_buffer_dirty(mdb->bitmap[block_nr]);
400
                        return -1;
401
                }
402
                ++bit_nr;
403
                --left;
404
        }
405
 
406
        hfs_buffer_dirty(mdb->bitmap[block_nr]);
407
        mdb->free_ablocks += count;
408
 
409
        /* successful completion */
410
        hfs_mdb_dirty(mdb->sys_mdb);
411
        return 0;
412
}

powered by: WebSVN 2.1.0

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