There doesn't seem to be a standard header for makedev(), but this is close.
[oweals/busybox.git] / e2fsprogs / ext2fs / ext2fs_inline.c
1 /*
2  * ext2fs.h --- ext2fs
3  * 
4  * 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
12 #include "ext2fs.h"
13 #include "bitops.h"
14
15 /*
16  *  Allocate memory
17  */
18 errcode_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  */
31 errcode_t ext2fs_free_mem(void *ptr)
32 {
33         void **pp = (void **)ptr;
34
35         free(*pp);
36         *pp = 0;
37         return 0;
38 }
39         
40 /*
41  *  Resize memory
42  */
43 errcode_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  */
59 void 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  */
67 void 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  */
75 int ext2fs_test_changed(ext2_filsys fs)
76 {
77         return (fs->flags & EXT2_FLAG_CHANGED);
78 }
79
80 /*
81  * Mark a filesystem as valid
82  */
83 void ext2fs_mark_valid(ext2_filsys fs)
84 {
85         fs->flags |= EXT2_FLAG_VALID;
86 }
87
88 /*
89  * Mark a filesystem as NOT valid
90  */
91 void 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  */
99 int 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  */
107 void 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  */
115 void 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  */
123 int 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  */
131 int 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  */
139 int 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  */
148 int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
149 {
150         return (ino - 1) / fs->super->s_inodes_per_group;
151 }
152
153 blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
154                                         struct ext2_inode *inode)
155 {
156        return inode->i_blocks -
157               (inode->i_file_acl ? fs->blocksize >> 9 : 0);
158 }
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
179 int ext2fs_find_first_bit_set(void * addr, unsigned size)
180 {
181         char    *cp = (unsigned char *) addr;
182         int     res = 0, d0;
183
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;
194         
195         return res + d0 - 1;
196 }
197
198 int 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;
202         
203         res = offset >> 3;
204         p = ((unsigned char *) addr) + res;
205         
206         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
224 int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
225                                         blk_t bitno);
226
227 int 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
237 int 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
245 int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
246                                          blk_t block)
247 {
248         return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
249                                             block);
250 }
251
252 int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
253                                        blk_t block)
254 {
255         return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
256                                           block);
257 }
258
259 int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
260                                        ext2_ino_t inode)
261 {
262         return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
263                                           inode);
264 }
265
266 int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
267                                          ext2_ino_t inode)
268 {
269         return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
270                                      inode);
271 }
272
273 int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
274                                        ext2_ino_t inode)
275 {
276         return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
277                                           inode);
278 }
279
280 void 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         }
289 #endif  
290         ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
291 }
292
293 void 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
306 int 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
319 void 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
332 void 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
345 int 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
358 blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
359 {
360         return bitmap->start;
361 }
362
363 ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
364 {
365         return bitmap->start;
366 }
367
368 blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
369 {
370         return bitmap->end;
371 }
372
373 ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
374 {
375         return bitmap->end;
376 }
377
378 int 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
395 int 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
414 void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
415                                              blk_t block, int num)
416 {
417         int     i;
418         
419         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
428 void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
429                                                   blk_t block, int num)
430 {
431         int     i;
432         
433 #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         }
439 #endif  
440         for (i=0; i < num; i++)
441                 ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
442 }
443
444 void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
445                                                blk_t block, int num)
446 {
447         int     i;
448         
449         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
458 void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
459                                                     blk_t block, int num)
460 {
461         int     i;
462         
463 #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         }
469 #endif  
470         for (i=0; i < num; i++)
471                 ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
472 }