diff --git a/bench/inodeop_bench/Android.bp b/bench/inodeop_bench/Android.bp
new file mode 100644
index 0000000..a01ddd1
--- /dev/null
+++ b/bench/inodeop_bench/Android.bp
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+cc_binary {
+    name: "inodeop_bench",
+    srcs: ["inodeop_bench.cpp"],
+}
diff --git a/bench/inodeop_bench/OWNERS b/bench/inodeop_bench/OWNERS
new file mode 100644
index 0000000..3ced4a1
--- /dev/null
+++ b/bench/inodeop_bench/OWNERS
@@ -0,0 +1,3 @@
+balsini@google.com
+stefanoduo@google.com
+zezeozue@google.com
diff --git a/bench/inodeop_bench/inodeop_bench.cpp b/bench/inodeop_bench/inodeop_bench.cpp
new file mode 100644
index 0000000..8ff544f
--- /dev/null
+++ b/bench/inodeop_bench/inodeop_bench.cpp
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <chrono>
+#include <functional>
+#include <iostream>
+#include <ratio>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+static constexpr char VERSION[] = "0";
+
+// Self-contained class for collecting and reporting benchmark metrics
+// (currently only execution time).
+class Collector {
+    using time_point = std::chrono::time_point<std::chrono::steady_clock>;
+    using time_unit = std::chrono::duration<double, std::milli>;
+
+    struct Metric {
+        std::string workload;
+        time_unit exec_time;
+        Metric(const std::string& workload, const time_unit& exec_time)
+            : workload(workload), exec_time(exec_time) {}
+    };
+
+    static constexpr char TIME_UNIT[] = "ms";
+    static constexpr char VERSION[] = "0";
+    std::vector<Metric> metrics;
+    time_point reset_time;
+
+  public:
+    Collector() { reset(); }
+
+    void reset() { reset_time = std::chrono::steady_clock::now(); }
+
+    void collect_metric(const std::string& workload) {
+        auto elapsed = std::chrono::steady_clock::now() - reset_time;
+        metrics.emplace_back(workload, std::chrono::duration_cast<time_unit>(elapsed));
+    }
+
+    void report_metrics() {
+        for (const Metric& metric : metrics)
+            std::cout << VERSION << ";" << metric.workload << ";" << metric.exec_time.count() << ";"
+                      << TIME_UNIT << std::endl;
+    }
+};
+
+struct Command {
+    static constexpr char CREATE[] = "create";
+    static constexpr char DELETE[] = "delete";
+    static constexpr char MOVE[] = "move";
+    static constexpr char HARDLINK[] = "hardlink";
+    static constexpr char SYMLINK[] = "symlink";
+    static constexpr char READDIR[] = "readdir";
+    std::string workload;
+    std::string from_dir;
+    std::string from_basename;
+    std::string to_dir;
+    std::string to_basename;
+    bool drop_state;
+    int n_file;
+
+    Command() { reset(); }
+
+    std::string to_string() const {
+        std::stringstream string_repr;
+        string_repr << "Command {\n";
+        string_repr << "\t.workload = " << workload << ",\n";
+        string_repr << "\t.from_dir = " << from_dir << ",\n";
+        string_repr << "\t.from_basename = " << from_basename << ",\n";
+        string_repr << "\t.to_dir = " << to_dir << ",\n";
+        string_repr << "\t.to_basename = " << to_basename << ",\n";
+        string_repr << "\t.drop_state = " << drop_state << ",\n";
+        string_repr << "\t.n_file = " << n_file << "\n";
+        string_repr << "}\n";
+        return string_repr.str();
+    }
+
+    void reset() {
+        workload = "";
+        from_dir = to_dir = "./";
+        from_basename = "from_file";
+        to_basename = "to_file";
+        drop_state = true;
+        n_file = 0;
+    }
+};
+
+void print_version() {
+    std::cout << VERSION << std::endl;
+}
+
+void print_commands(const std::vector<Command>& commands) {
+    for (const Command& command : commands) std::cout << command.to_string();
+}
+
+void usage(std::ostream& ostr, const std::string& program_name) {
+    Command command;
+
+    ostr << "Usage: " << program_name << " [global_options] {[workload_options] -w WORKLOAD_T}\n";
+    ostr << "WORKLOAD_T = {" << Command::CREATE << ", " << Command::DELETE << ", " << Command::MOVE
+         << ", " << Command::HARDLINK << ", " << Command::SYMLINK << "}\n";
+    ostr << "Global options\n";
+    ostr << "\t-v: Print version.\n";
+    ostr << "\t-p: Print parsed workloads and exit.\n";
+    ostr << "Workload options\n";
+    ostr << "\t-d DIR\t\t: Work directory for " << Command::CREATE << "/" << Command::DELETE
+         << " (default '" << command.from_dir << "').\n";
+    ostr << "\t-f FROM-DIR\t: Source directory for " << Command::MOVE << "/" << Command::SYMLINK
+         << "/" << Command::HARDLINK << " (default '" << command.from_dir << "').\n";
+    ostr << "\t-t TO-DIR\t: Destination directory for " << Command::MOVE << "/" << Command::SYMLINK
+         << "/" << Command::HARDLINK << " (default '" << command.to_dir << "').\n";
+    ostr << "\t-n N_FILES\t: Number of files to create/delete etc. (default " << command.n_file
+         << ").\n";
+    ostr << "\t-s\t\t: Do not drop state (caches) before running the workload (default "
+         << !command.drop_state << ").\n";
+    ostr << "NOTE: -w WORKLOAD_T defines a new command and must come after its workload_options."
+         << std::endl;
+}
+
+void drop_state() {
+    // Drop inode/dentry/page caches.
+    std::system("sync; echo 3 > /proc/sys/vm/drop_caches");
+}
+
+static constexpr int OPEN_DIR_FLAGS = O_RDONLY | O_DIRECTORY | O_PATH | O_CLOEXEC;
+
+bool create_files(const std::string& dir, int n_file, const std::string& basename) {
+    int dir_fd = open(dir.c_str(), OPEN_DIR_FLAGS);
+    if (dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open work directory '" << dir << "', error '" << strerror(error)
+                  << "'." << std::endl;
+        return false;
+    }
+
+    for (int i = 0; i < n_file; i++) {
+        std::string filename = basename + std::to_string(i);
+        int fd = openat(dir_fd, filename.c_str(), O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0777);
+        close(fd);
+    }
+
+    close(dir_fd);
+    return true;
+}
+
+bool delete_files(const std::string& dir, int n_file, const std::string& basename) {
+    int dir_fd = open(dir.c_str(), OPEN_DIR_FLAGS);
+    if (dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open work directory '" << dir << "', error '" << strerror(error)
+                  << "'." << std::endl;
+        return false;
+    }
+
+    for (int i = 0; i < n_file; i++) {
+        std::string filename = basename + std::to_string(i);
+        unlinkat(dir_fd, filename.c_str(), 0);
+    }
+
+    close(dir_fd);
+    return true;
+}
+
+bool move_files(const std::string& from_dir, const std::string& to_dir, int n_file,
+                const std::string& from_basename, const std::string& to_basename) {
+    int from_dir_fd = open(from_dir.c_str(), OPEN_DIR_FLAGS);
+    if (from_dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open source directory '" << from_dir << "', error '"
+                  << strerror(error) << "'." << std::endl;
+        return false;
+    }
+    int to_dir_fd = open(to_dir.c_str(), OPEN_DIR_FLAGS);
+    if (to_dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open destination directory '" << to_dir << "', error '"
+                  << strerror(error) << "'." << std::endl;
+        close(from_dir_fd);
+        return false;
+    }
+
+    for (int i = 0; i < n_file; i++) {
+        std::string from_filename = from_basename + std::to_string(i);
+        std::string to_filename = to_basename + std::to_string(i);
+        renameat(from_dir_fd, from_filename.c_str(), to_dir_fd, to_filename.c_str());
+    }
+
+    close(from_dir_fd);
+    close(from_dir_fd);
+    return true;
+}
+
+bool hardlink_files(const std::string& from_dir, const std::string& to_dir, int n_file,
+                    const std::string& from_basename, const std::string& to_basename) {
+    int from_dir_fd = open(from_dir.c_str(), OPEN_DIR_FLAGS);
+    if (from_dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open source directory '" << from_dir << "', error '"
+                  << strerror(error) << "'." << std::endl;
+        return false;
+    }
+    int to_dir_fd = open(to_dir.c_str(), OPEN_DIR_FLAGS);
+    if (to_dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open destination directory '" << to_dir << "', error '"
+                  << strerror(error) << "'." << std::endl;
+        close(from_dir_fd);
+        return false;
+    }
+
+    for (int i = 0; i < n_file; i++) {
+        std::string from_filename = from_basename + std::to_string(i);
+        std::string to_filename = to_basename + std::to_string(i);
+        linkat(from_dir_fd, from_filename.c_str(), to_dir_fd, to_filename.c_str(), 0);
+    }
+
+    close(from_dir_fd);
+    close(to_dir_fd);
+    return true;
+}
+
+bool symlink_files(std::string from_dir, const std::string& to_dir, int n_file,
+                   const std::string& from_basename, const std::string& to_basename) {
+    if (from_dir.back() != '/') from_dir.push_back('/');
+    int to_dir_fd = open(to_dir.c_str(), OPEN_DIR_FLAGS);
+    if (to_dir_fd == -1) {
+        int error = errno;
+        std::cerr << "Failed to open destination directory '" << to_dir << "', error '"
+                  << strerror(error) << "'." << std::endl;
+        return false;
+    }
+
+    for (int i = 0; i < n_file; i++) {
+        std::string from_filepath = from_dir + from_basename + std::to_string(i);
+        std::string to_filename = to_basename + std::to_string(i);
+        symlinkat(from_filepath.c_str(), to_dir_fd, to_filename.c_str());
+    }
+
+    close(to_dir_fd);
+    return true;
+}
+
+bool exhaustive_readdir(const std::string& from_dir) {
+    DIR* dir = opendir(from_dir.c_str());
+    if (dir == nullptr) {
+        int error = errno;
+        std::cerr << "Failed to open working directory '" << from_dir << "', error '"
+                  << strerror(error) << "'." << std::endl;
+        return false;
+    }
+
+    while (readdir(dir) != nullptr)
+        ;
+
+    closedir(dir);
+    return true;
+}
+
+void create_workload(Collector* collector, const Command& command) {
+    if (command.drop_state) drop_state();
+    collector->reset();
+    if (create_files(command.from_dir, command.n_file, command.from_basename))
+        collector->collect_metric(command.workload);
+
+    delete_files(command.from_dir, command.n_file, command.from_basename);
+}
+
+void delete_workload(Collector* collector, const Command& command) {
+    if (!create_files(command.from_dir, command.n_file, command.from_basename)) return;
+
+    if (command.drop_state) drop_state();
+    collector->reset();
+    if (delete_files(command.from_dir, command.n_file, command.from_basename))
+        collector->collect_metric(command.workload);
+}
+
+void move_workload(Collector* collector, const Command& command) {
+    if (!create_files(command.from_dir, command.n_file, command.from_basename)) return;
+
+    if (command.drop_state) drop_state();
+    collector->reset();
+    if (move_files(command.from_dir, command.to_dir, command.n_file, command.from_basename,
+                   command.to_basename))
+        collector->collect_metric(command.workload);
+
+    delete_files(command.to_dir, command.n_file, command.to_basename);
+}
+
+void hardlink_workload(Collector* collector, const Command& command) {
+    if (!create_files(command.from_dir, command.n_file, command.from_basename)) return;
+
+    if (command.drop_state) drop_state();
+    collector->reset();
+    if (hardlink_files(command.from_dir, command.to_dir, command.n_file, command.from_basename,
+                       command.to_basename))
+        collector->collect_metric(command.workload);
+
+    delete_files(command.from_dir, command.n_file, command.from_basename);
+    delete_files(command.to_dir, command.n_file, command.to_basename);
+}
+
+void symlink_workload(Collector* collector, const Command& command) {
+    if (!create_files(command.from_dir, command.n_file, command.from_basename)) return;
+
+    if (command.drop_state) drop_state();
+    collector->reset();
+    if (symlink_files(command.from_dir, command.to_dir, command.n_file, command.from_basename,
+                      command.to_basename))
+        collector->collect_metric(command.workload);
+
+    delete_files(command.to_dir, command.n_file, command.to_basename);
+    delete_files(command.from_dir, command.n_file, command.from_basename);
+}
+
+void readdir_workload(Collector* collector, const Command& command) {
+    if (!create_files(command.from_dir, command.n_file, command.from_basename)) return;
+
+    if (command.drop_state) drop_state();
+    collector->reset();
+    if (exhaustive_readdir(command.from_dir)) collector->collect_metric(command.workload);
+
+    delete_files(command.from_dir, command.n_file, command.from_basename);
+}
+
+using workload_executor_t = std::function<void(Collector*, const Command&)>;
+
+std::unordered_map<std::string, workload_executor_t> executors = {
+        {Command::CREATE, create_workload},   {Command::DELETE, delete_workload},
+        {Command::MOVE, move_workload},       {Command::HARDLINK, hardlink_workload},
+        {Command::SYMLINK, symlink_workload}, {Command::READDIR, readdir_workload}};
+
+int main(int argc, char** argv) {
+    std::vector<Command> commands;
+    Command command;
+    int opt;
+
+    while ((opt = getopt(argc, argv, "hvpsw:d:f:t:n:")) != -1) {
+        switch (opt) {
+            case 'h':
+                usage(std::cout, argv[0]);
+                return EXIT_SUCCESS;
+            case 'v':
+                print_version();
+                return EXIT_SUCCESS;
+            case 'p':
+                print_commands(commands);
+                return EXIT_SUCCESS;
+            case 's':
+                command.drop_state = false;
+                break;
+            case 'w':
+                command.workload = optarg;
+                commands.push_back(command);
+                command.reset();
+                break;
+            case 'd':
+            case 'f':
+                command.from_dir = optarg;
+                break;
+            case 't':
+                command.to_dir = optarg;
+                break;
+            case 'n':
+                command.n_file = std::stoi(optarg);
+                break;
+            default:
+                usage(std::cerr, argv[0]);
+                return EXIT_FAILURE;
+        }
+    }
+
+    Collector collector;
+    for (const Command& command : commands) {
+        auto executor = executors.find(command.workload);
+        if (executor == executors.end()) continue;
+        executor->second(&collector, command);
+    }
+    collector.report_metrics();
+
+    return EXIT_SUCCESS;
+}
