From 6369ef2a5d3875b8965be03c310169ea7cc3cc47 Mon Sep 17 00:00:00 2001 From: Nitin Singla Date: Wed, 17 Dec 2025 08:07:38 +0000 Subject: [PATCH 1/2] First change to detect tar and zip files. --- turbonfs/inc/fs-handler.h | 28 ++++++++++++++++++---------- turbonfs/inc/nfs_client.h | 3 ++- turbonfs/inc/nfs_inode.h | 13 ++++++++++++- turbonfs/inc/util.h | 5 +++++ turbonfs/src/nfs_client.cpp | 21 ++++++++++++++++----- turbonfs/src/nfs_inode.cpp | 4 +++- turbonfs/src/util.cpp | 23 +++++++++++++++++++++++ 7 files changed, 79 insertions(+), 18 deletions(-) diff --git a/turbonfs/inc/fs-handler.h b/turbonfs/inc/fs-handler.h index ccdc59c81..ff094f842 100644 --- a/turbonfs/inc/fs-handler.h +++ b/turbonfs/inc/fs-handler.h @@ -308,6 +308,18 @@ static void aznfsc_ll_open(fuse_req_t req, AZLogDebug("aznfsc_ll_open(req={}, ino={}, fi={})", fmt::ptr(req), ino, fmt::ptr(fi)); + struct nfs_client *client = get_nfs_client_from_fuse_req(req); + struct nfs_inode *inode = client->get_nfs_inode_from_ino(ino); + + // Make sure it's not called for directories. + assert(!inode->is_dir()); + + /* + * Should we require kernel cache for this inode? + * We enable kernel cache explicit for tar and zip files. + */ + bool require_kernel_cache = inode->get_require_kernel_cache(); + /* * We plan to manage our own file cache for better control over writes. * @@ -322,8 +334,8 @@ static void aznfsc_ll_open(fuse_req_t req, * doesn't send another write before the prev one completes. We depend * on that. */ - fi->direct_io = !aznfsc_cfg.cache.data.kernel.enable; - fi->keep_cache = aznfsc_cfg.cache.data.kernel.enable; + fi->direct_io = !require_kernel_cache; + fi->keep_cache = require_kernel_cache; fi->nonseekable = 0; fi->parallel_direct_writes = 0; fi->noflush = 0; @@ -334,12 +346,6 @@ static void aznfsc_ll_open(fuse_req_t req, */ fi->fh = 12345678; - struct nfs_client *client = get_nfs_client_from_fuse_req(req); - struct nfs_inode *inode = client->get_nfs_inode_from_ino(ino); - - // Make sure it's not called for directories. - assert(!inode->is_dir()); - /* * For cto consistency open should force revalidate the inode by making a * getattr call and if that indicates that file data has changed (mtime @@ -741,8 +747,10 @@ static void aznfsc_ll_create(fuse_req_t req, /* * See aznfsc_ll_open(). */ - fi->direct_io = !aznfsc_cfg.cache.data.kernel.enable; - fi->keep_cache = aznfsc_cfg.cache.data.kernel.enable; + bool require_kernel_cache = has_tar_or_zip_extension(name); + + fi->direct_io = !require_kernel_cache; + fi->keep_cache = require_kernel_cache; fi->nonseekable = 0; fi->parallel_direct_writes = 0; fi->noflush = 0; diff --git a/turbonfs/inc/nfs_client.h b/turbonfs/inc/nfs_client.h index 489d8c55b..f079e0f7f 100644 --- a/turbonfs/inc/nfs_client.h +++ b/turbonfs/inc/nfs_client.h @@ -368,7 +368,8 @@ struct nfs_client struct nfs_inode *__get_nfs_inode(LOC_PARAMS const nfs_fh3 *fh, const struct fattr3 *fattr, - bool is_root_inode = false); + bool is_root_inode = false, + bool require_kernel_cache = false); #define get_nfs_inode(fh, fattr, ...) \ __get_nfs_inode(LOC_VAL fh, fattr, ## __VA_ARGS__) diff --git a/turbonfs/inc/nfs_inode.h b/turbonfs/inc/nfs_inode.h index 12910d085..ad0d45822 100644 --- a/turbonfs/inc/nfs_inode.h +++ b/turbonfs/inc/nfs_inode.h @@ -327,6 +327,8 @@ struct nfs_inode */ bool stable_write = true; + bool require_kernel_cache = false; + /* * XXX This is for debugging. * It's set in truncate_start() and cleared in truncate_end(). @@ -462,7 +464,8 @@ struct nfs_inode const struct fattr3 *fattr, struct nfs_client *_client, uint32_t _file_type, - fuse_ino_t _ino = 0); + fuse_ino_t _ino = 0, + bool require_kernel_cache = false); ~nfs_inode(); @@ -1791,6 +1794,14 @@ struct nfs_inode return stable_write; } + /** + * Does this inode require kernel cache? + */ + bool get_require_kernel_cache() const + { + return require_kernel_cache; + } + /** * Directory cache lookup method. * diff --git a/turbonfs/inc/util.h b/turbonfs/inc/util.h index 38e48b45e..657cc90b0 100644 --- a/turbonfs/inc/util.h +++ b/turbonfs/inc/util.h @@ -28,6 +28,11 @@ namespace aznfsc { */ uint64_t get_total_ram(); +/* + * Check file extension has tar or zip. + */ +bool has_tar_or_zip_extension(const char *filename); + /** * Set readahead_kb for kernel readahead. * This sets the kernel readahead value of aznfsc_cfg.readahead_kb iff kernel diff --git a/turbonfs/src/nfs_client.cpp b/turbonfs/src/nfs_client.cpp index 01d234963..bc275335e 100644 --- a/turbonfs/src/nfs_client.cpp +++ b/turbonfs/src/nfs_client.cpp @@ -67,7 +67,8 @@ bool nfs_client::init() */ root_fh = get_nfs_inode(nfs_get_rootfh(transport.get_nfs_context()), &fattr, - true /* is_root_inode */); + true /* is_root_inode */, + false /* require_kernel_cache */); assert(root_fh->lookupcnt == 1); assert(root_fh->dircachecnt == 0); @@ -740,7 +741,8 @@ struct nfs_inode *nfs_client::__inode_from_inode_map(const nfs_fh3 *fh, struct nfs_inode *nfs_client::__get_nfs_inode(LOC_PARAMS const nfs_fh3 *fh, const struct fattr3 *fattr, - bool is_root_inode) + bool is_root_inode, + bool require_kernel_cache) { assert(fh); assert(fattr); @@ -864,7 +866,8 @@ struct nfs_inode *nfs_client::__get_nfs_inode(LOC_PARAMS struct nfs_inode *new_inode = new nfs_inode(fh, fattr, this, file_type, - is_root_inode ? FUSE_ROOT_ID : 0); + is_root_inode ? FUSE_ROOT_ID : 0, + require_kernel_cache); { std::unique_lock lock(inode_map_lock_0); @@ -1205,10 +1208,13 @@ static void lookup_sync_callback( if (status == 0) { assert(res->LOOKUP3res_u.resok.obj_attributes.attributes_follow); + bool require_kernel_cache = has_tar_or_zip_extension( + task->rpc_api->lookup_task.get_file_name()); const nfs_fh3 *fh = (const nfs_fh3 *) &res->LOOKUP3res_u.resok.object; const struct fattr3 *fattr = (const struct fattr3 *) &res->LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes; - const struct nfs_inode *inode = task->get_client()->get_nfs_inode(fh, fattr); + const struct nfs_inode *inode = task->get_client()->get_nfs_inode(fh, fattr, false /* is_root_inode */, + require_kernel_cache); (*child_ino_p) = inode->get_fuse_ino(); if (ctx->fattr) { *(ctx->fattr) = *fattr; @@ -1997,6 +2003,11 @@ void nfs_client::reply_entry( enum fuse_opcode optype = task->get_op_type(); struct nfs_inode *inode = nullptr; fuse_entry_param entry; + bool require_kernel_cache = false; + if (file) { + require_kernel_cache = file->keep_cache; + } + /* * Kernel must cache lookup result. */ @@ -2013,7 +2024,7 @@ void nfs_client::reply_entry( * This will grab a lookupcnt ref on the inode, which will be freed * from fuse forget callback. */ - inode = get_nfs_inode(fh, fattr); + inode = get_nfs_inode(fh, fattr, false, require_kernel_cache); entry.ino = inode->get_fuse_ino(); entry.generation = inode->get_generation(); diff --git a/turbonfs/src/nfs_inode.cpp b/turbonfs/src/nfs_inode.cpp index eadb40db9..669563df8 100644 --- a/turbonfs/src/nfs_inode.cpp +++ b/turbonfs/src/nfs_inode.cpp @@ -17,11 +17,13 @@ nfs_inode::nfs_inode(const struct nfs_fh3 *filehandle, const struct fattr3 *fattr, struct nfs_client *_client, uint32_t _file_type, - fuse_ino_t _ino) : + fuse_ino_t _ino, + bool require_kernel_cache) : file_type(_file_type), fh(*filehandle), crc(calculate_crc32(fh.get_fh())), ino(_ino == 0 ? (fuse_ino_t) this : _ino), + require_kernel_cache(require_kernel_cache), generation(get_current_usecs()), client(_client) { diff --git a/turbonfs/src/util.cpp b/turbonfs/src/util.cpp index 2bff1725e..ebf9c8f38 100644 --- a/turbonfs/src/util.cpp +++ b/turbonfs/src/util.cpp @@ -34,6 +34,29 @@ uint64_t get_total_ram() return num_pages * page_size; } +/* + * Check file extension has tar or zip. + */ +bool has_tar_or_zip_extension(const char *filename) +{ + assert(filename != nullptr); + + const char *ext = ::strrchr(filename, '.'); + if (ext == nullptr) { + return false; + } + + if ((::strcasecmp(ext, ".tar") == 0) || + (::strcasecmp(ext, ".zip") == 0) || + (::strcasecmp(ext, ".tar.gz") == 0) || + (::strcasecmp(ext, ".tgz") == 0)) { + return true; + } + + return false; +} + + /** * Set readahead_kb for kernel readahead. * This sets the kernel readahead value of aznfsc_cfg.readahead_kb iff kernel From 1f802c0a4779f4fbd1e02c4bb90b28468e76e9b4 Mon Sep 17 00:00:00 2001 From: Nitin Singla Date: Wed, 17 Dec 2025 08:22:33 +0000 Subject: [PATCH 2/2] Build Fix --- turbonfs/inc/fs-handler.h | 2 ++ turbonfs/inc/nfs_inode.h | 8 ++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/turbonfs/inc/fs-handler.h b/turbonfs/inc/fs-handler.h index ff094f842..a9f961f74 100644 --- a/turbonfs/inc/fs-handler.h +++ b/turbonfs/inc/fs-handler.h @@ -319,6 +319,7 @@ static void aznfsc_ll_open(fuse_req_t req, * We enable kernel cache explicit for tar and zip files. */ bool require_kernel_cache = inode->get_require_kernel_cache(); + require_kernel_cache = require_kernel_cache ? true : aznfsc_cfg.cache.data.kernel.enable; /* * We plan to manage our own file cache for better control over writes. @@ -748,6 +749,7 @@ static void aznfsc_ll_create(fuse_req_t req, * See aznfsc_ll_open(). */ bool require_kernel_cache = has_tar_or_zip_extension(name); + require_kernel_cache = require_kernel_cache ? true : aznfsc_cfg.cache.data.kernel.enable; fi->direct_io = !require_kernel_cache; fi->keep_cache = require_kernel_cache; diff --git a/turbonfs/inc/nfs_inode.h b/turbonfs/inc/nfs_inode.h index ad0d45822..6d8ee18d1 100644 --- a/turbonfs/inc/nfs_inode.h +++ b/turbonfs/inc/nfs_inode.h @@ -327,8 +327,6 @@ struct nfs_inode */ bool stable_write = true; - bool require_kernel_cache = false; - /* * XXX This is for debugging. * It's set in truncate_start() and cleared in truncate_end(). @@ -354,6 +352,12 @@ struct nfs_inode * IMPORTANT: Need to ensure time is sync'ed and it doesn't go back. */ const fuse_ino_t ino; + + /* + * Does this inode require kernel cache? + */ + const bool require_kernel_cache; + const uint64_t generation; /*