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;
60 * Flags for the ext2_filsys structure
63 #define EXT2_FLAG_RW 0x01
64 #define EXT2_FLAG_CHANGED 0x02
65 #define EXT2_FLAG_DIRTY 0x04
66 #define EXT2_FLAG_VALID 0x08
67 #define EXT2_FLAG_IB_DIRTY 0x10
68 #define EXT2_FLAG_BB_DIRTY 0x20
69 #define EXT2_SWAP_BYTES 0x40
71 struct struct_ext2_filsys {
76 struct ext2_super_block * super;
79 unsigned long group_desc_count;
80 unsigned long desc_blocks;
81 struct ext2_group_desc * group_desc;
82 int inode_blocks_per_group;
83 ext2fs_inode_bitmap inode_map;
84 ext2fs_block_bitmap block_map;
85 errcode_t (*get_blocks)(ext2_filsys fs, ino_t ino, blk_t *blocks);
86 errcode_t (*check_directory)(ext2_filsys fs, ino_t ino);
87 errcode_t (*write_bitmaps)(ext2_filsys fs);
91 * Not used by ext2fs library; reserved for the use of the
92 * calling application.
98 * badblocks list definitions
101 typedef struct struct_badblocks_list *badblocks_list;
103 struct struct_badblocks_list {
112 #define BADBLOCKS_FLAG_DIRTY 1
114 typedef struct struct_badblocks_iterate *badblocks_iterate;
116 struct struct_badblocks_iterate {
123 #include "ext2fs/bitops.h"
126 * Return flags for the block iterator functions
128 #define BLOCK_CHANGED 1
129 #define BLOCK_ABORT 2
130 #define BLOCK_ERROR 4
133 * Block interate flags
135 * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
136 * function should be called on blocks where the block number is zero.
137 * This is used by ext2fs_expand_dir() to be able to add a new block
138 * to an inode. It can also be used for programs that want to be able
139 * to deal with files that contain "holes".
141 * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
142 * indirect, doubly indirect, etc. blocks should be called after all
143 * of the blocks containined in the indirect blocks are processed.
144 * This is useful if you are going to be deallocating blocks from an
147 #define BLOCK_FLAG_APPEND 1
148 #define BLOCK_FLAG_HOLE 1
149 #define BLOCK_FLAG_DEPTH_TRAVERSE 2
152 * Return flags for the directory iterator functions
154 #define DIRENT_CHANGED 1
155 #define DIRENT_ABORT 2
156 #define DIRENT_ERROR 3
159 * Directory iterator flags
162 #define DIRENT_FLAG_INCLUDE_EMPTY 1
165 * Inode scan definitions
167 typedef struct ext2_struct_inode_scan *ext2_inode_scan;
169 struct ext2_struct_inode_scan {
174 dgrp_t current_group;
175 int inodes_left, blocks_left, groups_left;
176 int inode_buffer_blocks;
178 struct ext2_inode * inode_scan_ptr;
179 errcode_t (*done_group)(ext2_filsys fs,
180 ext2_inode_scan scan,
183 void * done_group_data;
188 * ext2fs_check_if_mounted flags
190 #define EXT2_MF_MOUNTED 1
191 #define EXT2_MF_ISROOT 2
192 #define EXT2_MF_READONLY 4
195 * Ext2/linux mode flags. We define them here so that we don't need
196 * to depend on the OS's sys/stat.h, since we may be compiling on a
199 #define LINUX_S_IFMT 00170000
200 #define LINUX_S_IFSOCK 0140000
201 #define LINUX_S_IFLNK 0120000
202 #define LINUX_S_IFREG 0100000
203 #define LINUX_S_IFBLK 0060000
204 #define LINUX_S_IFDIR 0040000
205 #define LINUX_S_IFCHR 0020000
206 #define LINUX_S_IFIFO 0010000
207 #define LINUX_S_ISUID 0004000
208 #define LINUX_S_ISGID 0002000
209 #define LINUX_S_ISVTX 0001000
211 #define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
212 #define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
213 #define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
214 #define LINUX_S_ISCHR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
215 #define LINUX_S_ISBLK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
216 #define LINUX_S_ISFIFO(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
217 #define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
220 * For checking structure magic numbers...
223 #define EXT2_CHECK_MAGIC(struct, code) \
224 if ((struct)->magic != (code)) return (code)
227 * function prototypes
231 extern errcode_t ext2fs_new_inode(ext2_filsys fs, ino_t dir, int mode,
232 ext2fs_inode_bitmap map, ino_t *ret);
233 extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
234 ext2fs_block_bitmap map, blk_t *ret);
235 extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
236 blk_t finish, int num,
237 ext2fs_block_bitmap map,
241 extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
242 extern void badblocks_list_free(badblocks_list bb);
243 extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
244 extern int badblocks_list_test(badblocks_list bb, blk_t blk);
245 extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
246 badblocks_iterate *ret);
247 extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
248 extern void badblocks_list_iterate_end(badblocks_iterate iter);
251 extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
252 badblocks_list bb_list);
255 extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
256 extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
257 extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
258 extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
259 extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
261 ext2fs_block_bitmap *ret);
262 extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
264 ext2fs_inode_bitmap *ret);
265 extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
266 ino_t end, ino_t *oend);
267 extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
268 blk_t end, blk_t *oend);
269 extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
270 extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
271 extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
272 extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
275 extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
279 int (*func)(ext2_filsys fs,
286 extern errcode_t ext2fs_check_desc(ext2_filsys fs);
289 extern errcode_t ext2fs_close(ext2_filsys fs);
290 extern errcode_t ext2fs_flush(ext2_filsys fs);
293 extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
294 ext2fs_block_bitmap bm2);
295 extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
296 ext2fs_inode_bitmap bm2);
300 extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
302 extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
306 extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir);
309 extern void ext2fs_free(ext2_filsys fs);
310 extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
311 extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
314 extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
318 extern errcode_t ext2fs_initialize(const char *name, int flags,
319 struct ext2_super_block *param,
320 io_manager manager, ext2_filsys *ret_fs);
323 extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
324 ext2_inode_scan *ret_scan);
325 extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
326 extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ino_t *ino,
327 struct ext2_inode *inode);
328 void ext2fs_set_inode_callback(ext2_inode_scan scan,
329 errcode_t (*done_group)(ext2_filsys fs,
330 ext2_inode_scan scan,
333 void *done_group_data);
334 void ext2fs_set_inode_callback(ext2_inode_scan scan,
335 errcode_t (*done_group)(ext2_filsys fs,
336 ext2_inode_scan scan,
339 void *done_group_data);
340 extern errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
341 struct ext2_inode * inode);
342 extern errcode_t ext2fs_write_inode(ext2_filsys fs, unsigned long ino,
343 struct ext2_inode * inode);
344 extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
345 extern errcode_t ext2fs_check_directory(ext2_filsys fs, ino_t ino);
348 extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
351 extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
355 int (*func)(struct ext2_dir_entry *dirent,
361 extern errcode_t ext2fs_lookup(ext2_filsys fs, ino_t dir, const char *name,
362 int namelen, char *buf, ino_t *inode);
363 extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
364 const char *name, ino_t *inode);
367 extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ino_t dir_ino,
368 ino_t parent_ino, char **block);
371 extern errcode_t ext2fs_mkdir(ext2_filsys fs, ino_t parent, ino_t inum,
375 extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
376 int block_size, io_manager manager,
377 ext2_filsys *ret_fs);
380 extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ino_t dir, ino_t ino,
384 errcode_t ext2fs_link(ext2_filsys fs, ino_t dir, const char *name,
385 ino_t ino, int flags);
386 errcode_t ext2fs_unlink(ext2_filsys fs, ino_t dir, const char *name,
387 ino_t ino, int flags);
390 extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs, badblocks_list *bb_list);
393 extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
394 badblocks_list *bb_list,
395 void (*invalid)(ext2_filsys fs,
399 extern void ext2fs_swap_super(struct ext2_super_block * super);
400 extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
402 /* inline functions */
403 extern void ext2fs_mark_super_dirty(ext2_filsys fs);
404 extern void ext2fs_mark_changed(ext2_filsys fs);
405 extern int ext2fs_test_changed(ext2_filsys fs);
406 extern void ext2fs_mark_valid(ext2_filsys fs);
407 extern void ext2fs_unmark_valid(ext2_filsys fs);
408 extern int ext2fs_test_valid(ext2_filsys fs);
409 extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
410 extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
411 extern int ext2fs_test_ib_dirty(ext2_filsys fs);
412 extern int ext2fs_test_bb_dirty(ext2_filsys fs);
413 extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
414 extern int ext2fs_group_of_ino(ext2_filsys fs, ino_t ino);
417 * The actual inlined functions definitions themselves...
419 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
422 #if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
423 #ifdef INCLUDE_INLINE_FUNCS
424 #define _INLINE_ extern
426 #define _INLINE_ extern __inline__
430 * Mark a filesystem superblock as dirty
432 _INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
434 fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
438 * Mark a filesystem as changed
440 _INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
442 fs->flags |= EXT2_FLAG_CHANGED;
446 * Check to see if a filesystem has changed
448 _INLINE_ int ext2fs_test_changed(ext2_filsys fs)
450 return (fs->flags & EXT2_FLAG_CHANGED);
454 * Mark a filesystem as valid
456 _INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
458 fs->flags |= EXT2_FLAG_VALID;
462 * Mark a filesystem as NOT valid
464 _INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
466 fs->flags &= ~EXT2_FLAG_VALID;
470 * Check to see if a filesystem is valid
472 _INLINE_ int ext2fs_test_valid(ext2_filsys fs)
474 return (fs->flags & EXT2_FLAG_VALID);
478 * Mark the inode bitmap as dirty
480 _INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
482 fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
486 * Mark the block bitmap as dirty
488 _INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
490 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
494 * Check to see if a filesystem's inode bitmap is dirty
496 _INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
498 return (fs->flags & EXT2_FLAG_IB_DIRTY);
502 * Check to see if a filesystem's block bitmap is dirty
504 _INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
506 return (fs->flags & EXT2_FLAG_BB_DIRTY);
510 * Return the group # of a block
512 _INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
514 return (blk - fs->super->s_first_data_block) /
515 fs->super->s_blocks_per_group;
519 * Return the group # of an inode number
521 _INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ino_t ino)
523 return (ino - 1) / fs->super->s_inodes_per_group;