From 6177090eca2f48b25d8f48b2c994f946c040f599 Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Wed, 9 Aug 2023 18:32:46 +0200 Subject: [PATCH] Don't enable `readlink` if filesystem has no symlinks This reduces the number of `getattr` calls with WinFsp and should improve performance on Windows. --- include/dwarfs/filesystem_v2.h | 3 +++ include/dwarfs/metadata_v2.h | 4 ++++ src/dwarfs/filesystem_v2.cpp | 1 + src/dwarfs/metadata_v2.cpp | 2 ++ src/dwarfs_main.cpp | 22 ++++++++++++++-------- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/include/dwarfs/filesystem_v2.h b/include/dwarfs/filesystem_v2.h index fa8a854c..12b18cd9 100644 --- a/include/dwarfs/filesystem_v2.h +++ b/include/dwarfs/filesystem_v2.h @@ -169,6 +169,8 @@ class filesystem_v2 { size_t num_blocks() const { return impl_->num_blocks(); } + bool has_symlinks() const { return impl_->has_symlinks(); } + class impl { public: virtual ~impl() = default; @@ -207,6 +209,7 @@ class filesystem_v2 { virtual void set_num_workers(size_t num) = 0; virtual void set_cache_tidy_config(cache_tidy_config const& cfg) = 0; virtual size_t num_blocks() const = 0; + virtual bool has_symlinks() const = 0; }; private: diff --git a/include/dwarfs/metadata_v2.h b/include/dwarfs/metadata_v2.h index 3a64c222..b382638f 100644 --- a/include/dwarfs/metadata_v2.h +++ b/include/dwarfs/metadata_v2.h @@ -132,6 +132,8 @@ class metadata_v2 { size_t block_size() const { return impl_->block_size(); } + bool has_symlinks() const { return impl_->has_symlinks(); } + static std::pair, std::vector> freeze(const thrift::metadata::metadata& data); @@ -184,6 +186,8 @@ class metadata_v2 { virtual std::optional get_chunks(int inode) const = 0; virtual size_t block_size() const = 0; + + virtual bool has_symlinks() const = 0; }; private: diff --git a/src/dwarfs/filesystem_v2.cpp b/src/dwarfs/filesystem_v2.cpp index bf11a17a..e5bc88b0 100644 --- a/src/dwarfs/filesystem_v2.cpp +++ b/src/dwarfs/filesystem_v2.cpp @@ -356,6 +356,7 @@ class filesystem_ final : public filesystem_v2::impl { ir_.set_cache_tidy_config(cfg); } size_t num_blocks() const override { return ir_.num_blocks(); } + bool has_symlinks() const override { return meta_.has_symlinks(); } private: filesystem_info const& get_info() const; diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 4f9e9bef..052eb594 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -428,6 +428,8 @@ class metadata_ final : public metadata_v2::impl { size_t block_size() const override { return meta_.block_size(); } + bool has_symlinks() const override { return !meta_.symlink_table().empty(); } + private: template using set_type = folly::F14ValueSet; diff --git a/src/dwarfs_main.cpp b/src/dwarfs_main.cpp index 09ca412c..66d2ddd9 100644 --- a/src/dwarfs_main.cpp +++ b/src/dwarfs_main.cpp @@ -1014,12 +1014,15 @@ int option_hdl(void* data, char const* arg, int key, #if DWARFS_FUSE_LOWLEVEL template -void init_fuse_ops(struct fuse_lowlevel_ops& ops) { +void init_fuse_ops(struct fuse_lowlevel_ops& ops, + dwarfs_userdata const& userdata) { ops.init = &op_init; ops.lookup = &op_lookup; ops.getattr = &op_getattr; ops.access = &op_access; - ops.readlink = &op_readlink; + if (userdata.fs.has_symlinks()) { + ops.readlink = &op_readlink; + } ops.open = &op_open; ops.read = &op_read; ops.readdir = &op_readdir; @@ -1029,11 +1032,14 @@ void init_fuse_ops(struct fuse_lowlevel_ops& ops) { } #else template -void init_fuse_ops(struct fuse_operations& ops) { +void init_fuse_ops(struct fuse_operations& ops, + dwarfs_userdata const& userdata) { ops.init = &op_init; ops.getattr = &op_getattr; ops.access = &op_access; - ops.readlink = &op_readlink; + if (userdata.fs.has_symlinks()) { + ops.readlink = &op_readlink; + } ops.open = &op_open; ops.read = &op_read; ops.readdir = &op_readdir; @@ -1060,9 +1066,9 @@ int run_fuse(struct fuse_args& args, ::memset(&fsops, 0, sizeof(fsops)); if (userdata.opts.debuglevel >= logger::DEBUG) { - init_fuse_ops(fsops); + init_fuse_ops(fsops, userdata); } else { - init_fuse_ops(fsops); + init_fuse_ops(fsops, userdata); } int err = 1; @@ -1108,9 +1114,9 @@ int run_fuse(struct fuse_args& args, char* mountpoint, int mt, int fg, ::memset(&fsops, 0, sizeof(fsops)); if (userdata.opts.debuglevel >= logger::DEBUG) { - init_fuse_ops(fsops); + init_fuse_ops(fsops, userdata); } else { - init_fuse_ops(fsops); + init_fuse_ops(fsops, userdata); } int err = 1;