changeset 76:e6332139adae

More work on mke2fs.
author Rob Landley <rob@landley.net>
date Tue, 23 Jan 2007 19:54:01 -0500
parents 89ca591a9236
children 8018c40605d9
files toys.h toys/e2fs.h toys/mke2fs.c toys/toylist.h
diffstat 4 files changed, 99 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/toys.h	Tue Jan 23 13:20:38 2007 -0500
+++ b/toys.h	Tue Jan 23 19:54:01 2007 -0500
@@ -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"
--- a/toys/e2fs.h	Tue Jan 23 13:20:38 2007 -0500
+++ b/toys/e2fs.h	Tue Jan 23 19:54:01 2007 -0500
@@ -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 @@
 	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 @@
 	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 @@
 
 #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.
 
--- a/toys/mke2fs.c	Tue Jan 23 13:20:38 2007 -0500
+++ b/toys/mke2fs.c	Tue Jan 23 19:54:01 2007 -0500
@@ -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 @@
 
 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));
-
-	if (toy.mke2fs.blocksize && toy.mke2fs.blocksize!=1024
-		&& toy.mke2fs.blocksize!=2048 && toy.mke2fs.blocksize!=4096)
-			error_exit("bad blocksize");
+	length = fdlength(TT.fsfd = xcreate(*toys.optargs, temp, 0777));
 
-	// 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 @@
 
 	// 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;
 }
--- a/toys/toylist.h	Tue Jan 23 13:20:38 2007 -0500
+++ b/toys/toylist.h	Tue Jan 23 19:54:01 2007 -0500
@@ -32,6 +32,7 @@
 	long inodes;
 	long reserved_percent;
 
+	unsigned blocks, groups;
 	int fsfd, noseek;
 };