From 5650b976733e1f7d712ef842d7d461bb5ca23403 Mon Sep 17 00:00:00 2001 From: Jim906 Date: Thu, 27 Mar 2025 13:01:41 -0400 Subject: [PATCH] nfs4: Acquire fFileCacheLock in Inode::Read() * Prevent file_cache_read() from being called in the middle of Inode::RevalidateFileCache(). * Correct an apparent typo in RevalidateFileCache. * Fixes #16395. If file_cache_read is called in one thread while RevalidateFileCache is in progress in another thread, the file_cache_ref could be deleted while file_cache_read is in progress. Currently, RevalidateFileCache does not update fChange after it obtains a new change value from the server. As a result, for a file that has been changed at least once since its node was constructed, RevalidateFileCache will delete and recreate the file cache each time it is called, instead of returning early as it would if fChange had been updated the last time it ran. Change-Id: Ifbf5a892c3003e41b2c73d9c3c806d8fbd79dff7 Reviewed-on: https://review.haiku-os.org/c/haiku/+/9147 Tested-by: Commit checker robot Reviewed-by: waddlesplash --- src/add-ons/kernel/file_systems/nfs4/Inode.cpp | 2 +- src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index a60345c973..aad4b5eef8 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -182,7 +182,7 @@ Inode::RevalidateFileCache() fMaxFileSize = st.st_size; fFileCache = file_cache_create(fFileSystem->DevId(), ID(), fMaxFileSize); - change = fChange; + fChange = change; return B_OK; } diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp index c97ae59613..a792fc05e5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp @@ -353,6 +353,8 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length) bool eof = false; if ((cookie->fMode & O_NOCACHE) != 0) return ReadDirect(cookie, pos, buffer, _length, &eof); + + MutexLocker _(fFileCacheLock); return file_cache_read(fFileCache, cookie, pos, buffer, _length); }