| From 9fca37737ec96fd715ab24ab8199dd5c9a9d53df Mon Sep 17 00:00:00 2001 |
| From: Dongjin Kim <dongjin_.kim@samsung.com> |
| Date: Tue, 8 Jun 2021 19:23:09 +0900 |
| Subject: [PATCH] [f2fs] Add filesystem specific mkfs option |
| |
| "-p" option is delivered to filesystem, and filesystem will parse it. |
| (currently only for f2fs) |
| |
| Change-Id: Id10a624c5e1177ca53b3f900fadf5a0646f212c2 |
| --- |
| .../cpp/include/fs-management/admin.h | 2 + |
| src/lib/storage/fs_management/cpp/mkfs.cc | 53 ++++++++++++++++++- |
| src/storage/bin/mkfs/main.cc | 10 +++- |
| 3 files changed, 62 insertions(+), 3 deletions(-) |
| |
| diff --git a/src/lib/storage/fs_management/cpp/include/fs-management/admin.h b/src/lib/storage/fs_management/cpp/include/fs-management/admin.h |
| index 6d5b7476e9c..420d0ea091e 100644 |
| --- a/src/lib/storage/fs_management/cpp/include/fs-management/admin.h |
| +++ b/src/lib/storage/fs_management/cpp/include/fs-management/admin.h |
| @@ -58,6 +58,8 @@ typedef struct mkfs_options { |
| // The initial number of inodes to allocate space for. If 0, a default is used. Only supported |
| // for blobfs. |
| uint64_t num_inodes; |
| + // Filesystem-specific options (currently for f2fs) |
| + char* private_options = nullptr; |
| } mkfs_options_t; |
| |
| __EXPORT |
| diff --git a/src/lib/storage/fs_management/cpp/mkfs.cc b/src/lib/storage/fs_management/cpp/mkfs.cc |
| index 506512aaf51..cc6030084a4 100644 |
| --- a/src/lib/storage/fs_management/cpp/mkfs.cc |
| +++ b/src/lib/storage/fs_management/cpp/mkfs.cc |
| @@ -18,6 +18,7 @@ |
| |
| #include <iterator> |
| #include <new> |
| +#include <sstream> |
| #include <vector> |
| |
| #include <fbl/algorithm.h> |
| @@ -97,6 +98,55 @@ zx_status_t MkfsFat(const char* device_path, LaunchCallback cb, const mkfs_optio |
| return cb(argv.size() - 1, argv.data(), NULL, NULL, 0); |
| } |
| |
| +zx_status_t MkfsF2fs(const char* device_path, LaunchCallback cb, const mkfs_options_t* options) { |
| + fbl::unique_fd device_fd; |
| + device_fd.reset(open(device_path, O_RDWR)); |
| + if (!device_fd) { |
| + fprintf(stderr, "Failed to open device\n"); |
| + return ZX_ERR_BAD_STATE; |
| + } |
| + zx::channel block_device; |
| + zx_status_t status = |
| + fdio_get_service_handle(device_fd.release(), block_device.reset_and_get_address()); |
| + if (status != ZX_OK) { |
| + return status; |
| + } |
| + |
| + const std::string tool_path = fs_management::GetBinaryPath("f2fs"); |
| + std::vector<const char*> argv = {tool_path.c_str()}; |
| + argv.push_back("mkfs"); |
| + |
| + std::vector<std::string> private_options_buf(10, ""); |
| + |
| + if (options->private_options != nullptr) { |
| + std::istringstream iss(options->private_options); |
| + std::string token; |
| + uint32_t idx = 0; |
| + |
| + while (std::getline(iss, token, ' ')) { |
| + if (token == "") |
| + continue; |
| + |
| + if (idx >= private_options_buf.size()) { |
| + private_options_buf.resize(private_options_buf.size() * 2, ""); |
| + } |
| + private_options_buf[idx++] = token; |
| + } |
| + |
| + for (uint32_t i = 0; i < idx; i++) { |
| + argv.push_back(private_options_buf[i].c_str()); |
| + } |
| + } |
| + |
| + argv.push_back(nullptr); |
| + |
| + zx_handle_t hnd = block_device.release(); |
| + uint32_t id = FS_HANDLE_BLOCK_DEVICE_ID; |
| + status = |
| + static_cast<zx_status_t>(cb(static_cast<int>(argv.size() - 1), argv.data(), &hnd, &id, 1)); |
| + return status; |
| +} |
| + |
| } // namespace |
| |
| __EXPORT |
| @@ -118,8 +168,7 @@ zx_status_t mkfs(const char* device_path, disk_format_t df, LaunchCallback cb, |
| return MkfsNativeFs(fs_management::GetBinaryPath("blobfs").c_str(), device_path, cb, options, |
| true); |
| case DISK_FORMAT_F2FS: |
| - return MkfsNativeFs(fs_management::GetBinaryPath("f2fs").c_str(), device_path, cb, options, |
| - true); |
| + return MkfsF2fs(device_path, cb, options); |
| default: |
| return ZX_ERR_NOT_SUPPORTED; |
| } |
| diff --git a/src/storage/bin/mkfs/main.cc b/src/storage/bin/mkfs/main.cc |
| index 9d370619483..0124d28f1e8 100644 |
| --- a/src/storage/bin/mkfs/main.cc |
| +++ b/src/storage/bin/mkfs/main.cc |
| @@ -40,6 +40,10 @@ int usage(void) { |
| " -s|--fvm_data_slices SLICES If block device is on top of a FVM,\n" |
| " the filesystem will have at least SLICES slices\n" |
| " allocated for data.\n"); |
| + fprintf(stderr, " -p|--private_options OPTIONS Filesystem-specific options, wrapped in \"\".\n"); |
| + fprintf(stderr, |
| + " It is delivered to filesystem without parsing,\n"); |
| + fprintf(stderr, " and the filesystem will parse it.\n"); |
| fprintf(stderr, " values for 'filesystem' include:\n"); |
| for (size_t i = 0; i < countof(FILESYSTEMS); i++) { |
| fprintf(stderr, " '%s'\n", FILESYSTEMS[i].name); |
| @@ -53,13 +57,14 @@ int parse_args(int argc, char** argv, mkfs_options_t* options, disk_format_t* df |
| {"help", no_argument, NULL, 'h'}, |
| {"verbose", no_argument, NULL, 'v'}, |
| {"fvm_data_slices", required_argument, NULL, 's'}, |
| + {"private_options", required_argument, NULL, 'p'}, |
| {0, 0, 0, 0}, |
| }; |
| |
| int opt_index = -1; |
| int c = -1; |
| |
| - while ((c = getopt_long(argc, argv, "hvs:", cmds, &opt_index)) >= 0) { |
| + while ((c = getopt_long(argc, argv, "hvs:p:", cmds, &opt_index)) >= 0) { |
| switch (c) { |
| case 'v': |
| options->verbose = true; |
| @@ -73,6 +78,9 @@ int parse_args(int argc, char** argv, mkfs_options_t* options, disk_format_t* df |
| break; |
| case 'h': |
| return usage(); |
| + case 'p': |
| + options->private_options = optarg; |
| + break; |
| default: |
| break; |
| }; |
| -- |
| 2.25.1 |
| |