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 make_root_dir(int fd
) {
71 struct btrfs_root
*root
;
72 struct btrfs_trans_handle
*trans
;
73 struct btrfs_key location
;
76 root
= open_ctree_fd(fd
, 0);
79 fprintf(stderr
, "ctree init failed\n");
82 trans
= btrfs_start_transaction(root
, 1);
83 ret
= btrfs_make_block_groups(trans
, root
);
84 ret
= btrfs_make_root_dir(trans
, root
->fs_info
->tree_root
,
85 BTRFS_ROOT_TREE_DIR_OBJECTID
);
88 ret
= btrfs_make_root_dir(trans
, root
, BTRFS_FIRST_FREE_OBJECTID
);
91 memcpy(&location
, &root
->fs_info
->fs_root
->root_key
, sizeof(location
));
92 location
.offset
= (u64
)-1;
93 ret
= btrfs_insert_dir_item(trans
, root
->fs_info
->tree_root
,
95 btrfs_super_root_dir(&root
->fs_info
->super_copy
),
96 &location
, BTRFS_FT_DIR
);
100 ret
= btrfs_insert_inode_ref(trans
, root
->fs_info
->tree_root
,
101 "default", 7, location
.objectid
,
102 BTRFS_ROOT_TREE_DIR_OBJECTID
);
106 btrfs_commit_transaction(trans
, root
);
107 ret
= close_ctree(root
);
112 u64
device_size(int fd
, struct stat
*st
)
115 if (S_ISREG(st
->st_mode
)) {
118 if (!S_ISBLK(st
->st_mode
)) {
121 if (ioctl(fd
, BLKGETSIZE64
, &size
) >= 0) {
127 static void print_usage(void)
129 fprintf(stderr
, "usage: mkfs.btrfs [ -l leafsize ] [ -n nodesize] dev [ blocks ]\n");
133 int main(int ac
, char **av
)
141 u32 leafsize
= 16 * 1024;
142 u32 sectorsize
= 4096;
143 u32 nodesize
= 16 * 1024;
144 u32 stripesize
= 4096;
146 char *buf
= malloc(sectorsize
);
150 c
= getopt(ac
, av
, "l:n:s:");
155 leafsize
= parse_size(optarg
);
158 nodesize
= parse_size(optarg
);
161 stripesize
= parse_size(optarg
);
167 if (leafsize
< sectorsize
|| (leafsize
& (sectorsize
- 1))) {
168 fprintf(stderr
, "Illegal leafsize %u\n", leafsize
);
171 if (nodesize
< sectorsize
|| (nodesize
& (sectorsize
- 1))) {
172 fprintf(stderr
, "Illegal nodesize %u\n", nodesize
);
179 block_count
= parse_size(av
[optind
+ 1]);
181 fprintf(stderr
, "error finding block count\n");
188 fd
= open(file
, O_RDWR
);
190 fprintf(stderr
, "unable to open %s\n", file
);
193 ret
= fstat(fd
, &st
);
195 fprintf(stderr
, "unable to stat %s\n", file
);
198 if (block_count
== 0) {
199 block_count
= device_size(fd
, &st
);
200 if (block_count
== 0) {
201 fprintf(stderr
, "unable to find %s size\n", file
);
205 block_count
/= sectorsize
;
206 block_count
*= sectorsize
;
208 if (block_count
< 256 * 1024 * 1024) {
209 fprintf(stderr
, "device %s is too small\n", file
);
212 memset(buf
, 0, sectorsize
);
213 for(i
= 0; i
< 64; i
++) {
214 ret
= write(fd
, buf
, sectorsize
);
215 if (ret
!= sectorsize
) {
216 fprintf(stderr
, "unable to zero fill device\n");
220 for (i
= 0; i
< 4; i
++)
221 blocks
[i
] = BTRFS_SUPER_INFO_OFFSET
+ leafsize
* i
;
222 ret
= make_btrfs(fd
, blocks
, block_count
, nodesize
, leafsize
,
223 sectorsize
, stripesize
);
225 fprintf(stderr
, "error during mkfs %d\n", ret
);
228 ret
= make_root_dir(fd
);
230 fprintf(stderr
, "failed to setup the root directory\n");
233 printf("fs created on %s nodesize %u leafsize %u sectorsize %u bytes %llu\n",
234 file
, nodesize
, leafsize
, sectorsize
,
235 (unsigned long long)block_count
);