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 "kerncompat.h"
24 #include <sys/ioctl.h>
25 #include <sys/mount.h>
29 #include <sys/types.h>
35 #include <uuid/uuid.h>
37 #include <attr/xattr.h>
38 #include <blkid/blkid.h>
43 #include "transaction.h"
47 static u64 index_cnt
= 2;
49 #define DEFAULT_MKFS_FEATURES (BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
51 #define DEFAULT_MKFS_LEAF_SIZE 16384
53 struct directory_name_entry
{
57 struct list_head list
;
60 static int make_root_dir(struct btrfs_root
*root
, int mixed
)
62 struct btrfs_trans_handle
*trans
;
63 struct btrfs_key location
;
69 trans
= btrfs_start_transaction(root
, 1);
70 bytes_used
= btrfs_super_bytes_used(root
->fs_info
->super_copy
);
72 root
->fs_info
->system_allocs
= 1;
73 ret
= btrfs_make_block_group(trans
, root
, bytes_used
,
74 BTRFS_BLOCK_GROUP_SYSTEM
,
75 BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
76 0, BTRFS_MKFS_SYSTEM_GROUP_SIZE
);
80 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
81 &chunk_start
, &chunk_size
,
82 BTRFS_BLOCK_GROUP_METADATA
|
83 BTRFS_BLOCK_GROUP_DATA
);
86 "no space to alloc data/metadata chunk\n");
90 ret
= btrfs_make_block_group(trans
, root
, 0,
91 BTRFS_BLOCK_GROUP_METADATA
|
92 BTRFS_BLOCK_GROUP_DATA
,
93 BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
94 chunk_start
, chunk_size
);
96 printf("Created a data/metadata chunk of size %llu\n", chunk_size
);
98 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
99 &chunk_start
, &chunk_size
,
100 BTRFS_BLOCK_GROUP_METADATA
);
101 if (ret
== -ENOSPC
) {
102 fprintf(stderr
, "no space to alloc metadata chunk\n");
106 ret
= btrfs_make_block_group(trans
, root
, 0,
107 BTRFS_BLOCK_GROUP_METADATA
,
108 BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
109 chunk_start
, chunk_size
);
113 root
->fs_info
->system_allocs
= 0;
114 btrfs_commit_transaction(trans
, root
);
115 trans
= btrfs_start_transaction(root
, 1);
119 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
120 &chunk_start
, &chunk_size
,
121 BTRFS_BLOCK_GROUP_DATA
);
122 if (ret
== -ENOSPC
) {
123 fprintf(stderr
, "no space to alloc data chunk\n");
127 ret
= btrfs_make_block_group(trans
, root
, 0,
128 BTRFS_BLOCK_GROUP_DATA
,
129 BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
130 chunk_start
, chunk_size
);
134 ret
= btrfs_make_root_dir(trans
, root
->fs_info
->tree_root
,
135 BTRFS_ROOT_TREE_DIR_OBJECTID
);
138 ret
= btrfs_make_root_dir(trans
, root
, BTRFS_FIRST_FREE_OBJECTID
);
141 memcpy(&location
, &root
->fs_info
->fs_root
->root_key
, sizeof(location
));
142 location
.offset
= (u64
)-1;
143 ret
= btrfs_insert_dir_item(trans
, root
->fs_info
->tree_root
,
145 btrfs_super_root_dir(root
->fs_info
->super_copy
),
146 &location
, BTRFS_FT_DIR
, 0);
150 ret
= btrfs_insert_inode_ref(trans
, root
->fs_info
->tree_root
,
151 "default", 7, location
.objectid
,
152 BTRFS_ROOT_TREE_DIR_OBJECTID
, 0);
156 btrfs_commit_transaction(trans
, root
);
161 static void __recow_root(struct btrfs_trans_handle
*trans
,
162 struct btrfs_root
*root
)
165 struct extent_buffer
*tmp
;
167 if (trans
->transid
!= btrfs_root_generation(&root
->root_item
)) {
168 extent_buffer_get(root
->node
);
169 ret
= __btrfs_cow_block(trans
, root
, root
->node
,
170 NULL
, 0, &tmp
, 0, 0);
172 free_extent_buffer(tmp
);
176 static void recow_roots(struct btrfs_trans_handle
*trans
,
177 struct btrfs_root
*root
)
179 struct btrfs_fs_info
*info
= root
->fs_info
;
181 __recow_root(trans
, info
->fs_root
);
182 __recow_root(trans
, info
->tree_root
);
183 __recow_root(trans
, info
->extent_root
);
184 __recow_root(trans
, info
->chunk_root
);
185 __recow_root(trans
, info
->dev_root
);
186 __recow_root(trans
, info
->csum_root
);
189 static int create_one_raid_group(struct btrfs_trans_handle
*trans
,
190 struct btrfs_root
*root
, u64 type
)
196 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
197 &chunk_start
, &chunk_size
, type
);
198 if (ret
== -ENOSPC
) {
199 fprintf(stderr
, "not enough free space\n");
203 ret
= btrfs_make_block_group(trans
, root
->fs_info
->extent_root
, 0,
204 type
, BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
205 chunk_start
, chunk_size
);
210 static int create_raid_groups(struct btrfs_trans_handle
*trans
,
211 struct btrfs_root
*root
, u64 data_profile
,
212 int data_profile_opt
, u64 metadata_profile
,
213 int metadata_profile_opt
, int mixed
, int ssd
)
215 u64 num_devices
= btrfs_super_num_devices(root
->fs_info
->super_copy
);
218 if (metadata_profile
) {
219 u64 meta_flags
= BTRFS_BLOCK_GROUP_METADATA
;
221 ret
= create_one_raid_group(trans
, root
,
222 BTRFS_BLOCK_GROUP_SYSTEM
|
227 meta_flags
|= BTRFS_BLOCK_GROUP_DATA
;
229 ret
= create_one_raid_group(trans
, root
, meta_flags
|
234 if (!mixed
&& num_devices
> 1 && data_profile
) {
235 ret
= create_one_raid_group(trans
, root
,
236 BTRFS_BLOCK_GROUP_DATA
|
240 recow_roots(trans
, root
);
245 static int create_data_reloc_tree(struct btrfs_trans_handle
*trans
,
246 struct btrfs_root
*root
)
248 struct btrfs_key location
;
249 struct btrfs_root_item root_item
;
250 struct extent_buffer
*tmp
;
251 u64 objectid
= BTRFS_DATA_RELOC_TREE_OBJECTID
;
254 ret
= btrfs_copy_root(trans
, root
, root
->node
, &tmp
, objectid
);
257 memcpy(&root_item
, &root
->root_item
, sizeof(root_item
));
258 btrfs_set_root_bytenr(&root_item
, tmp
->start
);
259 btrfs_set_root_level(&root_item
, btrfs_header_level(tmp
));
260 btrfs_set_root_generation(&root_item
, trans
->transid
);
261 free_extent_buffer(tmp
);
263 location
.objectid
= objectid
;
264 location
.type
= BTRFS_ROOT_ITEM_KEY
;
266 ret
= btrfs_insert_root(trans
, root
->fs_info
->tree_root
,
267 &location
, &root_item
);
273 static void print_usage(void) __attribute__((noreturn
));
274 static void print_usage(void)
276 fprintf(stderr
, "usage: mkfs.btrfs [options] dev [ dev ... ]\n");
277 fprintf(stderr
, "options:\n");
278 fprintf(stderr
, "\t -A --alloc-start the offset to start the FS\n");
279 fprintf(stderr
, "\t -b --byte-count total number of bytes in the FS\n");
280 fprintf(stderr
, "\t -d --data data profile, raid0, raid1, raid5, raid6, raid10, dup or single\n");
281 fprintf(stderr
, "\t -f --force force overwrite of existing filesystem\n");
282 fprintf(stderr
, "\t -l --leafsize size of btree leaves\n");
283 fprintf(stderr
, "\t -L --label set a label\n");
284 fprintf(stderr
, "\t -m --metadata metadata profile, values like data profile\n");
285 fprintf(stderr
, "\t -M --mixed mix metadata and data together\n");
286 fprintf(stderr
, "\t -n --nodesize size of btree nodes\n");
287 fprintf(stderr
, "\t -s --sectorsize min block allocation (may not mountable by current kernel)\n");
288 fprintf(stderr
, "\t -r --rootdir the source directory\n");
289 fprintf(stderr
, "\t -K --nodiscard do not perform whole device TRIM\n");
290 fprintf(stderr
, "\t -O --features comma separated list of filesystem features\n");
291 fprintf(stderr
, "\t -V --version print the mkfs.btrfs version and exit\n");
292 fprintf(stderr
, "%s\n", BTRFS_BUILD_VERSION
);
296 static void print_version(void) __attribute__((noreturn
));
297 static void print_version(void)
299 fprintf(stderr
, "mkfs.btrfs, part of %s\n", BTRFS_BUILD_VERSION
);
303 static u64
parse_profile(char *s
)
305 if (strcmp(s
, "raid0") == 0) {
306 return BTRFS_BLOCK_GROUP_RAID0
;
307 } else if (strcmp(s
, "raid1") == 0) {
308 return BTRFS_BLOCK_GROUP_RAID1
;
309 } else if (strcmp(s
, "raid5") == 0) {
310 return BTRFS_BLOCK_GROUP_RAID5
;
311 } else if (strcmp(s
, "raid6") == 0) {
312 return BTRFS_BLOCK_GROUP_RAID6
;
313 } else if (strcmp(s
, "raid10") == 0) {
314 return BTRFS_BLOCK_GROUP_RAID10
;
315 } else if (strcmp(s
, "dup") == 0) {
316 return BTRFS_BLOCK_GROUP_DUP
;
317 } else if (strcmp(s
, "single") == 0) {
320 fprintf(stderr
, "Unknown profile %s\n", s
);
327 static char *parse_label(char *input
)
329 int len
= strlen(input
);
331 if (len
>= BTRFS_LABEL_SIZE
) {
332 fprintf(stderr
, "Label %s is too long (max %d)\n", input
,
333 BTRFS_LABEL_SIZE
- 1);
336 return strdup(input
);
339 static struct option long_options
[] = {
340 { "alloc-start", 1, NULL
, 'A'},
341 { "byte-count", 1, NULL
, 'b' },
342 { "force", 0, NULL
, 'f' },
343 { "leafsize", 1, NULL
, 'l' },
344 { "label", 1, NULL
, 'L'},
345 { "metadata", 1, NULL
, 'm' },
346 { "mixed", 0, NULL
, 'M' },
347 { "nodesize", 1, NULL
, 'n' },
348 { "sectorsize", 1, NULL
, 's' },
349 { "data", 1, NULL
, 'd' },
350 { "version", 0, NULL
, 'V' },
351 { "rootdir", 1, NULL
, 'r' },
352 { "nodiscard", 0, NULL
, 'K' },
353 { "features", 0, NULL
, 'O' },
357 static int add_directory_items(struct btrfs_trans_handle
*trans
,
358 struct btrfs_root
*root
, u64 objectid
,
359 ino_t parent_inum
, const char *name
,
360 struct stat
*st
, int *dir_index_cnt
)
364 struct btrfs_key location
;
367 name_len
= strlen(name
);
369 location
.objectid
= objectid
;
371 btrfs_set_key_type(&location
, BTRFS_INODE_ITEM_KEY
);
373 if (S_ISDIR(st
->st_mode
))
374 filetype
= BTRFS_FT_DIR
;
375 if (S_ISREG(st
->st_mode
))
376 filetype
= BTRFS_FT_REG_FILE
;
377 if (S_ISLNK(st
->st_mode
))
378 filetype
= BTRFS_FT_SYMLINK
;
380 ret
= btrfs_insert_dir_item(trans
, root
, name
, name_len
,
381 parent_inum
, &location
,
382 filetype
, index_cnt
);
384 *dir_index_cnt
= index_cnt
;
390 static int fill_inode_item(struct btrfs_trans_handle
*trans
,
391 struct btrfs_root
*root
,
392 struct btrfs_inode_item
*dst
, struct stat
*src
)
395 u64 sectorsize
= root
->sectorsize
;
398 * btrfs_inode_item has some reserved fields
399 * and represents on-disk inode entry, so
400 * zero everything to prevent information leak
402 memset(dst
, 0, sizeof (*dst
));
404 btrfs_set_stack_inode_generation(dst
, trans
->transid
);
405 btrfs_set_stack_inode_size(dst
, src
->st_size
);
406 btrfs_set_stack_inode_nbytes(dst
, 0);
407 btrfs_set_stack_inode_block_group(dst
, 0);
408 btrfs_set_stack_inode_nlink(dst
, src
->st_nlink
);
409 btrfs_set_stack_inode_uid(dst
, src
->st_uid
);
410 btrfs_set_stack_inode_gid(dst
, src
->st_gid
);
411 btrfs_set_stack_inode_mode(dst
, src
->st_mode
);
412 btrfs_set_stack_inode_rdev(dst
, 0);
413 btrfs_set_stack_inode_flags(dst
, 0);
414 btrfs_set_stack_timespec_sec(&dst
->atime
, src
->st_atime
);
415 btrfs_set_stack_timespec_nsec(&dst
->atime
, 0);
416 btrfs_set_stack_timespec_sec(&dst
->ctime
, src
->st_ctime
);
417 btrfs_set_stack_timespec_nsec(&dst
->ctime
, 0);
418 btrfs_set_stack_timespec_sec(&dst
->mtime
, src
->st_mtime
);
419 btrfs_set_stack_timespec_nsec(&dst
->mtime
, 0);
420 btrfs_set_stack_timespec_sec(&dst
->otime
, 0);
421 btrfs_set_stack_timespec_nsec(&dst
->otime
, 0);
423 if (S_ISDIR(src
->st_mode
)) {
424 btrfs_set_stack_inode_size(dst
, 0);
425 btrfs_set_stack_inode_nlink(dst
, 1);
427 if (S_ISREG(src
->st_mode
)) {
428 btrfs_set_stack_inode_size(dst
, (u64
)src
->st_size
);
429 if (src
->st_size
<= BTRFS_MAX_INLINE_DATA_SIZE(root
))
430 btrfs_set_stack_inode_nbytes(dst
, src
->st_size
);
432 blocks
= src
->st_size
/ sectorsize
;
433 if (src
->st_size
% sectorsize
)
435 blocks
*= sectorsize
;
436 btrfs_set_stack_inode_nbytes(dst
, blocks
);
439 if (S_ISLNK(src
->st_mode
))
440 btrfs_set_stack_inode_nbytes(dst
, src
->st_size
+ 1);
445 static int directory_select(const struct direct
*entry
)
447 if ((strncmp(entry
->d_name
, ".", entry
->d_reclen
) == 0) ||
448 (strncmp(entry
->d_name
, "..", entry
->d_reclen
) == 0))
454 static void free_namelist(struct direct
**files
, int count
)
461 for (i
= 0; i
< count
; ++i
)
466 static u64
calculate_dir_inode_size(char *dirname
)
469 struct direct
**files
, *cur_file
;
470 u64 dir_inode_size
= 0;
472 count
= scandir(dirname
, &files
, directory_select
, NULL
);
474 for (i
= 0; i
< count
; i
++) {
476 dir_inode_size
+= strlen(cur_file
->d_name
);
479 free_namelist(files
, count
);
482 return dir_inode_size
;
485 static int add_inode_items(struct btrfs_trans_handle
*trans
,
486 struct btrfs_root
*root
,
487 struct stat
*st
, char *name
,
488 u64 self_objectid
, ino_t parent_inum
,
489 int dir_index_cnt
, struct btrfs_inode_item
*inode_ret
)
492 struct btrfs_key inode_key
;
493 struct btrfs_inode_item btrfs_inode
;
498 name_len
= strlen(name
);
499 fill_inode_item(trans
, root
, &btrfs_inode
, st
);
500 objectid
= self_objectid
;
502 if (S_ISDIR(st
->st_mode
)) {
503 inode_size
= calculate_dir_inode_size(name
);
504 btrfs_set_stack_inode_size(&btrfs_inode
, inode_size
);
507 inode_key
.objectid
= objectid
;
508 inode_key
.offset
= 0;
509 btrfs_set_key_type(&inode_key
, BTRFS_INODE_ITEM_KEY
);
511 ret
= btrfs_insert_inode(trans
, root
, objectid
, &btrfs_inode
);
515 ret
= btrfs_insert_inode_ref(trans
, root
, name
, name_len
,
516 objectid
, parent_inum
, dir_index_cnt
);
520 *inode_ret
= btrfs_inode
;
525 static int add_xattr_item(struct btrfs_trans_handle
*trans
,
526 struct btrfs_root
*root
, u64 objectid
,
527 const char *file_name
)
531 char xattr_list
[XATTR_LIST_MAX
];
533 char cur_value
[XATTR_SIZE_MAX
];
534 char delimiter
= '\0';
535 char *next_location
= xattr_list
;
537 ret
= llistxattr(file_name
, xattr_list
, XATTR_LIST_MAX
);
541 fprintf(stderr
, "get a list of xattr failed for %s\n",
548 cur_name
= strtok(xattr_list
, &delimiter
);
549 while (cur_name
!= NULL
) {
550 cur_name_len
= strlen(cur_name
);
551 next_location
+= cur_name_len
+ 1;
553 ret
= getxattr(file_name
, cur_name
, cur_value
, XATTR_SIZE_MAX
);
557 fprintf(stderr
, "get a xattr value failed for %s attr %s\n",
558 file_name
, cur_name
);
562 ret
= btrfs_insert_xattr_item(trans
, root
, cur_name
,
563 cur_name_len
, cur_value
,
566 fprintf(stderr
, "insert a xattr item failed for %s\n",
570 cur_name
= strtok(next_location
, &delimiter
);
576 static int add_symbolic_link(struct btrfs_trans_handle
*trans
,
577 struct btrfs_root
*root
,
578 u64 objectid
, const char *path_name
)
581 u64 sectorsize
= root
->sectorsize
;
582 char *buf
= malloc(sectorsize
);
584 ret
= readlink(path_name
, buf
, sectorsize
);
586 fprintf(stderr
, "readlink failed for %s\n", path_name
);
589 if (ret
>= sectorsize
) {
590 fprintf(stderr
, "symlink too long for %s", path_name
);
595 buf
[ret
] = '\0'; /* readlink does not do it for us */
596 ret
= btrfs_insert_inline_extent(trans
, root
, objectid
, 0,
603 static int add_file_items(struct btrfs_trans_handle
*trans
,
604 struct btrfs_root
*root
,
605 struct btrfs_inode_item
*btrfs_inode
, u64 objectid
,
606 ino_t parent_inum
, struct stat
*st
,
607 const char *path_name
, int out_fd
)
612 struct btrfs_key key
;
614 u32 sectorsize
= root
->sectorsize
;
619 struct extent_buffer
*eb
= NULL
;
622 fd
= open(path_name
, O_RDONLY
);
624 fprintf(stderr
, "%s open failed\n", path_name
);
628 blocks
= st
->st_size
/ sectorsize
;
629 if (st
->st_size
% sectorsize
)
632 if (st
->st_size
<= BTRFS_MAX_INLINE_DATA_SIZE(root
)) {
633 char *buffer
= malloc(st
->st_size
);
634 ret_read
= pread64(fd
, buffer
, st
->st_size
, bytes_read
);
635 if (ret_read
== -1) {
636 fprintf(stderr
, "%s read failed\n", path_name
);
641 ret
= btrfs_insert_inline_extent(trans
, root
, objectid
, 0,
642 buffer
, st
->st_size
);
647 /* round up our st_size to the FS blocksize */
648 total_bytes
= (u64
)blocks
* sectorsize
;
651 * do our IO in extent buffers so it can work
652 * against any raid type
654 eb
= malloc(sizeof(*eb
) + sectorsize
);
659 memset(eb
, 0, sizeof(*eb
) + sectorsize
);
664 * keep our extent size at 1MB max, this makes it easier to work inside
665 * the tiny block groups created during mkfs
667 cur_bytes
= min(total_bytes
, 1024ULL * 1024);
668 ret
= btrfs_reserve_extent(trans
, root
, cur_bytes
, 0, 0, (u64
)-1,
673 first_block
= key
.objectid
;
676 while (bytes_read
< cur_bytes
) {
678 memset(eb
->data
, 0, sectorsize
);
680 ret_read
= pread64(fd
, eb
->data
, sectorsize
, file_pos
+ bytes_read
);
681 if (ret_read
== -1) {
682 fprintf(stderr
, "%s read failed\n", path_name
);
686 eb
->start
= first_block
+ bytes_read
;
687 eb
->len
= sectorsize
;
690 * we're doing the csum before we record the extent, but
693 ret
= btrfs_csum_file_block(trans
, root
->fs_info
->csum_root
,
694 first_block
+ bytes_read
+ sectorsize
,
695 first_block
+ bytes_read
,
696 eb
->data
, sectorsize
);
700 ret
= write_and_map_eb(trans
, root
, eb
);
702 fprintf(stderr
, "output file write failed\n");
706 bytes_read
+= sectorsize
;
710 ret
= btrfs_record_file_extent(trans
, root
, objectid
, btrfs_inode
,
711 file_pos
, first_block
, cur_bytes
);
717 file_pos
+= cur_bytes
;
718 total_bytes
-= cur_bytes
;
729 static char *make_path(char *dir
, char *name
)
733 path
= malloc(strlen(dir
) + strlen(name
) + 2);
737 if (dir
[strlen(dir
) - 1] != '/')
743 static int traverse_directory(struct btrfs_trans_handle
*trans
,
744 struct btrfs_root
*root
, char *dir_name
,
745 struct directory_name_entry
*dir_head
, int out_fd
)
749 struct btrfs_inode_item cur_inode
;
750 struct btrfs_inode_item
*inode_item
;
751 int count
, i
, dir_index_cnt
;
752 struct direct
**files
;
754 struct directory_name_entry
*dir_entry
, *parent_dir_entry
;
755 struct direct
*cur_file
;
756 ino_t parent_inum
, cur_inum
;
757 ino_t highest_inum
= 0;
758 char *parent_dir_name
;
759 struct btrfs_path path
;
760 struct extent_buffer
*leaf
;
761 struct btrfs_key root_dir_key
;
762 u64 root_dir_inode_size
= 0;
764 /* Add list for source directory */
765 dir_entry
= malloc(sizeof(struct directory_name_entry
));
766 dir_entry
->dir_name
= dir_name
;
767 dir_entry
->path
= strdup(dir_name
);
769 parent_inum
= highest_inum
+ BTRFS_FIRST_FREE_OBJECTID
;
770 dir_entry
->inum
= parent_inum
;
771 list_add_tail(&dir_entry
->list
, &dir_head
->list
);
773 btrfs_init_path(&path
);
775 root_dir_key
.objectid
= btrfs_root_dirid(&root
->root_item
);
776 root_dir_key
.offset
= 0;
777 btrfs_set_key_type(&root_dir_key
, BTRFS_INODE_ITEM_KEY
);
778 ret
= btrfs_lookup_inode(trans
, root
, &path
, &root_dir_key
, 1);
780 fprintf(stderr
, "root dir lookup error\n");
784 leaf
= path
.nodes
[0];
785 inode_item
= btrfs_item_ptr(leaf
, path
.slots
[0],
786 struct btrfs_inode_item
);
788 root_dir_inode_size
= calculate_dir_inode_size(dir_name
);
789 btrfs_set_inode_size(leaf
, inode_item
, root_dir_inode_size
);
790 btrfs_mark_buffer_dirty(leaf
);
792 btrfs_release_path(&path
);
795 parent_dir_entry
= list_entry(dir_head
->list
.next
,
796 struct directory_name_entry
,
798 list_del(&parent_dir_entry
->list
);
800 parent_inum
= parent_dir_entry
->inum
;
801 parent_dir_name
= parent_dir_entry
->dir_name
;
802 if (chdir(parent_dir_entry
->path
)) {
803 fprintf(stderr
, "chdir error for %s\n",
808 count
= scandir(parent_dir_entry
->path
, &files
,
809 directory_select
, NULL
);
812 fprintf(stderr
, "scandir for %s failed: %s\n",
813 parent_dir_name
, strerror (errno
));
817 for (i
= 0; i
< count
; i
++) {
820 if (lstat(cur_file
->d_name
, &st
) == -1) {
821 fprintf(stderr
, "lstat failed for file %s\n",
826 cur_inum
= ++highest_inum
+ BTRFS_FIRST_FREE_OBJECTID
;
827 ret
= add_directory_items(trans
, root
,
828 cur_inum
, parent_inum
,
830 &st
, &dir_index_cnt
);
832 fprintf(stderr
, "add_directory_items failed\n");
836 ret
= add_inode_items(trans
, root
, &st
,
837 cur_file
->d_name
, cur_inum
,
838 parent_inum
, dir_index_cnt
,
841 fprintf(stderr
, "add_inode_items failed\n");
845 ret
= add_xattr_item(trans
, root
,
846 cur_inum
, cur_file
->d_name
);
848 fprintf(stderr
, "add_xattr_item failed\n");
853 if (S_ISDIR(st
.st_mode
)) {
854 dir_entry
= malloc(sizeof(struct directory_name_entry
));
855 dir_entry
->dir_name
= cur_file
->d_name
;
856 dir_entry
->path
= make_path(parent_dir_entry
->path
,
858 dir_entry
->inum
= cur_inum
;
859 list_add_tail(&dir_entry
->list
, &dir_head
->list
);
860 } else if (S_ISREG(st
.st_mode
)) {
861 ret
= add_file_items(trans
, root
, &cur_inode
,
862 cur_inum
, parent_inum
, &st
,
863 cur_file
->d_name
, out_fd
);
865 fprintf(stderr
, "add_file_items failed\n");
868 } else if (S_ISLNK(st
.st_mode
)) {
869 ret
= add_symbolic_link(trans
, root
,
870 cur_inum
, cur_file
->d_name
);
872 fprintf(stderr
, "add_symbolic_link failed\n");
878 free_namelist(files
, count
);
879 free(parent_dir_entry
->path
);
880 free(parent_dir_entry
);
884 } while (!list_empty(&dir_head
->list
));
888 free_namelist(files
, count
);
890 free(parent_dir_entry
->path
);
891 free(parent_dir_entry
);
895 static int open_target(char *output_name
)
898 output_fd
= open(output_name
, O_CREAT
| O_RDWR
| O_TRUNC
,
899 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
);
904 static int create_chunks(struct btrfs_trans_handle
*trans
,
905 struct btrfs_root
*root
, u64 num_of_meta_chunks
,
910 u64 meta_type
= BTRFS_BLOCK_GROUP_METADATA
;
911 u64 data_type
= BTRFS_BLOCK_GROUP_DATA
;
912 u64 minimum_data_chunk_size
= 8 * 1024 * 1024;
916 for (i
= 0; i
< num_of_meta_chunks
; i
++) {
917 ret
= btrfs_alloc_chunk(trans
, root
->fs_info
->extent_root
,
918 &chunk_start
, &chunk_size
, meta_type
);
920 ret
= btrfs_make_block_group(trans
, root
->fs_info
->extent_root
, 0,
921 meta_type
, BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
922 chunk_start
, chunk_size
);
924 set_extent_dirty(&root
->fs_info
->free_space_cache
,
925 chunk_start
, chunk_start
+ chunk_size
- 1, 0);
928 if (size_of_data
< minimum_data_chunk_size
)
929 size_of_data
= minimum_data_chunk_size
;
931 ret
= btrfs_alloc_data_chunk(trans
, root
->fs_info
->extent_root
,
932 &chunk_start
, size_of_data
, data_type
);
934 ret
= btrfs_make_block_group(trans
, root
->fs_info
->extent_root
, 0,
935 data_type
, BTRFS_FIRST_CHUNK_TREE_OBJECTID
,
936 chunk_start
, size_of_data
);
938 set_extent_dirty(&root
->fs_info
->free_space_cache
,
939 chunk_start
, chunk_start
+ size_of_data
- 1, 0);
943 static int make_image(char *source_dir
, struct btrfs_root
*root
, int out_fd
)
946 struct btrfs_trans_handle
*trans
;
950 struct directory_name_entry dir_head
;
952 struct directory_name_entry
*dir_entry
= NULL
;
954 ret
= lstat(source_dir
, &root_st
);
956 fprintf(stderr
, "unable to lstat the %s\n", source_dir
);
960 INIT_LIST_HEAD(&dir_head
.list
);
962 trans
= btrfs_start_transaction(root
, 1);
963 ret
= traverse_directory(trans
, root
, source_dir
, &dir_head
, out_fd
);
965 fprintf(stderr
, "unable to traverse_directory\n");
968 btrfs_commit_transaction(trans
, root
);
970 printf("Making image is completed.\n");
973 while (!list_empty(&dir_head
.list
)) {
974 dir_entry
= list_entry(dir_head
.list
.next
,
975 struct directory_name_entry
, list
);
976 list_del(&dir_entry
->list
);
979 fprintf(stderr
, "Making image is aborted.\n");
984 * This ignores symlinks with unreadable targets and subdirs that can't
985 * be read. It's a best-effort to give a rough estimate of the size of
986 * a subdir. It doesn't guarantee that prepopulating btrfs from this
987 * tree won't still run out of space.
989 * The rounding up to 4096 is questionable. Previous code used du -B 4096.
991 static u64 global_total_size
;
992 static int ftw_add_entry_size(const char *fpath
, const struct stat
*st
,
995 if (type
== FTW_F
|| type
== FTW_D
)
996 global_total_size
+= round_up(st
->st_size
, 4096);
1001 static u64
size_sourcedir(char *dir_name
, u64 sectorsize
,
1002 u64
*num_of_meta_chunks_ret
, u64
*size_of_data_ret
)
1007 u64 default_chunk_size
= 8 * 1024 * 1024; /* 8MB */
1008 u64 allocated_meta_size
= 8 * 1024 * 1024; /* 8MB */
1009 u64 allocated_total_size
= 20 * 1024 * 1024; /* 20MB */
1010 u64 num_of_meta_chunks
= 0;
1011 u64 num_of_data_chunks
= 0;
1012 u64 num_of_allocated_meta_chunks
=
1013 allocated_meta_size
/ default_chunk_size
;
1015 global_total_size
= 0;
1016 ret
= ftw(dir_name
, ftw_add_entry_size
, 10);
1017 dir_size
= global_total_size
;
1019 fprintf(stderr
, "ftw subdir walk of '%s' failed: %s\n",
1020 dir_name
, strerror(errno
));
1024 num_of_data_chunks
= (dir_size
+ default_chunk_size
- 1) /
1027 num_of_meta_chunks
= (dir_size
/ 2) / default_chunk_size
;
1028 if (((dir_size
/ 2) % default_chunk_size
) != 0)
1029 num_of_meta_chunks
++;
1030 if (num_of_meta_chunks
<= num_of_allocated_meta_chunks
)
1031 num_of_meta_chunks
= 0;
1033 num_of_meta_chunks
-= num_of_allocated_meta_chunks
;
1035 total_size
= allocated_total_size
+
1036 (num_of_data_chunks
* default_chunk_size
) +
1037 (num_of_meta_chunks
* default_chunk_size
);
1039 *num_of_meta_chunks_ret
= num_of_meta_chunks
;
1040 *size_of_data_ret
= num_of_data_chunks
* default_chunk_size
;
1044 static int zero_output_file(int out_fd
, u64 size
, u32 sectorsize
)
1046 int len
= sectorsize
;
1047 int loop_num
= size
/ sectorsize
;
1049 char *buf
= malloc(len
);
1055 memset(buf
, 0, len
);
1056 for (i
= 0; i
< loop_num
; i
++) {
1057 written
= pwrite64(out_fd
, buf
, len
, location
);
1060 location
+= sectorsize
;
1066 static int check_leaf_or_node_size(u32 size
, u32 sectorsize
)
1068 if (size
< sectorsize
) {
1070 "Illegal leafsize (or nodesize) %u (smaller than %u)\n",
1073 } else if (size
> BTRFS_MAX_METADATA_BLOCKSIZE
) {
1075 "Illegal leafsize (or nodesize) %u (larger than %u)\n",
1076 size
, BTRFS_MAX_METADATA_BLOCKSIZE
);
1078 } else if (size
& (sectorsize
- 1)) {
1080 "Illegal leafsize (or nodesize) %u (not align to %u)\n",
1087 static int is_ssd(const char *file
)
1091 char sysfs_path
[PATH_MAX
];
1097 probe
= blkid_new_probe_from_filename(file
);
1101 /* Device number of this disk (possibly a partition) */
1102 devno
= blkid_probe_get_devno(probe
);
1104 blkid_free_probe(probe
);
1108 /* Get whole disk name (not full path) for this devno */
1109 ret
= blkid_devno_to_wholedisk(devno
,
1110 wholedisk
, sizeof(wholedisk
), NULL
);
1112 blkid_free_probe(probe
);
1116 snprintf(sysfs_path
, PATH_MAX
, "/sys/block/%s/queue/rotational",
1119 blkid_free_probe(probe
);
1121 fd
= open(sysfs_path
, O_RDONLY
);
1126 if (read(fd
, &rotational
, sizeof(char)) < sizeof(char)) {
1132 return !atoi((const char *)&rotational
);
1135 #define BTRFS_FEATURE_LIST_ALL (1ULL << 63)
1137 static const struct btrfs_fs_feature
{
1141 } mkfs_features
[] = {
1142 { "mixed-bg", BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS
,
1143 "mixed data and metadata block groups" },
1144 { "extref", BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF
,
1145 "increased hardlink limit per file to 65536" },
1146 { "raid56", BTRFS_FEATURE_INCOMPAT_RAID56
,
1147 "raid56 extended format" },
1148 { "skinny-metadata", BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA
,
1149 "reduced-size metadata extent refs" },
1150 /* Keep this one last */
1151 { "list-all", BTRFS_FEATURE_LIST_ALL
, NULL
}
1154 static void list_all_fs_features(void)
1158 fprintf(stderr
, "Filesystem features available at mkfs time:\n");
1159 for (i
= 0; i
< ARRAY_SIZE(mkfs_features
) - 1; i
++) {
1160 char *is_default
= "";
1162 if (mkfs_features
[i
].flag
& DEFAULT_MKFS_FEATURES
)
1163 is_default
= ", default";
1164 fprintf(stderr
, "%-20s- %s (0x%llx%s)\n",
1165 mkfs_features
[i
].name
,
1166 mkfs_features
[i
].desc
,
1167 mkfs_features
[i
].flag
,
1172 static int parse_one_fs_feature(const char *name
, u64
*flags
)
1177 for (i
= 0; i
< ARRAY_SIZE(mkfs_features
); i
++) {
1178 if (name
[0] == '^' &&
1179 !strcmp(mkfs_features
[i
].name
, name
+ 1)) {
1180 *flags
&= ~ mkfs_features
[i
].flag
;
1182 } else if (!strcmp(mkfs_features
[i
].name
, name
)) {
1183 *flags
|= mkfs_features
[i
].flag
;
1191 static void process_fs_features(u64 flags
)
1195 for (i
= 0; i
< ARRAY_SIZE(mkfs_features
); i
++) {
1196 if (flags
& mkfs_features
[i
].flag
) {
1197 printf("Turning ON incompat feature '%s': %s\n",
1198 mkfs_features
[i
].name
,
1199 mkfs_features
[i
].desc
);
1206 * Return NULL if all features were parsed fine, otherwise return the name of
1207 * the first unparsed.
1209 static char* parse_fs_features(char *namelist
, u64
*flags
)
1212 char *save_ptr
= NULL
; /* Satisfy static checkers */
1214 for (this_char
= strtok_r(namelist
, ",", &save_ptr
);
1216 this_char
= strtok_r(NULL
, ",", &save_ptr
)) {
1217 if (parse_one_fs_feature(this_char
, flags
))
1224 int main(int ac
, char **av
)
1227 struct btrfs_root
*root
;
1228 struct btrfs_trans_handle
*trans
;
1231 u64 block_count
= 0;
1232 u64 dev_block_count
= 0;
1234 u64 alloc_start
= 0;
1235 u64 metadata_profile
= 0;
1236 u64 data_profile
= 0;
1237 u32 leafsize
= max_t(u32
, sysconf(_SC_PAGESIZE
), DEFAULT_MKFS_LEAF_SIZE
);
1238 u32 sectorsize
= 4096;
1239 u32 nodesize
= leafsize
;
1240 u32 stripesize
= 4096;
1242 int option_index
= 0;
1247 int leaf_forced
= 0;
1248 int data_profile_opt
= 0;
1249 int metadata_profile_opt
= 0;
1252 int force_overwrite
= 0;
1254 char *source_dir
= NULL
;
1255 int source_dir_set
= 0;
1256 u64 num_of_meta_chunks
= 0;
1257 u64 size_of_data
= 0;
1258 u64 source_dir_size
= 0;
1262 u64 features
= DEFAULT_MKFS_FEATURES
;
1266 c
= getopt_long(ac
, av
, "A:b:fl:n:s:m:d:L:O:r:VMK",
1267 long_options
, &option_index
);
1272 alloc_start
= parse_size(optarg
);
1275 force_overwrite
= 1;
1278 data_profile
= parse_profile(optarg
);
1279 data_profile_opt
= 1;
1283 nodesize
= parse_size(optarg
);
1284 leafsize
= parse_size(optarg
);
1288 label
= parse_label(optarg
);
1291 metadata_profile
= parse_profile(optarg
);
1292 metadata_profile_opt
= 1;
1298 char *orig
= strdup(optarg
);
1301 tmp
= parse_fs_features(tmp
, &features
);
1304 "Unrecognized filesystem feature '%s'\n",
1310 if (features
& BTRFS_FEATURE_LIST_ALL
) {
1311 list_all_fs_features();
1317 sectorsize
= parse_size(optarg
);
1320 block_count
= parse_size(optarg
);
1321 if (block_count
<= 1024*1024*1024) {
1322 printf("SMALL VOLUME: forcing mixed "
1323 "metadata/data groups\n");
1332 source_dir
= optarg
;
1342 sectorsize
= max(sectorsize
, (u32
)sysconf(_SC_PAGESIZE
));
1343 if (check_leaf_or_node_size(leafsize
, sectorsize
))
1345 if (check_leaf_or_node_size(nodesize
, sectorsize
))
1347 saved_optind
= optind
;
1348 dev_cnt
= ac
- optind
;
1352 if (source_dir_set
&& dev_cnt
> 1) {
1354 "The -r option is limited to a single device\n");
1357 while (dev_cnt
-- > 0) {
1358 file
= av
[optind
++];
1359 if (is_block_device(file
))
1360 if (test_dev_for_mkfs(file
, force_overwrite
, estr
)) {
1361 fprintf(stderr
, "Error: %s", estr
);
1366 optind
= saved_optind
;
1367 dev_cnt
= ac
- optind
;
1369 file
= av
[optind
++];
1372 if (is_vol_small(file
)) {
1373 printf("SMALL VOLUME: forcing mixed metadata/data groups\n");
1378 * Set default profiles according to number of added devices.
1379 * For mixed groups defaults are single/single.
1382 if (!metadata_profile_opt
) {
1383 if (dev_cnt
== 1 && ssd
)
1384 printf("Detected a SSD, turning off metadata "
1385 "duplication. Mkfs with -m dup if you want to "
1386 "force metadata duplication.\n");
1388 metadata_profile
= (dev_cnt
> 1) ?
1389 BTRFS_BLOCK_GROUP_RAID1
: (ssd
) ?
1390 0: BTRFS_BLOCK_GROUP_DUP
;
1392 if (!data_profile_opt
) {
1393 data_profile
= (dev_cnt
> 1) ?
1394 BTRFS_BLOCK_GROUP_RAID0
: 0; /* raid0 or single */
1397 u32 best_leafsize
= max_t(u32
, sysconf(_SC_PAGESIZE
), sectorsize
);
1399 if (metadata_profile_opt
|| data_profile_opt
) {
1400 if (metadata_profile
!= data_profile
) {
1402 "ERROR: With mixed block groups data and metadata profiles must be the same\n");
1408 leafsize
= best_leafsize
;
1409 nodesize
= best_leafsize
;
1410 if (check_leaf_or_node_size(leafsize
, sectorsize
))
1413 if (leafsize
!= sectorsize
) {
1414 fprintf(stderr
, "Error: mixed metadata/data block groups "
1415 "require metadata blocksizes equal to the sectorsize\n");
1420 ret
= test_num_disk_vs_raid(metadata_profile
, data_profile
,
1421 dev_cnt
, mixed
, estr
);
1423 fprintf(stderr
, "Error: %s\n", estr
);
1427 /* if we are here that means all devs are good to btrfsify */
1428 printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION
);
1429 printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n");
1433 if (!source_dir_set
) {
1435 * open without O_EXCL so that the problem should not
1436 * occur by the following processing.
1437 * (btrfs_register_one_device() fails if O_EXCL is on)
1439 fd
= open(file
, O_RDWR
);
1441 fprintf(stderr
, "unable to open %s: %s\n", file
,
1446 ret
= btrfs_prepare_device(fd
, file
, zero_end
, &dev_block_count
,
1447 block_count
, &mixed
, discard
);
1452 if (block_count
&& block_count
> dev_block_count
) {
1453 fprintf(stderr
, "%s is smaller than requested size\n", file
);
1457 fd
= open_target(file
);
1459 fprintf(stderr
, "unable to open the %s\n", file
);
1464 source_dir_size
= size_sourcedir(source_dir
, sectorsize
,
1465 &num_of_meta_chunks
, &size_of_data
);
1466 if(block_count
< source_dir_size
)
1467 block_count
= source_dir_size
;
1468 ret
= zero_output_file(fd
, block_count
, sectorsize
);
1470 fprintf(stderr
, "unable to zero the output file\n");
1473 /* our "device" is the new image file */
1474 dev_block_count
= block_count
;
1477 /* To create the first block group and chunk 0 in make_btrfs */
1478 if (dev_block_count
< BTRFS_MKFS_SYSTEM_GROUP_SIZE
) {
1479 fprintf(stderr
, "device is too small to make filesystem\n");
1483 blocks
[0] = BTRFS_SUPER_INFO_OFFSET
;
1484 for (i
= 1; i
< 7; i
++) {
1485 blocks
[i
] = BTRFS_SUPER_INFO_OFFSET
+ 1024 * 1024 +
1490 * FS features that can be set by other means than -O
1491 * just set the bit here
1494 features
|= BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS
;
1496 if ((data_profile
| metadata_profile
) &
1497 (BTRFS_BLOCK_GROUP_RAID5
| BTRFS_BLOCK_GROUP_RAID6
)) {
1498 features
|= BTRFS_FEATURE_INCOMPAT_RAID56
;
1501 process_fs_features(features
);
1503 ret
= make_btrfs(fd
, file
, label
, blocks
, dev_block_count
,
1505 sectorsize
, stripesize
, features
);
1507 fprintf(stderr
, "error during mkfs: %s\n", strerror(-ret
));
1511 root
= open_ctree(file
, 0, OPEN_CTREE_WRITES
);
1513 fprintf(stderr
, "Open ctree failed\n");
1517 root
->fs_info
->alloc_start
= alloc_start
;
1519 ret
= make_root_dir(root
, mixed
);
1521 fprintf(stderr
, "failed to setup the root directory\n");
1525 trans
= btrfs_start_transaction(root
, 1);
1530 btrfs_register_one_device(file
);
1533 while (dev_cnt
-- > 0) {
1534 int old_mixed
= mixed
;
1536 file
= av
[optind
++];
1539 * open without O_EXCL so that the problem should not
1540 * occur by the following processing.
1541 * (btrfs_register_one_device() fails if O_EXCL is on)
1543 fd
= open(file
, O_RDWR
);
1545 fprintf(stderr
, "unable to open %s: %s\n", file
,
1549 ret
= btrfs_device_already_in_root(root
, fd
,
1550 BTRFS_SUPER_INFO_OFFSET
);
1552 fprintf(stderr
, "skipping duplicate device %s in FS\n",
1557 ret
= btrfs_prepare_device(fd
, file
, zero_end
, &dev_block_count
,
1558 block_count
, &mixed
, discard
);
1565 ret
= btrfs_add_to_fsid(trans
, root
, fd
, file
, dev_block_count
,
1566 sectorsize
, sectorsize
, sectorsize
);
1568 btrfs_register_one_device(file
);
1572 if (!source_dir_set
) {
1573 ret
= create_raid_groups(trans
, root
, data_profile
,
1574 data_profile_opt
, metadata_profile
,
1575 metadata_profile_opt
, mixed
, ssd
);
1579 ret
= create_data_reloc_tree(trans
, root
);
1582 printf("fs created label %s on %s\n\tnodesize %u leafsize %u "
1583 "sectorsize %u size %s\n",
1584 label
, first_file
, nodesize
, leafsize
, sectorsize
,
1585 pretty_size(btrfs_super_total_bytes(root
->fs_info
->super_copy
)));
1587 printf("%s\n", BTRFS_BUILD_VERSION
);
1588 btrfs_commit_transaction(trans
, root
);
1590 if (source_dir_set
) {
1591 trans
= btrfs_start_transaction(root
, 1);
1592 ret
= create_chunks(trans
, root
,
1593 num_of_meta_chunks
, size_of_data
);
1595 btrfs_commit_transaction(trans
, root
);
1597 ret
= make_image(source_dir
, root
, fd
);
1601 ret
= close_ctree(root
);