ext2_mkfs.c revision 7e7bd3dccbfe8f79e25e5c1554b5bc3a9aaca321
/*
ext2_mkfs.c -- ext2 fs creator
Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#ifndef DISCOVER_ONLY
#define USE_EXT2_IS_DATA_BLOCK
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "ext2.h"
/* formula grabbed from linux ext2 kernel source
*
* returns 1 iff:
* x == y^N, N is some natural number
* OR x == 0
*/
static __inline__ int is_root(int x, int y)
{
if (!x) return 1;
while (1)
{
if (x == 1) return 1;
if (x % y) return 0;
x /= y;
}
}
{
if (!sparsesbfs)
return 1;
return 1;
return 0;
}
/* has implicit parameter 'sb' !! */
struct ext2_super_block *sb,
struct ext2_group_desc *gd)
{
int freeit;
int i;
int numgroups;
int gdblocks;
unsigned char *sbbuf;
struct ext2_super_block *sb_for_io;
freeit = 0;
if (EXT2_SUPER_LOG_BLOCK_SIZE(*sb))
{
return 0;
freeit = 1;
}
for (i=0;i<numgroups;i++)
{
if (is_sparse(i))
{
int offset;
+ i * EXT2_SUPER_BLOCKS_PER_GROUP(*sb);
offset, 1))
return 0;
gdblocks))
return 0;
}
}
sb_for_io->s_block_group_nr = 0;
if (freeit)
return 1;
}
struct ext2_super_block *sb,
struct ext2_group_desc *gd,
{
int blocksize;
int gdtsize;
int i;
int itsize;
int numgroups;
unsigned char *bb;
unsigned char *ib;
unsigned char *zero;
if (!ib) goto error_free_bb;
if (!zero) goto error_free_zero;
for (i=0;i<numgroups;i++)
{
int admin;
int groupsize;
int groupoffset;
int j;
if (is_sparse(i))
{
}
{
if (is_sparse(i))
for (j=0;j<gdtsize+1;j++)
j = bbblock - groupoffset;
j = ibblock - groupoffset;
for (j=0;j<itsize;j++)
{
int k = j + gdtsize + 3;
}
goto error_free_zero;
}
{
goto error_free_zero;
}
goto error_free_zero;
+ 3);
gd[i].bg_used_dirs_count = 0;
gd[i].bg_used_dirs_count = 0;
gd[i].bg_reserved[0] = 0;
+ EXT2_GROUP_FREE_BLOCKS_COUNT(gd[i]));
}
return 1;
return 0;
}
/* returns the offset into the buffer of the start of the next dir entry */
{
int rec_len;
if (is_last)
else
}
{
struct ext2_buffer_head *bh;
int i;
struct ext2_inode inode;
int offset;
for (i=0;i<12;i++)
{
return 0;
return 0;
}
/* create the directory entries, preallocating lots of blocks */
/* first block contains . and .. */
if (!bh)
return 0;
/* subsequent blocks are empty */
data[0] = 0;
for (i=1;i<12;i++)
{
}
/* create inode */
for (i=0;i<12;i++)
return 0;
return 1;
}
{
struct ext2_buffer_head *bh;
struct ext2_inode inode;
int offset;
return 0;
return 0;
/* create directory entries */
return 0;
/* create inode */
return 0;
return 1;
}
{
int i;
for (i=1;i<12;i++)
return 0;
return 1;
}
int numgroups, int first_block,
int inodes_per_group, int sparse_sb,
{
/* catch a bug in gcc 2.95.2 */
PED_ASSERT(numgroups != 0, return 0);
* reserved_block_percentage) / 100);
/* hack: this get's inc'd as we go through each group in
* ext2_mkfs_write_meta()
*/
sb->s_free_blocks_count = 0;
* inodes_per_group);
sb->s_mnt_count = 0;
sb->s_minor_rev_level = 0;
sb->s_lastcheck = 0;
sb->s_checkinterval = 0;
sb->s_creator_os = 0;
sb->s_def_resuid = 0;
sb->s_def_resgid = 0;
sb->s_block_group_nr = 0;
sb->s_feature_compat = 0;
sb->s_feature_incompat = 0;
sb->s_feature_ro_compat = 0;
if (sparse_sb)
/* FIXME: let the user decide? _set_dirent() assumes FILETYPE */
sb->s_algorithm_usage_bitmap = 0;
sb->s_prealloc_blocks = 0;
sb->s_prealloc_dir_blocks = 0;
sb->s_padding1 = 0;
return 1;
}
/* Given these five inputs, compute the three outputs. */
static void
int *last_group_blocks,
int *last_group_admin,
int *inodes_per_group)
{
if (!*last_group_blocks)
/ sizeof(struct ext2_inode)));
/ block_size);
*last_group_admin +=
block_size));
}
}
int log_block_size,
int inodes_per_group,
int sparse_sb,
{
struct ext2_super_block sb;
struct ext2_group_desc *gd;
int numgroups;
int first_block;
int last_group_blocks;
int last_group_admin;
/* if the FS is > 512Mb, use 4k blocks, otherwise 1k blocks */
if (log_block_size == 0) {
log_block_size = 12;
else
log_block_size = 10;
}
/* FIXME: block size must be > MAX(logicalbs, physicalbs)
* to avoid modify-on-write.
* -- Leslie
*/
if (numblocks == 0)
if (numblocks == 0)
goto diagnose_fs_too_small;
if (blocks_per_group == (unsigned int) 0)
if (sparse_sb == -1)
sparse_sb = 1;
/* FIXME: 5% not appropriate for modern drive sizes */
if (reserved_block_percentage == -1)
int fs_too_small = 0;
{
numgroups--;
if (numgroups == 0)
fs_too_small = 1;
else
{
}
}
if (numgroups == 1
|| inodes_per_group < 16
/* This final term ensures that we detect
mkpartfs primary ext2 10KB 27650B as invalid. */
|| (inodes_per_group == 16
fs_too_small = 1;
if (fs_too_small) {
_("File system too small for ext2."));
goto error;
}
+ (1 << log_block_size));
if (!gd)
goto error;
goto error_free_gd;
goto error_free_gd;
goto error_free_gd;
if (!fs) goto error_close_fs;
goto error_close_fs;
return fs;
ext2_close(fs);
return NULL;
}
#endif /* !DISCOVER_ONLY */