1 /*
   2     ext2.h -- ext2 header
   3     Copyright (C) 1998-2000, 2007 Free Software Foundation, Inc.
   4 
   5     This program is free software; you can redistribute it and/or modify
   6     it under the terms of the GNU General Public License as published by
   7     the Free Software Foundation; either version 3 of the License, or
   8     (at your option) any later version.
   9 
  10     This program is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13     GNU General Public License for more details.
  14 
  15     You should have received a copy of the GNU General Public License
  16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18 
  19 #ifndef _EXT2_H
  20 #define _EXT2_H
  21 
  22 #include <parted/parted.h>
  23 #include <parted/debug.h>
  24 #include <sys/types.h>
  25 #include "tune.h"
  26 
  27 #if HAVE_INTTYPES_H
  28 #  include <inttypes.h>
  29 #endif
  30 
  31 #if ENABLE_NLS
  32 #  include <libintl.h>
  33 #  define _(String) dgettext (PACKAGE, String)
  34 #else
  35 #  define _(String) (String)
  36 #endif /* ENABLE_NLS */
  37 
  38 
  39 /* Ehrm.... sorry, pedanticists! :-) */
  40 #ifndef offsetof
  41 #  define offsetof(type, field) ((size_t)(&(((type *)0)->field)))
  42 #endif
  43 
  44 #ifdef __BEOS__
  45   typedef off_t loff_t;
  46 #endif
  47 
  48 #if defined(__sun)
  49 typedef off_t loff_t;
  50 typedef uint32_t blk_t;
  51 #else
  52 typedef u_int32_t blk_t;
  53 #endif
  54 
  55 #ifdef HAVE_LINUX_EXT2_FS_H
  56 #define _LINUX_TYPES_H
  57 #define i_version i_generation
  58 #include <linux/ext2_fs.h>
  59 #else
  60 #include "ext2_fs.h"
  61 #endif
  62 
  63 extern unsigned char _bitmap[8];
  64 
  65 struct ext2_buffer_cache
  66 {
  67         struct ext2_buffer_head  *cache;
  68         struct ext2_buffer_head  *heads;
  69         struct ext2_buffer_head **hash;
  70         struct ext2_fs           *fs;
  71 
  72         int                       size;
  73         int                       numalloc;
  74         unsigned char            *buffermem;
  75 };
  76 
  77 struct ext2_buffer_head
  78 {
  79         struct ext2_buffer_head  *next;
  80         struct ext2_buffer_head  *prev;
  81         unsigned char            *data;
  82         blk_t                     block;
  83 
  84         int                       usecount;
  85         int                       dirty;
  86 
  87         struct ext2_buffer_cache *bc;
  88         int                       alloc;
  89 };
  90 
  91 struct ext2_dev_ops
  92 {
  93         int     (*close)(void *cookie);
  94         blk_t   (*get_size)(void *cookie);
  95         int     (*read)(void *cookie, void *ptr, blk_t block, blk_t num);
  96         int     (*set_blocksize)(void *cookie, int logsize);
  97         int     (*sync)(void *cookie);
  98         int     (*write)(void *cookie, void *ptr, blk_t block, blk_t num);
  99 };
 100 
 101 struct ext2_dev_handle
 102 {
 103         struct ext2_dev_ops     *ops;
 104         void                    *cookie;
 105 };
 106 
 107 struct ext2_fs
 108 {      
 109         struct ext2_dev_handle           *devhandle;
 110 
 111         struct ext2_super_block           sb;
 112         struct ext2_group_desc           *gd;
 113         struct ext2_buffer_cache         *bc;
 114         int                               metadirty;                    /* 0:all sb&gd copies clean
 115                                                                            1:all sb&gd copies dirty
 116                                                                            2:only first sb&gd copy clean */
 117 
 118         int                               dynamic_version;
 119         int                               sparse;                       /* sparse superblocks */
 120         int                               has_journal;                  /* journal */
 121         int                               has_internal_journal;
 122 
 123         int                               blocksize;
 124         int                               logsize;
 125         blk_t                             adminblocks;
 126         blk_t                             gdblocks;
 127         blk_t                             itoffset;
 128         blk_t                             inodeblocks;
 129         int                               numgroups;
 130         int                               r_frac;                       /* reserved % of blocks */
 131 
 132         unsigned char                    *relocator_pool;
 133         unsigned char                    *relocator_pool_end;
 134 
 135         int                              opt_debug;
 136         int                              opt_safe;
 137         int                              opt_verbose;
 138 
 139         void                             *journal;
 140 };
 141 
 142 
 143 #define EXT2_ACTION_ADD         1
 144 #define EXT2_ACTION_DELETE      2
 145 #define EXT2_ACTION_FIND        3
 146 
 147 #define EXT2_META_CLEAN         0
 148 #define EXT2_META_PRIMARY_SB    1
 149 #define EXT2_META_BACKUP_SB     2
 150 #define EXT2_META_PRIMARY_GD    4
 151 #define EXT2_META_BACKUP_GD     8
 152 
 153 #define EXT2_META_PRIMARY       (EXT2_META_PRIMARY_SB | EXT2_META_PRIMARY_GD)
 154 #define EXT2_META_BACKUP        (EXT2_META_BACKUP_SB | EXT2_META_BACKUP_GD)
 155 #define EXT2_META_SB            (EXT2_META_PRIMARY_SB | EXT2_META_BACKUP_SB)
 156 #define EXT2_META_GD            (EXT2_META_PRIMARY_GD | EXT2_META_BACKUP_GD)
 157 
 158 /* generic stuff */
 159 int             ext2_copy_block                 (struct ext2_fs *fs, blk_t from, blk_t to);
 160 void            ext2_close                      (struct ext2_fs *fs);
 161 int             ext2_commit_metadata            (struct ext2_fs *fs, int copies);
 162 off_t           ext2_get_inode_offset           (struct ext2_fs *fs, ino_t inode, blk_t *block);
 163 blk_t           ext2_find_free_block            (struct ext2_fs *fs);
 164 ino_t           ext2_find_free_inode            (struct ext2_fs *fs);
 165 int             ext2_get_inode_state            (struct ext2_fs *fs, ino_t inode);
 166 int             ext2_is_group_sparse            (struct ext2_fs *fs, int group);
 167 int             ext2_move_blocks                (struct ext2_fs *fs, blk_t src, blk_t num, blk_t dest);
 168 struct ext2_fs *ext2_open                       (struct ext2_dev_handle *handle, int state);
 169 int             ext2_read_blocks                (struct ext2_fs *fs, void *ptr, blk_t block, blk_t numblocks);
 170 int             ext2_read_inode                 (struct ext2_fs *fs, ino_t inode, struct ext2_inode *inodep);
 171 int             ext2_set_inode_state            (struct ext2_fs *fs, ino_t inode, int state, int updatemetadata);
 172 int             ext2_do_inode                   (struct ext2_fs *fs, struct ext2_inode *inode, blk_t block, int action);
 173 int             ext2_sync                       (struct ext2_fs *fs);
 174 int             ext2_write_blocks               (struct ext2_fs *fs, void *ptr, blk_t block, blk_t numblocks);
 175 int             ext2_write_inode                (struct ext2_fs *fs, ino_t inode, const struct ext2_inode *inodep);
 176 int             ext2_zero_blocks                (struct ext2_fs *fs, blk_t block, blk_t num);
 177 int             ext2_zero_inode                 (struct ext2_fs *fs, ino_t inode);
 178 
 179 /* block related */
 180 void            ext2_bgbitmap_cache_deinit      (struct ext2_fs *fs);
 181 int             ext2_bgbitmap_cache_flush       (struct ext2_fs *fs);
 182 int             ext2_bgbitmap_cache_init        (struct ext2_fs *fs);
 183 int             ext2_get_block_state            (struct ext2_fs *, blk_t block);
 184 int             ext2_set_block_state            (struct ext2_fs *, blk_t block, int state, int updatemetadata);
 185 
 186 /* block relocator */
 187 int             ext2_block_relocate             (struct ext2_fs *fs, blk_t newsize);
 188 
 189 /* buffer */
 190 void            ext2_bcache_deinit              (struct ext2_fs *fs);
 191 void            ext2_bcache_dump                (struct ext2_fs *fs);
 192 int             ext2_bcache_flush               (struct ext2_fs *fs, blk_t block);
 193 int             ext2_bcache_flush_range         (struct ext2_fs *fs, blk_t first, blk_t last);
 194 int             ext2_bcache_init                (struct ext2_fs *fs);
 195 int             ext2_bcache_sync                (struct ext2_fs *fs);
 196 struct ext2_buffer_head *ext2_bcreate           (struct ext2_fs *fs, blk_t block);
 197 struct ext2_buffer_head *ext2_bread             (struct ext2_fs *fs, blk_t block);
 198 int             ext2_brelse                     (struct ext2_buffer_head *bh, int forget);
 199 
 200 /* inode relocator */
 201 int             ext2_inode_relocate             (struct ext2_fs *fs, int newgroups);
 202 
 203 /* journalling */
 204 void            ext2_journal_deinit             (struct ext2_fs *fs);
 205 int             ext2_journal_init               (struct ext2_fs *fs);
 206 
 207 /* metadata mover */
 208 int             ext2_metadata_push              (struct ext2_fs *fs, blk_t newsize);
 209 
 210 /* fs creation */
 211 struct ext2_fs *ext2_mkfs                       (struct ext2_dev_handle *handle, blk_t numblocks, int log_block_size, blk_t blocks_per_group, int inodes_per_group, int sparse_sb, int reserved_block_percentage, PedTimer* timer);
 212 
 213 /* resize */
 214 int             ext2_resize_fs                  (struct ext2_fs *fs, blk_t newsize, PedTimer* timer);
 215 
 216 /* unix I/O */
 217 struct ext2_dev_handle *ext2_make_dev_handle_from_file(char *dev);
 218 
 219 
 220 
 221 
 222 static __inline__ int ext2_is_data_block(struct ext2_fs *fs, blk_t block)
 223 {
 224         blk_t blk;
 225         int   group;
 226 
 227         PED_ASSERT (block >= EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb), return 0);
 228         PED_ASSERT (block < EXT2_SUPER_BLOCKS_COUNT(fs->sb), return 0);
 229 
 230         blk = block - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
 231 
 232         group = blk / EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
 233         blk %= EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
 234 
 235         if (ext2_is_group_sparse(fs, group) && blk <= fs->gdblocks)
 236                 return 0;
 237 
 238         if (block == EXT2_GROUP_BLOCK_BITMAP(fs->gd[group]) ||
 239             block == EXT2_GROUP_INODE_BITMAP(fs->gd[group]))
 240                 return 0;
 241 
 242         if (block >= EXT2_GROUP_INODE_TABLE(fs->gd[group]) &&
 243             block < EXT2_GROUP_INODE_TABLE(fs->gd[group]) + fs->inodeblocks)
 244                 return 0;
 245 
 246         return 1;
 247 }
 248 
 249 #endif