diff options
author | Qu Wenruo <wqu@suse.com> | 2017-10-19 13:41:38 +0800 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-01-08 18:11:33 +0100 |
commit | 8719161b4c2cefdf1bbb87800ee6fada57bcac9c (patch) | |
tree | fe3251b3e3e32229b22eeef2947a9256c8d03e12 /mkfs/rootdir.c | |
parent | 075580471e0f7435c52df486eb4354031337a7d3 (diff) |
btrfs-progs: mkfs: move source dir size calculation to its own files
Also rename the function from size_sourcedir() to mkfs_size_dir().
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'mkfs/rootdir.c')
-rw-r--r-- | mkfs/rootdir.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c index 2cc8a3ac..83a3191d 100644 --- a/mkfs/rootdir.c +++ b/mkfs/rootdir.c @@ -24,6 +24,7 @@ #include <dirent.h> #include <unistd.h> #include <fcntl.h> +#include <ftw.h> #include "ctree.h" #include "internal.h" #include "disk-io.h" @@ -33,6 +34,15 @@ #include "mkfs/rootdir.h" #include "send-utils.h" +/* + * This ignores symlinks with unreadable targets and subdirs that can't + * be read. It's a best-effort to give a rough estimate of the size of + * a subdir. It doesn't guarantee that prepopulating btrfs from this + * tree won't still run out of space. + */ +static u64 global_total_size; +static u64 fs_block_size; + static u64 index_cnt = 2; static int add_directory_items(struct btrfs_trans_handle *trans, @@ -670,3 +680,56 @@ fail: out: return ret; } + +static int ftw_add_entry_size(const char *fpath, const struct stat *st, + int type) +{ + if (type == FTW_F || type == FTW_D) + global_total_size += round_up(st->st_size, fs_block_size); + + return 0; +} + +u64 btrfs_mkfs_size_dir(const char *dir_name, u64 sectorsize, + u64 *num_of_meta_chunks_ret, u64 *size_of_data_ret) +{ + u64 dir_size = 0; + u64 total_size = 0; + int ret; + u64 default_chunk_size = SZ_8M; + u64 allocated_meta_size = SZ_8M; + u64 allocated_total_size = 20 * SZ_1M; /* 20MB */ + u64 num_of_meta_chunks = 0; + u64 num_of_data_chunks = 0; + u64 num_of_allocated_meta_chunks = + allocated_meta_size / default_chunk_size; + + global_total_size = 0; + fs_block_size = sectorsize; + ret = ftw(dir_name, ftw_add_entry_size, 10); + dir_size = global_total_size; + if (ret < 0) { + error("ftw subdir walk of %s failed: %s", dir_name, + strerror(errno)); + exit(1); + } + + num_of_data_chunks = (dir_size + default_chunk_size - 1) / + default_chunk_size; + + num_of_meta_chunks = (dir_size / 2) / default_chunk_size; + if (((dir_size / 2) % default_chunk_size) != 0) + num_of_meta_chunks++; + if (num_of_meta_chunks <= num_of_allocated_meta_chunks) + num_of_meta_chunks = 0; + else + num_of_meta_chunks -= num_of_allocated_meta_chunks; + + total_size = allocated_total_size + + (num_of_data_chunks * default_chunk_size) + + (num_of_meta_chunks * default_chunk_size); + + *num_of_meta_chunks_ret = num_of_meta_chunks; + *size_of_data_ret = num_of_data_chunks * default_chunk_size; + return total_size; +} |