Skip to content

Commit 337dbd5

Browse files
committed
Merge branch 'fix/SDK-5577_FileCache_current_accesses_the_file_cache_folder_but_it_is_locked' into 'release/v9.13.0'
SDK-5577 FileCache::current accesses the file cache folder but it is locked (release 9.13.0) See merge request sdk/sdk!6887
2 parents 04d4037 + 579e3ca commit 337dbd5

File tree

4 files changed

+65
-42
lines changed

4 files changed

+65
-42
lines changed

include/mega/fuse/common/file_cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class FileCache
6161
const FileAccess& fileAccess,
6262
InodeID id);
6363

64+
// Purge unreferenced files from the cache.
65+
void purge();
66+
6467
// Remove context from the index.
6568
void remove(const FileIOContext& context, FileCacheLock lock);
6669

src/fuse/common/file_cache.cpp

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,48 @@ FileInfoRef FileCache::info(const FileExtension& extension,
103103
return FileInfoRef(i->second.get());
104104
}
105105

106+
void FileCache::purge()
107+
{
108+
// Convenience.
109+
auto& fsAccess = client().fsAccess();
110+
111+
auto dirAccess = fsAccess.newdiraccess();
112+
auto path = mCachePath;
113+
114+
// Try and open the cache directory for iteration.
115+
if (!dirAccess->dopen(&path, nullptr, false))
116+
return;
117+
118+
LocalPath name;
119+
nodetype_t type;
120+
121+
// Iterate over each file the cache.
122+
while (dirAccess->dnext(path, name, false, &type))
123+
{
124+
// Entry isn't a file.
125+
if (type != FILENODE)
126+
continue;
127+
128+
// Convert file name to inode ID.
129+
auto id = InodeID::fromFileName(name.toPath(false));
130+
131+
// Invalid ID.
132+
if (!id)
133+
continue;
134+
135+
// Inode's still present in the database.
136+
if (mContext.mInodeDB.exists(id))
137+
continue;
138+
139+
LocalPath newPath{path};
140+
newPath.appendWithSeparator(name, true);
141+
142+
// Try and remove the file.
143+
if (!fsAccess.unlinklocal(newPath))
144+
FUSEWarningF("Couldn't remove stale cache file: %s", newPath.toPath(false).c_str());
145+
}
146+
}
147+
106148
void FileCache::remove(const FileIOContext& context,
107149
FileCacheLock lock)
108150
{
@@ -160,10 +202,6 @@ FileCache::FileCache(platform::ServiceContext& context)
160202
FUSEDebug1("File Cache constructed");
161203

162204
ensureCachePathExists(client(), mCachePath);
163-
164-
// Prevent others, especially file explorer, from opening files under the folder, generating
165-
// thumbnail while we're running. We have seen we're blocked to open files forever due to this.
166-
WINDOWS_ONLY(mFolderLocker = platform::FolderLocker{mCachePath.asPlatformEncoded(true)});
167205
}
168206

169207
FileCache::~FileCache()
@@ -300,44 +338,15 @@ ErrorOr<FileInfoRef> FileCache::create(const FileExtension& extension,
300338

301339
void FileCache::current()
302340
{
303-
// Convenience.
304-
auto& fsAccess = client().fsAccess();
341+
// Preventive
342+
WINDOWS_ONLY(mFolderLocker.release());
305343

306-
auto dirAccess = fsAccess.newdiraccess();
307-
auto path = mCachePath;
308-
309-
// Try and open the cache directory for iteration.
310-
if (!dirAccess->dopen(&path, nullptr, false))
311-
return;
344+
// Purge any unreferenced files in the cache.
345+
purge();
312346

313-
LocalPath name;
314-
nodetype_t type;
315-
316-
// Iterate over each file the cache.
317-
while (dirAccess->dnext(path, name, false, &type))
318-
{
319-
// Entry isn't a file.
320-
if (type != FILENODE)
321-
continue;
322-
323-
// Convert file name to inode ID.
324-
auto id = InodeID::fromFileName(name.toPath(false));
325-
326-
// Invalid ID.
327-
if (!id)
328-
continue;
329-
330-
// Inode's still present in the database.
331-
if (mContext.mInodeDB.exists(id))
332-
continue;
333-
334-
LocalPath newPath{path};
335-
newPath.appendWithSeparator(name, true);
336-
337-
// Try and remove the file.
338-
if (!fsAccess.unlinklocal(newPath))
339-
FUSEWarningF("Couldn't remove stale cache file: %s", newPath.toPath(false).c_str());
340-
}
347+
// Prevent others, especially file explorer, from opening files under the folder, generating
348+
// thumbnail while we're running. We have seen we're blocked to open files forever due to this.
349+
WINDOWS_ONLY(mFolderLocker = platform::FolderLocker{mCachePath.asPlatformEncoded(true)});
341350
}
342351

343352
TaskExecutor& FileCache::executor() const

src/fuse/supported/windows/mega/fuse/platform/utility.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ class FolderLocker
5555
FolderLocker& operator=(FolderLocker&& other);
5656

5757
~FolderLocker();
58+
59+
void release();
5860
};
5961

6062
} // platform

src/fuse/supported/windows/utility.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,18 @@ FolderLocker& FolderLocker::operator=(FolderLocker&& other)
280280

281281
FolderLocker::~FolderLocker()
282282
{
283-
if (mHandle != INVALID_HANDLE_VALUE)
284-
CloseHandle(mHandle);
283+
release();
285284
}
285+
286+
void FolderLocker::release()
287+
{
288+
if (mHandle == INVALID_HANDLE_VALUE)
289+
return;
290+
291+
CloseHandle(mHandle);
292+
mHandle = INVALID_HANDLE_VALUE;
293+
}
294+
286295
} // platform
287296
} // fuse
288297
} // mega

0 commit comments

Comments
 (0)