More work on mke2fs.
This commit is contained in:
parent
e2580dbebb
commit
6b7092fd08
1
toys.h
1
toys.h
@ -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"
|
||||
|
78
toys/e2fs.h
78
toys/e2fs.h
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ struct mke2fs_data {
|
||||
long inodes;
|
||||
long reserved_percent;
|
||||
|
||||
unsigned blocks, groups;
|
||||
int fsfd, noseek;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user