#include <stdlib.h>
/* #include <sys/dir.h> included via androidcompat.h */
#include <fcntl.h>
+#include <limits.h>
#include <unistd.h>
#include <getopt.h>
#include <uuid/uuid.h>
bytes_used = btrfs_super_bytes_used(fs_info->super_copy);
root->fs_info->system_allocs = 1;
+ /*
+ * First temporary system chunk must match the chunk layout
+ * created in make_btrfs().
+ */
ret = btrfs_make_block_group(trans, fs_info, bytes_used,
BTRFS_BLOCK_GROUP_SYSTEM,
- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
- 0, BTRFS_MKFS_SYSTEM_GROUP_SIZE);
+ BTRFS_BLOCK_RESERVED_1M_FOR_SUPER,
+ BTRFS_MKFS_SYSTEM_GROUP_SIZE);
allocation->system += BTRFS_MKFS_SYSTEM_GROUP_SIZE;
if (ret)
return ret;
ret = btrfs_make_block_group(trans, fs_info, 0,
BTRFS_BLOCK_GROUP_METADATA |
BTRFS_BLOCK_GROUP_DATA,
- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
chunk_start, chunk_size);
if (ret)
return ret;
return ret;
ret = btrfs_make_block_group(trans, fs_info, 0,
BTRFS_BLOCK_GROUP_METADATA,
- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
chunk_start, chunk_size);
allocation->metadata += chunk_size;
if (ret)
return ret;
ret = btrfs_make_block_group(trans, fs_info, 0,
BTRFS_BLOCK_GROUP_DATA,
- BTRFS_FIRST_CHUNK_TREE_OBJECTID,
chunk_start, chunk_size);
allocation->data += chunk_size;
if (ret)
return ret;
ret = btrfs_make_block_group(trans, fs_info, 0,
- type, BTRFS_FIRST_CHUNK_TREE_OBJECTID,
- chunk_start, chunk_size);
+ type, chunk_start, chunk_size);
type &= BTRFS_BLOCK_GROUP_TYPE_MASK;
if (type == BTRFS_BLOCK_GROUP_DATA) {
struct btrfs_key location;
struct btrfs_root_item root_item;
struct extent_buffer *tmp;
+ u8 uuid[BTRFS_UUID_SIZE] = {0};
int ret;
ret = btrfs_copy_root(trans, root, root->node, &tmp, objectid);
btrfs_set_root_bytenr(&root_item, tmp->start);
btrfs_set_root_level(&root_item, btrfs_header_level(tmp));
btrfs_set_root_generation(&root_item, trans->transid);
+ /* clear uuid and o/ctime of source tree */
+ memcpy(root_item.uuid, uuid, BTRFS_UUID_SIZE);
+ btrfs_set_stack_timespec_sec(&root_item.otime, 0);
+ btrfs_set_stack_timespec_sec(&root_item.ctime, 0);
free_extent_buffer(tmp);
location.objectid = objectid;
printf(" creation:\n");
printf("\t-b|--byte-count SIZE set filesystem size to SIZE (on the first device)\n");
printf("\t-r|--rootdir DIR copy files from DIR to the image root directory\n");
+ printf("\t--shrink (with --rootdir) shrink the filled filesystem to minimal size\n");
printf("\t-K|--nodiscard do not perform whole device TRIM\n");
printf("\t-f|--force force overwrite of existing filesystem\n");
printf(" general:\n");
* This must be done before minimal device size checks.
*/
if (source_dir_set) {
- fd = open(file, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP |
- S_IWGRP | S_IROTH);
+ int oflags = O_RDWR;
+ struct stat statbuf;
+
+ if (is_path_exist(file) == 0)
+ oflags |= O_CREAT;
+
+ fd = open(file, oflags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
+ S_IROTH);
if (fd < 0) {
- error("unable to open %s: %s", file, strerror(errno));
+ error("unable to open %s: %m", file);
+ goto error;
+ }
+
+ ret = fstat(fd, &statbuf);
+ if (ret < 0) {
+ error("unable to stat %s: %m", file);
+ ret = -errno;
goto error;
}
+ /*
+ * Block_count not specified, use file/device size first.
+ * Or we will always use source_dir_size calculated for mkfs.
+ */
+ if (!block_count)
+ block_count = btrfs_device_size(fd, &statbuf);
source_dir_size = btrfs_mkfs_size_dir(source_dir, sectorsize,
min_dev_size, metadata_profile, data_profile);
if (block_count < source_dir_size)
path = argv[i];
ret = test_minimum_size(path, min_dev_size);
if (ret < 0) {
- error("failed to check size for %s: %s",
- path, strerror(-ret));
+ error("failed to check size for %s: %m", path);
goto error;
}
if (ret > 0) {
*/
fd = open(file, O_RDWR);
if (fd < 0) {
- error("unable to open %s: %s", file, strerror(errno));
+ error("unable to open %s: %m", file);
goto error;
}
ret = btrfs_prepare_device(fd, file, &dev_block_count, block_count,
*/
fd = open(file, O_RDWR);
if (fd < 0) {
- error("unable to open %s: %s", file, strerror(errno));
+ error("unable to open %s: %m", file);
goto error;
}
ret = btrfs_device_already_in_root(root, fd,
goto out;
}
+ ret = create_tree(trans, root, BTRFS_UUID_TREE_OBJECTID);
+ if (ret)
+ warning(
+ "unable to create uuid tree, will be created after mount: %d", ret);
+
ret = btrfs_commit_transaction(trans, root);
if (ret) {
error("unable to commit transaction: %d", ret);