4 * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
9 * Where the master copy of the superblock is located, and how big
10 * superblocks are supposed to be. We define SUPERBLOCK_SIZE because
11 * the size of the superblock structure is not necessarily trustworthy
12 * (some versions have the padding set up so that the superblock is
15 #define SUPERBLOCK_OFFSET 1024
16 #define SUPERBLOCK_SIZE 1024
19 * The last ext2fs revision level that this version of the library is
22 #define EXT2_LIB_CURRENT_REV 0
24 #include <linux/types.h>
27 typedef unsigned int dgrp_t;
29 #include "et/com_err.h"
30 #include "ext2fs/io.h"
31 #include "ext2fs/ext2_err.h"
33 typedef struct struct_ext2_filsys *ext2_filsys;
35 struct ext2fs_struct_inode_bitmap {
45 typedef struct ext2fs_struct_inode_bitmap *ext2fs_inode_bitmap;
47 struct ext2fs_struct_block_bitmap {
57 typedef struct ext2fs_struct_block_bitmap *ext2fs_block_bitmap;
59 #ifdef EXT2_DYNAMIC_REV
60 #define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
62 #define EXT2_FIRST_INODE(s) EXT2_FIRST_INO
63 #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
67 * Flags for the ext2_filsys structure
70 #define EXT2_FLAG_RW 0x01
71 #define EXT2_FLAG_CHANGED 0x02
72 #define EXT2_FLAG_DIRTY 0x04
73 #define EXT2_FLAG_VALID 0x08
74 #define EXT2_FLAG_IB_DIRTY 0x10
75 #define EXT2_FLAG_BB_DIRTY 0x20
76 #define EXT2_SWAP_BYTES 0x40
79 * Special flag in the ext2 inode i_flag field that means that this is
80 * a new inode. (So that ext2_write_inode() can clear extra fields.)
82 #define EXT2_NEW_INODE_FL 0x80000000
84 struct struct_ext2_filsys {
89 struct ext2_super_block * super;
92 unsigned long group_desc_count;
93 unsigned long desc_blocks;
94 struct ext2_group_desc * group_desc;
95 int inode_blocks_per_group;
96 ext2fs_inode_bitmap inode_map;
97 ext2fs_block_bitmap block_map;
98 errcode_t (*get_blocks)(ext2_filsys fs, ino_t ino, blk_t *blocks);
99 errcode_t (*check_directory)(ext2_filsys fs, ino_t ino);
100 errcode_t (*write_bitmaps)(ext2_filsys fs);
104 * Not used by ext2fs library; reserved for the use of the
105 * calling application.
111 * badblocks list definitions
114 typedef struct struct_badblocks_list *badblocks_list;
116 struct struct_badblocks_list {
125 #define BADBLOCKS_FLAG_DIRTY 1
127 typedef struct struct_badblocks_iterate *badblocks_iterate;
129 struct struct_badblocks_iterate {
136 #include "ext2fs/bitops.h"
139 * Return flags for the block iterator functions
141 #define BLOCK_CHANGED 1
142 #define BLOCK_ABORT 2
143 #define BLOCK_ERROR 4
146 * Block interate flags
148 * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
149 * function should be called on blocks where the block number is zero.
150 * This is used by ext2fs_expand_dir() to be able to add a new block
151 * to an inode. It can also be used for programs that want to be able
152 * to deal with files that contain "holes".
154 * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
155 * indirect, doubly indirect, etc. blocks should be called after all
156 * of the blocks containined in the indirect blocks are processed.
157 * This is useful if you are going to be deallocating blocks from an
160 #define BLOCK_FLAG_APPEND 1
161 #define BLOCK_FLAG_HOLE 1
162 #define BLOCK_FLAG_DEPTH_TRAVERSE 2
165 * Return flags for the directory iterator functions
167 #define DIRENT_CHANGED 1
168 #define DIRENT_ABORT 2
169 #define DIRENT_ERROR 3
172 * Directory iterator flags
175 #define DIRENT_FLAG_INCLUDE_EMPTY 1
178 * Inode scan definitions
180 typedef struct ext2_struct_inode_scan *ext2_inode_scan;
182 struct ext2_struct_inode_scan {
187 dgrp_t current_group;
188 int inodes_left, blocks_left, groups_left;
189 int inode_buffer_blocks;
195 errcode_t (*done_group)(ext2_filsys fs,
196 ext2_inode_scan scan,
199 void * done_group_data;
204 * ext2fs_check_if_mounted flags
206 #define EXT2_MF_MOUNTED 1
207 #define EXT2_MF_ISROOT 2
208 #define EXT2_MF_READONLY 4
211 * Ext2/linux mode flags. We define them here so that we don't need
212 * to depend on the OS's sys/stat.h, since we may be compiling on a
215 #define LINUX_S_IFMT 00170000
216 #define LINUX_S_IFSOCK 0140000
217 #define LINUX_S_IFLNK 0120000
218 #define LINUX_S_IFREG 0100000
219 #define LINUX_S_IFBLK 0060000
220 #define LINUX_S_IFDIR 0040000
221 #define LINUX_S_IFCHR 0020000
222 #define LINUX_S_IFIFO 0010000
223 #define LINUX_S_ISUID 0004000
224 #define LINUX_S_ISGID 0002000
225 #define LINUX_S_ISVTX 0001000
227 #define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
228 #define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
229 #define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
230 #define LINUX_S_ISCHR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
231 #define LINUX_S_ISBLK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
232 #define LINUX_S_ISFIFO(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
233 #define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
236 * For checking structure magic numbers...
239 #define EXT2_CHECK_MAGIC(struct, code) \
240 if ((struct)->magic != (code)) return (code)
243 * function prototypes
247 extern errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
248 ext2fs_inode_bitmap map, ino_t *ret);
249 extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
250 ext2fs_block_bitmap map, blk_t *ret);
251 extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
252 blk_t finish, int num,
253 ext2fs_block_bitmap map,
257 extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
258 extern void badblocks_list_free(badblocks_list bb);
259 extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
260 extern int badblocks_list_test(badblocks_list bb, blk_t blk);
261 extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
262 badblocks_iterate *ret);
263 extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
264 extern void badblocks_list_iterate_end(badblocks_iterate iter);
267 extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
268 badblocks_list bb_list);
271 extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
272 extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
273 extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
274 extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
275 extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
277 ext2fs_block_bitmap *ret);
278 extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
280 ext2fs_inode_bitmap *ret);
281 extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
282 ino_t end, ino_t *oend);
283 extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
284 blk_t end, blk_t *oend);
285 extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
286 extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
287 extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
288 extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
291 extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
295 int (*func)(ext2_filsys fs,
302 extern errcode_t ext2fs_check_desc(ext2_filsys fs);
305 extern errcode_t ext2fs_close(ext2_filsys fs);
306 extern errcode_t ext2fs_flush(ext2_filsys fs);
309 extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
310 ext2fs_block_bitmap bm2);
311 extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
312 ext2fs_inode_bitmap bm2);
316 extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
318 extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
322 extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir);
325 extern void ext2fs_free(ext2_filsys fs);
326 extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
327 extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
330 extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
334 extern errcode_t ext2fs_initialize(const char *name, int flags,
335 struct ext2_super_block *param,
336 io_manager manager, ext2_filsys *ret_fs);
339 extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
340 ext2_inode_scan *ret_scan);
341 extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
342 extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
343 struct ext2_inode *inode);
344 void ext2fs_set_inode_callback(ext2_inode_scan scan,
345 errcode_t (*done_group)(ext2_filsys fs,
346 ext2_inode_scan scan,
349 void *done_group_data);
350 void ext2fs_set_inode_callback(ext2_inode_scan scan,
351 errcode_t (*done_group)(ext2_filsys fs,
352 ext2_inode_scan scan,
355 void *done_group_data);
356 extern errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
357 struct ext2_inode * inode);
358 extern errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
359 struct ext2_inode * inode);
360 extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
361 extern errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino);
364 extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
367 extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
371 int (*func)(struct ext2_dir_entry *dirent,
377 extern errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
378 int namelen, char *buf, ino_t *inode);
379 extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
380 const char *name, ino_t *inode);
383 extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ino_t dir_ino,
384 ino_t parent_ino, char **block);
387 extern errcode_t ext2fs_mkdir(ext2_filsys fs, ino_t parent, ino_t inum,
391 extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
392 int block_size, io_manager manager,
393 ext2_filsys *ret_fs);
396 extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ino_t dir, ino_t ino,
400 errcode_t ext2fs_link(ext2_filsys fs, ino_t dir, const char *name,
401 ino_t ino, int flags);
402 errcode_t ext2fs_unlink(ext2_filsys fs, ino_t dir, const char *name,
403 ino_t ino, int flags);
406 extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs, badblocks_list *bb_list);
409 extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
410 badblocks_list *bb_list,
411 void (*invalid)(ext2_filsys fs,
415 extern void ext2fs_swap_super(struct ext2_super_block * super);
416 extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
418 /* inline functions */
419 extern void ext2fs_mark_super_dirty(ext2_filsys fs);
420 extern void ext2fs_mark_changed(ext2_filsys fs);
421 extern int ext2fs_test_changed(ext2_filsys fs);
422 extern void ext2fs_mark_valid(ext2_filsys fs);
423 extern void ext2fs_unmark_valid(ext2_filsys fs);
424 extern int ext2fs_test_valid(ext2_filsys fs);
425 extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
426 extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
427 extern int ext2fs_test_ib_dirty(ext2_filsys fs);
428 extern int ext2fs_test_bb_dirty(ext2_filsys fs);
429 extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
430 extern int ext2fs_group_of_ino(ext2_filsys fs, ino_t ino);
433 * The actual inlined functions definitions themselves...
435 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
438 #if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
439 #ifdef INCLUDE_INLINE_FUNCS
440 #define _INLINE_ extern
442 #define _INLINE_ extern __inline__
446 * Mark a filesystem superblock as dirty
448 _INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
450 fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
454 * Mark a filesystem as changed
456 _INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
458 fs->flags |= EXT2_FLAG_CHANGED;
462 * Check to see if a filesystem has changed
464 _INLINE_ int ext2fs_test_changed(ext2_filsys fs)
466 return (fs->flags & EXT2_FLAG_CHANGED);
470 * Mark a filesystem as valid
472 _INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
474 fs->flags |= EXT2_FLAG_VALID;
478 * Mark a filesystem as NOT valid
480 _INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
482 fs->flags &= ~EXT2_FLAG_VALID;
486 * Check to see if a filesystem is valid
488 _INLINE_ int ext2fs_test_valid(ext2_filsys fs)
490 return (fs->flags & EXT2_FLAG_VALID);
494 * Mark the inode bitmap as dirty
496 _INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
498 fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
502 * Mark the block bitmap as dirty
504 _INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
506 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
510 * Check to see if a filesystem's inode bitmap is dirty
512 _INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
514 return (fs->flags & EXT2_FLAG_IB_DIRTY);
518 * Check to see if a filesystem's block bitmap is dirty
520 _INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
522 return (fs->flags & EXT2_FLAG_BB_DIRTY);
526 * Return the group # of a block
528 _INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
530 return (blk - fs->super->s_first_data_block) /
531 fs->super->s_blocks_per_group;
535 * Return the group # of an inode number
537 _INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ino_t ino)
539 return (ino - 1) / fs->super->s_inodes_per_group;