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