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
21 #include <sys/ioctl.h>
22 #include <sys/mount.h>
26 #include <sys/types.h>
30 #include <uuid/uuid.h>
33 #include "kerncompat.h"
36 #include "transaction.h"
40 #define BLKGETSIZE64 0
41 static inline int ioctl(int fd
, int define
, u64
*size
) { return 0; }
44 static u64
parse_size(char *s
)
50 if (!isdigit(s
[len
- 1])) {
51 c
= tolower(s
[len
- 1]);
62 fprintf(stderr
, "Unknown size descriptor %c\n", c
);
67 return atol(s
) * mult
;
70 static int zero_blocks(int fd
, off_t start
, size_t len
)
72 char *buf
= malloc(len
);
79 written
= pwrite(fd
, buf
, len
, start
);
86 static int zero_dev_start(int fd
)
89 size_t len
= 2 * 1024 * 1024;
92 /* don't overwrite the disk labels on sparc */
96 return zero_blocks(fd
, start
, len
);
99 static int zero_dev_end(int fd
, u64 dev_size
)
101 size_t len
= 2 * 1024 * 1024;
102 off_t start
= dev_size
- len
;
104 return zero_blocks(fd
, start
, len
);
107 static int make_root_dir(int fd
) {
108 struct btrfs_root
*root
;
109 struct btrfs_trans_handle
*trans
;
110 struct btrfs_key location
;
113 root
= open_ctree_fd(fd
, 0);
116 fprintf(stderr
, "ctree init failed\n");
119 trans
= btrfs_start_transaction(root
, 1);
120 ret
= btrfs_make_block_groups(trans
, root
);
121 ret
= btrfs_make_root_dir(trans
, root
->fs_info
->tree_root
,
122 BTRFS_ROOT_TREE_DIR_OBJECTID
);
125 ret
= btrfs_make_root_dir(trans
, root
, BTRFS_FIRST_FREE_OBJECTID
);
128 memcpy(&location
, &root
->fs_info
->fs_root
->root_key
, sizeof(location
));
129 location
.offset
= (u64
)-1;
130 ret
= btrfs_insert_dir_item(trans
, root
->fs_info
->tree_root
,
132 btrfs_super_root_dir(&root
->fs_info
->super_copy
),
133 &location
, BTRFS_FT_DIR
);
137 ret
= btrfs_insert_inode_ref(trans
, root
->fs_info
->tree_root
,
138 "default", 7, location
.objectid
,
139 BTRFS_ROOT_TREE_DIR_OBJECTID
);
143 btrfs_commit_transaction(trans
, root
);
144 ret
= close_ctree(root
);
149 u64
device_size(int fd
, struct stat
*st
)
152 if (S_ISREG(st
->st_mode
)) {
155 if (!S_ISBLK(st
->st_mode
)) {
158 if (ioctl(fd
, BLKGETSIZE64
, &size
) >= 0) {
164 static void print_usage(void)
166 fprintf(stderr
, "usage: mkfs.btrfs [ -l leafsize ] [ -n nodesize] dev [ blocks ]\n");
170 int main(int ac
, char **av
)
178 u32 leafsize
= 16 * 1024;
179 u32 sectorsize
= 4096;
180 u32 nodesize
= 16 * 1024;
181 u32 stripesize
= 4096;
187 c
= getopt(ac
, av
, "l:n:s:");
192 leafsize
= parse_size(optarg
);
195 nodesize
= parse_size(optarg
);
198 stripesize
= parse_size(optarg
);
204 if (leafsize
< sectorsize
|| (leafsize
& (sectorsize
- 1))) {
205 fprintf(stderr
, "Illegal leafsize %u\n", leafsize
);
208 if (nodesize
< sectorsize
|| (nodesize
& (sectorsize
- 1))) {
209 fprintf(stderr
, "Illegal nodesize %u\n", nodesize
);
216 block_count
= parse_size(av
[optind
+ 1]);
218 fprintf(stderr
, "error finding block count\n");
225 fd
= open(file
, O_RDWR
);
227 fprintf(stderr
, "unable to open %s\n", file
);
230 ret
= fstat(fd
, &st
);
232 fprintf(stderr
, "unable to stat %s\n", file
);
235 if (block_count
== 0) {
236 block_count
= device_size(fd
, &st
);
237 if (block_count
== 0) {
238 fprintf(stderr
, "unable to find %s size\n", file
);
243 block_count
/= sectorsize
;
244 block_count
*= sectorsize
;
246 if (block_count
< 256 * 1024 * 1024) {
247 fprintf(stderr
, "device %s is too small\n", file
);
250 ret
= zero_dev_start(fd
);
252 fprintf(stderr
, "failed to zero device start %d\n", ret
);
257 ret
= zero_dev_end(fd
, block_count
);
259 fprintf(stderr
, "failed to zero device end %d\n", ret
);
264 for (i
= 0; i
< 4; i
++)
265 blocks
[i
] = BTRFS_SUPER_INFO_OFFSET
+ leafsize
* i
;
267 ret
= make_btrfs(fd
, blocks
, block_count
, nodesize
, leafsize
,
268 sectorsize
, stripesize
);
270 fprintf(stderr
, "error during mkfs %d\n", ret
);
273 ret
= make_root_dir(fd
);
275 fprintf(stderr
, "failed to setup the root directory\n");
278 printf("fs created on %s nodesize %u leafsize %u sectorsize %u bytes %llu\n",
279 file
, nodesize
, leafsize
, sectorsize
,
280 (unsigned long long)block_count
);