diff options
Diffstat (limited to 'ext2fs/ext2fs.h')
-rw-r--r-- | ext2fs/ext2fs.h | 190 |
1 files changed, 108 insertions, 82 deletions
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h index 8a4bde9d..2ad4a9df 100644 --- a/ext2fs/ext2fs.h +++ b/ext2fs/ext2fs.h @@ -1,8 +1,7 @@ /* Common definitions for the ext2 filesystem translator - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - - Written by Miles Bader <miles@gnu.ai.mit.edu> + Copyright (C) 1995, 1996, 1999, 2002, 2004 Free Software Foundation, Inc. + Written by Miles Bader <miles@gnu.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -27,10 +26,35 @@ #include <hurd/diskfs.h> #include <assert.h> #include <rwlock.h> +#include <sys/mman.h> #define __hurd__ /* Enable some hurd-specific fields. */ + +/* Types used by the ext2 header files. */ +typedef u_int32_t __u32; +typedef int32_t __s32; +typedef u_int16_t __u16; +typedef int16_t __s16; +typedef u_int8_t __u8; +typedef int8_t __s8; + #include "ext2_fs.h" #include "ext2_fs_i.h" + +#define i_mode_high osd2.hurd2.h_i_mode_high /* missing from ext2_fs.h */ + + +/* If ext2_fs.h defined a debug routine, undef it and use our own. */ +#undef ext2_debug + +#ifdef EXT2FS_DEBUG +extern int ext2_debug_flag; +#define ext2_debug(f, a...) \ + do { if (ext2_debug_flag) printf ("ext2fs: (debug) %s: " f "\n", __FUNCTION__ , ## a); } while (0) +#else +#define ext2_debug(f, a...) (void)0 +#endif + #undef __hurd__ /* Define this if memory objects should not be cached by the kernel. @@ -42,7 +66,7 @@ int printf (const char *fmt, ...); /* A block number. */ -typedef u32 block_t; +typedef __u32 block_t; /* ---------------------------------------------------------------- */ @@ -77,64 +101,52 @@ void pokel_flush (struct pokel *pokel); /* Transfer all regions from FROM to POKEL, which must have the same pager. */ void pokel_inherit (struct pokel *pokel, struct pokel *from); +#include <features.h> +#ifdef EXT2FS_DEFINE_EI +#define EXT2FS_EI +#else +#define EXT2FS_EI __extern_inline +#endif + /* ---------------------------------------------------------------- */ /* Bitmap routines. */ +#include <stdint.h> + +extern int test_bit (unsigned num, char *bitmap); + +extern int set_bit (unsigned num, char *bitmap); + +#if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI) /* Returns TRUE if bit NUM is set in BITMAP. */ -extern inline int +EXT2FS_EI int test_bit (unsigned num, char *bitmap) { - return bitmap[num >> 3] & (1 << (num & 0x7)); + const uint32_t *const bw = (uint32_t *) bitmap + (num >> 5); + const uint_fast32_t mask = 1 << (num & 31); + return *bw & mask; } /* Sets bit NUM in BITMAP, and returns the previous state of the bit. Unlike the linux version, this function is NOT atomic! */ -extern inline int +EXT2FS_EI int set_bit (unsigned num, char *bitmap) { - char *p = bitmap + (num >> 3); - char byte = *p; - char mask = (1 << (num & 0x7)); - - if (byte & mask) - return 1; - else - { - *p = byte | mask; - return 0; - } + uint32_t *const bw = (uint32_t *) bitmap + (num >> 5); + const uint_fast32_t mask = 1 << (num & 31); + return (*bw & mask) ?: (*bw |= mask, 0); } /* Clears bit NUM in BITMAP, and returns the previous state of the bit. Unlike the linux version, this function is NOT atomic! */ -extern inline int +EXT2FS_EI int clear_bit (unsigned num, char *bitmap) { - char *p = bitmap + (num >> 3); - char byte = *p; - char mask = (1 << (num & 0x7)); - - if (byte & mask) - { - *p = byte & ~mask; - return 1; - } - else - return 0; + uint32_t *const bw = (uint32_t *) bitmap + (num >> 5); + const uint_fast32_t mask = 1 << (num & 31); + return (*bw & mask) ? (*bw &= ~mask, mask) : 0; } - -/* Counts the number of bits unset in MAP, a bitmap NUMCHARS long. */ -unsigned long count_free (char * map, unsigned int numchars); - -extern int find_first_zero_bit(void * addr, unsigned size); - -extern int find_next_zero_bit (void * addr, int size, int offset); - -extern unsigned long ffz(unsigned long word); - -/* Returns a pointer to the first occurence of CH in the buffer BUF of len - LEN, or BUF + LEN if CH doesn't occur. */ -void *memscan(void *buf, unsigned char ch, unsigned len); +#endif /* Use extern inlines. */ /* ---------------------------------------------------------------- */ @@ -156,6 +168,7 @@ struct disknode /* Random extra info used by the ext2 routines. */ struct ext2_inode_info info; + uint32_t info_i_translator; /* That struct from Linux source lacks this. */ /* This file's pager. */ struct pager *pager; @@ -163,6 +176,9 @@ struct disknode /* True if the last page of the file has been made writable, but is only partially allocated. */ int last_page_partially_writable; + + /* Index to start a directory lookup at. */ + int dir_idx; }; struct user_pager_info @@ -197,23 +213,34 @@ void flush_node_pager (struct node *node); /* ---------------------------------------------------------------- */ -/* Our in-core copy of the super-block. */ +/* The physical media. */ +extern struct store *store; +/* What the user specified. */ +extern struct store_parsed *store_parsed; + +/* Mapped image of the disk. */ +extern void *disk_image; + +/* Our in-core copy of the super-block (pointer into the disk_image). */ struct ext2_super_block *sblock; /* True if sblock has been modified. */ int sblock_dirty; /* Where the super-block is located on disk (at min-block 1). */ -#define SBLOCK_BLOCK 1 -#define SBLOCK_OFFS (SBLOCK_BLOCK * EXT2_MIN_BLOCK_SIZE) -#define SBLOCK_SIZE (sizeof (struct ext2_super_block)) +#define SBLOCK_BLOCK 1 /* Default location, second 1k block. */ +#define SBLOCK_SIZE (sizeof (struct ext2_super_block)) +extern unsigned int sblock_block; /* Specified location (in 1k blocks). */ +#define SBLOCK_OFFS (sblock_block << 10) /* Byte offset of superblock. */ /* The filesystem block-size. */ -unsigned long block_size; +unsigned int block_size; /* The log base 2 of BLOCK_SIZE. */ -unsigned log2_block_size; +unsigned int log2_block_size; -/* log2 of the number of device blocks (DISKFS_DEVICE_BLOCK_SIZE) in a - filesystem block (BLOCK_SIZE). */ +/* The number of bits to scale min-blocks to get filesystem blocks. */ +#define BLOCKSIZE_SCALE (sblock->s_log_block_size) + +/* log2 of the number of device blocks in a filesystem block. */ unsigned log2_dev_blocks_per_fs_block; /* log2 of the number of stat blocks (512 bytes) in a filesystem block. */ @@ -226,14 +253,6 @@ vm_address_t zeroblock; void get_hypermetadata (); /* ---------------------------------------------------------------- */ - -/* Returns a single page page-aligned buffer. */ -vm_address_t get_page_buf (); - -/* Frees a block returned by get_page_buf. */ -void free_page_buf (vm_address_t buf); - -/* ---------------------------------------------------------------- */ /* Random stuff calculated from the super block. */ unsigned long frag_size; /* Size of a fragment in bytes */ @@ -277,32 +296,28 @@ unsigned long next_generation; #define bptr_block(ptr) boffs_block(bptr_offs(ptr)) /* Get the descriptor for block group NUM. The block group descriptors are - stored starting in the block following the super block. */ -extern inline struct ext2_group_desc * -group_desc(unsigned long num) -{ - int desc_per_block = EXT2_DESC_PER_BLOCK(sblock); - unsigned long group_desc = num / desc_per_block; - unsigned long desc = num % desc_per_block; - return - ((struct ext2_group_desc *)boffs_ptr(SBLOCK_OFFS + boffs(1 + group_desc))) - + desc; -} + stored starting in the filesystem block following the super block. + We cache a pointer into the disk image for easy lookup. */ +#define group_desc(num) (&group_desc_image[num]) +struct ext2_group_desc *group_desc_image; #define inode_group_num(inum) (((inum) - 1) / sblock->s_inodes_per_group) +extern struct ext2_inode *dino (ino_t inum); + +#if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI) /* Convert an inode number to the dinode on disk. */ -extern inline struct ext2_inode * +EXT2FS_EI struct ext2_inode * dino (ino_t inum) { unsigned long inodes_per_group = sblock->s_inodes_per_group; unsigned long bg_num = (inum - 1) / inodes_per_group; unsigned long group_inum = (inum - 1) % inodes_per_group; struct ext2_group_desc *bg = group_desc(bg_num); - unsigned long inodes_per_block = EXT2_INODES_PER_BLOCK(sblock); block_t block = bg->bg_inode_table + (group_inum / inodes_per_block); return ((struct ext2_inode *)bptr(block)) + group_inum % inodes_per_block; } +#endif /* Use extern inlines. */ /* ---------------------------------------------------------------- */ /* inode.c */ @@ -331,11 +346,19 @@ struct pokel global_pokel; char *modified_global_blocks; spin_lock_t modified_global_blocks_lock; +extern int global_block_modified (block_t block); +extern void record_global_poke (void *ptr); +extern void sync_global_ptr (void *bptr, int wait); +extern void record_indir_poke (struct node *node, void *ptr); +extern void sync_global (int wait); +extern void alloc_sync (struct node *np); + +#if defined(__USE_EXTERN_INLINES) || defined(EXT2FS_DEFINE_EI) /* Marks the global block BLOCK as being modified, and returns true if we think it may have been clean before (but we may not be sure). Note that this isn't enough to cause the block to be synced; you must call record_global_poke to do that. */ -extern inline int +EXT2FS_EI int global_block_modified (block_t block) { if (modified_global_blocks) @@ -351,7 +374,7 @@ global_block_modified (block_t block) } /* This records a modification to a non-file block. */ -extern inline void +EXT2FS_EI void record_global_poke (void *ptr) { int boffs = trunc_block (bptr_offs (ptr)); @@ -360,16 +383,16 @@ record_global_poke (void *ptr) } /* This syncs a modification to a non-file block. */ -extern inline void +EXT2FS_EI void sync_global_ptr (void *bptr, int wait) { vm_offset_t boffs = trunc_block (bptr_offs (bptr)); global_block_modified (boffs_block (boffs)); - pager_sync_some (disk_pager, trunc_page (boffs), vm_page_size, wait); + pager_sync_some (diskfs_disk_pager, trunc_page (boffs), vm_page_size, wait); } /* This records a modification to one of a file's indirect blocks. */ -extern inline void +EXT2FS_EI void record_indir_poke (struct node *node, void *ptr) { int boffs = trunc_block (bptr_offs (ptr)); @@ -379,14 +402,14 @@ record_indir_poke (struct node *node, void *ptr) /* ---------------------------------------------------------------- */ -extern inline void +EXT2FS_EI void sync_global (int wait) { pokel_sync (&global_pokel, wait); } /* Sync all allocation information and node NP if diskfs_synchronous. */ -extern inline void +EXT2FS_EI void alloc_sync (struct node *np) { if (diskfs_synchronous) @@ -399,18 +422,21 @@ alloc_sync (struct node *np) diskfs_set_hypermetadata (1, 0); } } +#endif /* Use extern inlines. */ /* ---------------------------------------------------------------- */ /* getblk.c */ void ext2_discard_prealloc (struct node *node); -/* Returns in DISK_BLOCK the disk block correspding to BLOCK in NODE. If - there is no such block yet, but CREATE is true, then it is created, +/* Returns in DISK_BLOCK the disk block corresponding to BLOCK in NODE. + If there is no such block yet, but CREATE is true, then it is created, otherwise EINVAL is returned. */ error_t ext2_getblk (struct node *node, block_t block, int create, block_t *disk_block); -block_t ext2_new_block (block_t goal, block_t *prealloc_count, block_t *prealloc_block); +block_t ext2_new_block (block_t goal, + block_t prealloc_goal, + block_t *prealloc_count, block_t *prealloc_block); void ext2_free_blocks (block_t block, unsigned long count); |