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/statvfs.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "lib/lib.h"
|
#include "lib/lib.h"
|
||||||
|
78
toys/e2fs.h
78
toys/e2fs.h
@ -9,33 +9,7 @@
|
|||||||
|
|
||||||
#define EXT2_SUPER_MAGIC 0xEF53
|
#define EXT2_SUPER_MAGIC 0xEF53
|
||||||
|
|
||||||
struct ext2_inode {
|
struct ext2_superblock {
|
||||||
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 {
|
|
||||||
uint32_t inodes_count; // Inodes count
|
uint32_t inodes_count; // Inodes count
|
||||||
uint32_t blocks_count; // Blocks count
|
uint32_t blocks_count; // Blocks count
|
||||||
uint32_t r_blocks_count; // Reserved 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 first_data_block; // First Data Block
|
||||||
uint32_t log_block_size; // Block size
|
uint32_t log_block_size; // Block size
|
||||||
uint32_t log_frag_size; // Fragment size
|
uint32_t log_frag_size; // Fragment size
|
||||||
uint32_t blocks_per_group; // # Blocks per group
|
uint32_t blocks_per_group; // Blocks per group
|
||||||
uint32_t frags_per_group; // # Fragments per group
|
uint32_t frags_per_group; // Fragments per group
|
||||||
uint32_t inodes_per_group; // # Inodes per group
|
uint32_t inodes_per_group; // Inodes per group
|
||||||
uint32_t mtime; // Mount time
|
uint32_t mtime; // Mount time
|
||||||
uint32_t wtime; // Write time
|
uint32_t wtime; // Write time
|
||||||
uint16_t mnt_count; // Mount count
|
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
|
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_DIR_PREALLOC 0x0001
|
||||||
#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
|
#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
|
||||||
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
|
#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
|
||||||
@ -109,14 +119,6 @@ struct ext2_super_block {
|
|||||||
|
|
||||||
#define EXT2_NAME_LEN 255
|
#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
|
// Ext2 directory file types. Only the low 3 bits are used. The
|
||||||
// other bits are reserved for now.
|
// other bits are reserved for now.
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "toys.h"
|
#include "toys.h"
|
||||||
|
|
||||||
|
#define TT toy.mke2fs
|
||||||
|
|
||||||
// b - block size (1024, 2048, 4096)
|
// b - block size (1024, 2048, 4096)
|
||||||
// F - force (run on mounted device or non-block device)
|
// F - force (run on mounted device or non-block device)
|
||||||
// i - bytes per inode
|
// i - bytes per inode
|
||||||
@ -54,39 +56,76 @@ void create_uuid(char *uuid)
|
|||||||
|
|
||||||
int mke2fs_main(void)
|
int mke2fs_main(void)
|
||||||
{
|
{
|
||||||
struct ext2_super_block *sb = xzalloc(sizeof(struct ext2_super_block));
|
struct ext2_superblock *sb = xzalloc(sizeof(struct ext2_superblock));
|
||||||
int temp;
|
uint32_t temp;
|
||||||
off_t length;
|
off_t length;
|
||||||
|
|
||||||
// Handle command line arguments.
|
// Handle command line arguments.
|
||||||
|
|
||||||
if (toys.optargs[1]) {
|
if (toys.optargs[1]) {
|
||||||
sscanf(toys.optargs[1], "%u", &(sb->inodes_count));
|
sscanf(toys.optargs[1], "%u", &TT.blocks);
|
||||||
temp = O_RDWR|O_CREAT;
|
temp = O_RDWR|O_CREAT;
|
||||||
} else temp = O_RDWR;
|
} 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.
|
// 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
|
// TODO: collect gene2fs list, calculate requirements.
|
||||||
&& 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;
|
|
||||||
|
|
||||||
// Fill out superblock structure
|
// 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->rev_level = SWAP_LE32(1);
|
||||||
|
sb->inode_size = sizeof(struct ext2_inode);
|
||||||
sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE);
|
sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE);
|
||||||
sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);
|
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 we're called as mke3fs or mkfs.ext3, do a journal.
|
||||||
|
|
||||||
//if (strchr(toys.which->name,'3'))
|
//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
|
// We skip the first 1k (to avoid the boot sector, if any). Use this to
|
||||||
// figure out if this file is seekable.
|
// figure out if this file is seekable.
|
||||||
if(-1 == lseek(toy.mke2fs.fsfd, 1024, SEEK_SET)) perror_exit("lseek");
|
if(-1 == lseek(TT.fsfd, 1024, SEEK_SET)) perror_exit("lseek");
|
||||||
//{ toy.mke2fs.noseek=1; xwrite(toy.mke2fs.fsfd, sb, 1024); }
|
//{ TT.noseek=1; xwrite(TT.fsfd, sb, 1024); }
|
||||||
|
|
||||||
// Write superblock to disk.
|
// Write superblock to disk.
|
||||||
xwrite(toy.mke2fs.fsfd, sb, 3072); // 4096-1024
|
xwrite(TT.fsfd, sb, sizeof(struct ext2_superblock)); // 4096-1024
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ struct mke2fs_data {
|
|||||||
long inodes;
|
long inodes;
|
||||||
long reserved_percent;
|
long reserved_percent;
|
||||||
|
|
||||||
|
unsigned blocks, groups;
|
||||||
int fsfd, noseek;
|
int fsfd, noseek;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user