summaryrefslogtreecommitdiff
path: root/jni
diff options
context:
space:
mode:
Diffstat (limited to 'jni')
-rw-r--r--jni/Android.bp3
-rw-r--r--jni/FuseDaemon.cpp20
2 files changed, 18 insertions, 5 deletions
diff --git a/jni/Android.bp b/jni/Android.bp
index 35721d5a6..71b51188a 100644
--- a/jni/Android.bp
+++ b/jni/Android.bp
@@ -71,6 +71,9 @@ cc_library_shared {
sdk_version: "current",
stl: "c++_static",
min_sdk_version: "30",
+ apex_available: [
+ "com.android.mediaprovider",
+ ],
}
cc_test {
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index e2390e890..73f92d6f7 100644
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -702,7 +702,7 @@ static node* make_node_entry(fuse_req_t req, node* parent, const string& name,
// directories.
if (!fuse->bpf || !is_bpf_backing_path(parent_path)) {
e->entry_timeout = get_entry_timeout(path, should_invalidate, fuse);
- e->attr_timeout = std::numeric_limits<double>::max();
+ e->attr_timeout = fuse->ShouldNotCache(path) ? 0 : std::numeric_limits<double>::max();
}
return node;
}
@@ -720,11 +720,19 @@ namespace fuse {
static void pf_init(void* userdata, struct fuse_conn_info* conn) {
struct fuse* fuse = reinterpret_cast<struct fuse*>(userdata);
+ // Check the same property as android.os.Build.IS_ARC.
+ const bool is_arc = android::base::GetBoolProperty("ro.boot.container", false);
+
// We don't want a getattr request with every read request
conn->want &= ~FUSE_CAP_AUTO_INVAL_DATA & ~FUSE_CAP_READDIRPLUS_AUTO;
uint64_t mask = (FUSE_CAP_SPLICE_WRITE | FUSE_CAP_SPLICE_MOVE | FUSE_CAP_SPLICE_READ |
FUSE_CAP_ASYNC_READ | FUSE_CAP_ATOMIC_O_TRUNC | FUSE_CAP_WRITEBACK_CACHE |
- FUSE_CAP_EXPORT_SUPPORT | FUSE_CAP_FLOCK_LOCKS);
+ FUSE_CAP_EXPORT_SUPPORT | FUSE_CAP_FLOCK_LOCKS | FUSE_CAP_PARALLEL_DIROPS);
+ // Disable writeback cache if it's uncached mode or if it's ARC. In ARC, due to the Downloads
+ // bind-mount, we need to disable it on the primary emulated volume as well as on StubVolumes.
+ if (fuse->uncached_mode || is_arc) {
+ mask &= ~FUSE_CAP_WRITEBACK_CACHE;
+ }
bool disable_splice_write = false;
if (fuse->passthrough) {
@@ -1038,7 +1046,8 @@ static void pf_getattr(fuse_req_t req,
if (lstat(path.c_str(), &s) < 0) {
fuse_reply_err(req, errno);
} else {
- fuse_reply_attr(req, &s, std::numeric_limits<double>::max());
+ fuse_reply_attr(req, &s,
+ fuse->ShouldNotCache(path) ? 0 : std::numeric_limits<double>::max());
}
}
@@ -1141,7 +1150,7 @@ static void pf_setattr(fuse_req_t req,
}
lstat(path.c_str(), attr);
- fuse_reply_attr(req, attr, std::numeric_limits<double>::max());
+ fuse_reply_attr(req, attr, fuse->ShouldNotCache(path) ? 0 : std::numeric_limits<double>::max());
}
static void pf_canonical_path(fuse_req_t req, fuse_ino_t ino)
@@ -2381,7 +2390,8 @@ void FuseDaemon::InvalidateFuseDentryCache(const std::string& path) {
}
if (!name.empty()) {
- fuse_inval(fuse->se, parent, child, name, path);
+ std::thread t([=]() { fuse_inval(fuse->se, parent, child, name, path); });
+ t.detach();
}
} else {
LOG(WARNING) << "FUSE daemon is inactive. Cannot invalidate dentry";