ReactOS  0.4.13-dev-259-g5ca9c9c
Memory.c
Go to the documentation of this file.
1 /*
2  * PROJECT: Mke2fs
3  * FILE: Memory.c
4  * PROGRAMMER: Matt Wu <mattwu@163.com>
5  * HOMEPAGE: http://ext2.yeah.net
6  */
7 
8 /* INCLUDES **************************************************************/
9 
10 #include "Mke2fs.h"
11 #include <debug.h>
12 
13 /* DEFINITIONS ***********************************************************/
14 
15 extern char *device_name;
16 
17 /* FUNCTIONS *************************************************************/
18 
19 
20 /*
21  * Return the group # of an inode number
22  */
24 {
25  return (ino - 1) / fs->ext2_sb->s_inodes_per_group;
26 }
27 
28 /*
29  * Return the group # of a block
30  */
32 {
33  return (blk - fs->ext2_sb->s_first_data_block) /
34  fs->ext2_sb->s_blocks_per_group;
35 }
36 
38  int inuse, int isdir)
39 {
40  int group = ext2_group_of_ino(fs, ino);
41 
42  if (inuse > 0)
43  ext2_mark_inode_bitmap(fs->inode_map, ino);
44  else
45  ext2_unmark_inode_bitmap(fs->inode_map, ino);
46 
47  fs->group_desc[group].bg_free_inodes_count -= inuse;
48 
49  if (isdir)
50  fs->group_desc[group].bg_used_dirs_count += inuse;
51 
52  fs->ext2_sb->s_free_inodes_count -= inuse;
53 }
54 
55 
57 {
58  ext2_inode_alloc_stats2(fs, ino, inuse, 0);
59 }
60 
62 {
63  int group = ext2_group_of_blk(fs, blk);
64 
65  if (inuse > 0)
66  ext2_mark_block_bitmap(fs->block_map, blk);
67  else
68  ext2_unmark_block_bitmap(fs->block_map, blk);
69 
70  fs->group_desc[group].bg_free_blocks_count -= inuse;
71  fs->ext2_sb->s_free_blocks_count -= inuse;
72 }
73 
74 
76 {
77  bool retval;
78  ULONG i;
79 
80  for (i = 0; i < Ext2Sys->group_desc_count; i++)
81  {
82  retval = ext2_allocate_group_table(Ext2Sys, i, Ext2Sys->block_map);
83 
84  if (!retval)
85  return retval;
86  }
87 
88  return true;
89 }
90 
91 
94 {
95  bool retval;
96  ULONG group_blk, start_blk, last_blk, new_blk, blk, j;
97 
98  group_blk = fs->ext2_sb->s_first_data_block +
99  (group * fs->ext2_sb->s_blocks_per_group);
100 
101  last_blk = group_blk + fs->ext2_sb->s_blocks_per_group;
102  if (last_blk >= fs->ext2_sb->s_blocks_count)
103  last_blk = fs->ext2_sb->s_blocks_count - 1;
104 
105  start_blk = group_blk + 3 + fs->desc_blocks;
106  if (start_blk > last_blk)
107  start_blk = group_blk;
108 
109  if (!bmap)
110  bmap = fs->block_map;
111 
112  /*
113  * Allocate the inode table
114  */
115  if (!fs->group_desc[group].bg_inode_table)
116  {
117  retval = ext2_get_free_blocks(fs, start_blk, last_blk,
118  fs->inode_blocks_per_group,
119  bmap, &new_blk);
120  if (!retval)
121  return retval;
122 
123  for (j=0, blk = new_blk;
124  j < fs->inode_blocks_per_group;
125  j++, blk++)
127 
128  fs->group_desc[group].bg_inode_table = new_blk;
129  }
130 
131  /*
132  * Allocate the block and inode bitmaps, if necessary
133  */
134  if (fs->stride)
135  {
136  start_blk += fs->inode_blocks_per_group;
137  start_blk += ((fs->stride * group) %
138  (last_blk - start_blk));
139  if (start_blk > last_blk)
140  /* should never happen */
141  start_blk = group_blk;
142  }
143  else
144  {
145  start_blk = group_blk;
146  }
147 
148  if (!fs->group_desc[group].bg_block_bitmap)
149  {
150  retval = ext2_get_free_blocks(fs, start_blk, last_blk,
151  1, bmap, &new_blk);
152 
153  if (!retval)
154  retval = ext2_get_free_blocks(fs, group_blk,
155  last_blk, 1, bmap, &new_blk);
156 
157  if (!retval)
158  return retval;
159 
160  ext2_mark_block_bitmap(bmap, new_blk);
161  fs->group_desc[group].bg_block_bitmap = new_blk;
162  }
163 
164  if (!fs->group_desc[group].bg_inode_bitmap)
165  {
166  retval = ext2_get_free_blocks(fs, start_blk, last_blk,
167  1, bmap, &new_blk);
168  if (!retval)
169  retval = ext2_get_free_blocks(fs, group_blk,
170  last_blk, 1, bmap, &new_blk);
171  if (!retval)
172  return retval;
173 
174  ext2_mark_block_bitmap(bmap, new_blk);
175  fs->group_desc[group].bg_inode_bitmap = new_blk;
176  }
177 
178  return true;
179 }
180 
181 
184 {
185  ULONG b = start;
186 
187  if (!map)
188  map = fs->block_map;
189 
190  if (!map)
191  return false;
192 
193  if (!b)
194  b = fs->ext2_sb->s_first_data_block;
195 
196  if (!finish)
197  finish = start;
198 
199  if (!num)
200  num = 1;
201 
202  do
203  {
204  if (b+num-1 > fs->ext2_sb->s_blocks_count)
205  b = fs->ext2_sb->s_first_data_block;
206 
208  {
209  *ret = b;
210  return true;
211  }
212 
213  b++;
214 
215  } while (b != finish);
216 
217  return false;
218 }
219 
220 
222 {
223  bool retval;
224  ULONG blk, num;
225  int i;
226 
227  for (i = 0; (ULONG)i < fs->group_desc_count; i++)
228  {
229  blk = fs->group_desc[i].bg_inode_table;
230  num = fs->inode_blocks_per_group;
231 
232  retval = zero_blocks(fs, blk, num, &blk, &num);
233  if (!retval)
234  {
235  DPRINT1("\nMke2fs: Could not write %lu blocks "
236  "in inode table starting at %lu.\n",
237  num, blk);
238 
239  zero_blocks(0, 0, 0, 0, 0);
240  return false;
241  }
242  }
243 
244  zero_blocks(0, 0, 0, 0, 0);
245 
246  return true;
247 }
248 
249 
250 /*
251  * Stupid algorithm --- we now just search forward starting from the
252  * goal. Should put in a smarter one someday....
253  */
256 {
257  ULONG i;
258 
259  if (!map)
260  map = fs->block_map;
261 
262  if (!map)
263  return false;
264 
265  if (!goal || (goal >= fs->ext2_sb->s_blocks_count))
266  goal = fs->ext2_sb->s_first_data_block;
267 
268  i = goal;
269 
270  do
271  {
273  {
274  *ret = i;
275  return true;
276  }
277 
278  i++;
279 
280  if (i >= fs->ext2_sb->s_blocks_count)
281  i = fs->ext2_sb->s_first_data_block;
282 
283  } while (i != goal);
284 
285  return false;
286 }
287 
288 
289 /*
290  * This function zeros out the allocated block, and updates all of the
291  * appropriate filesystem records.
292  */
294 {
295  bool retval;
296  ULONG block;
297  char *buf = NULL;
298 
299  buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, fs->blocksize);
300  if (!buf)
301  return false;
302 
303  if (!fs->block_map)
304  {
305  retval = ext2_read_block_bitmap(fs);
306  if (!retval)
307  goto fail;
308  }
309 
310  retval = ext2_new_block(fs, goal, 0, &block);
311 
312  if (!retval)
313  goto fail;
314 
315  retval = NT_SUCCESS(Ext2WriteDisk(
316  fs,
317  ((LONGLONG)block * fs->blocksize),
318  fs->blocksize, (unsigned char *)buf));
319 
320  if (!retval)
321  {
322  goto fail;
323  }
324 
326  *ret = block;
327 
328  if (buf)
329  {
330  RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
331  }
332 
333  return true;
334 
335 fail:
336 
337  if (buf)
338  {
339  RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
340  }
341 
342  return false;
343 }
344 
345 
346 /*
347  * Create new directory block
348  */
350  ULONG parent_ino, char **block)
351 {
353  char *buf;
354  int rec_len;
355  int filetype = 0;
356 
357  buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, fs->blocksize);
358  if (!buf)
359  return false;
360 
361  dir = (PEXT2_DIR_ENTRY) buf;
362  dir->rec_len = fs->blocksize;
363 
364  if (dir_ino)
365  {
366  if (fs->ext2_sb->s_feature_incompat &
368  filetype = EXT2_FT_DIR << 8;
369  /*
370  * Set up entry for '.'
371  */
372  dir->inode = dir_ino;
373  dir->name_len = 1 | filetype;
374  dir->name[0] = '.';
375  rec_len = dir->rec_len - EXT2_DIR_REC_LEN(1);
376  dir->rec_len = EXT2_DIR_REC_LEN(1);
377 
378  /*
379  * Set up entry for '..'
380  */
381  dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
382  dir->rec_len = rec_len;
383  dir->inode = parent_ino;
384  dir->name_len = 2 | filetype;
385  dir->name[0] = '.';
386  dir->name[1] = '.';
387  }
388 
389  *block = buf;
390 
391  return true;
392 }
393 
395 {
396  bool retval = false;
397 
398  retval = NT_SUCCESS(Ext2WriteDisk(
399  fs,
400  ((ULONGLONG)block * fs->blocksize),
401  fs->blocksize, (unsigned char *)inbuf));
402 
403  return retval;
404 }
405 
407 {
408  bool retval = false;
409 
410  retval = NT_SUCCESS(Ext2ReadDisk(
411  fs,
412  ((ULONGLONG)block * fs->blocksize),
413  fs->blocksize, (unsigned char *)inbuf));
414 
415  return retval;
416 }
static unsigned int block
Definition: xmlmemory.c:118
int ext2_group_of_blk(PEXT2_FILESYS fs, ULONG blk)
Definition: Memory.c:31
__u16 rec_len
Definition: ext2_fs.h:494
char * device_name
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
NTSTATUS Ext2WriteDisk(PEXT2_FILESYS Ext2Sys, ULONGLONG Offset, ULONG Length, PVOID Buffer)
Definition: Disk.c:1059
ULONG group_desc_count
Definition: Mke2fs.h:156
void ext2_inode_alloc_stats2(PEXT2_FILESYS fs, ULONG ino, int inuse, int isdir)
Definition: Memory.c:37
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
NTSTATUS Ext2ReadDisk(IN PEXT2_VCB Vcb, IN ULONGLONG Offset, IN ULONG Size, IN PVOID Buffer, IN BOOLEAN bVerify)
Definition: block.c:539
bool ext2_get_free_blocks(PEXT2_FILESYS fs, ULONG start, ULONG finish, int num, PEXT2_BLOCK_BITMAP map, ULONG *ret)
Definition: Memory.c:182
bool ext2_read_block(PEXT2_FILESYS fs, ULONG block, void *inbuf)
Definition: Memory.c:406
#define EXT2_DIR_REC_LEN(name_len)
Definition: ext2_fs.h:536
Definition: fs.h:235
void ext2_block_alloc_stats(PEXT2_FILESYS fs, ULONG blk, int inuse)
Definition: Memory.c:61
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
bool ext2_test_block_bitmap(PEXT2_BLOCK_BITMAP bitmap, ULONG block)
Definition: Bitmap.c:73
Definition: ext2_fs.h:492
smooth NULL
Definition: ftsmooth.c:416
unsigned int dir
Definition: maze.c:112
bool ext2_allocate_tables(PEXT2_FILESYS Ext2Sys)
Definition: Memory.c:75
#define b
Definition: ke_i.h:79
#define EXT2_FEATURE_INCOMPAT_FILETYPE
Definition: ext2_fs.h:471
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
GLboolean GLuint group
Definition: glext.h:11120
int64_t LONGLONG
Definition: typedefs.h:66
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
bool ext2_allocate_group_table(PEXT2_FILESYS fs, ULONG group, PEXT2_BLOCK_BITMAP bmap)
Definition: Memory.c:92
struct ext2_dirent * PEXT2_DIR_ENTRY
Definition: ext2.h:174
GLuint GLuint num
Definition: glext.h:9618
Definition: _map.h:44
uchar inbuf[M_BLOCK]
Definition: unzcrash.c:40
int ret
#define ext2_unmark_inode_bitmap
Definition: Mke2fs.h:218
ULONGLONG bmap(struct inode *i, ULONGLONG b)
Definition: linux.c:934
#define blk
Definition: linetest.c:70
#define ext2_mark_inode_bitmap
Definition: Mke2fs.h:216
bool ext2_test_block_bitmap_range(PEXT2_BLOCK_BITMAP bitmap, ULONG block, int num)
Definition: Bitmap.c:80
bool zero_blocks(PEXT2_FILESYS fs, ULONG blk, ULONG num, ULONG *ret_blk, ULONG *ret_count)
Definition: Mke2fs.c:122
#define ext2_unmark_block_bitmap
Definition: Mke2fs.h:217
bool ext2_new_block(PEXT2_FILESYS fs, ULONG goal, PEXT2_BLOCK_BITMAP map, ULONG *ret)
Definition: Memory.c:254
GLuint start
Definition: gl.h:1545
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
LOCAL char * filetype(int t)
Definition: tree.c:114
bool ext2_write_block(PEXT2_FILESYS fs, ULONG block, void *inbuf)
Definition: Memory.c:394
bool ext2_new_dir_block(PEXT2_FILESYS fs, ULONG dir_ino, ULONG parent_ino, char **block)
Definition: Memory.c:349
void ext2_inode_alloc_stats(PEXT2_FILESYS fs, ULONG ino, int inuse)
Definition: Memory.c:56
bool ext2_read_block_bitmap(PEXT2_FILESYS fs)
Definition: Bitmap.c:487
#define ext2_mark_block_bitmap
Definition: Mke2fs.h:215
bool write_inode_tables(PEXT2_FILESYS fs)
Definition: Memory.c:221
bool ext2_alloc_block(PEXT2_FILESYS fs, ULONG goal, ULONG *ret)
Definition: Memory.c:293
int ext2_group_of_ino(PEXT2_FILESYS fs, ULONG ino)
Definition: Memory.c:23
PEXT2_BLOCK_BITMAP block_map
Definition: Mke2fs.h:162