[f2fs] Use typed channel APIs instead of raw zx::channel

It removes using deprecated raw channels and
updates patch files to main fuchsia for f2fs.

Test: fx test f2fs-unittest f2fs-fs-tests f2fs-slow-fs-tests

Change-Id: I00578b5c38bce802540a4902972d5fcfca91e6e8
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/f2fs/+/563221
Reviewed-by: Brett Wilson <brettw@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index fb0c87c..9b9257a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -80,7 +80,6 @@
 
   deps = [
     "//sdk/fidl/fuchsia.io",
-    "//sdk/fidl/fuchsia.io:fuchsia.io_llcpp",
     "//sdk/lib/fdio",
     "//sdk/lib/syslog/cpp",
     "//src/lib/storage/vfs/cpp/metrics:metrics-cobalt",
@@ -113,11 +112,6 @@
   if (f2fs_roll_fwd) {
     defines += [ "F2FS_ROLL_FORWARD" ]
   }
-
-  # TODO(fxbug.dev/69585): This target uses raw zx::channel with LLCPP which is deprecated.
-  # Please migrate to typed channel APIs (fidl::ClientEnd<T>, fidl::ServerEnd<T>).
-  # See linked bug for details.
-  configs += [ "//build/cpp:fidl-llcpp-deprecated-raw-channels" ]
 }
 
 group("tests") {
diff --git a/bcache.cc b/bcache.cc
index 5e31793..411791c 100644
--- a/bcache.cc
+++ b/bcache.cc
@@ -111,30 +111,6 @@
   return device()->BlockDetachVmo(std::move(vmoid));
 }
 
-zx_status_t FdToBlockDevice(fbl::unique_fd& fd, std::unique_ptr<block_client::BlockDevice>* out) {
-  zx::channel channel, server;
-  zx_status_t status = zx::channel::create(0, &channel, &server);
-  if (status != ZX_OK) {
-    return status;
-  }
-  fdio_cpp::UnownedFdioCaller caller(fd.get());
-  status = fidl::WireCall<fuchsia_io::Node>(zx::unowned_channel(caller.borrow_channel()))
-               .Clone(fuchsia_io::wire::kCloneFlagSameRights, std::move(server))
-               .status();
-  if (status != ZX_OK) {
-    return status;
-  }
-  std::unique_ptr<block_client::RemoteBlockDevice> device;
-  status = block_client::RemoteBlockDevice::Create(std::move(channel), &device);
-  if (status != ZX_OK) {
-    FX_LOGS(ERROR) << "cannot create block device: " << status;
-    return status;
-  }
-
-  *out = std::move(device);
-  return ZX_OK;
-}
-
 zx_status_t Bcache::Create(std::unique_ptr<block_client::BlockDevice> device, uint64_t max_blocks,
                            uint64_t block_size, std::unique_ptr<Bcache>* out) {
   zx_status_t status = Create(device.get(), max_blocks, block_size, out);
diff --git a/bcache.h b/bcache.h
index b5d3b7f..05c1c85 100644
--- a/bcache.h
+++ b/bcache.h
@@ -116,8 +116,6 @@
   std::shared_mutex mutex_;
 };
 
-// A helper function for converting "fd" to "BlockDevice".
-zx_status_t FdToBlockDevice(fbl::unique_fd& fd, std::unique_ptr<block_client::BlockDevice>* out);
 zx_status_t CreateBcache(std::unique_ptr<block_client::BlockDevice> device, bool* out_readonly,
                          std::unique_ptr<Bcache>* out);
 
