aboutsummaryrefslogtreecommitdiff
path: root/toys/mke2fs.c
blob: 8266cec49ad5b02dfe2e4b3425b69d6388aef0ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* vi: set ts=4:
 *
 * mke2fs.c - Create an ext2 filesystem image.
 *
 * Copyright 2006 Rob Landley <rob@landley.net>
 */

#include "toys.h"

	// b - block size (1024, 2048, 4096)
	// F - force (run on mounted device or non-block device)
	// i - bytes per inode 
	// N - number of inodes
	// m - reserved blocks percentage
	// n - Don't write
	// q - quiet

	// L - volume label
	// M - last mounted path
	// o - creator os
	
	// j - create journal
	// J - journal options (size=1024-102400 blocks,device=)
	//        device=/dev/blah or LABEL=label UUID=uuid

	// E - extended options (stride=stripe-size blocks)
	// O - none,dir_index,filetype,has_journal,journal_dev,sparse_super


// According to http://www.opengroup.org/onlinepubs/9629399/apdxa.htm
// we should generate a uuid structure by reading a clock with 100 nanosecond
// precision, normalizing it to the start of the gregorian calendar in 1582,
// and looking up our eth0 mac address.
//
// On the other hand, we have 128 bits to come up with a unique identifier, of
// which 6 have a defined value.  /dev/urandom it is.

void create_uuid(char *uuid)
{
	// Read 128 random bytes
	int fd = xopen("/dev/urandom", O_RDONLY);
	xreadall(fd, uuid, 16);
	close(fd);

	// Claim to be a DCE format UUID.
	uuid[6] = (uuid[6] & 0x0F) | 0x40;
	uuid[8] = (uuid[8] & 0x3F) | 0x80;

    // rfc2518 section 6.4.1 suggests if we're not using a macaddr, we should
	// set bit 1 of the node ID, which is the mac multicast bit.  This means we
	// should never collide with anybody actually using a macaddr.
	uuid[11] = uuid[11] | 128;
}

int mke2fs_main(void)
{
	struct ext2_super_block *sb = xzalloc(sizeof(struct ext2_super_block));
	int temp;
	off_t length;

	// Handle command line arguments.

	if (toys.optargs[1]) {
		sscanf(toys.optargs[1], "%u", &(sb->inodes_count));
		temp = O_RDWR|O_CREAT;
	} else temp = O_RDWR;

	// Check if filesystem is mounted

	// 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");

	// 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

	sb->rev_level = SWAP_LE32(1);
	sb->feature_incompat = SWAP_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE);
	sb->feature_ro_compat = SWAP_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);

	// If we're called as mke3fs or mkfs.ext3, do a journal.

	//if (strchr(toys.which->name,'3'))
	//	sb->feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;

	// 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); }

	// Write superblock to disk.	
	xwrite(toy.mke2fs.fsfd, sb, 3072); // 4096-1024

	return 0;
}