ext2fs.h revision a7a63675af85b4b636e9df4961ca44ea03bf160b
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 Library
8 * General Public License, version 2.
9 * %End-Header%
10 */
11
12#ifndef _EXT2FS_EXT2FS_H
13#define _EXT2FS_EXT2FS_H
14
15#ifdef __GNUC__
16#define EXT2FS_ATTR(x) __attribute__(x)
17#else
18#define EXT2FS_ATTR(x)
19#endif
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25/*
26 * Non-GNU C compilers won't necessarily understand inline
27 */
28#if (!defined(__GNUC__) && !defined(__WATCOMC__))
29#define NO_INLINE_FUNCS
30#endif
31
32#ifndef _XOPEN_SOURCE
33#define _XOPEN_SOURCE 600	/* for posix_memalign() */
34#endif
35
36/*
37 * Where the master copy of the superblock is located, and how big
38 * superblocks are supposed to be.  We define SUPERBLOCK_SIZE because
39 * the size of the superblock structure is not necessarily trustworthy
40 * (some versions have the padding set up so that the superblock is
41 * 1032 bytes long).
42 */
43#define SUPERBLOCK_OFFSET	1024
44#define SUPERBLOCK_SIZE		1024
45
46/*
47 * The last ext2fs revision level that this version of the library is
48 * able to support.
49 */
50#define EXT2_LIB_CURRENT_REV	EXT2_DYNAMIC_REV
51
52#ifdef HAVE_SYS_TYPES_H
53#include <sys/types.h>
54#endif
55
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59#include <errno.h>
60
61#ifndef __USE_XOPEN2K
62/* If the "#define _XOPEN_SOURCE 600" didn't succeed in declaring
63 * posix_memalign(), maybe due to <features.h> or <stdlib.h> included beforej
64 * _XOPEN_SOURCE, declare it here to avoid compiler warnings. */
65extern int posix_memalign(void **__memptr, size_t __alignment, size_t __size);
66#endif
67
68#if EXT2_FLAT_INCLUDES
69#include "e2_types.h"
70#include "ext2_fs.h"
71#include "ext3_extents.h"
72#else
73#include <ext2fs/ext2_types.h>
74#include <ext2fs/ext2_fs.h>
75#include <ext2fs/ext3_extents.h>
76#endif /* EXT2_FLAT_INCLUDES */
77
78typedef __u32		ext2_ino_t;
79typedef __u32		blk_t;
80typedef __u64		blk64_t;
81typedef __u32		dgrp_t;
82typedef __u32		ext2_off_t;
83typedef __u64		ext2_off64_t;
84typedef __s64		e2_blkcnt_t;
85typedef __u32		ext2_dirhash_t;
86
87#if EXT2_FLAT_INCLUDES
88#include "com_err.h"
89#include "ext2_io.h"
90#include "ext2_err.h"
91#include "ext2_ext_attr.h"
92#else
93#include <et/com_err.h>
94#include <ext2fs/ext2_io.h>
95#include <ext2fs/ext2_err.h>
96#include <ext2fs/ext2_ext_attr.h>
97#endif
98
99/*
100 * Portability help for Microsoft Visual C++
101 */
102#ifdef _MSC_VER
103#define EXT2_QSORT_TYPE int __cdecl
104#else
105#define EXT2_QSORT_TYPE int
106#endif
107
108typedef struct struct_ext2_filsys *ext2_filsys;
109
110#define EXT2FS_MARK_ERROR 	0
111#define EXT2FS_UNMARK_ERROR 	1
112#define EXT2FS_TEST_ERROR	2
113
114typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
115typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
116typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
117
118#define EXT2_FIRST_INODE(s)	EXT2_FIRST_INO(s)
119
120
121/*
122 * Badblocks list definitions
123 */
124
125typedef struct ext2_struct_u32_list *ext2_badblocks_list;
126typedef struct ext2_struct_u32_iterate *ext2_badblocks_iterate;
127
128typedef struct ext2_struct_u32_list *ext2_u32_list;
129typedef struct ext2_struct_u32_iterate *ext2_u32_iterate;
130
131/* old */
132typedef struct ext2_struct_u32_list *badblocks_list;
133typedef struct ext2_struct_u32_iterate *badblocks_iterate;
134
135#define BADBLOCKS_FLAG_DIRTY	1
136
137/*
138 * ext2_dblist structure and abstractions (see dblist.c)
139 */
140struct ext2_db_entry2 {
141	ext2_ino_t	ino;
142	blk64_t	blk;
143	e2_blkcnt_t	blockcnt;
144};
145
146/* Ye Olde 32-bit version */
147struct ext2_db_entry {
148	ext2_ino_t	ino;
149	blk_t	blk;
150	int	blockcnt;
151};
152
153typedef struct ext2_struct_dblist *ext2_dblist;
154
155#define DBLIST_ABORT	1
156
157/*
158 * ext2_fileio definitions
159 */
160
161#define EXT2_FILE_WRITE		0x0001
162#define EXT2_FILE_CREATE	0x0002
163
164#define EXT2_FILE_MASK		0x00FF
165
166#define EXT2_FILE_BUF_DIRTY	0x4000
167#define EXT2_FILE_BUF_VALID	0x2000
168
169typedef struct ext2_file *ext2_file_t;
170
171#define EXT2_SEEK_SET	0
172#define EXT2_SEEK_CUR	1
173#define EXT2_SEEK_END	2
174
175/*
176 * Flags for the ext2_filsys structure and for ext2fs_open()
177 */
178#define EXT2_FLAG_RW			0x01
179#define EXT2_FLAG_CHANGED		0x02
180#define EXT2_FLAG_DIRTY			0x04
181#define EXT2_FLAG_VALID			0x08
182#define EXT2_FLAG_IB_DIRTY		0x10
183#define EXT2_FLAG_BB_DIRTY		0x20
184#define EXT2_FLAG_SWAP_BYTES		0x40
185#define EXT2_FLAG_SWAP_BYTES_READ	0x80
186#define EXT2_FLAG_SWAP_BYTES_WRITE	0x100
187#define EXT2_FLAG_MASTER_SB_ONLY	0x200
188#define EXT2_FLAG_FORCE			0x400
189#define EXT2_FLAG_SUPER_ONLY		0x800
190#define EXT2_FLAG_JOURNAL_DEV_OK	0x1000
191#define EXT2_FLAG_IMAGE_FILE		0x2000
192#define EXT2_FLAG_EXCLUSIVE		0x4000
193#define EXT2_FLAG_SOFTSUPP_FEATURES	0x8000
194#define EXT2_FLAG_NOFREE_ON_ERROR	0x10000
195#define EXT2_FLAG_64BITS		0x20000
196#define EXT2_FLAG_PRINT_PROGRESS	0x40000
197#define EXT2_FLAG_DIRECT_IO		0x80000
198#define EXT2_FLAG_SKIP_MMP		0x100000
199
200/*
201 * Special flag in the ext2 inode i_flag field that means that this is
202 * a new inode.  (So that ext2_write_inode() can clear extra fields.)
203 */
204#define EXT2_NEW_INODE_FL	0x80000000
205
206/*
207 * Flags for mkjournal
208 */
209#define EXT2_MKJOURNAL_V1_SUPER	0x0000001 /* create V1 superblock (deprecated) */
210#define EXT2_MKJOURNAL_LAZYINIT	0x0000002 /* don't zero journal inode before use*/
211
212struct opaque_ext2_group_desc;
213
214struct struct_ext2_filsys {
215	errcode_t			magic;
216	io_channel			io;
217	int				flags;
218	char *				device_name;
219	struct ext2_super_block	* 	super;
220	unsigned int			blocksize;
221	int				fragsize;
222	dgrp_t				group_desc_count;
223	unsigned long			desc_blocks;
224	struct opaque_ext2_group_desc *	group_desc;
225	unsigned int			inode_blocks_per_group;
226	ext2fs_inode_bitmap		inode_map;
227	ext2fs_block_bitmap		block_map;
228	/* XXX FIXME-64: not 64-bit safe, but not used? */
229	errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
230	errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
231	errcode_t (*write_bitmaps)(ext2_filsys fs);
232	errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
233				struct ext2_inode *inode);
234	errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
235				struct ext2_inode *inode);
236	ext2_badblocks_list		badblocks;
237	ext2_dblist			dblist;
238	__u32				stride;	/* for mke2fs */
239	struct ext2_super_block *	orig_super;
240	struct ext2_image_hdr *		image_header;
241	__u32				umask;
242	time_t				now;
243	int				cluster_ratio_bits;
244	/*
245	 * Reserved for future expansion
246	 */
247	__u32				reserved[6];
248
249	/*
250	 * Reserved for the use of the calling application.
251	 */
252	void *				priv_data;
253
254	/*
255	 * Inode cache
256	 */
257	struct ext2_inode_cache		*icache;
258	io_channel			image_io;
259
260	/*
261	 * Buffers for Multiple mount protection(MMP) block.
262	 */
263	void *mmp_buf;
264	void *mmp_cmp;
265	int mmp_fd;
266
267	/*
268	 * Time at which e2fsck last updated the MMP block.
269	 */
270	long mmp_last_written;
271
272	/*
273	 * More callback functions
274	 */
275	errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal,
276				     blk64_t *ret);
277	void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse);
278};
279
280#if EXT2_FLAT_INCLUDES
281#include "e2_bitops.h"
282#else
283#include <ext2fs/bitops.h>
284#endif
285
286/*
287 * Return flags for the block iterator functions
288 */
289#define BLOCK_CHANGED	1
290#define BLOCK_ABORT	2
291#define BLOCK_ERROR	4
292
293/*
294 * Block interate flags
295 *
296 * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
297 * function should be called on blocks where the block number is zero.
298 * This is used by ext2fs_expand_dir() to be able to add a new block
299 * to an inode.  It can also be used for programs that want to be able
300 * to deal with files that contain "holes".
301 *
302 * BLOCK_FLAG_DEPTH_TRAVERSE indicates that the iterator function for
303 * the indirect, doubly indirect, etc. blocks should be called after
304 * all of the blocks containined in the indirect blocks are processed.
305 * This is useful if you are going to be deallocating blocks from an
306 * inode.
307 *
308 * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
309 * called for data blocks only.
310 *
311 * BLOCK_FLAG_READ_ONLY is a promise by the caller that it will not
312 * modify returned block number.
313 *
314 * BLOCK_FLAG_NO_LARGE is for internal use only.  It informs
315 * ext2fs_block_iterate2 that large files won't be accepted.
316 */
317#define BLOCK_FLAG_APPEND	1
318#define BLOCK_FLAG_HOLE		1
319#define BLOCK_FLAG_DEPTH_TRAVERSE	2
320#define BLOCK_FLAG_DATA_ONLY	4
321#define BLOCK_FLAG_READ_ONLY	8
322
323#define BLOCK_FLAG_NO_LARGE	0x1000
324
325/*
326 * Magic "block count" return values for the block iterator function.
327 */
328#define BLOCK_COUNT_IND		(-1)
329#define BLOCK_COUNT_DIND	(-2)
330#define BLOCK_COUNT_TIND	(-3)
331#define BLOCK_COUNT_TRANSLATOR	(-4)
332
333#if 0
334/*
335 * Flags for ext2fs_move_blocks
336 */
337#define EXT2_BMOVE_GET_DBLIST	0x0001
338#define EXT2_BMOVE_DEBUG	0x0002
339#endif
340
341/*
342 * Generic (non-filesystem layout specific) extents structure
343 */
344
345#define EXT2_EXTENT_FLAGS_LEAF		0x0001
346#define EXT2_EXTENT_FLAGS_UNINIT	0x0002
347#define EXT2_EXTENT_FLAGS_SECOND_VISIT	0x0004
348
349struct ext2fs_extent {
350	blk64_t	e_pblk;		/* first physical block */
351	blk64_t	e_lblk;		/* first logical block extent covers */
352	__u32	e_len;		/* number of blocks covered by extent */
353	__u32	e_flags;	/* extent flags */
354};
355
356typedef struct ext2_extent_handle *ext2_extent_handle_t;
357typedef struct ext2_extent_path *ext2_extent_path_t;
358
359/*
360 * Flags used by ext2fs_extent_get()
361 */
362#define EXT2_EXTENT_CURRENT	0x0000
363#define EXT2_EXTENT_MOVE_MASK	0x000F
364#define EXT2_EXTENT_ROOT	0x0001
365#define EXT2_EXTENT_LAST_LEAF	0x0002
366#define EXT2_EXTENT_FIRST_SIB	0x0003
367#define EXT2_EXTENT_LAST_SIB	0x0004
368#define EXT2_EXTENT_NEXT_SIB	0x0005
369#define EXT2_EXTENT_PREV_SIB	0x0006
370#define EXT2_EXTENT_NEXT_LEAF	0x0007
371#define EXT2_EXTENT_PREV_LEAF	0x0008
372#define EXT2_EXTENT_NEXT	0x0009
373#define EXT2_EXTENT_PREV	0x000A
374#define EXT2_EXTENT_UP		0x000B
375#define EXT2_EXTENT_DOWN	0x000C
376#define EXT2_EXTENT_DOWN_AND_LAST 0x000D
377
378/*
379 * Flags used by ext2fs_extent_insert()
380 */
381#define EXT2_EXTENT_INSERT_AFTER	0x0001 /* insert after handle loc'n */
382#define EXT2_EXTENT_INSERT_NOSPLIT	0x0002 /* insert may not cause split */
383
384/*
385 * Flags used by ext2fs_extent_delete()
386 */
387#define EXT2_EXTENT_DELETE_KEEP_EMPTY	0x001 /* keep node if last extnt gone */
388
389/*
390 * Flags used by ext2fs_extent_set_bmap()
391 */
392#define EXT2_EXTENT_SET_BMAP_UNINIT	0x0001
393
394/*
395 * Data structure returned by ext2fs_extent_get_info()
396 */
397struct ext2_extent_info {
398	int		curr_entry;
399	int		curr_level;
400	int		num_entries;
401	int		max_entries;
402	int		max_depth;
403	int		bytes_avail;
404	blk64_t		max_lblk;
405	blk64_t		max_pblk;
406	__u32		max_len;
407	__u32		max_uninit_len;
408};
409
410/*
411 * Flags for directory block reading and writing functions
412 */
413#define EXT2_DIRBLOCK_V2_STRUCT	0x0001
414
415/*
416 * Return flags for the directory iterator functions
417 */
418#define DIRENT_CHANGED	1
419#define DIRENT_ABORT	2
420#define DIRENT_ERROR	3
421
422/*
423 * Directory iterator flags
424 */
425
426#define DIRENT_FLAG_INCLUDE_EMPTY	1
427#define DIRENT_FLAG_INCLUDE_REMOVED	2
428
429#define DIRENT_DOT_FILE		1
430#define DIRENT_DOT_DOT_FILE	2
431#define DIRENT_OTHER_FILE	3
432#define DIRENT_DELETED_FILE	4
433
434/*
435 * Inode scan definitions
436 */
437typedef struct ext2_struct_inode_scan *ext2_inode_scan;
438
439/*
440 * ext2fs_scan flags
441 */
442#define EXT2_SF_CHK_BADBLOCKS	0x0001
443#define EXT2_SF_BAD_INODE_BLK	0x0002
444#define EXT2_SF_BAD_EXTRA_BYTES	0x0004
445#define EXT2_SF_SKIP_MISSING_ITABLE	0x0008
446#define EXT2_SF_DO_LAZY		0x0010
447
448/*
449 * ext2fs_check_if_mounted flags
450 */
451#define EXT2_MF_MOUNTED		1
452#define EXT2_MF_ISROOT		2
453#define EXT2_MF_READONLY	4
454#define EXT2_MF_SWAP		8
455#define EXT2_MF_BUSY		16
456
457/*
458 * Ext2/linux mode flags.  We define them here so that we don't need
459 * to depend on the OS's sys/stat.h, since we may be compiling on a
460 * non-Linux system.
461 */
462#define LINUX_S_IFMT  00170000
463#define LINUX_S_IFSOCK 0140000
464#define LINUX_S_IFLNK	 0120000
465#define LINUX_S_IFREG  0100000
466#define LINUX_S_IFBLK  0060000
467#define LINUX_S_IFDIR  0040000
468#define LINUX_S_IFCHR  0020000
469#define LINUX_S_IFIFO  0010000
470#define LINUX_S_ISUID  0004000
471#define LINUX_S_ISGID  0002000
472#define LINUX_S_ISVTX  0001000
473
474#define LINUX_S_IRWXU 00700
475#define LINUX_S_IRUSR 00400
476#define LINUX_S_IWUSR 00200
477#define LINUX_S_IXUSR 00100
478
479#define LINUX_S_IRWXG 00070
480#define LINUX_S_IRGRP 00040
481#define LINUX_S_IWGRP 00020
482#define LINUX_S_IXGRP 00010
483
484#define LINUX_S_IRWXO 00007
485#define LINUX_S_IROTH 00004
486#define LINUX_S_IWOTH 00002
487#define LINUX_S_IXOTH 00001
488
489#define LINUX_S_ISLNK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
490#define LINUX_S_ISREG(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
491#define LINUX_S_ISDIR(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
492#define LINUX_S_ISCHR(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
493#define LINUX_S_ISBLK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
494#define LINUX_S_ISFIFO(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
495#define LINUX_S_ISSOCK(m)	(((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
496
497/*
498 * ext2 size of an inode
499 */
500#define EXT2_I_SIZE(i)	((i)->i_size | ((__u64) (i)->i_size_high << 32))
501
502/*
503 * ext2_icount_t abstraction
504 */
505#define EXT2_ICOUNT_OPT_INCREMENT	0x01
506
507typedef struct ext2_icount *ext2_icount_t;
508
509/*
510 * Flags for ext2fs_bmap
511 */
512#define BMAP_ALLOC	0x0001
513#define BMAP_SET	0x0002
514
515/*
516 * Returned flags from ext2fs_bmap
517 */
518#define BMAP_RET_UNINIT	0x0001
519
520/*
521 * Flags for imager.c functions
522 */
523#define IMAGER_FLAG_INODEMAP	1
524#define IMAGER_FLAG_SPARSEWRITE	2
525
526/*
527 * For checking structure magic numbers...
528 */
529
530#define EXT2_CHECK_MAGIC(struct, code) \
531	  if ((struct)->magic != (code)) return (code)
532
533
534/*
535 * For ext2 compression support
536 */
537#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) -1)
538#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
539
540/*
541 * Features supported by this version of the library
542 */
543#define EXT2_LIB_FEATURE_COMPAT_SUPP	(EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
544					 EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
545					 EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
546					 EXT2_FEATURE_COMPAT_RESIZE_INODE|\
547					 EXT2_FEATURE_COMPAT_DIR_INDEX|\
548					 EXT2_FEATURE_COMPAT_EXT_ATTR)
549
550/* This #ifdef is temporary until compression is fully supported */
551#ifdef ENABLE_COMPRESSION
552#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
553/* If the below warning bugs you, then have
554   `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
555   environment at configure time. */
556 #warning "Compression support is experimental"
557#endif
558#define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
559					 EXT2_FEATURE_INCOMPAT_COMPRESSION|\
560					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
561					 EXT2_FEATURE_INCOMPAT_META_BG|\
562					 EXT3_FEATURE_INCOMPAT_RECOVER|\
563					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
564					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
565					 EXT4_FEATURE_INCOMPAT_MMP|\
566					 EXT4_FEATURE_INCOMPAT_64BIT)
567#else
568#define EXT2_LIB_FEATURE_INCOMPAT_SUPP	(EXT2_FEATURE_INCOMPAT_FILETYPE|\
569					 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
570					 EXT2_FEATURE_INCOMPAT_META_BG|\
571					 EXT3_FEATURE_INCOMPAT_RECOVER|\
572					 EXT3_FEATURE_INCOMPAT_EXTENTS|\
573					 EXT4_FEATURE_INCOMPAT_FLEX_BG|\
574					 EXT4_FEATURE_INCOMPAT_MMP|\
575					 EXT4_FEATURE_INCOMPAT_64BIT)
576#endif
577#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP	(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
578					 EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
579					 EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
580					 EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
581					 EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
582					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM|\
583					 EXT4_FEATURE_RO_COMPAT_BIGALLOC|\
584					 EXT4_FEATURE_RO_COMPAT_QUOTA)
585
586/*
587 * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
588 * to ext2fs_openfs()
589 */
590#define EXT2_LIB_SOFTSUPP_INCOMPAT	(0)
591#define EXT2_LIB_SOFTSUPP_RO_COMPAT	(EXT4_FEATURE_RO_COMPAT_BIGALLOC)
592
593
594/* Translate a block number to a cluster number */
595#define EXT2FS_CLUSTER_RATIO(fs)	(1 << (fs)->cluster_ratio_bits)
596#define EXT2FS_CLUSTER_MASK(fs)		(EXT2FS_CLUSTER_RATIO(fs) - 1)
597#define EXT2FS_B2C(fs, blk)		((blk) >> (fs)->cluster_ratio_bits)
598/* Translate a cluster number to a block number */
599#define EXT2FS_C2B(fs, cluster)		((cluster) << (fs)->cluster_ratio_bits)
600/* Translate # of blks to # of clusters */
601#define EXT2FS_NUM_B2C(fs, blks)	(((blks) + EXT2FS_CLUSTER_MASK(fs)) >> \
602					 (fs)->cluster_ratio_bits)
603
604#if defined(HAVE_STAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
605typedef struct stat64 ext2fs_struct_stat;
606#else
607typedef struct stat ext2fs_struct_stat;
608#endif
609
610/*
611 * For ext2fs_close2() and ext2fs_flush2(), this flag allows you to
612 * avoid the fsync call.
613 */
614#define EXT2_FLAG_FLUSH_NO_SYNC          1
615
616/*
617 * function prototypes
618 */
619
620/* alloc.c */
621extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
622				  ext2fs_inode_bitmap map, ext2_ino_t *ret);
623extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
624				  ext2fs_block_bitmap map, blk_t *ret);
625extern errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
626				   ext2fs_block_bitmap map, blk64_t *ret);
627extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
628					blk_t finish, int num,
629					ext2fs_block_bitmap map,
630					blk_t *ret);
631extern errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start,
632					 blk64_t finish, int num,
633					 ext2fs_block_bitmap map,
634					 blk64_t *ret);
635extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
636				    char *block_buf, blk_t *ret);
637extern errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
638				     char *block_buf, blk64_t *ret);
639extern void ext2fs_set_alloc_block_callback(ext2_filsys fs,
640					    errcode_t (*func)(ext2_filsys fs,
641							      blk64_t goal,
642							      blk64_t *ret),
643					    errcode_t (**old)(ext2_filsys fs,
644							      blk64_t goal,
645							      blk64_t *ret));
646
647/* alloc_sb.c */
648extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
649					dgrp_t group,
650					ext2fs_block_bitmap bmap);
651extern void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
652						  void (*func)(ext2_filsys fs,
653							       blk64_t blk,
654							       int inuse),
655						  void (**old)(ext2_filsys fs,
656							       blk64_t blk,
657							       int inuse));
658
659/* alloc_stats.c */
660void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse);
661void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
662			       int inuse, int isdir);
663void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
664void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse);
665
666/* alloc_tables.c */
667extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
668extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
669					     ext2fs_block_bitmap bmap);
670
671/* badblocks.c */
672extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
673extern errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk);
674extern int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk);
675extern int ext2fs_u32_list_test(ext2_u32_list bb, blk_t blk);
676extern errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
677					       ext2_u32_iterate *ret);
678extern int ext2fs_u32_list_iterate(ext2_u32_iterate iter, blk_t *blk);
679extern void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter);
680extern errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest);
681extern int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2);
682
683extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
684					    int size);
685extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
686					   blk_t blk);
687extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
688				    blk_t blk);
689extern int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk);
690extern void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk);
691extern errcode_t
692	ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
693					    ext2_badblocks_iterate *ret);
694extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
695					 blk_t *blk);
696extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
697extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
698				       ext2_badblocks_list *dest);
699extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
700				  ext2_badblocks_list bb2);
701extern int ext2fs_u32_list_count(ext2_u32_list bb);
702
703/* bb_compat */
704extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
705extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
706extern int badblocks_list_test(badblocks_list bb, blk_t blk);
707extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
708					      badblocks_iterate *ret);
709extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
710extern void badblocks_list_iterate_end(badblocks_iterate iter);
711extern void badblocks_list_free(badblocks_list bb);
712
713/* bb_inode.c */
714extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
715					ext2_badblocks_list bb_list);
716
717/* bitmaps.c */
718extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
719extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
720extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
721				    ext2fs_generic_bitmap *dest);
722extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
723extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
724extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
725extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
726extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
727					      const char *descr,
728					      ext2fs_block_bitmap *ret);
729extern errcode_t ext2fs_allocate_subcluster_bitmap(ext2_filsys fs,
730						   const char *descr,
731						   ext2fs_block_bitmap *ret);
732extern int ext2fs_get_bitmap_granularity(ext2fs_block_bitmap bitmap);
733extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
734					      const char *descr,
735					      ext2fs_inode_bitmap *ret);
736extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
737					       ext2_ino_t end, ext2_ino_t *oend);
738extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
739					       blk_t end, blk_t *oend);
740extern errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap,
741					 blk64_t end, blk64_t *oend);
742extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
743extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
744extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
745extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
746extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
747					    ext2fs_inode_bitmap bmap);
748extern errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end,
749					     __u64 new_real_end,
750					     ext2fs_inode_bitmap bmap);
751extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
752					    ext2fs_block_bitmap bmap);
753extern errcode_t ext2fs_resize_block_bitmap2(__u64 new_end,
754					     __u64 new_real_end,
755					     ext2fs_block_bitmap bmap);
756extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
757					     ext2fs_block_bitmap bm2);
758extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
759					     ext2fs_inode_bitmap bm2);
760extern errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap,
761					ext2_ino_t start, unsigned int num,
762					void *in);
763extern errcode_t ext2fs_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
764					 __u64 start, size_t num,
765					 void *in);
766extern errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap,
767					ext2_ino_t start, unsigned int num,
768					void *out);
769extern errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
770					 __u64 start, size_t num,
771					 void *out);
772extern errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap,
773					blk_t start, unsigned int num,
774					void *in);
775extern errcode_t ext2fs_set_block_bitmap_range2(ext2fs_block_bitmap bmap,
776					 blk64_t start, size_t num,
777					 void *in);
778extern errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap,
779					blk_t start, unsigned int num,
780					void *out);
781extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap,
782					 blk64_t start, size_t num,
783					 void *out);
784
785/* blknum.c */
786extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t);
787extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group);
788extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group);
789extern int ext2fs_group_blocks_count(ext2_filsys fs, dgrp_t group);
790extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
791					 struct ext2_inode *inode);
792extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
793					 struct ext2_inode *inode);
794extern blk64_t ext2fs_blocks_count(struct ext2_super_block *super);
795extern void ext2fs_blocks_count_set(struct ext2_super_block *super,
796				    blk64_t blk);
797extern void ext2fs_blocks_count_add(struct ext2_super_block *super,
798				    blk64_t blk);
799extern blk64_t ext2fs_r_blocks_count(struct ext2_super_block *super);
800extern void ext2fs_r_blocks_count_set(struct ext2_super_block *super,
801				      blk64_t blk);
802extern void ext2fs_r_blocks_count_add(struct ext2_super_block *super,
803				      blk64_t blk);
804extern blk64_t ext2fs_free_blocks_count(struct ext2_super_block *super);
805extern void ext2fs_free_blocks_count_set(struct ext2_super_block *super,
806					 blk64_t blk);
807extern void ext2fs_free_blocks_count_add(struct ext2_super_block *super,
808					 blk64_t blk);
809/* Block group descriptor accessor functions */
810extern struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
811					  struct opaque_ext2_group_desc *gdp,
812					  dgrp_t group);
813extern blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group);
814extern void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
815					blk64_t blk);
816extern blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group);
817extern void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
818					blk64_t blk);
819extern blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group);
820extern void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group,
821				       blk64_t blk);
822extern __u32 ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group);
823extern void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group,
824					 __u32 n);
825extern __u32 ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group);
826extern void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group,
827					 __u32 n);
828extern __u32 ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group);
829extern void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group,
830				       __u32 n);
831extern __u32 ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group);
832extern void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group,
833				     __u32 n);
834extern __u16 ext2fs_bg_flags(ext2_filsys fs, dgrp_t group);
835extern void ext2fs_bg_flags_zap(ext2_filsys fs, dgrp_t group);
836extern int ext2fs_bg_flags_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag);
837extern void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
838extern void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
839extern __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group);
840extern void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum);
841extern blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode);
842extern void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk);
843
844/* block.c */
845extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
846				      ext2_ino_t	ino,
847				      int	flags,
848				      char *block_buf,
849				      int (*func)(ext2_filsys fs,
850						  blk_t	*blocknr,
851						  int	blockcnt,
852						  void	*priv_data),
853				      void *priv_data);
854errcode_t ext2fs_block_iterate2(ext2_filsys fs,
855				ext2_ino_t	ino,
856				int	flags,
857				char *block_buf,
858				int (*func)(ext2_filsys fs,
859					    blk_t	*blocknr,
860					    e2_blkcnt_t	blockcnt,
861					    blk_t	ref_blk,
862					    int		ref_offset,
863					    void	*priv_data),
864				void *priv_data);
865errcode_t ext2fs_block_iterate3(ext2_filsys fs,
866				ext2_ino_t ino,
867				int	flags,
868				char *block_buf,
869				int (*func)(ext2_filsys fs,
870					    blk64_t	*blocknr,
871					    e2_blkcnt_t	blockcnt,
872					    blk64_t	ref_blk,
873					    int		ref_offset,
874					    void	*priv_data),
875				void *priv_data);
876
877/* bmap.c */
878extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
879			     struct ext2_inode *inode,
880			     char *block_buf, int bmap_flags,
881			     blk_t block, blk_t *phys_blk);
882extern errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino,
883			      struct ext2_inode *inode,
884			      char *block_buf, int bmap_flags, blk64_t block,
885			      int *ret_flags, blk64_t *phys_blk);
886
887#if 0
888/* bmove.c */
889extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
890				    ext2fs_block_bitmap reserve,
891				    ext2fs_block_bitmap alloc_map,
892				    int flags);
893#endif
894
895/* check_desc.c */
896extern errcode_t ext2fs_check_desc(ext2_filsys fs);
897
898/* closefs.c */
899extern errcode_t ext2fs_close(ext2_filsys fs);
900extern errcode_t ext2fs_close2(ext2_filsys fs, int flags);
901extern errcode_t ext2fs_flush(ext2_filsys fs);
902extern errcode_t ext2fs_flush2(ext2_filsys fs, int flags);
903extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
904extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
905				    dgrp_t group,
906				    blk64_t *ret_super_blk,
907				    blk64_t *ret_old_desc_blk,
908				    blk64_t *ret_new_desc_blk,
909				    blk_t *ret_used_blks);
910extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
911				    dgrp_t group,
912				    blk_t *ret_super_blk,
913				    blk_t *ret_old_desc_blk,
914				    blk_t *ret_new_desc_blk,
915				    int *ret_meta_bg);
916extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
917
918/* crc32c.c */
919extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len);
920extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len);
921
922/* csum.c */
923extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
924extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
925extern errcode_t ext2fs_set_gdt_csum(ext2_filsys fs);
926
927/* dblist.c */
928
929extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
930extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
931extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
932				      blk_t blk, int blockcnt);
933extern errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
934				       blk64_t blk, e2_blkcnt_t blockcnt);
935extern void ext2fs_dblist_sort(ext2_dblist dblist,
936			       EXT2_QSORT_TYPE (*sortfunc)(const void *,
937							   const void *));
938extern void ext2fs_dblist_sort2(ext2_dblist dblist,
939				EXT2_QSORT_TYPE (*sortfunc)(const void *,
940							    const void *));
941extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
942	int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
943		    void	*priv_data),
944       void *priv_data);
945extern errcode_t ext2fs_dblist_iterate2(ext2_dblist dblist,
946	int (*func)(ext2_filsys fs, struct ext2_db_entry2 *db_info,
947		    void	*priv_data),
948       void *priv_data);
949extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
950				      blk_t blk, int blockcnt);
951extern errcode_t ext2fs_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
952				       blk64_t blk, e2_blkcnt_t blockcnt);
953extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
954				    ext2_dblist *dest);
955extern int ext2fs_dblist_count(ext2_dblist dblist);
956extern blk64_t ext2fs_dblist_count2(ext2_dblist dblist);
957extern errcode_t ext2fs_dblist_get_last(ext2_dblist dblist,
958					struct ext2_db_entry **entry);
959extern errcode_t ext2fs_dblist_get_last2(ext2_dblist dblist,
960					struct ext2_db_entry2 **entry);
961extern errcode_t ext2fs_dblist_drop_last(ext2_dblist dblist);
962
963/* dblist_dir.c */
964extern errcode_t
965	ext2fs_dblist_dir_iterate(ext2_dblist dblist,
966				  int	flags,
967				  char	*block_buf,
968				  int (*func)(ext2_ino_t	dir,
969					      int		entry,
970					      struct ext2_dir_entry *dirent,
971					      int	offset,
972					      int	blocksize,
973					      char	*buf,
974					      void	*priv_data),
975				  void *priv_data);
976
977/* dirblock.c */
978extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
979				       void *buf);
980extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
981					void *buf, int flags);
982extern errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
983					void *buf, int flags);
984extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
985					void *buf);
986extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
987					 void *buf, int flags);
988extern errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
989					 void *buf, int flags);
990
991/* dirhash.c */
992extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
993				const __u32 *seed,
994				ext2_dirhash_t *ret_hash,
995				ext2_dirhash_t *ret_minor_hash);
996
997
998/* dir_iterate.c */
999extern errcode_t ext2fs_get_rec_len(ext2_filsys fs,
1000				    struct ext2_dir_entry *dirent,
1001				    unsigned int *rec_len);
1002extern errcode_t ext2fs_set_rec_len(ext2_filsys fs,
1003				    unsigned int len,
1004				    struct ext2_dir_entry *dirent);
1005extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
1006			      ext2_ino_t dir,
1007			      int flags,
1008			      char *block_buf,
1009			      int (*func)(struct ext2_dir_entry *dirent,
1010					  int	offset,
1011					  int	blocksize,
1012					  char	*buf,
1013					  void	*priv_data),
1014			      void *priv_data);
1015extern errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
1016			      ext2_ino_t dir,
1017			      int flags,
1018			      char *block_buf,
1019			      int (*func)(ext2_ino_t	dir,
1020					  int	entry,
1021					  struct ext2_dir_entry *dirent,
1022					  int	offset,
1023					  int	blocksize,
1024					  char	*buf,
1025					  void	*priv_data),
1026			      void *priv_data);
1027
1028/* dupfs.c */
1029extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
1030
1031/* expanddir.c */
1032extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
1033
1034/* ext_attr.c */
1035extern __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
1036					void *data);
1037extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
1038extern errcode_t ext2fs_read_ext_attr2(ext2_filsys fs, blk64_t block,
1039				       void *buf);
1040extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
1041				       void *buf);
1042extern errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block,
1043				       void *buf);
1044extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
1045					   char *block_buf,
1046					   int adjust, __u32 *newcount);
1047extern errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk,
1048					   char *block_buf,
1049					   int adjust, __u32 *newcount);
1050
1051/* extent.c */
1052extern errcode_t ext2fs_extent_header_verify(void *ptr, int size);
1053extern errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino,
1054				    ext2_extent_handle_t *handle);
1055extern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino,
1056					struct ext2_inode *inode,
1057					ext2_extent_handle_t *ret_handle);
1058extern void ext2fs_extent_free(ext2_extent_handle_t handle);
1059extern errcode_t ext2fs_extent_get(ext2_extent_handle_t handle,
1060				   int flags, struct ext2fs_extent *extent);
1061extern errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle, int flags,
1062				       struct ext2fs_extent *extent);
1063extern errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags,
1064				      struct ext2fs_extent *extent);
1065extern errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
1066					blk64_t logical, blk64_t physical,
1067					int flags);
1068extern errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags);
1069extern errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle,
1070					struct ext2_extent_info *info);
1071extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
1072				    blk64_t blk);
1073
1074/* fileio.c */
1075extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
1076				   struct ext2_inode *inode,
1077				   int flags, ext2_file_t *ret);
1078extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
1079				  int flags, ext2_file_t *ret);
1080extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
1081struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file);
1082extern errcode_t ext2fs_file_close(ext2_file_t file);
1083extern errcode_t ext2fs_file_flush(ext2_file_t file);
1084extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
1085				  unsigned int wanted, unsigned int *got);
1086extern errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
1087				   unsigned int nbytes, unsigned int *written);
1088extern errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
1089				   int whence, __u64 *ret_pos);
1090extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
1091				   int whence, ext2_off_t *ret_pos);
1092errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
1093extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
1094extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
1095extern errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size);
1096
1097/* finddev.c */
1098extern char *ext2fs_find_block_device(dev_t device);
1099
1100/* flushb.c */
1101extern errcode_t ext2fs_sync_device(int fd, int flushb);
1102
1103/* freefs.c */
1104extern void ext2fs_free(ext2_filsys fs);
1105extern void ext2fs_free_dblist(ext2_dblist dblist);
1106extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
1107extern void ext2fs_u32_list_free(ext2_u32_list bb);
1108
1109/* gen_bitmap.c */
1110extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
1111extern errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
1112					    __u32 start, __u32 end,
1113					    __u32 real_end,
1114					    const char *descr, char *init_map,
1115					    ext2fs_generic_bitmap *ret);
1116extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
1117						__u32 end,
1118						__u32 real_end,
1119						const char *descr,
1120						ext2fs_generic_bitmap *ret);
1121extern errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
1122					    ext2fs_generic_bitmap *dest);
1123extern void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap);
1124extern errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
1125						 errcode_t magic,
1126						 errcode_t neq,
1127						 ext2_ino_t end,
1128						 ext2_ino_t *oend);
1129extern void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map);
1130extern errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
1131					      __u32 new_end,
1132					      __u32 new_real_end,
1133					      ext2fs_generic_bitmap bmap);
1134extern errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
1135					       ext2fs_generic_bitmap bm1,
1136					       ext2fs_generic_bitmap bm2);
1137extern errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
1138						 errcode_t magic,
1139						 __u32 start, __u32 num,
1140						 void *out);
1141extern errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
1142						 errcode_t magic,
1143						 __u32 start, __u32 num,
1144						 void *in);
1145
1146/* gen_bitmap64.c */
1147void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap);
1148errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
1149				    int type, __u64 start, __u64 end,
1150				    __u64 real_end,
1151				    const char *descr,
1152				    ext2fs_generic_bitmap *ret);
1153errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
1154				   ext2fs_generic_bitmap *dest);
1155void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap);
1156errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
1157					errcode_t neq,
1158					__u64 end, __u64 *oend);
1159void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap);
1160errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
1161				     __u64 new_end,
1162				     __u64 new_real_end);
1163errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
1164				      ext2fs_generic_bitmap bm1,
1165				      ext2fs_generic_bitmap bm2);
1166errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
1167					__u64 start, unsigned int num,
1168					void *out);
1169errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
1170					__u64 start, unsigned int num,
1171					void *in);
1172errcode_t ext2fs_convert_subcluster_bitmap(ext2_filsys fs,
1173					   ext2fs_block_bitmap *bitmap);
1174
1175/* getsize.c */
1176extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
1177					blk_t *retblocks);
1178extern errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
1179					blk64_t *retblocks);
1180
1181/* getsectsize.c */
1182errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
1183errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize);
1184
1185/* i_block.c */
1186errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
1187				 blk64_t num_blocks);
1188errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
1189				 blk64_t num_blocks);
1190errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b);
1191
1192/* imager.c */
1193extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
1194extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
1195extern errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags);
1196extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
1197extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
1198extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
1199
1200/* ind_block.c */
1201errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
1202errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
1203
1204/* initialize.c */
1205extern errcode_t ext2fs_initialize(const char *name, int flags,
1206				   struct ext2_super_block *param,
1207				   io_manager manager, ext2_filsys *ret_fs);
1208
1209/* icount.c */
1210extern void ext2fs_free_icount(ext2_icount_t icount);
1211extern errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
1212					  int flags, ext2_icount_t *ret);
1213extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags,
1214				       unsigned int size,
1215				       ext2_icount_t hint, ext2_icount_t *ret);
1216extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags,
1217				      unsigned int size,
1218				      ext2_icount_t *ret);
1219extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
1220				     __u16 *ret);
1221extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
1222					 __u16 *ret);
1223extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
1224					 __u16 *ret);
1225extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
1226				     __u16 count);
1227extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
1228errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
1229
1230/* inode.c */
1231extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
1232extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan,
1233					    ext2_ino_t *ino,
1234					    struct ext2_inode *inode,
1235					    int bufsize);
1236extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
1237				  ext2_inode_scan *ret_scan);
1238extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
1239extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
1240			       struct ext2_inode *inode);
1241extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
1242						   int	group);
1243extern void ext2fs_set_inode_callback
1244	(ext2_inode_scan scan,
1245	 errcode_t (*done_group)(ext2_filsys fs,
1246				 ext2_inode_scan scan,
1247				 dgrp_t group,
1248				 void * priv_data),
1249	 void *done_group_data);
1250extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
1251				   int clear_flags);
1252extern errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
1253					struct ext2_inode * inode,
1254					int bufsize);
1255extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
1256			    struct ext2_inode * inode);
1257extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
1258					 struct ext2_inode * inode,
1259					 int bufsize);
1260extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
1261			    struct ext2_inode * inode);
1262extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
1263			    struct ext2_inode * inode);
1264extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
1265extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
1266
1267/* inode_io.c */
1268extern io_manager inode_io_manager;
1269extern errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
1270					char **name);
1271extern errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
1272					 struct ext2_inode *inode,
1273					 char **name);
1274
1275/* ismounted.c */
1276extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
1277extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
1278					  char *mtpt, int mtlen);
1279
1280/* punch.c */
1281extern errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino,
1282			      struct ext2_inode *inode,
1283			      char *block_buf, blk64_t start,
1284			      blk64_t end);
1285
1286/* namei.c */
1287extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
1288			 int namelen, char *buf, ext2_ino_t *inode);
1289extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
1290			const char *name, ext2_ino_t *inode);
1291errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
1292			      const char *name, ext2_ino_t *inode);
1293extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
1294			ext2_ino_t inode, ext2_ino_t *res_inode);
1295
1296/* native.c */
1297int ext2fs_native_flag(void);
1298
1299/* newdir.c */
1300extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
1301				ext2_ino_t parent_ino, char **block);
1302
1303/* mkdir.c */
1304extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
1305			      const char *name);
1306
1307/* mkjournal.c */
1308extern errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
1309				    blk_t *ret_blk, int *ret_count);
1310extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
1311				     blk64_t *ret_blk, int *ret_count);
1312extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
1313						  __u32 num_blocks, int flags,
1314						  char  **ret_jsb);
1315extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
1316					   ext2_filsys journal_dev);
1317extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
1318					  int flags);
1319extern int ext2fs_default_journal_size(__u64 num_blocks);
1320
1321/* openfs.c */
1322extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
1323			     unsigned int block_size, io_manager manager,
1324			     ext2_filsys *ret_fs);
1325extern errcode_t ext2fs_open2(const char *name, const char *io_options,
1326			      int flags, int superblock,
1327			      unsigned int block_size, io_manager manager,
1328			      ext2_filsys *ret_fs);
1329extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs,
1330					blk64_t group_block, dgrp_t i);
1331extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block,
1332					 dgrp_t i);
1333errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
1334errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
1335errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
1336
1337/* get_pathname.c */
1338extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
1339			       char **name);
1340
1341/* link.c */
1342errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
1343		      ext2_ino_t ino, int flags);
1344errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
1345			ext2_ino_t ino, int flags);
1346
1347/* mmp.c */
1348errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf);
1349errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf);
1350errcode_t ext2fs_mmp_clear(ext2_filsys fs);
1351errcode_t ext2fs_mmp_init(ext2_filsys fs);
1352errcode_t ext2fs_mmp_start(ext2_filsys fs);
1353errcode_t ext2fs_mmp_update(ext2_filsys fs);
1354errcode_t ext2fs_mmp_stop(ext2_filsys fs);
1355unsigned ext2fs_mmp_new_seq();
1356
1357/* read_bb.c */
1358extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
1359				      ext2_badblocks_list *bb_list);
1360
1361/* read_bb_file.c */
1362extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f,
1363				      ext2_badblocks_list *bb_list,
1364				      void *priv_data,
1365				      void (*invalid)(ext2_filsys fs,
1366						      blk_t blk,
1367						      char *badstr,
1368						      void *priv_data));
1369extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
1370				     ext2_badblocks_list *bb_list,
1371				     void (*invalid)(ext2_filsys fs,
1372						     blk_t blk));
1373
1374/* res_gdt.c */
1375extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
1376
1377/* swapfs.c */
1378extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize,
1379				 int has_header);
1380extern void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
1381					struct ext2_ext_attr_header *from_hdr);
1382extern void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
1383				       struct ext2_ext_attr_entry *from_entry);
1384extern void ext2fs_swap_super(struct ext2_super_block * super);
1385extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
1386extern void ext2fs_swap_group_desc2(ext2_filsys, struct ext2_group_desc *gdp);
1387extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
1388				   struct ext2_inode_large *f, int hostorder,
1389				   int bufsize);
1390extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
1391			      struct ext2_inode *f, int hostorder);
1392extern void ext2fs_swap_mmp(struct mmp_struct *mmp);
1393
1394/* valid_blk.c */
1395extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
1396
1397/* version.c */
1398extern int ext2fs_parse_version_string(const char *ver_string);
1399extern int ext2fs_get_library_version(const char **ver_string,
1400				      const char **date_string);
1401
1402/* write_bb_file.c */
1403extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
1404				      unsigned int flags,
1405				      FILE *f);
1406
1407
1408/* inline functions */
1409extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
1410extern errcode_t ext2fs_get_memalign(unsigned long size,
1411				     unsigned long align, void *ptr);
1412extern errcode_t ext2fs_get_memzero(unsigned long size, void *ptr);
1413extern errcode_t ext2fs_get_array(unsigned long count,
1414				  unsigned long size, void *ptr);
1415extern errcode_t ext2fs_get_arrayzero(unsigned long count,
1416				      unsigned long size, void *ptr);
1417extern errcode_t ext2fs_free_mem(void *ptr);
1418extern errcode_t ext2fs_resize_mem(unsigned long old_size,
1419				   unsigned long size, void *ptr);
1420extern void ext2fs_mark_super_dirty(ext2_filsys fs);
1421extern void ext2fs_mark_changed(ext2_filsys fs);
1422extern int ext2fs_test_changed(ext2_filsys fs);
1423extern void ext2fs_mark_valid(ext2_filsys fs);
1424extern void ext2fs_unmark_valid(ext2_filsys fs);
1425extern int ext2fs_test_valid(ext2_filsys fs);
1426extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
1427extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
1428extern int ext2fs_test_ib_dirty(ext2_filsys fs);
1429extern int ext2fs_test_bb_dirty(ext2_filsys fs);
1430extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
1431extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
1432extern blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group);
1433extern blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group);
1434extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
1435				      struct ext2_inode *inode);
1436extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b);
1437extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
1438extern int ext2fs_open_file(const char *pathname, int flags, ...);
1439extern int ext2fs_stat(const char *path, ext2fs_struct_stat *buf);
1440extern int ext2fs_fstat(int fd, ext2fs_struct_stat *buf);
1441
1442/*
1443 * The actual inlined functions definitions themselves...
1444 *
1445 * If NO_INLINE_FUNCS is defined, then we won't try to do inline
1446 * functions at all!
1447 */
1448#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
1449#ifdef INCLUDE_INLINE_FUNCS
1450#define _INLINE_ extern
1451#else
1452#ifdef __GNUC__
1453#define _INLINE_ extern __inline__
1454#else				/* For Watcom C */
1455#define _INLINE_ extern inline
1456#endif
1457#endif
1458
1459#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
1460#include <string.h>
1461/*
1462 *  Allocate memory
1463 */
1464_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
1465{
1466	void *pp;
1467
1468	pp = malloc(size);
1469	if (!pp)
1470		return EXT2_ET_NO_MEMORY;
1471	memcpy(ptr, &pp, sizeof (pp));
1472	return 0;
1473}
1474
1475_INLINE_ errcode_t ext2fs_get_memalign(unsigned long size,
1476				       unsigned long align, void *ptr)
1477{
1478	errcode_t retval;
1479
1480	if (align == 0)
1481		align = 8;
1482	retval = posix_memalign((void **) ptr, align, size);
1483	if (retval) {
1484		if (retval == ENOMEM)
1485			return EXT2_ET_NO_MEMORY;
1486		return retval;
1487	}
1488	return 0;
1489}
1490
1491_INLINE_ errcode_t ext2fs_get_memzero(unsigned long size, void *ptr)
1492{
1493	void *pp;
1494
1495	pp = malloc(size);
1496	if (!pp)
1497		return EXT2_ET_NO_MEMORY;
1498	memset(pp, 0, size);
1499	memcpy(ptr, &pp, sizeof(pp));
1500	return 0;
1501}
1502
1503_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
1504{
1505	if (count && (-1UL)/count<size)
1506		return EXT2_ET_NO_MEMORY;
1507	return ext2fs_get_mem(count*size, ptr);
1508}
1509
1510_INLINE_ errcode_t ext2fs_get_arrayzero(unsigned long count,
1511					unsigned long size, void *ptr)
1512{
1513	void *pp;
1514
1515	if (count && (-1UL)/count<size)
1516		return EXT2_ET_NO_MEMORY;
1517	pp = calloc(count, size);
1518	if (!pp)
1519		return EXT2_ET_NO_MEMORY;
1520	memcpy(ptr, &pp, sizeof(pp));
1521	return 0;
1522}
1523
1524/*
1525 * Free memory
1526 */
1527_INLINE_ errcode_t ext2fs_free_mem(void *ptr)
1528{
1529	void *p;
1530
1531	memcpy(&p, ptr, sizeof(p));
1532	free(p);
1533	p = 0;
1534	memcpy(ptr, &p, sizeof(p));
1535	return 0;
1536}
1537
1538/*
1539 *  Resize memory
1540 */
1541_INLINE_ errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
1542				     unsigned long size, void *ptr)
1543{
1544	void *p;
1545
1546	/* Use "memcpy" for pointer assignments here to avoid problems
1547	 * with C99 strict type aliasing rules. */
1548	memcpy(&p, ptr, sizeof(p));
1549	p = realloc(p, size);
1550	if (!p)
1551		return EXT2_ET_NO_MEMORY;
1552	memcpy(ptr, &p, sizeof(p));
1553	return 0;
1554}
1555#endif	/* Custom memory routines */
1556
1557/*
1558 * Mark a filesystem superblock as dirty
1559 */
1560_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
1561{
1562	fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
1563}
1564
1565/*
1566 * Mark a filesystem as changed
1567 */
1568_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
1569{
1570	fs->flags |= EXT2_FLAG_CHANGED;
1571}
1572
1573/*
1574 * Check to see if a filesystem has changed
1575 */
1576_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
1577{
1578	return (fs->flags & EXT2_FLAG_CHANGED);
1579}
1580
1581/*
1582 * Mark a filesystem as valid
1583 */
1584_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
1585{
1586	fs->flags |= EXT2_FLAG_VALID;
1587}
1588
1589/*
1590 * Mark a filesystem as NOT valid
1591 */
1592_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
1593{
1594	fs->flags &= ~EXT2_FLAG_VALID;
1595}
1596
1597/*
1598 * Check to see if a filesystem is valid
1599 */
1600_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
1601{
1602	return (fs->flags & EXT2_FLAG_VALID);
1603}
1604
1605/*
1606 * Mark the inode bitmap as dirty
1607 */
1608_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
1609{
1610	fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
1611}
1612
1613/*
1614 * Mark the block bitmap as dirty
1615 */
1616_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
1617{
1618	fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
1619}
1620
1621/*
1622 * Check to see if a filesystem's inode bitmap is dirty
1623 */
1624_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
1625{
1626	return (fs->flags & EXT2_FLAG_IB_DIRTY);
1627}
1628
1629/*
1630 * Check to see if a filesystem's block bitmap is dirty
1631 */
1632_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
1633{
1634	return (fs->flags & EXT2_FLAG_BB_DIRTY);
1635}
1636
1637/*
1638 * Return the group # of a block
1639 */
1640_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
1641{
1642	return ext2fs_group_of_blk2(fs, blk);
1643}
1644/*
1645 * Return the group # of an inode number
1646 */
1647_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
1648{
1649	return (ino - 1) / fs->super->s_inodes_per_group;
1650}
1651
1652/*
1653 * Return the first block (inclusive) in a group
1654 */
1655_INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group)
1656{
1657	return ext2fs_group_first_block2(fs, group);
1658}
1659
1660/*
1661 * Return the last block (inclusive) in a group
1662 */
1663_INLINE_ blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group)
1664{
1665	return ext2fs_group_last_block2(fs, group);
1666}
1667
1668_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
1669					struct ext2_inode *inode)
1670{
1671	return ext2fs_inode_data_blocks2(fs, inode);
1672}
1673
1674/*
1675 * This is an efficient, overflow safe way of calculating ceil((1.0 * a) / b)
1676 */
1677_INLINE_ unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b)
1678{
1679	if (!a)
1680		return 0;
1681	return ((a - 1) / b) + 1;
1682}
1683
1684_INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b)
1685{
1686	if (!a)
1687		return 0;
1688	return ((a - 1) / b) + 1;
1689}
1690
1691_INLINE_ int ext2fs_open_file(const char *pathname, int flags, ...)
1692{
1693	va_list args;
1694	mode_t mode;
1695
1696	va_start(args, flags);
1697	mode = va_arg(args, mode_t);
1698	va_end(args);
1699
1700	if (mode)
1701#if defined(HAVE_OPEN64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
1702		return open64(pathname, flags, mode);
1703	else
1704		return open64(pathname, flags);
1705#else
1706		return open(pathname, flags, mode);
1707	else
1708		return open(pathname, flags);
1709#endif
1710}
1711
1712_INLINE_ int ext2fs_stat(const char *path, ext2fs_struct_stat *buf)
1713{
1714#if defined(HAVE_STAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
1715	return stat64(path, buf);
1716#else
1717	return stat(path, buf);
1718#endif
1719}
1720
1721_INLINE_ int ext2fs_fstat(int fd, ext2fs_struct_stat *buf)
1722{
1723#if defined(HAVE_STAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
1724	return fstat64(fd, buf);
1725#else
1726	return fstat(fd, buf);
1727#endif
1728}
1729
1730#undef _INLINE_
1731#endif
1732
1733#ifdef __cplusplus
1734}
1735#endif
1736
1737#endif /* _EXT2FS_EXT2FS_H */
1738