blob: 73d393d20a1fcd623ae901e211de9554f9bfb0fc [file] [log] [blame]
Mike Frysinger7ad97802005-09-25 05:18:04 +00001/*
2 * ext2fs.h --- ext2fs
Tim Rikerc1ef7bd2006-01-25 00:08:53 +00003 *
Mike Frysinger7ad97802005-09-25 05:18:04 +00004 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
10 */
11
"Vladimir N. Oleynik"083d3f42005-10-10 11:35:17 +000012#include "ext2fs.h"
13#include "bitops.h"
Mike Frysinger7ad97802005-09-25 05:18:04 +000014
15/*
16 * Allocate memory
17 */
18errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
19{
20 void **pp = (void **)ptr;
21
22 *pp = malloc(size);
23 if (!*pp)
24 return EXT2_ET_NO_MEMORY;
25 return 0;
26}
27
28/*
29 * Free memory
30 */
31errcode_t ext2fs_free_mem(void *ptr)
32{
33 void **pp = (void **)ptr;
34
35 free(*pp);
36 *pp = 0;
37 return 0;
38}
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000039
Mike Frysinger7ad97802005-09-25 05:18:04 +000040/*
41 * Resize memory
42 */
43errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
44 unsigned long size, void *ptr)
45{
46 void *p;
47 void **pp = (void **)ptr;
48
49 p = realloc(*pp, size);
50 if (!p)
51 return EXT2_ET_NO_MEMORY;
52 *pp = p;
53 return 0;
54}
55
56/*
57 * Mark a filesystem superblock as dirty
58 */
59void ext2fs_mark_super_dirty(ext2_filsys fs)
60{
61 fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
62}
63
64/*
65 * Mark a filesystem as changed
66 */
67void ext2fs_mark_changed(ext2_filsys fs)
68{
69 fs->flags |= EXT2_FLAG_CHANGED;
70}
71
72/*
73 * Check to see if a filesystem has changed
74 */
75int ext2fs_test_changed(ext2_filsys fs)
76{
77 return (fs->flags & EXT2_FLAG_CHANGED);
78}
79
80/*
81 * Mark a filesystem as valid
82 */
83void ext2fs_mark_valid(ext2_filsys fs)
84{
85 fs->flags |= EXT2_FLAG_VALID;
86}
87
88/*
89 * Mark a filesystem as NOT valid
90 */
91void ext2fs_unmark_valid(ext2_filsys fs)
92{
93 fs->flags &= ~EXT2_FLAG_VALID;
94}
95
96/*
97 * Check to see if a filesystem is valid
98 */
99int ext2fs_test_valid(ext2_filsys fs)
100{
101 return (fs->flags & EXT2_FLAG_VALID);
102}
103
104/*
105 * Mark the inode bitmap as dirty
106 */
107void ext2fs_mark_ib_dirty(ext2_filsys fs)
108{
109 fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
110}
111
112/*
113 * Mark the block bitmap as dirty
114 */
115void ext2fs_mark_bb_dirty(ext2_filsys fs)
116{
117 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
118}
119
120/*
121 * Check to see if a filesystem's inode bitmap is dirty
122 */
123int ext2fs_test_ib_dirty(ext2_filsys fs)
124{
125 return (fs->flags & EXT2_FLAG_IB_DIRTY);
126}
127
128/*
129 * Check to see if a filesystem's block bitmap is dirty
130 */
131int ext2fs_test_bb_dirty(ext2_filsys fs)
132{
133 return (fs->flags & EXT2_FLAG_BB_DIRTY);
134}
135
136/*
137 * Return the group # of a block
138 */
139int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
140{
141 return (blk - fs->super->s_first_data_block) /
142 fs->super->s_blocks_per_group;
143}
144
145/*
146 * Return the group # of an inode number
147 */
148int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
149{
150 return (ino - 1) / fs->super->s_inodes_per_group;
151}
152
153blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
154 struct ext2_inode *inode)
155{
156 return inode->i_blocks -
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000157 (inode->i_file_acl ? fs->blocksize >> 9 : 0);
Mike Frysinger7ad97802005-09-25 05:18:04 +0000158}
159
160
161
162
163
164
165
166
167
168__u16 ext2fs_swab16(__u16 val)
169{
170 return (val >> 8) | (val << 8);
171}
172
173__u32 ext2fs_swab32(__u32 val)
174{
175 return ((val>>24) | ((val>>8)&0xFF00) |
176 ((val<<8)&0xFF0000) | (val<<24));
177}
178
179int ext2fs_find_first_bit_set(void * addr, unsigned size)
180{
Eric Andersen3496fdc2006-01-30 23:09:20 +0000181 unsigned char *cp = (unsigned char *) addr;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000182 int res = 0, d0;
Mike Frysinger7ad97802005-09-25 05:18:04 +0000183
184 if (!size)
185 return 0;
186
187 while ((size > res) && (*cp == 0)) {
188 cp++;
189 res += 8;
190 }
191 d0 = ffs(*cp);
192 if (d0 == 0)
193 return size;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000194
Mike Frysinger7ad97802005-09-25 05:18:04 +0000195 return res + d0 - 1;
196}
197
198int ext2fs_find_next_bit_set (void * addr, int size, int offset)
199{
200 unsigned char * p;
201 int set = 0, bit = offset & 7, res = 0, d0;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000202
Mike Frysinger7ad97802005-09-25 05:18:04 +0000203 res = offset >> 3;
204 p = ((unsigned char *) addr) + res;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000205
Mike Frysinger7ad97802005-09-25 05:18:04 +0000206 if (bit) {
207 set = ffs(*p & ~((1 << bit) - 1));
208 if (set)
209 return (offset & ~7) + set - 1;
210 p++;
211 res += 8;
212 }
213 while ((size > res) && (*p == 0)) {
214 p++;
215 res += 8;
216 }
217 d0 = ffs(*p);
218 if (d0 == 0)
219 return size;
220
221 return (res + d0 - 1);
222}
223
224int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
225 blk_t bitno);
226
227int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
228 blk_t bitno)
229{
230 if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
231 ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
232 return 0;
233 }
234 return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
235}
236
237int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
238 blk_t block)
239{
240 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
241 bitmap,
242 block);
243}
244
245int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
246 blk_t block)
247{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000248 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000249 block);
250}
251
252int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
253 blk_t block)
254{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000255 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000256 block);
257}
258
259int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
260 ext2_ino_t inode)
261{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000262 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000263 inode);
264}
265
266int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
267 ext2_ino_t inode)
268{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000269 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000270 inode);
271}
272
273int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
274 ext2_ino_t inode)
275{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000276 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000277 inode);
278}
279
280void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
281 blk_t block)
282{
283#ifdef EXT2FS_DEBUG_FAST_OPS
284 if ((block < bitmap->start) || (block > bitmap->end)) {
285 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
286 bitmap->description);
287 return;
288 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000289#endif
Mike Frysinger7ad97802005-09-25 05:18:04 +0000290 ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
291}
292
293void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
294 blk_t block)
295{
296#ifdef EXT2FS_DEBUG_FAST_OPS
297 if ((block < bitmap->start) || (block > bitmap->end)) {
298 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
299 block, bitmap->description);
300 return;
301 }
302#endif
303 ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
304}
305
306int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
307 blk_t block)
308{
309#ifdef EXT2FS_DEBUG_FAST_OPS
310 if ((block < bitmap->start) || (block > bitmap->end)) {
311 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
312 block, bitmap->description);
313 return 0;
314 }
315#endif
316 return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
317}
318
319void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
320 ext2_ino_t inode)
321{
322#ifdef EXT2FS_DEBUG_FAST_OPS
323 if ((inode < bitmap->start) || (inode > bitmap->end)) {
324 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
325 inode, bitmap->description);
326 return;
327 }
328#endif
329 ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
330}
331
332void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
333 ext2_ino_t inode)
334{
335#ifdef EXT2FS_DEBUG_FAST_OPS
336 if ((inode < bitmap->start) || (inode > bitmap->end)) {
337 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
338 inode, bitmap->description);
339 return;
340 }
341#endif
342 ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
343}
344
345int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
346 ext2_ino_t inode)
347{
348#ifdef EXT2FS_DEBUG_FAST_OPS
349 if ((inode < bitmap->start) || (inode > bitmap->end)) {
350 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
351 inode, bitmap->description);
352 return 0;
353 }
354#endif
355 return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
356}
357
358blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
359{
360 return bitmap->start;
361}
362
363ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
364{
365 return bitmap->start;
366}
367
368blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
369{
370 return bitmap->end;
371}
372
373ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
374{
375 return bitmap->end;
376}
377
378int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
379 blk_t block, int num)
380{
381 int i;
382
383 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
384 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
385 block, bitmap->description);
386 return 0;
387 }
388 for (i=0; i < num; i++) {
389 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
390 return 0;
391 }
392 return 1;
393}
394
395int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
396 blk_t block, int num)
397{
398 int i;
399
400#ifdef EXT2FS_DEBUG_FAST_OPS
401 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
402 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
403 block, bitmap->description);
404 return 0;
405 }
406#endif
407 for (i=0; i < num; i++) {
408 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
409 return 0;
410 }
411 return 1;
412}
413
414void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
415 blk_t block, int num)
416{
417 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000418
Mike Frysinger7ad97802005-09-25 05:18:04 +0000419 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
420 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
421 bitmap->description);
422 return;
423 }
424 for (i=0; i < num; i++)
425 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
426}
427
428void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
429 blk_t block, int num)
430{
431 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000432
Mike Frysinger7ad97802005-09-25 05:18:04 +0000433#ifdef EXT2FS_DEBUG_FAST_OPS
434 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
435 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
436 bitmap->description);
437 return;
438 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000439#endif
Mike Frysinger7ad97802005-09-25 05:18:04 +0000440 for (i=0; i < num; i++)
441 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
442}
443
444void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
445 blk_t block, int num)
446{
447 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000448
Mike Frysinger7ad97802005-09-25 05:18:04 +0000449 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
450 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
451 bitmap->description);
452 return;
453 }
454 for (i=0; i < num; i++)
455 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
456}
457
458void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
459 blk_t block, int num)
460{
461 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000462
Mike Frysinger7ad97802005-09-25 05:18:04 +0000463#ifdef EXT2FS_DEBUG_FAST_OPS
464 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
465 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
466 bitmap->description);
467 return;
468 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000469#endif
Mike Frysinger7ad97802005-09-25 05:18:04 +0000470 for (i=0; i < num; i++)
471 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
472}