blob: d670065d20ee4a4344f4e40ee2f0ea685c8034b3 [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"
Rob Landley43ac8882006-04-01 00:40:33 +000014#include <string.h>
Mike Frysinger7ad97802005-09-25 05:18:04 +000015
16/*
17 * Allocate memory
18 */
19errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
20{
21 void **pp = (void **)ptr;
22
23 *pp = malloc(size);
24 if (!*pp)
25 return EXT2_ET_NO_MEMORY;
26 return 0;
27}
28
29/*
30 * Free memory
31 */
32errcode_t ext2fs_free_mem(void *ptr)
33{
34 void **pp = (void **)ptr;
35
36 free(*pp);
37 *pp = 0;
38 return 0;
39}
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000040
Mike Frysinger7ad97802005-09-25 05:18:04 +000041/*
42 * Resize memory
43 */
44errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
45 unsigned long size, void *ptr)
46{
47 void *p;
Mike Frysinger7ad97802005-09-25 05:18:04 +000048
Mike Frysinger874af852006-03-08 07:03:27 +000049 /* Use "memcpy" for pointer assignments here to avoid problems
50 * with C99 strict type aliasing rules. */
51 memcpy(&p, ptr, sizeof (p));
52 p = realloc(p, size);
Mike Frysinger7ad97802005-09-25 05:18:04 +000053 if (!p)
54 return EXT2_ET_NO_MEMORY;
Mike Frysinger874af852006-03-08 07:03:27 +000055 memcpy(ptr, &p, sizeof (p));
Mike Frysinger7ad97802005-09-25 05:18:04 +000056 return 0;
57}
58
59/*
60 * Mark a filesystem superblock as dirty
61 */
62void ext2fs_mark_super_dirty(ext2_filsys fs)
63{
64 fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
65}
66
67/*
68 * Mark a filesystem as changed
69 */
70void ext2fs_mark_changed(ext2_filsys fs)
71{
72 fs->flags |= EXT2_FLAG_CHANGED;
73}
74
75/*
76 * Check to see if a filesystem has changed
77 */
78int ext2fs_test_changed(ext2_filsys fs)
79{
80 return (fs->flags & EXT2_FLAG_CHANGED);
81}
82
83/*
84 * Mark a filesystem as valid
85 */
86void ext2fs_mark_valid(ext2_filsys fs)
87{
88 fs->flags |= EXT2_FLAG_VALID;
89}
90
91/*
92 * Mark a filesystem as NOT valid
93 */
94void ext2fs_unmark_valid(ext2_filsys fs)
95{
96 fs->flags &= ~EXT2_FLAG_VALID;
97}
98
99/*
100 * Check to see if a filesystem is valid
101 */
102int ext2fs_test_valid(ext2_filsys fs)
103{
104 return (fs->flags & EXT2_FLAG_VALID);
105}
106
107/*
108 * Mark the inode bitmap as dirty
109 */
110void ext2fs_mark_ib_dirty(ext2_filsys fs)
111{
112 fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
113}
114
115/*
116 * Mark the block bitmap as dirty
117 */
118void ext2fs_mark_bb_dirty(ext2_filsys fs)
119{
120 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
121}
122
123/*
124 * Check to see if a filesystem's inode bitmap is dirty
125 */
126int ext2fs_test_ib_dirty(ext2_filsys fs)
127{
128 return (fs->flags & EXT2_FLAG_IB_DIRTY);
129}
130
131/*
132 * Check to see if a filesystem's block bitmap is dirty
133 */
134int ext2fs_test_bb_dirty(ext2_filsys fs)
135{
136 return (fs->flags & EXT2_FLAG_BB_DIRTY);
137}
138
139/*
140 * Return the group # of a block
141 */
142int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
143{
144 return (blk - fs->super->s_first_data_block) /
145 fs->super->s_blocks_per_group;
146}
147
148/*
149 * Return the group # of an inode number
150 */
151int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
152{
153 return (ino - 1) / fs->super->s_inodes_per_group;
154}
155
156blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
157 struct ext2_inode *inode)
158{
159 return inode->i_blocks -
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000160 (inode->i_file_acl ? fs->blocksize >> 9 : 0);
Mike Frysinger7ad97802005-09-25 05:18:04 +0000161}
162
163
164
165
166
167
168
169
170
171__u16 ext2fs_swab16(__u16 val)
172{
173 return (val >> 8) | (val << 8);
174}
175
176__u32 ext2fs_swab32(__u32 val)
177{
178 return ((val>>24) | ((val>>8)&0xFF00) |
179 ((val<<8)&0xFF0000) | (val<<24));
180}
181
182int ext2fs_find_first_bit_set(void * addr, unsigned size)
183{
Eric Andersen3496fdc2006-01-30 23:09:20 +0000184 unsigned char *cp = (unsigned char *) addr;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000185 int res = 0, d0;
Mike Frysinger7ad97802005-09-25 05:18:04 +0000186
187 if (!size)
188 return 0;
189
190 while ((size > res) && (*cp == 0)) {
191 cp++;
192 res += 8;
193 }
194 d0 = ffs(*cp);
195 if (d0 == 0)
196 return size;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000197
Mike Frysinger7ad97802005-09-25 05:18:04 +0000198 return res + d0 - 1;
199}
200
201int ext2fs_find_next_bit_set (void * addr, int size, int offset)
202{
203 unsigned char * p;
204 int set = 0, bit = offset & 7, res = 0, d0;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000205
Mike Frysinger7ad97802005-09-25 05:18:04 +0000206 res = offset >> 3;
207 p = ((unsigned char *) addr) + res;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000208
Mike Frysinger7ad97802005-09-25 05:18:04 +0000209 if (bit) {
210 set = ffs(*p & ~((1 << bit) - 1));
211 if (set)
212 return (offset & ~7) + set - 1;
213 p++;
214 res += 8;
215 }
216 while ((size > res) && (*p == 0)) {
217 p++;
218 res += 8;
219 }
220 d0 = ffs(*p);
221 if (d0 == 0)
222 return size;
223
224 return (res + d0 - 1);
225}
226
227int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
228 blk_t bitno);
229
230int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
231 blk_t bitno)
232{
233 if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
234 ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
235 return 0;
236 }
237 return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
238}
239
240int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
241 blk_t block)
242{
243 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
244 bitmap,
245 block);
246}
247
248int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
249 blk_t block)
250{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000251 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000252 block);
253}
254
255int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
256 blk_t block)
257{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000258 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000259 block);
260}
261
262int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
263 ext2_ino_t inode)
264{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000265 return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000266 inode);
267}
268
269int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
270 ext2_ino_t inode)
271{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000272 return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000273 inode);
274}
275
276int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
277 ext2_ino_t inode)
278{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000279 return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
Mike Frysinger7ad97802005-09-25 05:18:04 +0000280 inode);
281}
282
283void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
284 blk_t block)
285{
286#ifdef EXT2FS_DEBUG_FAST_OPS
287 if ((block < bitmap->start) || (block > bitmap->end)) {
288 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
289 bitmap->description);
290 return;
291 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000292#endif
Mike Frysinger7ad97802005-09-25 05:18:04 +0000293 ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
294}
295
296void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
297 blk_t block)
298{
299#ifdef EXT2FS_DEBUG_FAST_OPS
300 if ((block < bitmap->start) || (block > bitmap->end)) {
301 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
302 block, bitmap->description);
303 return;
304 }
305#endif
306 ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
307}
308
309int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
310 blk_t block)
311{
312#ifdef EXT2FS_DEBUG_FAST_OPS
313 if ((block < bitmap->start) || (block > bitmap->end)) {
314 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
315 block, bitmap->description);
316 return 0;
317 }
318#endif
319 return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
320}
321
322void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
323 ext2_ino_t inode)
324{
325#ifdef EXT2FS_DEBUG_FAST_OPS
326 if ((inode < bitmap->start) || (inode > bitmap->end)) {
327 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
328 inode, bitmap->description);
329 return;
330 }
331#endif
332 ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
333}
334
335void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
336 ext2_ino_t inode)
337{
338#ifdef EXT2FS_DEBUG_FAST_OPS
339 if ((inode < bitmap->start) || (inode > bitmap->end)) {
340 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
341 inode, bitmap->description);
342 return;
343 }
344#endif
345 ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
346}
347
348int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
349 ext2_ino_t inode)
350{
351#ifdef EXT2FS_DEBUG_FAST_OPS
352 if ((inode < bitmap->start) || (inode > bitmap->end)) {
353 ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
354 inode, bitmap->description);
355 return 0;
356 }
357#endif
358 return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
359}
360
361blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
362{
363 return bitmap->start;
364}
365
366ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
367{
368 return bitmap->start;
369}
370
371blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
372{
373 return bitmap->end;
374}
375
376ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
377{
378 return bitmap->end;
379}
380
381int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
382 blk_t block, int num)
383{
384 int i;
385
386 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
387 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
388 block, bitmap->description);
389 return 0;
390 }
391 for (i=0; i < num; i++) {
392 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
393 return 0;
394 }
395 return 1;
396}
397
398int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
399 blk_t block, int num)
400{
401 int i;
402
403#ifdef EXT2FS_DEBUG_FAST_OPS
404 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
405 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
406 block, bitmap->description);
407 return 0;
408 }
409#endif
410 for (i=0; i < num; i++) {
411 if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
412 return 0;
413 }
414 return 1;
415}
416
417void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
418 blk_t block, int num)
419{
420 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000421
Mike Frysinger7ad97802005-09-25 05:18:04 +0000422 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
423 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
424 bitmap->description);
425 return;
426 }
427 for (i=0; i < num; i++)
428 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
429}
430
431void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
432 blk_t block, int num)
433{
434 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000435
Mike Frysinger7ad97802005-09-25 05:18:04 +0000436#ifdef EXT2FS_DEBUG_FAST_OPS
437 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
438 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
439 bitmap->description);
440 return;
441 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000442#endif
Mike Frysinger7ad97802005-09-25 05:18:04 +0000443 for (i=0; i < num; i++)
444 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
445}
446
447void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
448 blk_t block, int num)
449{
450 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000451
Mike Frysinger7ad97802005-09-25 05:18:04 +0000452 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
453 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
454 bitmap->description);
455 return;
456 }
457 for (i=0; i < num; i++)
458 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
459}
460
461void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
462 blk_t block, int num)
463{
464 int i;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000465
Mike Frysinger7ad97802005-09-25 05:18:04 +0000466#ifdef EXT2FS_DEBUG_FAST_OPS
467 if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
468 ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
469 bitmap->description);
470 return;
471 }
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000472#endif
Mike Frysinger7ad97802005-09-25 05:18:04 +0000473 for (i=0; i < num; i++)
474 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
475}