Don't enable readlink if filesystem has no symlinks

This reduces the number of `getattr` calls with WinFsp and should
improve performance on Windows.
This commit is contained in:
Marcus Holland-Moritz 2023-08-09 18:32:46 +02:00
parent 1eeab7bfef
commit 6177090eca
5 changed files with 24 additions and 8 deletions

View File

@ -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:

View File

@ -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<uint8_t>, std::vector<uint8_t>>
freeze(const thrift::metadata::metadata& data);
@ -184,6 +186,8 @@ class metadata_v2 {
virtual std::optional<chunk_range> get_chunks(int inode) const = 0;
virtual size_t block_size() const = 0;
virtual bool has_symlinks() const = 0;
};
private:

View File

@ -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;

View File

@ -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 <typename K>
using set_type = folly::F14ValueSet<K>;

View File

@ -1014,12 +1014,15 @@ int option_hdl(void* data, char const* arg, int key,
#if DWARFS_FUSE_LOWLEVEL
template <typename LoggerPolicy>
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<LoggerPolicy>;
ops.lookup = &op_lookup<LoggerPolicy>;
ops.getattr = &op_getattr<LoggerPolicy>;
ops.access = &op_access<LoggerPolicy>;
ops.readlink = &op_readlink<LoggerPolicy>;
if (userdata.fs.has_symlinks()) {
ops.readlink = &op_readlink<LoggerPolicy>;
}
ops.open = &op_open<LoggerPolicy>;
ops.read = &op_read<LoggerPolicy>;
ops.readdir = &op_readdir<LoggerPolicy>;
@ -1029,11 +1032,14 @@ void init_fuse_ops(struct fuse_lowlevel_ops& ops) {
}
#else
template <typename LoggerPolicy>
void init_fuse_ops(struct fuse_operations& ops) {
void init_fuse_ops(struct fuse_operations& ops,
dwarfs_userdata const& userdata) {
ops.init = &op_init<LoggerPolicy>;
ops.getattr = &op_getattr<LoggerPolicy>;
ops.access = &op_access<LoggerPolicy>;
ops.readlink = &op_readlink<LoggerPolicy>;
if (userdata.fs.has_symlinks()) {
ops.readlink = &op_readlink<LoggerPolicy>;
}
ops.open = &op_open<LoggerPolicy>;
ops.read = &op_read<LoggerPolicy>;
ops.readdir = &op_readdir<LoggerPolicy>;
@ -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<debug_logger_policy>(fsops);
init_fuse_ops<debug_logger_policy>(fsops, userdata);
} else {
init_fuse_ops<prod_logger_policy>(fsops);
init_fuse_ops<prod_logger_policy>(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<debug_logger_policy>(fsops);
init_fuse_ops<debug_logger_policy>(fsops, userdata);
} else {
init_fuse_ops<prod_logger_policy>(fsops);
init_fuse_ops<prod_logger_policy>(fsops, userdata);
}
int err = 1;