diff --git a/f2fs.cc b/f2fs.cc
index 2d3e9ef..304a185 100644
--- a/f2fs.cc
+++ b/f2fs.cc
@@ -92,7 +92,7 @@
 zx::status<std::unique_ptr<F2fs>> CreateFsAndRoot(const MountOptions& mount_options,
                                                   async_dispatcher_t* dispatcher,
                                                   std::unique_ptr<f2fs::Bcache> bcache,
-                                                  zx::channel mount_channel,
+                                                  fidl::ServerEnd<fuchsia_io::Directory> root,
                                                   fbl::Closure on_unmount,
                                                   ServeLayout serve_layout) {
   TRACE_DURATION("f2fs", "CreateFsAndRoot");
@@ -127,7 +127,7 @@
 
   FX_LOGS(INFO) << "CreateFsAndRoot";
 
-  if (zx_status_t status = fs->ServeDirectory(std::move(export_root), std::move(mount_channel));
+  if (zx_status_t status = fs->ServeDirectory(std::move(export_root), std::move(root));
       status != ZX_OK) {
     FX_LOGS(ERROR) << "failed to establish mount_channel" << status;
     return zx::error(status);
diff --git a/f2fs.h b/f2fs.h
index 9675730..2de2952 100644
--- a/f2fs.h
+++ b/f2fs.h
@@ -67,7 +67,7 @@
 zx::status<std::unique_ptr<F2fs>> CreateFsAndRoot(const MountOptions &mount_options,
                                                   async_dispatcher_t *dispatcher,
                                                   std::unique_ptr<f2fs::Bcache> bcache,
-                                                  zx::channel mount_channel,
+                                                  fidl::ServerEnd<fuchsia_io::Directory> root,
                                                   fbl::Closure on_unmount,
                                                   ServeLayout serve_layout);
 
diff --git a/mount.cc b/mount.cc
index aea989d..8c52b30 100644
--- a/mount.cc
+++ b/mount.cc
@@ -42,13 +42,13 @@
     return ZX_ERR_BAD_STATE;
   }
 
-  zx::channel export_root;
+  fidl::ServerEnd<fuchsia_io::Directory> export_root;
   f2fs::ServeLayout serve_layout;
   if (outgoing_server.is_valid()) {
-    export_root = std::move(outgoing_server);
+    export_root = fidl::ServerEnd<fuchsia_io::Directory>(std::move(outgoing_server));
     serve_layout = f2fs::ServeLayout::kExportDirectory;
   } else if (root_server.is_valid()) {
-    export_root = std::move(root_server);
+    export_root = fidl::ServerEnd<fuchsia_io::Directory>(std::move(root_server));
     serve_layout = f2fs::ServeLayout::kDataRootOnly;
   } else {
     FX_LOGS(ERROR) << "could not get startup handle to serve on";
diff --git a/patches/0001-f2fs-Add-fs-management-support-for-f2fs.patch b/patches/0001-f2fs-Add-fs-management-support-for-f2fs.patch
index 1838210..fd74e2b 100644
--- a/patches/0001-f2fs-Add-fs-management-support-for-f2fs.patch
+++ b/patches/0001-f2fs-Add-fs-management-support-for-f2fs.patch
@@ -1,11 +1,10 @@
-From 617f20bc95103823bf035971ce92634cb3c7b6b2 Mon Sep 17 00:00:00 2001
+From 61607c904f61947f52d0a92a8892c9ec8d1dccfb Mon Sep 17 00:00:00 2001
 From: Seokhwan Kim <sukka.kim@samsung.com>
 Date: Fri, 23 Jul 2021 09:00:56 +0900
 Subject: [PATCH 1/5] [f2fs] Add fs-management support for f2fs
 
 Change-Id: Ia3248bdcab038f09fe4454caeaf9dfab2bbdbe12
 ---
- build/cpp/BUILD.gn                                        | 1 +
  src/lib/storage/fs_management/cpp/admin.cc                | 3 +++
  src/lib/storage/fs_management/cpp/format.cc               | 1 +
  src/lib/storage/fs_management/cpp/fsck.cc                 | 2 ++
@@ -19,25 +18,13 @@
  src/storage/fshost/block-device.cc                        | 1 +
  zircon/system/public/zircon/device/vfs.h                  | 1 +
  zircon/system/ulib/fs-test-utils/perftest.cc              | 7 +++++--
- 14 files changed, 35 insertions(+), 10 deletions(-)
+ 13 files changed, 34 insertions(+), 10 deletions(-)
 
-diff --git a/build/cpp/BUILD.gn b/build/cpp/BUILD.gn
-index 11599855838..898a327ea9b 100644
---- a/build/cpp/BUILD.gn
-+++ b/build/cpp/BUILD.gn
-@@ -263,6 +263,7 @@ config("fidl-llcpp-deprecated-raw-channels") {
-     "//src/ui/tools/print-input-report:print-input-report-test-bin",
-     "//src/virtualization/bin/guest:bin",
-     "//src/virtualization/bin/guest_runner:bin",
-+    "//third_party/f2fs:f2fs",
-     "//vendor/*",
-     "//zircon/system/ulib/block-client:block-client",
-     "//zircon/system/ulib/c/test:cdebugdata-test",
 diff --git a/src/lib/storage/fs_management/cpp/admin.cc b/src/lib/storage/fs_management/cpp/admin.cc
-index 98452ea923d..a00bbea936b 100644
+index 689d9d54434..6f4586b409d 100644
 --- a/src/lib/storage/fs_management/cpp/admin.cc
 +++ b/src/lib/storage/fs_management/cpp/admin.cc
-@@ -128,6 +128,9 @@ zx::status<> FsInit(zx::channel device, disk_format_t df, const init_options_t&
+@@ -128,6 +128,9 @@ zx::status<> FsInit(zx::channel device, disk_format_t df, const InitOptions& opt
      case DISK_FORMAT_FXFS:
        return InitNativeFs(fs_management::GetBinaryPath("fxfs").c_str(), std::move(device), options,
                            std::move(outgoing_directory));
@@ -60,10 +47,10 @@
  
    if (fs_type < DISK_FORMAT_COUNT_) {
 diff --git a/src/lib/storage/fs_management/cpp/fsck.cc b/src/lib/storage/fs_management/cpp/fsck.cc
-index d645ddbf1ef..ff52d3ce142 100644
+index 354aea35839..5eaa5af5f37 100644
 --- a/src/lib/storage/fs_management/cpp/fsck.cc
 +++ b/src/lib/storage/fs_management/cpp/fsck.cc
-@@ -94,6 +94,8 @@ zx_status_t fsck(const char* device_path, disk_format_t df, const fsck_options_t
+@@ -94,6 +94,8 @@ zx_status_t fsck(const char* device_path, disk_format_t df, const FsckOptions& o
        return FsckFat(device_path, options, cb);
      case DISK_FORMAT_BLOBFS:
        return FsckNativeFs(device_path, options, cb, fs_management::GetBinaryPath("blobfs").c_str());
@@ -99,10 +86,10 @@
  disk_format_t detect_disk_format_log_unknown(int fd);
  
 diff --git a/src/lib/storage/fs_management/cpp/mkfs.cc b/src/lib/storage/fs_management/cpp/mkfs.cc
-index 3e85ea91888..f6bc7dbf226 100644
+index fc9423798e5..93566c917be 100644
 --- a/src/lib/storage/fs_management/cpp/mkfs.cc
 +++ b/src/lib/storage/fs_management/cpp/mkfs.cc
-@@ -117,6 +117,9 @@ zx_status_t mkfs(const char* device_path, disk_format_t df, LaunchCallback cb,
+@@ -116,6 +116,9 @@ zx_status_t mkfs(const char* device_path, disk_format_t df, LaunchCallback cb,
      case DISK_FORMAT_BLOBFS:
        return MkfsNativeFs(fs_management::GetBinaryPath("blobfs").c_str(), device_path, cb, options,
                            true);
@@ -113,10 +100,10 @@
        auto* format = fs_management::CustomDiskFormat::Get(df);
        if (format == nullptr) {
 diff --git a/src/lib/storage/fs_management/cpp/mount.cc b/src/lib/storage/fs_management/cpp/mount.cc
-index c44f2b5720c..8ef4e6b9ec0 100644
+index 844def8a3b7..0a6fec3f492 100644
 --- a/src/lib/storage/fs_management/cpp/mount.cc
 +++ b/src/lib/storage/fs_management/cpp/mount.cc
-@@ -245,6 +245,10 @@ disk_format_t detect_disk_format_impl(int fd, DiskFormatLogVerbosity verbosity)
+@@ -215,6 +215,10 @@ disk_format_t detect_disk_format_impl(int fd, DiskFormatLogVerbosity verbosity)
      return DISK_FORMAT_MBR;
    }
  
@@ -140,7 +127,7 @@
  }
  
 diff --git a/src/storage/bin/fsck/main.cc b/src/storage/bin/fsck/main.cc
-index 924a59bdfa2..da78f361538 100644
+index e0582edabe3..7a7b93c31c2 100644
 --- a/src/storage/bin/fsck/main.cc
 +++ b/src/storage/bin/fsck/main.cc
 @@ -25,10 +25,8 @@ struct {
@@ -157,7 +144,7 @@
  
  int usage(void) {
 diff --git a/src/storage/bin/mkfs/main.cc b/src/storage/bin/mkfs/main.cc
-index 797d826f89d..9d370619483 100644
+index ba8b9bfb344..1d82a1ebf11 100644
 --- a/src/storage/bin/mkfs/main.cc
 +++ b/src/storage/bin/mkfs/main.cc
 @@ -28,10 +28,8 @@ struct {
@@ -186,10 +173,10 @@
  }
  
 diff --git a/src/storage/fshost/block-device.cc b/src/storage/fshost/block-device.cc
-index bf99b9f9bcd..c33c2000e96 100644
+index 61c54354fe9..b597b228cf6 100644
 --- a/src/storage/fshost/block-device.cc
 +++ b/src/storage/fshost/block-device.cc
-@@ -756,6 +756,7 @@ zx_status_t BlockDeviceInterface::Add(bool format_on_corruption) {
+@@ -754,6 +754,7 @@ zx_status_t BlockDeviceInterface::Add(bool format_on_corruption) {
      case DISK_FORMAT_VBMETA:
      case DISK_FORMAT_UNKNOWN:
      case DISK_FORMAT_FXFS:
@@ -198,10 +185,10 @@
        return ZX_ERR_NOT_SUPPORTED;
    }
 diff --git a/zircon/system/public/zircon/device/vfs.h b/zircon/system/public/zircon/device/vfs.h
-index 6b152277634..662dbac2f2a 100644
+index 27d10b7f0c3..4c1cdc0983e 100644
 --- a/zircon/system/public/zircon/device/vfs.h
 +++ b/zircon/system/public/zircon/device/vfs.h
-@@ -55,5 +55,6 @@ typedef struct {
+@@ -57,5 +57,6 @@ typedef struct {
  #define VFS_TYPE_MEMFS 0x3e694d21ul
  #define VFS_TYPE_FACTORYFS 0x1e694d21ul
  #define VFS_TYPE_FXFS 0x73667866ul
diff --git a/patches/0002-fs_test-Add-configurable-options-for-block-size-and-.patch b/patches/0002-f2fs-Add-configurable-options-for-block-size-and-blo.patch
similarity index 89%
rename from patches/0002-fs_test-Add-configurable-options-for-block-size-and-.patch
rename to patches/0002-f2fs-Add-configurable-options-for-block-size-and-blo.patch
index bf2e789..5b06fba 100644
--- a/patches/0002-fs_test-Add-configurable-options-for-block-size-and-.patch
+++ b/patches/0002-f2fs-Add-configurable-options-for-block-size-and-blo.patch
@@ -1,8 +1,8 @@
-From 4b9f4c37a67acf005be214776100f0b5cade5fd2 Mon Sep 17 00:00:00 2001
+From dfdf0c7e8b4a5b6b58c5e7536b7463d28cf5d25c Mon Sep 17 00:00:00 2001
 From: Seokhwan Kim <sukka.kim@samsung.com>
 Date: Sat, 24 Jul 2021 00:25:11 +0900
-Subject: [PATCH 2/5] [fs_test] Add configurable options for block size and
- block count
+Subject: [PATCH 2/5] [f2fs] Add configurable options for block size and block
+ count
 
 Change-Id: I81dfabb913cf9db02135a91021c10094994cb406
 ---
@@ -11,10 +11,10 @@
  2 files changed, 12 insertions(+), 2 deletions(-)
 
 diff --git a/src/storage/fs_test/fs_test.cc b/src/storage/fs_test/fs_test.cc
-index d5daa82ebd2..57670a5151b 100644
+index 9b4e399b554..537d988bbe8 100644
 --- a/src/storage/fs_test/fs_test.cc
 +++ b/src/storage/fs_test/fs_test.cc
-@@ -463,8 +463,8 @@ std::vector<TestFilesystemOptions> AllTestFilesystems() {
+@@ -464,8 +464,8 @@ std::vector<TestFilesystemOptions> AllTestFilesystems() {
          const auto& opt = iter->value[i];
          options->push_back(TestFilesystemOptions{.description = opt["description"].GetString(),
                                                   .use_fvm = opt["use_fvm"].GetBool(),
diff --git a/patches/0003-fs_test-Add-the-unordered-readdir-fs-case-in-TestDir.patch b/patches/0003-f2fs-Add-the-unordered-readdir-fs-case-in-TestDirect.patch
similarity index 92%
rename from patches/0003-fs_test-Add-the-unordered-readdir-fs-case-in-TestDir.patch
rename to patches/0003-f2fs-Add-the-unordered-readdir-fs-case-in-TestDirect.patch
index dfd87cf..ac04e29 100644
--- a/patches/0003-fs_test-Add-the-unordered-readdir-fs-case-in-TestDir.patch
+++ b/patches/0003-f2fs-Add-the-unordered-readdir-fs-case-in-TestDirect.patch
@@ -1,7 +1,7 @@
-From ba86d9a6406f7fbddd490065d70c373b7c259e45 Mon Sep 17 00:00:00 2001
+From e15cec74f7e09c826497bdf46e06896a0d33560f Mon Sep 17 00:00:00 2001
 From: Dongjin Kim <dongjin_.kim@samsung.com>
 Date: Sat, 24 Jul 2021 01:26:08 +0900
-Subject: [PATCH 3/5] [fs_test] Add the unordered readdir fs case in
+Subject: [PATCH 3/5] [f2fs] Add the unordered readdir fs case in
  TestDirectoryReaddirRmAll
 
 Change-Id: Idd521289e93b54097702945692df41da8727a5e4
diff --git a/patches/0004-fs_test-Configure-deivce-size-as-minimum-size-for-f2.patch b/patches/0004-f2fs-Configure-deivce-size-as-minimum-size-for-f2fs.patch
similarity index 94%
rename from patches/0004-fs_test-Configure-deivce-size-as-minimum-size-for-f2.patch
rename to patches/0004-f2fs-Configure-deivce-size-as-minimum-size-for-f2fs.patch
index f7c45b1..4f18465 100644
--- a/patches/0004-fs_test-Configure-deivce-size-as-minimum-size-for-f2.patch
+++ b/patches/0004-f2fs-Configure-deivce-size-as-minimum-size-for-f2fs.patch
@@ -1,7 +1,7 @@
-From 4ac95e6695e69c99d1037d81055e806e4f1ca306 Mon Sep 17 00:00:00 2001
+From 28cf7fcb735698ef8d96d73ef35e1a19c050add6 Mon Sep 17 00:00:00 2001
 From: Dongjin Kim <dongjin_.kim@samsung.com>
 Date: Sat, 24 Jul 2021 01:38:18 +0900
-Subject: [PATCH 4/5] [fs_test] Configure deivce size as minimum size for f2fs
+Subject: [PATCH 4/5] [f2fs] Configure deivce size as minimum size for f2fs
 
 Change-Id: I0e15a43953c03ff4dc94e75898942c0c62d8fe4d
 ---
diff --git a/patches/0005-f2fs-Add-filesystem-specific-mkfs-option.patch b/patches/0005-f2fs-Add-filesystem-specific-mkfs-option.patch
index f359db0..7f0c4de 100644
--- a/patches/0005-f2fs-Add-filesystem-specific-mkfs-option.patch
+++ b/patches/0005-f2fs-Add-filesystem-specific-mkfs-option.patch
@@ -1,30 +1,31 @@
-From e4a0416189bff1bfeb935e566e1011a1215812cb Mon Sep 17 00:00:00 2001
-From: Seokhwan Kim <sukka.kim@samsung.com>
-Date: Sat, 24 Jul 2021 01:44:21 +0900
+From 6d2019885330a84196ebd6d020e77f4e19b60836 Mon Sep 17 00:00:00 2001
+From: Jaeyoon Choi <j_yoon.choi@samsung.com>
+Date: Thu, 29 Jul 2021 20:25:41 +0900
 Subject: [PATCH 5/5] [f2fs] Add filesystem specific mkfs option
 
-Change-Id: I59049215522ba4fddac90c631d62e641da7ba50b
+Change-Id: I95efc450142b50808f4ba642eebc7083ee002e22
 ---
- .../cpp/include/fs-management/admin.h         |  2 +
+ .../cpp/include/fs-management/admin.h         |  3 ++
  src/lib/storage/fs_management/cpp/mkfs.cc     | 53 ++++++++++++++++++-
  src/storage/bin/mkfs/main.cc                  | 10 +++-
- 3 files changed, 62 insertions(+), 3 deletions(-)
+ 3 files changed, 63 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
+index 7fc1b358f12..611c01155e0 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 {
+@@ -65,6 +65,9 @@ struct MkfsOptions {
    // The initial number of inodes to allocate space for. If 0, a default is used. Only supported
    // for blobfs.
-   uint64_t num_inodes;
+   uint64_t num_inodes = 0;
++
 +  // Filesystem-specific options (currently for f2fs)
 +  char* private_options = nullptr;
- } mkfs_options_t;
+ };
  
- __EXPORT
+ struct FsckOptions {
 diff --git a/src/lib/storage/fs_management/cpp/mkfs.cc b/src/lib/storage/fs_management/cpp/mkfs.cc
-index f6bc7dbf226..85422d886a7 100644
+index 93566c917be..ee6d3b1d28c 100644
 --- a/src/lib/storage/fs_management/cpp/mkfs.cc
 +++ b/src/lib/storage/fs_management/cpp/mkfs.cc
 @@ -18,6 +18,7 @@
@@ -35,11 +36,11 @@
  #include <vector>
  
  #include <fbl/algorithm.h>
-@@ -97,6 +98,55 @@ zx_status_t MkfsFat(const char* device_path, LaunchCallback cb, const mkfs_optio
+@@ -96,6 +97,55 @@ zx_status_t MkfsFat(const char* device_path, LaunchCallback cb, const MkfsOption
    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) {
++zx_status_t MkfsF2fs(const char* device_path, LaunchCallback cb, const MkfsOptions& options) {
 +  fbl::unique_fd device_fd;
 +  device_fd.reset(open(device_path, O_RDWR));
 +  if (!device_fd) {
@@ -59,8 +60,8 @@
 +
 +  std::vector<std::string> private_options_buf(10, "");
 +
-+  if (options->private_options != nullptr) {
-+    std::istringstream iss(options->private_options);
++  if (options.private_options != nullptr) {
++    std::istringstream iss(options.private_options);
 +    std::string token;
 +    uint32_t idx = 0;
 +
@@ -91,7 +92,7 @@
  }  // namespace
  
  __EXPORT
-@@ -118,8 +168,7 @@ zx_status_t mkfs(const char* device_path, disk_format_t df, LaunchCallback cb,
+@@ -117,8 +167,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:
@@ -102,7 +103,7 @@
        auto* format = fs_management::CustomDiskFormat::Get(df);
        if (format == nullptr) {
 diff --git a/src/storage/bin/mkfs/main.cc b/src/storage/bin/mkfs/main.cc
-index 9d370619483..0124d28f1e8 100644
+index 1d82a1ebf11..22e2d860648 100644
 --- a/src/storage/bin/mkfs/main.cc
 +++ b/src/storage/bin/mkfs/main.cc
 @@ -40,6 +40,10 @@ int usage(void) {
@@ -116,7 +117,7 @@
    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
+@@ -52,13 +56,14 @@ int parse_args(int argc, char** argv, MkfsOptions* options, disk_format_t* df, c
        {"help", no_argument, NULL, 'h'},
        {"verbose", no_argument, NULL, 'v'},
        {"fvm_data_slices", required_argument, NULL, 's'},
@@ -132,7 +133,7 @@
      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
+@@ -72,6 +77,9 @@ int parse_args(int argc, char** argv, MkfsOptions* options, disk_format_t* df, c
          break;
        case 'h':
          return usage();
diff --git a/test/unit/checkpoint.cc b/test/unit/checkpoint.cc
index 5644ff0..9b7719c 100644
--- a/test/unit/checkpoint.cc
+++ b/test/unit/checkpoint.cc
@@ -13,6 +13,7 @@
 #include <gtest/gtest.h>
 
 #include "third_party/f2fs/f2fs.h"
+#include "unit_lib.h"
 
 namespace f2fs {
 namespace {
@@ -893,89 +894,73 @@
 void CheckpointTestMain(uint32_t test) {
   std::unique_ptr<f2fs::Bcache> bc;
   MountOptions options;
-  bool readonly_device = false;
   bool after_mkfs = true;
   int checkpoint_pack = kCheckpointPack0;
   uint8_t *pre_bitmap = nullptr;
   std::vector<fbl::RefPtr<VnodeF2fs>> vnodes;
   std::vector<uint32_t> prev_values;
-  auto device = std::make_unique<FakeBlockDevice>(FakeBlockDevice::Config{
-      .block_count = kBlockCount, .block_size = kDefaultSectorSize, .supports_trim = false});
-
-  ASSERT_TRUE(device);
-  ASSERT_EQ(CreateBcache(std::move(device), &readonly_device, &bc), ZX_OK);
-
-  std::vector<const char *> argv = {"-a 0"};
-  ASSERT_EQ(Mkfs(bc.get(), static_cast<int>(argv.size()), const_cast<char **>(argv.data())), ZX_OK);
-
   std::unique_ptr<F2fs> fs;
-  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
 
-  // Enclose the channels in a scope to ensure they are closed before we shut down.
-  {
-    zx::channel mount_channel, remote_mount_channel;
-    ASSERT_EQ(zx::channel::create(0, &mount_channel, &remote_mount_channel), ZX_OK);
-    auto fs_or = f2fs::CreateFsAndRoot(
-        options, loop.dispatcher(), std::move(bc), std::move(mount_channel), [] {},
-        ServeLayout::kExportDirectory);
+  unittest_lib::MkfsOnFakeDev(&bc, kBlockCount);
+  unittest_lib::MountWithOptions(options, &bc, &fs);
 
-    ASSERT_EQ(fs_or.is_ok(), true);
-    fs = std::move(fs_or).value();
+  fbl::RefPtr<VnodeF2fs> root;
+  unittest_lib::CreateRoot(fs.get(), &root);
 
-    // Validate checkpoint
-    for (uint32_t i = 1; i <= kCheckpointLoopCnt + 1; i++) {
-      if (!after_mkfs)
-        fs->WriteCheckpoint(false, true);
+  // Validate checkpoint
+  for (uint32_t i = 1; i <= kCheckpointLoopCnt + 1; i++) {
+    if (!after_mkfs)
+      fs->WriteCheckpoint(false, true);
 
-      switch (test) {
-        case kCheckpointVersionTest:
-          CheckpointTestVersion(fs.get(), checkpoint_pack, i, after_mkfs);
-          break;
-        case kCheckpointNatBitmapTest:
-          CheckpointTestNatBitmap(fs.get(), checkpoint_pack, i, after_mkfs, pre_bitmap);
-          break;
-        case kCheckpointSitBitmapTest:
-          CheckpointTestSitBitmap(fs.get(), checkpoint_pack, i, after_mkfs, pre_bitmap);
-          break;
-        case kCheckpointAddOrphanInodeTest:
-          CheckpointTestAddOrphanInode(fs.get(), checkpoint_pack, i, after_mkfs);
-          break;
-        case kCheckpointRemoveOrphanInodeTest:
-          CheckpointTestRemoveOrphanInode(fs.get(), checkpoint_pack, i, after_mkfs);
-          break;
-        case kCheckpointRecoverOrphanInodeTest:
-          CheckpointTestRecoverOrphanInode(fs.get(), checkpoint_pack, i, after_mkfs, vnodes);
-          break;
-        case kCheckpointCompactedSummariesTest:
-          CheckpointTestCompactedSummaries(fs.get(), checkpoint_pack, i, after_mkfs);
-          break;
-        case kCheckpointNormalSummariesTest:
-          CheckpointTestNormalSummaries(fs.get(), checkpoint_pack, i, after_mkfs);
-          break;
-        case kCheckpointSitJournalTest:
-          CheckpointTestSitJournal(fs.get(), checkpoint_pack, i, after_mkfs, prev_values);
-          break;
-        case kCheckpointNatJournalTest:
-          CheckpointTestNatJournal(fs.get(), checkpoint_pack, i, after_mkfs, prev_values);
-          break;
-        default:
-          ASSERT_EQ(0, 1);
-          break;
-      };
+    switch (test) {
+      case kCheckpointVersionTest:
+        CheckpointTestVersion(fs.get(), checkpoint_pack, i, after_mkfs);
+        break;
+      case kCheckpointNatBitmapTest:
+        CheckpointTestNatBitmap(fs.get(), checkpoint_pack, i, after_mkfs, pre_bitmap);
+        break;
+      case kCheckpointSitBitmapTest:
+        CheckpointTestSitBitmap(fs.get(), checkpoint_pack, i, after_mkfs, pre_bitmap);
+        break;
+      case kCheckpointAddOrphanInodeTest:
+        CheckpointTestAddOrphanInode(fs.get(), checkpoint_pack, i, after_mkfs);
+        break;
+      case kCheckpointRemoveOrphanInodeTest:
+        CheckpointTestRemoveOrphanInode(fs.get(), checkpoint_pack, i, after_mkfs);
+        break;
+      case kCheckpointRecoverOrphanInodeTest:
+        CheckpointTestRecoverOrphanInode(fs.get(), checkpoint_pack, i, after_mkfs, vnodes);
+        break;
+      case kCheckpointCompactedSummariesTest:
+        CheckpointTestCompactedSummaries(fs.get(), checkpoint_pack, i, after_mkfs);
+        break;
+      case kCheckpointNormalSummariesTest:
+        CheckpointTestNormalSummaries(fs.get(), checkpoint_pack, i, after_mkfs);
+        break;
+      case kCheckpointSitJournalTest:
+        CheckpointTestSitJournal(fs.get(), checkpoint_pack, i, after_mkfs, prev_values);
+        break;
+      case kCheckpointNatJournalTest:
+        CheckpointTestNatJournal(fs.get(), checkpoint_pack, i, after_mkfs, prev_values);
+        break;
+      default:
+        ASSERT_EQ(0, 1);
+        break;
+    };
 
-      if (after_mkfs)
-        after_mkfs = false;
+    if (after_mkfs)
+      after_mkfs = false;
 
-      if (checkpoint_pack == kCheckpointPack0) {
-        checkpoint_pack = kCheckpointPack1;
-      } else {
-        checkpoint_pack = kCheckpointPack0;
-      }
+    if (checkpoint_pack == kCheckpointPack0) {
+      checkpoint_pack = kCheckpointPack1;
+    } else {
+      checkpoint_pack = kCheckpointPack0;
     }
   }
-  fs->Shutdown([&loop](zx_status_t) { loop.Quit(); });
+  ASSERT_EQ(root->Close(), ZX_OK);
+  root = nullptr;
 
-  ASSERT_EQ(loop.Run(), ZX_ERR_CANCELED);
+  unittest_lib::Unmount(std::move(fs), &bc);
 
   delete[] pre_bitmap;
 }
diff --git a/test/unit/mount.cc b/test/unit/mount.cc
index b2ea864..887868b 100644
--- a/test/unit/mount.cc
+++ b/test/unit/mount.cc
@@ -9,6 +9,7 @@
 #include <gtest/gtest.h>
 
 #include "third_party/f2fs/f2fs.h"
+#include "unit_lib.h"
 
 namespace f2fs {
 namespace {
@@ -54,21 +55,24 @@
 }
 
 void MountTestDisableExt(F2fs *fs, uint32_t expectation) {
-  fbl::RefPtr<VnodeF2fs> data_root;
+  fbl::RefPtr<VnodeF2fs> root;
+  unittest_lib::CreateRoot(fs, &root);
+  Dir *root_dir = static_cast<Dir *>(root.get());
   bool result = (expectation > 0 ? true : false);
-  ASSERT_EQ(VnodeF2fs::Vget(fs, fs->RawSb().root_ino, &data_root), ZX_OK);
-  Dir *root_dir = static_cast<Dir *>(data_root.get());
 
   for (const char *ext_item : kMediaExtList) {
     std::string name = "test.";
     name += ext_item;
     fbl::RefPtr<fs::Vnode> vnode;
-    // Use S_IFDIR to create regular file
+    // create regular files with cold file extensions
     ASSERT_EQ(root_dir->Create(name, S_IFREG, &vnode), ZX_OK);
     File *file = static_cast<File *>(vnode.get());
     ASSERT_EQ(NodeMgr::IsColdFile(file), result);
     vnode->Close();
   }
+
+  ASSERT_EQ(root->Close(), ZX_OK);
+  root = nullptr;
 }
 
 void TestSegmentType(F2fs *fs, Dir *root_dir, const std::string_view name, bool is_dir,
@@ -106,9 +110,9 @@
 }
 
 void MountTestActiveLogs(F2fs *fs, MountOptions options) {
-  fbl::RefPtr<VnodeF2fs> data_root;
-  ASSERT_EQ(VnodeF2fs::Vget(fs, fs->RawSb().root_ino, &data_root), ZX_OK);
-  Dir *root_dir = static_cast<Dir *>(data_root.get());
+  fbl::RefPtr<VnodeF2fs> root;
+  unittest_lib::CreateRoot(fs, &root);
+  Dir *root_dir = static_cast<Dir *>(root.get());
   const char *filenames[] = {"dir", "warm.exe", "cold.mp4"};
   std::vector<CursegType> results(3, CursegType::kNoCheckType);
   uint32_t num_logs = 0;
@@ -152,53 +156,34 @@
       }
     }
   }
+
+  ASSERT_EQ(root->Close(), ZX_OK);
+  root = nullptr;
 }
 
 void MountTestMain(MountOptions &options, uint32_t test, uint32_t priv) {
   std::unique_ptr<f2fs::Bcache> bc;
-  bool readonly_device = false;
-  auto device = std::make_unique<FakeBlockDevice>(
-      FakeBlockDevice::Config{.block_count = kMinVolumeSize / kDefaultSectorSize,
-                              .block_size = kDefaultSectorSize,
-                              .supports_trim = false});
-
-  ASSERT_TRUE(device);
-  ASSERT_EQ(CreateBcache(std::move(device), &readonly_device, &bc), ZX_OK);
-
-  MkfsWorker mkfs(bc.get());
-  ASSERT_EQ(mkfs.DoMkfs(), ZX_OK);
+  unittest_lib::MkfsOnFakeDev(&bc);
 
   std::unique_ptr<F2fs> fs;
-  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
+  unittest_lib::MountWithOptions(options, &bc, &fs);
 
-  // Enclose the channels in a scope to ensure they are closed before we shut down.
-  {
-    zx::channel mount_channel, remote_mount_channel;
-    ASSERT_EQ(zx::channel::create(0, &mount_channel, &remote_mount_channel), ZX_OK);
-    auto fs_or = f2fs::CreateFsAndRoot(
-        options, loop.dispatcher(), std::move(bc), std::move(mount_channel), [] {},
-        ServeLayout::kExportDirectory);
+  switch (test) {
+    case kMountVerifyTest:
+      MountTestVerifyOptions(fs.get(), options);
+      break;
+    case kMountDisableExtTest:
+      MountTestDisableExt(fs.get(), priv);
+      break;
+    case kMountActiveLogsTest:
+      MountTestActiveLogs(fs.get(), options);
+      break;
+    default:
+      ASSERT_EQ(0, 1);
+      break;
+  };
 
-    ASSERT_EQ(fs_or.is_ok(), true);
-    fs = std::move(fs_or).value();
-    switch (test) {
-      case kMountVerifyTest:
-        MountTestVerifyOptions(fs.get(), options);
-        break;
-      case kMountDisableExtTest:
-        MountTestDisableExt(fs.get(), priv);
-        break;
-      case kMountActiveLogsTest:
-        MountTestActiveLogs(fs.get(), options);
-        break;
-      default:
-        ASSERT_EQ(0, 1);
-        break;
-    };
-  }
-  fs->Shutdown([&loop](zx_status_t) { loop.Quit(); });
-
-  ASSERT_EQ(loop.Run(), ZX_ERR_CANCELED);
+  unittest_lib::Unmount(std::move(fs), &bc);
 }
 
 TEST(MountTest, Verify) {