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