mkfs.c 4.8 KB
Newer Older
C
Chris Mason 已提交
1 2 3 4 5 6 7 8 9 10 11 12
#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "kerncompat.h"
#include "radix-tree.h"
#include "ctree.h"
#include "disk-io.h"

C
Chris Mason 已提交
13
int mkfs(int fd, u64 num_blocks, u32 blocksize)
14 15
{
	struct btrfs_super_block super;
C
Chris Mason 已提交
16
	struct btrfs_leaf *empty_leaf;
17 18 19 20 21
	struct btrfs_root_item root_item;
	struct btrfs_item item;
	struct btrfs_extent_item extent_item;
	char *block;
	int ret;
C
Chris Mason 已提交
22 23
	u32 itemoff;
	u32 start_block = BTRFS_SUPER_INFO_OFFSET / blocksize;
24

C
Chris Mason 已提交
25 26
	btrfs_set_super_blocknr(&super, start_block);
	btrfs_set_super_root(&super, start_block + 1);
27 28 29 30 31 32 33 34 35
	strcpy((char *)(&super.magic), BTRFS_MAGIC);
	btrfs_set_super_blocksize(&super, blocksize);
	btrfs_set_super_total_blocks(&super, num_blocks);
	btrfs_set_super_blocks_used(&super, 0);

	block = malloc(blocksize);
	memset(block, 0, blocksize);
	BUG_ON(sizeof(super) > blocksize);
	memcpy(block, &super, sizeof(super));
C
Chris Mason 已提交
36
	ret = pwrite(fd, block, blocksize, BTRFS_SUPER_INFO_OFFSET);
37 38 39
	BUG_ON(ret != blocksize);

	/* create the tree of root objects */
C
Chris Mason 已提交
40 41 42 43 44 45
	empty_leaf = malloc(blocksize);
	memset(empty_leaf, 0, blocksize);
	btrfs_set_header_parentid(&empty_leaf->header,
				  BTRFS_ROOT_TREE_OBJECTID);
	btrfs_set_header_blocknr(&empty_leaf->header, start_block + 1);
	btrfs_set_header_nritems(&empty_leaf->header, 2);
46 47

	/* create the items for the root tree */
C
Chris Mason 已提交
48
	btrfs_set_root_blocknr(&root_item, start_block + 2);
49
	btrfs_set_root_refs(&root_item, 1);
C
Chris Mason 已提交
50
	itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) - sizeof(root_item);
51 52 53 54 55
	btrfs_set_item_offset(&item, itemoff);
	btrfs_set_item_size(&item, sizeof(root_item));
	btrfs_set_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID);
	btrfs_set_key_offset(&item.key, 0);
	btrfs_set_key_flags(&item.key, 0);
C
Chris Mason 已提交
56 57 58
	memcpy(empty_leaf->items, &item, sizeof(item));
	memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
		&root_item, sizeof(root_item));
59

C
Chris Mason 已提交
60
	btrfs_set_root_blocknr(&root_item, start_block + 3);
61 62 63
	itemoff = itemoff - sizeof(root_item);
	btrfs_set_item_offset(&item, itemoff);
	btrfs_set_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID);
C
Chris Mason 已提交
64 65 66 67
	memcpy(empty_leaf->items + 1, &item, sizeof(item));
	memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
		&root_item, sizeof(root_item));
	ret = pwrite(fd, empty_leaf, blocksize, (start_block + 1) * blocksize);
68 69

	/* create the items for the extent tree */
C
Chris Mason 已提交
70
	btrfs_set_header_parentid(&empty_leaf->header,
71
				  BTRFS_EXTENT_TREE_OBJECTID);
C
Chris Mason 已提交
72 73
	btrfs_set_header_blocknr(&empty_leaf->header, start_block + 2);
	btrfs_set_header_nritems(&empty_leaf->header, 4);
74 75 76

	/* item1, reserve blocks 0-16 */
	btrfs_set_key_objectid(&item.key, 0);
C
Chris Mason 已提交
77
	btrfs_set_key_offset(&item.key, start_block + 1);
78
	btrfs_set_key_flags(&item.key, 0);
C
Chris Mason 已提交
79 80
	itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) -
			sizeof(struct btrfs_extent_item);
81 82 83 84
	btrfs_set_item_offset(&item, itemoff);
	btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
	btrfs_set_extent_refs(&extent_item, 1);
	btrfs_set_extent_owner(&extent_item, 0);
C
Chris Mason 已提交
85 86 87
	memcpy(empty_leaf->items, &item, sizeof(item));
	memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
		&extent_item, btrfs_item_size(&item));
88 89

	/* item2, give block 17 to the root */
C
Chris Mason 已提交
90
	btrfs_set_key_objectid(&item.key, start_block + 1);
91 92 93 94
	btrfs_set_key_offset(&item.key, 1);
	itemoff = itemoff - sizeof(struct btrfs_extent_item);
	btrfs_set_item_offset(&item, itemoff);
	btrfs_set_extent_owner(&extent_item, BTRFS_ROOT_TREE_OBJECTID);
C
Chris Mason 已提交
95 96 97
	memcpy(empty_leaf->items + 1, &item, sizeof(item));
	memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
		&extent_item, btrfs_item_size(&item));
98 99

	/* item3, give block 18 to the extent root */
C
Chris Mason 已提交
100
	btrfs_set_key_objectid(&item.key, start_block + 2);
101 102 103 104
	btrfs_set_key_offset(&item.key, 1);
	itemoff = itemoff - sizeof(struct btrfs_extent_item);
	btrfs_set_item_offset(&item, itemoff);
	btrfs_set_extent_owner(&extent_item, BTRFS_EXTENT_TREE_OBJECTID);
C
Chris Mason 已提交
105 106 107
	memcpy(empty_leaf->items + 2, &item, sizeof(item));
	memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
		&extent_item, btrfs_item_size(&item));
108 109

	/* item4, give block 19 to the FS root */
C
Chris Mason 已提交
110
	btrfs_set_key_objectid(&item.key, start_block + 3);
111 112 113 114
	btrfs_set_key_offset(&item.key, 1);
	itemoff = itemoff - sizeof(struct btrfs_extent_item);
	btrfs_set_item_offset(&item, itemoff);
	btrfs_set_extent_owner(&extent_item, BTRFS_FS_TREE_OBJECTID);
C
Chris Mason 已提交
115 116 117 118 119
	memcpy(empty_leaf->items + 3, &item, sizeof(item));
	memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
		&extent_item, btrfs_item_size(&item));
	ret = pwrite(fd, empty_leaf, blocksize, (start_block + 2) * blocksize);
	if (ret != blocksize)
120 121 122
		return -1;

	/* finally create the FS root */
C
Chris Mason 已提交
123 124 125 126 127
	btrfs_set_header_parentid(&empty_leaf->header, BTRFS_FS_TREE_OBJECTID);
	btrfs_set_header_blocknr(&empty_leaf->header, start_block + 3);
	btrfs_set_header_nritems(&empty_leaf->header, 0);
	ret = pwrite(fd, empty_leaf, blocksize, (start_block + 3) * blocksize);
	if (ret != blocksize)
128 129 130
		return -1;
	return 0;
}