[f2fs] add f2fs-tools to support mkfs/fsck/mount (29/30)

Change-Id: Ia2da8a3d16cd3543b5c3d4d0dab9bf6e28c0f9fa
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/f2fs/+/521504
Reviewed-by: Brett Wilson <brettw@google.com>
diff --git a/tools/BUILD.gn b/tools/BUILD.gn
new file mode 100644
index 0000000..0b85d2c
--- /dev/null
+++ b/tools/BUILD.gn
@@ -0,0 +1,45 @@
+# Copyright 2021 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# This file was generated by the `fx create` command. The template
+# is located at `//tools/create/templates/component-v2/BUILD.gn.tmpl-cpp`.
+# If you find something broken, we are eager to review fixes.
+
+import("//src/sys/build/components.gni")
+
+group("f2fs-tools") {
+  deps = [
+    ":package",
+  ]
+}
+
+executable("bin") {
+  output_name = "f2fs"
+
+  sources = [ "main.cc" ]
+
+  deps = [
+    "//third_party/f2fs",
+    "//sdk/lib/sys/inspect/cpp",
+    "//sdk/lib/syslog/cpp",
+    "//zircon/public/lib/async",
+    "//zircon/public/lib/async-cpp",
+    "//src/lib/uuid",
+    "//zircon/system/ulib/async-default",
+    "//zircon/system/ulib/async-loop:async-loop-cpp",
+    "//zircon/system/ulib/async-loop:async-loop-default",
+  ]
+}
+
+fuchsia_component("component") {
+  component_name = "f2fs-tools"
+  manifest = "meta/f2fs-tools.cml"
+  deps = [ ":bin" ]
+}
+
+fuchsia_package("package") {
+  package_name = "f2fs-tools"
+  deps = [ ":component" ]
+}
+
diff --git a/tools/main.cc b/tools/main.cc
new file mode 100644
index 0000000..d2802f8
--- /dev/null
+++ b/tools/main.cc
@@ -0,0 +1,81 @@
+// Copyright 2021 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <lib/async-loop/cpp/loop.h>
+#include <lib/async-loop/default.h>
+#include <lib/sys/cpp/component_context.h>
+#include <lib/sys/inspect/cpp/component.h>
+#include <lib/syslog/cpp/macros.h>
+#include <lib/syslog/cpp/log_settings.h>
+
+#include <lib/fdio/directory.h>
+#include <lib/fdio/fd.h>
+#include <lib/fdio/fdio.h>
+#include <lib/fdio/limits.h>
+#include <lib/fdio/vfs.h>
+#include <lib/zx/channel.h>
+
+
+#include <block-client/cpp/block-device.h>
+#include <block-client/cpp/remote-block-device.h>
+
+//#include "third_party/f2fs-tools/f2fs_tools.h"
+
+#include <iostream>
+#include <string>
+
+#include "third_party/f2fs/f2fs.h"
+
+int main(int argc, const char** argv) {
+  f2fs::MountOptions options;
+  f2fs::MkfsOptions mkfs_options;
+
+  std::cout << "f2fs arg= ";
+
+  for (int i=0; i < argc; i++) {
+    std::cout<< argv[i] << " ";
+  }
+
+  std::cout << std::endl;
+
+  if (argc <= 1) {
+    std::cout << "Hello F2FS!!!" << std::endl;
+    fprintf(stderr, "usage: mkfs [ <options>*] devicepath f2fs\n");
+    fprintf(stderr, "usage: fsck [ <options>*] devicepath f2fs\n");
+    fprintf(stderr, "usage: mount [ <options>*] devicepath f2fs\n");
+    return 0;
+  }
+
+
+  // Block device passed by handle
+  zx::channel device_channel = zx::channel(zx_take_startup_handle(FS_HANDLE_BLOCK_DEVICE_ID));
+
+  std::unique_ptr<block_client::RemoteBlockDevice> device;
+  zx_status_t status = block_client::RemoteBlockDevice::Create(std::move(device_channel), &device);
+  if (status != ZX_OK) {
+    FX_LOGS(ERROR) << "Could not access block device";
+    return -1;
+  }
+
+  std::unique_ptr<f2fs::Bcache> bc;
+  bool readonly_device = false;
+
+  if (f2fs::CreateBcache(std::move(device), &readonly_device, &bc) != ZX_OK) {
+    fprintf(stderr, "f2fs: error: cannot create block cache\n");
+    return -1;
+  }
+
+  //TODO: implement the fsck logic
+  if (!strcmp(argv[1], "mkfs")) {
+    f2fs::Mkfs(mkfs_options, std::move(bc));
+  } else if (!strcmp(argv[1], "fsck")) {
+    f2fs::Fsck(options, std::move(bc));
+  } else if (!strcmp(argv[1], "mount")) {
+    f2fs::Mount(options, std::move(bc));
+  } else {
+    std::cout << "F2FS: unknown operation:" << argv[1] << std::endl;
+  }
+
+  return 0;
+}
diff --git a/tools/meta/f2fs-tools.cml b/tools/meta/f2fs-tools.cml
new file mode 100644
index 0000000..ad9f824
--- /dev/null
+++ b/tools/meta/f2fs-tools.cml
@@ -0,0 +1,31 @@
+// Copyright 2021 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file was generated by the `fx create` command. The template
+// is located at `//tools/create/templates/component-v2/meta/{{PROJECT_NAME}}.cml.tmpl-cpp`.
+// If you find something broken, we are eager to review fixes.
+
+// f2fs-tools component manifest.
+// For information on manifest format and features,
+// see https://fuchsia.dev/fuchsia-src/concepts/components/component_manifests.
+{
+    include: [
+        "sdk/lib/diagnostics/inspect/client.shard.cml",
+        "sdk/lib/diagnostics/syslog/client.shard.cml",
+    ],
+
+    // Information about the program to run.
+    program: {
+        // Use the built-in ELF runner to run native binaries.
+        runner: "elf",
+        // The binary to run for this component.
+        binary: "bin/f2fs",
+    },
+
+    // Capabilities used by this component.
+    use: [
+        // List your component's dependencies here, ex:
+        // { protocol: "fuchsia.net.NameLookup" }
+    ],
+}