More work on mke2fs.

This commit is contained in:
Rob Landley 2007-01-23 19:54:01 -05:00
parent e2580dbebb
commit 6b7092fd08
4 changed files with 99 additions and 56 deletions

1
toys.h
View File

@ -26,6 +26,7 @@
#include <sys/statvfs.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "lib/lib.h"

View File

@ -9,33 +9,7 @@
#define EXT2_SUPER_MAGIC 0xEF53
struct ext2_inode {
uint16_t mode; // File mode
uint16_t uid; // Low 16 bits of Owner Uid
uint32_t size; // Size in bytes
uint32_t atime; // Access time
uint32_t ctime; // Creation time
uint32_t mtime; // Modification time
uint32_t dtime; // Deletion Time
uint16_t gid; // Low 16 bits of Group Id
uint16_t links_count; // Links count
uint32_t blocks; // Blocks count
uint32_t flags; // File flags
uint32_t reserved1;
uint32_t block[15]; // Pointers to blocks
uint32_t generation; // File version (for NFS)
uint32_t file_acl; // File ACL
uint32_t dir_acl; // Directory ACL
uint32_t faddr; // Fragment address
uint8_t frag; // Fragment number
uint8_t fsize; // Fragment size
uint16_t pad1;
uint16_t uid_high; // High bits of uid
uint16_t gid_high; // High bits of gid
uint32_t reserved2;
};
struct ext2_super_block {
struct ext2_superblock {
uint32_t inodes_count; // Inodes count
uint32_t blocks_count; // Blocks count
uint32_t r_blocks_count; // Reserved blocks count
@ -44,9 +18,9 @@ struct ext2_super_block {
uint32_t first_data_block; // First Data Block
uint32_t log_block_size; // Block size
uint32_t log_frag_size; // Fragment size
uint32_t blocks_per_group; // # Blocks per group
uint32_t frags_per_group; // # Fragments per group
uint32_t inodes_per_group; // # Inodes per group
uint32_t blocks_per_group; // Blocks per group
uint32_t frags_per_group; // Fragments per group
uint32_t inodes_per_group; // Inodes per group
uint32_t mtime; // Mount time
uint32_t wtime; // Write time
uint16_t mnt_count; // Mount count
@ -90,6 +64,42 @@ struct ext2_super_block {
uint32_t reserved[172]; // Padding to the end of the block
};
struct ext2_dentry {
uint32_t inode; // Inode number
uint16_t rec_len; // Directory entry length
uint8_t name_len; // Name length
uint8_t file_type;
char name[255]; // File name
};
struct ext2_inode {
uint16_t mode; // File mode
uint16_t uid; // Low 16 bits of Owner Uid
uint32_t size; // Size in bytes
uint32_t atime; // Access time
uint32_t ctime; // Creation time
uint32_t mtime; // Modification time
uint32_t dtime; // Deletion Time
uint16_t gid; // Low 16 bits of Group Id
uint16_t links_count; // Links count
uint32_t blocks; // Blocks count
uint32_t flags; // File flags
uint32_t reserved1;
uint32_t block[15]; // Pointers to blocks
uint32_t generation; // File version (for NFS)
uint32_t file_acl; // File ACL
uint32_t dir_acl; // Directory ACL
uint32_t faddr; // Fragment address
uint8_t frag; // Fragment number
uint8_t fsize; // Fragment size
uint16_t pad1;
uint16_t uid_high; // High bits of uid
uint16_t gid_high; // High bits of gid
uint32_t reserved2;
};
#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
@ -109,14 +119,6 @@ struct ext2_super_block {
#define EXT2_NAME_LEN 255
struct ext2_dentry {
uint32_t inode; // Inode number
uint16_t rec_len; // Directory entry length
uint8_t name_len; // Name length
uint8_t file_type;
char name[255]; // File name
};
// Ext2 directory file types. Only the low 3 bits are used. The
// other bits are reserved for now.

View File

@ -7,6 +7,8 @@
#include "toys.h"
#define TT toy.mke2fs
// b - block size (1024, 2048, 4096)
// F - force (run on mounted device or non-block device)
// i - bytes per inode
@ -54,39 +56,76 @@ void create_uuid(char *uuid)
int mke2fs_main(void)
{
struct ext2_super_block *sb = xzalloc(sizeof(struct ext2_super_block));
int temp;
struct ext2_superblock *sb = xzalloc(sizeof(struct ext2_superblock));
uint32_t temp;
off_t length;
// Handle command line arguments.
if (toys.optargs[1]) {
sscanf(toys.optargs[1], "%u", &(sb->inodes_count));
sscanf(toys.optargs[1], "%u", &TT.blocks);
temp = O_RDWR|O_CREAT;
} else temp = O_RDWR;
// Check if filesystem is mounted
// TODO: Check if filesystem is mounted here
// For mke?fs, open file. For gene?fs, create file.
length = fdlength(toy.mke2fs.fsfd = xcreate(*toys.optargs, temp, 0777));
length = fdlength(TT.fsfd = xcreate(*toys.optargs, temp, 0777));
if (toy.mke2fs.blocksize && toy.mke2fs.blocksize!=1024
&& toy.mke2fs.blocksize!=2048 && toy.mke2fs.blocksize!=4096)
error_exit("bad blocksize");
// Determine block size. If unspecified, use simple heuristic.
if (toy.mke2fs.blocksize)
sb->log_block_size = (length && length < 1<<24) ? 1024 : 4096;
else sb->log_block_size = toy.mke2fs.blocksize;
if (!sb->inodes_count) sb->inodes_count = length/toy.mke2fs.blocksize;
// TODO: collect gene2fs list, calculate requirements.
// Fill out superblock structure
// Determine appropriate block size, set log_block_size and log_frag_size.
if (!TT.blocksize) TT.blocksize = (length && length < 1<<29) ? 1024 : 4096;
if (TT.blocksize == 1024) temp = 0;
else if (TT.blocksize == 2048) temp = 1;
else if (TT.blocksize == 4096) temp = 2;
else error_exit("bad blocksize");
sb->log_block_size = sb->log_frag_size = SWAP_LE32(temp);
// Fill out blocks_count, inodes_count, r_blocks_count
if (!TT.blocks) TT.blocks = length/TT.blocksize;
sb->blocks_count = SWAP_LE32(TT.blocks);
if (!TT.inodes) {
if (!TT.bytes_per_inode) TT.bytes_per_inode = 8192;
TT.inodes = (TT.blocks * (uint64_t)TT.blocksize) / TT.bytes_per_inode;
}
sb->inodes_count = SWAP_LE32(TT.inodes);
if (!TT.reserved_percent) TT.reserved_percent = 5;
temp = (TT.blocks * (uint64_t)TT.reserved_percent) /100;
sb->r_blocks_count = SWAP_LE32(temp);
// Set blocks_per_group and frags_per_group, which is the size of an
// allocation bitmap that fits in one block (I.E. how many bits per block)?
temp = TT.blocksize*8;
sb->blocks_per_group = sb->frags_per_group = SWAP_LE32(temp);
// Set inodes_per_group
TT.groups = (TT.blocks)/temp;
if (TT.blocks & (temp-1)) TT.groups++; // Round up without int overflow.
temp = TT.inodes/TT.groups;
if (TT.blocks & (TT.groups-1)) TT.blocks++;
sb->inodes_per_group = SWAP_LE32(temp);
sb->max_mnt_count=0xFFFF;
sb->wtime = sb->lastcheck = sb->mkfs_time = SWAP_LE32(time(NULL));
sb->magic = SWAP_LE32(0xEF53);
sb->state = sb->errors = SWAP_LE16(1);
sb->rev_level = SWAP_LE32(1);
sb->inode_size = sizeof(struct ext2_inode);
sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE);
sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);
create_uuid(sb->uuid);
// If we're called as mke3fs or mkfs.ext3, do a journal.
//if (strchr(toys.which->name,'3'))
@ -94,11 +133,11 @@ int mke2fs_main(void)
// We skip the first 1k (to avoid the boot sector, if any). Use this to
// figure out if this file is seekable.
if(-1 == lseek(toy.mke2fs.fsfd, 1024, SEEK_SET)) perror_exit("lseek");
//{ toy.mke2fs.noseek=1; xwrite(toy.mke2fs.fsfd, sb, 1024); }
if(-1 == lseek(TT.fsfd, 1024, SEEK_SET)) perror_exit("lseek");
//{ TT.noseek=1; xwrite(TT.fsfd, sb, 1024); }
// Write superblock to disk.
xwrite(toy.mke2fs.fsfd, sb, 3072); // 4096-1024
xwrite(TT.fsfd, sb, sizeof(struct ext2_superblock)); // 4096-1024
return 0;
}

View File

@ -32,6 +32,7 @@ struct mke2fs_data {
long inodes;
long reserved_percent;
unsigned blocks, groups;
int fsfd, noseek;
};