Loading fastboot/fastboot.cpp +31 −5 Original line number Diff line number Diff line Loading @@ -454,6 +454,8 @@ static int show_help() { " --skip-reboot Don't reboot device after flashing.\n" " --disable-verity Sets disable-verity when flashing vbmeta.\n" " --disable-verification Sets disable-verification when flashing vbmeta.\n" " --fs-options=OPTION[,OPTION]\n" " Enable filesystem features. OPTION supports casefold, projid, compress\n" #if !defined(_WIN32) " --wipe-and-use-fbe Enable file-based encryption, wiping userdata.\n" #endif Loading Loading @@ -1581,7 +1583,7 @@ static unsigned fb_get_flash_block_size(std::string name) { static void fb_perform_format( const std::string& partition, int skip_if_not_supported, const std::string& type_override, const std::string& size_override, const std::string& initial_dir) { const std::string& initial_dir, const unsigned fs_options) { std::string partition_type, partition_size; struct fastboot_buffer buf; Loading Loading @@ -1644,7 +1646,7 @@ static void fb_perform_format( logicalBlkSize = fb_get_flash_block_size("logical-block-size"); if (fs_generator_generate(gen, output.path, size, initial_dir, eraseBlkSize, logicalBlkSize)) { eraseBlkSize, logicalBlkSize, fs_options)) { die("Cannot generate image for %s", partition.c_str()); } Loading Loading @@ -1778,6 +1780,7 @@ int FastBootTool::Main(int argc, char* argv[]) { bool skip_secondary = false; bool set_fbe_marker = false; bool force_flash = false; unsigned fs_options = 0; int longindex; std::string slot_override; std::string next_active; Loading @@ -1795,6 +1798,7 @@ int FastBootTool::Main(int argc, char* argv[]) { {"disable-verification", no_argument, 0, 0}, {"disable-verity", no_argument, 0, 0}, {"force", no_argument, 0, 0}, {"fs-options", required_argument, 0, 0}, {"header-version", required_argument, 0, 0}, {"help", no_argument, 0, 'h'}, {"kernel-offset", required_argument, 0, 0}, Loading Loading @@ -1834,6 +1838,8 @@ int FastBootTool::Main(int argc, char* argv[]) { g_disable_verity = true; } else if (name == "force") { force_flash = true; } else if (name == "fs-options") { fs_options = ParseFsOption(optarg); } else if (name == "header-version") { g_boot_img_hdr.header_version = strtoul(optarg, nullptr, 0); } else if (name == "dtb") { Loading Loading @@ -1990,7 +1996,7 @@ int FastBootTool::Main(int argc, char* argv[]) { std::string partition = next_arg(&args); auto format = [&](const std::string& partition) { fb_perform_format(partition, 0, type_override, size_override, ""); fb_perform_format(partition, 0, type_override, size_override, "", fs_options); }; do_for_partitions(partition, slot_override, format, true); } else if (command == "signature") { Loading Loading @@ -2180,10 +2186,10 @@ int FastBootTool::Main(int argc, char* argv[]) { if (partition == "userdata" && set_fbe_marker) { fprintf(stderr, "setting FBE marker on initial userdata...\n"); std::string initial_userdata_dir = create_fbemarker_tmpdir(); fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir); fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir, fs_options); delete_fbemarker_tmpdir(initial_userdata_dir); } else { fb_perform_format(partition, 1, partition_type, "", ""); fb_perform_format(partition, 1, partition_type, "", "", fs_options); } } } Loading Loading @@ -2233,3 +2239,23 @@ void FastBootTool::ParseOsVersion(boot_img_hdr_v1* hdr, const char* arg) { } hdr->SetOsVersion(major, minor, patch); } unsigned FastBootTool::ParseFsOption(const char* arg) { unsigned fsOptions = 0; std::vector<std::string> options = android::base::Split(arg, ","); if (options.size() < 1) syntax_error("bad options: %s", arg); for (size_t i = 0; i < options.size(); ++i) { if (options[i] == "casefold") fsOptions |= (1 << FS_OPT_CASEFOLD); else if (options[i] == "projid") fsOptions |= (1 << FS_OPT_PROJID); else if (options[i] == "compress") fsOptions |= (1 << FS_OPT_COMPRESS); else syntax_error("unsupported options: %s", options[i].c_str()); } return fsOptions; } fastboot/fastboot.h +1 −0 Original line number Diff line number Diff line Loading @@ -34,4 +34,5 @@ class FastBootTool { void ParseOsPatchLevel(boot_img_hdr_v1*, const char*); void ParseOsVersion(boot_img_hdr_v1*, const char*); unsigned ParseFsOption(const char*); }; fastboot/fs.cpp +34 −8 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ static int exec_cmd(const char* path, const char** argv, const char** envp) { static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) { unsigned logicalBlkSize, const unsigned fsOptions) { static constexpr int block_size = 4096; const std::string exec_dir = android::base::GetExecutableDirectory(); Loading @@ -137,6 +137,12 @@ static int generate_ext4_image(const char* fileName, long long partSize, mke2fs_args.push_back(ext_attr.c_str()); mke2fs_args.push_back("-O"); mke2fs_args.push_back("uninit_bg"); if (fsOptions & (1 << FS_OPT_PROJID)) { mke2fs_args.push_back("-I"); mke2fs_args.push_back("512"); } mke2fs_args.push_back(fileName); std::string size_str = std::to_string(partSize / block_size); Loading @@ -162,9 +168,9 @@ static int generate_ext4_image(const char* fileName, long long partSize, return exec_cmd(e2fsdroid_args[0], e2fsdroid_args.data(), nullptr); } static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned /* unused */, unsigned /* unused */) { static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned /* unused */, unsigned /* unused */, const unsigned fsOptions) { const std::string exec_dir = android::base::GetExecutableDirectory(); const std::string mkf2fs_path = exec_dir + "/make_f2fs"; std::vector<const char*> mkf2fs_args = {mkf2fs_path.c_str()}; Loading @@ -174,6 +180,26 @@ static int generate_f2fs_image(const char* fileName, long long partSize, const s mkf2fs_args.push_back(size_str.c_str()); mkf2fs_args.push_back("-g"); mkf2fs_args.push_back("android"); if (fsOptions & (1 << FS_OPT_PROJID)) { mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("project_quota,extra_attr"); } if (fsOptions & (1 << FS_OPT_CASEFOLD)) { mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("casefold"); mkf2fs_args.push_back("-C"); mkf2fs_args.push_back("utf8"); } if (fsOptions & (1 << FS_OPT_COMPRESS)) { mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("compression"); mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("extra_attr"); } mkf2fs_args.push_back(fileName); mkf2fs_args.push_back(nullptr); Loading @@ -198,7 +224,7 @@ static const struct fs_generator { //returns 0 or error value int (*generate)(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize); unsigned eraseBlkSize, unsigned logicalBlkSize, const unsigned fsOptions); } generators[] = { { "ext4", generate_ext4_image}, Loading @@ -215,7 +241,7 @@ const struct fs_generator* fs_get_generator(const std::string& fs_type) { } int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) { return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize); const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize, const unsigned fsOptions) { return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize, fsOptions); } fastboot/fs.h +8 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,13 @@ struct fs_generator; enum FS_OPTION { FS_OPT_CASEFOLD, FS_OPT_PROJID, FS_OPT_COMPRESS, }; const struct fs_generator* fs_get_generator(const std::string& fs_type); int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0); const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0, unsigned fsOptions = 0); Loading
fastboot/fastboot.cpp +31 −5 Original line number Diff line number Diff line Loading @@ -454,6 +454,8 @@ static int show_help() { " --skip-reboot Don't reboot device after flashing.\n" " --disable-verity Sets disable-verity when flashing vbmeta.\n" " --disable-verification Sets disable-verification when flashing vbmeta.\n" " --fs-options=OPTION[,OPTION]\n" " Enable filesystem features. OPTION supports casefold, projid, compress\n" #if !defined(_WIN32) " --wipe-and-use-fbe Enable file-based encryption, wiping userdata.\n" #endif Loading Loading @@ -1581,7 +1583,7 @@ static unsigned fb_get_flash_block_size(std::string name) { static void fb_perform_format( const std::string& partition, int skip_if_not_supported, const std::string& type_override, const std::string& size_override, const std::string& initial_dir) { const std::string& initial_dir, const unsigned fs_options) { std::string partition_type, partition_size; struct fastboot_buffer buf; Loading Loading @@ -1644,7 +1646,7 @@ static void fb_perform_format( logicalBlkSize = fb_get_flash_block_size("logical-block-size"); if (fs_generator_generate(gen, output.path, size, initial_dir, eraseBlkSize, logicalBlkSize)) { eraseBlkSize, logicalBlkSize, fs_options)) { die("Cannot generate image for %s", partition.c_str()); } Loading Loading @@ -1778,6 +1780,7 @@ int FastBootTool::Main(int argc, char* argv[]) { bool skip_secondary = false; bool set_fbe_marker = false; bool force_flash = false; unsigned fs_options = 0; int longindex; std::string slot_override; std::string next_active; Loading @@ -1795,6 +1798,7 @@ int FastBootTool::Main(int argc, char* argv[]) { {"disable-verification", no_argument, 0, 0}, {"disable-verity", no_argument, 0, 0}, {"force", no_argument, 0, 0}, {"fs-options", required_argument, 0, 0}, {"header-version", required_argument, 0, 0}, {"help", no_argument, 0, 'h'}, {"kernel-offset", required_argument, 0, 0}, Loading Loading @@ -1834,6 +1838,8 @@ int FastBootTool::Main(int argc, char* argv[]) { g_disable_verity = true; } else if (name == "force") { force_flash = true; } else if (name == "fs-options") { fs_options = ParseFsOption(optarg); } else if (name == "header-version") { g_boot_img_hdr.header_version = strtoul(optarg, nullptr, 0); } else if (name == "dtb") { Loading Loading @@ -1990,7 +1996,7 @@ int FastBootTool::Main(int argc, char* argv[]) { std::string partition = next_arg(&args); auto format = [&](const std::string& partition) { fb_perform_format(partition, 0, type_override, size_override, ""); fb_perform_format(partition, 0, type_override, size_override, "", fs_options); }; do_for_partitions(partition, slot_override, format, true); } else if (command == "signature") { Loading Loading @@ -2180,10 +2186,10 @@ int FastBootTool::Main(int argc, char* argv[]) { if (partition == "userdata" && set_fbe_marker) { fprintf(stderr, "setting FBE marker on initial userdata...\n"); std::string initial_userdata_dir = create_fbemarker_tmpdir(); fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir); fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir, fs_options); delete_fbemarker_tmpdir(initial_userdata_dir); } else { fb_perform_format(partition, 1, partition_type, "", ""); fb_perform_format(partition, 1, partition_type, "", "", fs_options); } } } Loading Loading @@ -2233,3 +2239,23 @@ void FastBootTool::ParseOsVersion(boot_img_hdr_v1* hdr, const char* arg) { } hdr->SetOsVersion(major, minor, patch); } unsigned FastBootTool::ParseFsOption(const char* arg) { unsigned fsOptions = 0; std::vector<std::string> options = android::base::Split(arg, ","); if (options.size() < 1) syntax_error("bad options: %s", arg); for (size_t i = 0; i < options.size(); ++i) { if (options[i] == "casefold") fsOptions |= (1 << FS_OPT_CASEFOLD); else if (options[i] == "projid") fsOptions |= (1 << FS_OPT_PROJID); else if (options[i] == "compress") fsOptions |= (1 << FS_OPT_COMPRESS); else syntax_error("unsupported options: %s", options[i].c_str()); } return fsOptions; }
fastboot/fastboot.h +1 −0 Original line number Diff line number Diff line Loading @@ -34,4 +34,5 @@ class FastBootTool { void ParseOsPatchLevel(boot_img_hdr_v1*, const char*); void ParseOsVersion(boot_img_hdr_v1*, const char*); unsigned ParseFsOption(const char*); };
fastboot/fs.cpp +34 −8 Original line number Diff line number Diff line Loading @@ -113,7 +113,7 @@ static int exec_cmd(const char* path, const char** argv, const char** envp) { static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) { unsigned logicalBlkSize, const unsigned fsOptions) { static constexpr int block_size = 4096; const std::string exec_dir = android::base::GetExecutableDirectory(); Loading @@ -137,6 +137,12 @@ static int generate_ext4_image(const char* fileName, long long partSize, mke2fs_args.push_back(ext_attr.c_str()); mke2fs_args.push_back("-O"); mke2fs_args.push_back("uninit_bg"); if (fsOptions & (1 << FS_OPT_PROJID)) { mke2fs_args.push_back("-I"); mke2fs_args.push_back("512"); } mke2fs_args.push_back(fileName); std::string size_str = std::to_string(partSize / block_size); Loading @@ -162,9 +168,9 @@ static int generate_ext4_image(const char* fileName, long long partSize, return exec_cmd(e2fsdroid_args[0], e2fsdroid_args.data(), nullptr); } static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned /* unused */, unsigned /* unused */) { static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, unsigned /* unused */, unsigned /* unused */, const unsigned fsOptions) { const std::string exec_dir = android::base::GetExecutableDirectory(); const std::string mkf2fs_path = exec_dir + "/make_f2fs"; std::vector<const char*> mkf2fs_args = {mkf2fs_path.c_str()}; Loading @@ -174,6 +180,26 @@ static int generate_f2fs_image(const char* fileName, long long partSize, const s mkf2fs_args.push_back(size_str.c_str()); mkf2fs_args.push_back("-g"); mkf2fs_args.push_back("android"); if (fsOptions & (1 << FS_OPT_PROJID)) { mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("project_quota,extra_attr"); } if (fsOptions & (1 << FS_OPT_CASEFOLD)) { mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("casefold"); mkf2fs_args.push_back("-C"); mkf2fs_args.push_back("utf8"); } if (fsOptions & (1 << FS_OPT_COMPRESS)) { mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("compression"); mkf2fs_args.push_back("-O"); mkf2fs_args.push_back("extra_attr"); } mkf2fs_args.push_back(fileName); mkf2fs_args.push_back(nullptr); Loading @@ -198,7 +224,7 @@ static const struct fs_generator { //returns 0 or error value int (*generate)(const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize); unsigned eraseBlkSize, unsigned logicalBlkSize, const unsigned fsOptions); } generators[] = { { "ext4", generate_ext4_image}, Loading @@ -215,7 +241,7 @@ const struct fs_generator* fs_get_generator(const std::string& fs_type) { } int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize) { return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize); const std::string& initial_dir, unsigned eraseBlkSize, unsigned logicalBlkSize, const unsigned fsOptions) { return gen->generate(fileName, partSize, initial_dir, eraseBlkSize, logicalBlkSize, fsOptions); }
fastboot/fs.h +8 −1 Original line number Diff line number Diff line Loading @@ -5,6 +5,13 @@ struct fs_generator; enum FS_OPTION { FS_OPT_CASEFOLD, FS_OPT_PROJID, FS_OPT_COMPRESS, }; const struct fs_generator* fs_get_generator(const std::string& fs_type); int fs_generator_generate(const struct fs_generator* gen, const char* fileName, long long partSize, const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0); const std::string& initial_dir, unsigned eraseBlkSize = 0, unsigned logicalBlkSize = 0, unsigned fsOptions = 0);