2 * Copyright (C) 2007 Oracle. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
19 #define _XOPEN_SOURCE 500
22 #include <sys/types.h>
26 #include <uuid/uuid.h>
29 #include "kerncompat.h"
33 #include "transaction.h"
36 static u64
parse_size(char *s
)
42 if (!isdigit(s
[len
- 1])) {
43 c
= tolower(s
[len
- 1]);
54 fprintf(stderr
, "Unknown size descriptor %c\n", c
);
59 return atol(s
) * mult
;
62 static int make_root_dir(int fd
, const char *device_name
) {
63 struct btrfs_root
*root
;
64 struct btrfs_trans_handle
*trans
;
65 struct btrfs_key location
;
71 root
= open_ctree_fd(fd
, device_name
, 0);
74 fprintf(stderr
, "ctree init failed\n");
77 trans
= btrfs_start_transaction(root
, 1);
78 bytes_used
= btrfs_super_bytes_used(&root
->fs_info
->super_copy
);
80 root
->fs_info
->force_system_allocs
= 1;
81 ret
= btrfs_make_block_group(trans
, root
, bytes_used
,
82 BTRFS_BLOCK_GROUP_SYSTEM
,
83 BTRFS_CHUNK_TREE_OBJECTID
,
84 0, BTRFS_MKFS_SYSTEM_GROUP_SIZE
);
86 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
87 &chunk_start
, &chunk_size
,
88 BTRFS_BLOCK_GROUP_METADATA
);
90 ret
= btrfs_make_block_group(trans
, root
, 0,
91 BTRFS_BLOCK_GROUP_METADATA
,
92 BTRFS_CHUNK_TREE_OBJECTID
,
93 chunk_start
, chunk_size
);
96 root
->fs_info
->force_system_allocs
= 0;
97 btrfs_commit_transaction(trans
, root
);
98 trans
= btrfs_start_transaction(root
, 1);
101 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
102 &chunk_start
, &chunk_size
,
103 BTRFS_BLOCK_GROUP_DATA
);
105 ret
= btrfs_make_block_group(trans
, root
, 0,
106 BTRFS_BLOCK_GROUP_DATA
,
107 BTRFS_CHUNK_TREE_OBJECTID
,
108 chunk_start
, chunk_size
);
111 // ret = btrfs_make_block_group(trans, root, 0, 1);
112 ret
= btrfs_make_root_dir(trans
, root
->fs_info
->tree_root
,
113 BTRFS_ROOT_TREE_DIR_OBJECTID
);
116 ret
= btrfs_make_root_dir(trans
, root
, BTRFS_FIRST_FREE_OBJECTID
);
119 memcpy(&location
, &root
->fs_info
->fs_root
->root_key
, sizeof(location
));
120 location
.offset
= (u64
)-1;
121 ret
= btrfs_insert_dir_item(trans
, root
->fs_info
->tree_root
,
123 btrfs_super_root_dir(&root
->fs_info
->super_copy
),
124 &location
, BTRFS_FT_DIR
);
128 ret
= btrfs_insert_inode_ref(trans
, root
->fs_info
->tree_root
,
129 "default", 7, location
.objectid
,
130 BTRFS_ROOT_TREE_DIR_OBJECTID
);
134 btrfs_commit_transaction(trans
, root
);
135 ret
= close_ctree(root
);
140 static void print_usage(void)
142 fprintf(stderr
, "usage: mkfs.btrfs [ -l leafsize ] [ -n nodesize] dev [ blocks ]\n");
146 int main(int ac
, char **av
)
150 u64 dev_block_count
= 0;
155 u32 leafsize
= 16 * 1024;
156 u32 sectorsize
= 4096;
157 u32 nodesize
= 16 * 1024;
158 u32 stripesize
= 4096;
161 struct btrfs_root
*root
;
162 struct btrfs_trans_handle
*trans
;
166 c
= getopt(ac
, av
, "b:l:n:s:");
171 leafsize
= parse_size(optarg
);
174 nodesize
= parse_size(optarg
);
177 stripesize
= parse_size(optarg
);
180 block_count
= parse_size(optarg
);
187 if (leafsize
< sectorsize
|| (leafsize
& (sectorsize
- 1))) {
188 fprintf(stderr
, "Illegal leafsize %u\n", leafsize
);
191 if (nodesize
< sectorsize
|| (nodesize
& (sectorsize
- 1))) {
192 fprintf(stderr
, "Illegal nodesize %u\n", nodesize
);
201 fd
= open(file
, O_RDWR
);
203 fprintf(stderr
, "unable to open %s\n", file
);
207 ret
= btrfs_prepare_device(fd
, file
, zero_end
, &dev_block_count
);
208 if (block_count
== 0)
209 block_count
= dev_block_count
;
211 for (i
= 0; i
< 6; i
++)
212 blocks
[i
] = BTRFS_SUPER_INFO_OFFSET
+ leafsize
* i
;
214 ret
= make_btrfs(fd
, file
, blocks
, block_count
, nodesize
, leafsize
,
215 sectorsize
, stripesize
);
217 fprintf(stderr
, "error during mkfs %d\n", ret
);
220 ret
= make_root_dir(fd
, file
);
222 fprintf(stderr
, "failed to setup the root directory\n");
225 printf("fs created on %s nodesize %u leafsize %u sectorsize %u bytes %llu\n",
226 file
, nodesize
, leafsize
, sectorsize
,
227 (unsigned long long)block_count
);
232 btrfs_register_one_device(file
);
233 root
= open_ctree(file
, 0);
236 fprintf(stderr
, "ctree init failed\n");
239 trans
= btrfs_start_transaction(root
, 1);
244 fd
= open(file
, O_RDWR
);
246 fprintf(stderr
, "unable to open %s\n", file
);
249 fprintf(stderr
, "adding device %s\n", file
);
250 ret
= btrfs_prepare_device(fd
, file
, zero_end
,
255 ret
= btrfs_add_to_fsid(trans
, root
, fd
, dev_block_count
,
256 sectorsize
, sectorsize
, sectorsize
);
259 btrfs_register_one_device(file
);
261 btrfs_commit_transaction(trans
, root
);
262 ret
= close_ctree(root
);