Reland: resolve FUSE and lower FS cache inconsistencies
Rf - Read FUSE, Wf - Write FUSE
Rl - Read lower fs, Wl - Write lower fs
File reads in the following scenarios may not see the latest data
because of different VFS caches:
1. Rf - Wl -Rf
2. Rl - Wf - Rl
To fix the scenarios above we dynamically return a FUSE or lower FS fd
from the MediaProvider#open or open with or without caching during
FUSE_OPEN. Here are the conditions:
MP open:
- Return FUSE fd if file already opened with caching via FUSE or we are
unable to SET_OFD_SETLK to F_RDLCK or F_WRLCK with fcntl(2).
- Return lower FS fd otherwise
FUSE open:
- Open with caching if F_OFD_GETLK with fcntl(2) returns F_UNLCK
- Open with direct_io otherwise
Unfortunately, we cannot place a F_RDLCK on a file opened in write
only mode and we cannot place a F_WRLCK twice. This means that if a
file is opened via MP in write only mode, we can only set a F_WRLCK
and subsequent opens will have to go through FUSE.
Pseudo code of algorithm implemented:
MP#opeFd
lowerFsFd = open(lowerPath)
useFuse = FuseD#shouldOpenWithFuse(lowerPath, fd)
if useFuse
upperFsFd = open(upperPath)
return upperFsFd
else
return lowerFsFd
FuseD#open
lowerFsFd = open(path)
hasLock = fcntl(get_lock, lowerFsFd)
if hasLock
return uncachedFileInfo
else
return cachedFileInfo
FuseD#shouldOpenWithFuse
if cached
return true
else
res = fcntl(set_read_or_write_lock, fd)
return res
Test: atest FuseDaemonHostTest#testVfsCacheConsistency
Test: atest FuseDaemonHostTest
Test: adb logcat -v color | grep --color=never -iE "using fuse|using lower|using direct|using cache"
Change-Id: I7726a75a51869c0e3ea3856103dd501b1aa19d14
FuseDaemon: [/storage/emulated] Using cache for /storage/emulated/0/DCIM/open_file_path_write_content_resolver.jpg
MediaProvider: Using FUSE for /storage/emulated/0/DCIM/open_file_path_write_content_resolver.jpg
FuseDaemon: [/storage/emulated] Using cache for /storage/emulated/0/DCIM/open_file_path_write_content_resolver.jpg
MediaProvider: Using lower FS for /storage/emulated/0/DCIM/open_content_resolver_write_content_resolver.jpg
FuseDaemon: [/storage/emulated] Using direct io for /storage/emulated/0/DCIM/open_content_resolver_write_content_resolver.jpg
FuseDaemon: [/storage/emulated] Using cache for /storage/emulated/0/DCIM/open_file_path_write_file_path.jpg
MediaProvider: Using FUSE for /storage/emulated/0/DCIM/open_file_path_write_file_path.jpg
FuseDaemon: [/storage/emulated] Using cache for /storage/emulated/0/DCIM/open_file_path_write_file_path.jpg
MediaProvider: Using lower FS for /storage/emulated/0/DCIM/open_content_resolver_write_file_path.jpg
FuseDaemon: [/storage/emulated] Using direct io for /storage/emulated/0/DCIM/open_content_resolver_write_file_path.jpg
MediaProvider: Using lower FS for /storage/emulated/0/DCIM/open_content_resolver_write_only.jpg
MediaProvider: Using FUSE for /storage/emulated/0/DCIM/open_content_resolver_write_only.jpg
FuseDaemon: [/storage/emulated] Using direct io for /storage/emulated/0/DCIM/open_content_resolver_write_only.jpg
MediaProvider: Using lower FS for /storage/emulated/0/DCIM/open_content_resolver_dup.jpg
FuseDaemon: [/storage/emulated] Using direct io for /storage/emulated/0/DCIM/open_content_resolver_dup.jpg
Bug: 135341433
8 files changed