summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xjni/FuseDaemon.cpp20
-rw-r--r--jni/node-inl.h4
-rw-r--r--src/com/android/providers/media/MediaProvider.java2
3 files changed, 17 insertions, 9 deletions
diff --git a/jni/FuseDaemon.cpp b/jni/FuseDaemon.cpp
index 74429f94d..ac9f7e502 100755
--- a/jni/FuseDaemon.cpp
+++ b/jni/FuseDaemon.cpp
@@ -495,6 +495,12 @@ static node* make_node_entry(fuse_req_t req, node* parent, const string& name, c
std::thread t([=]() { fuse_inval(fuse->se, parent_ino, child_ino, node_name, path); });
t.detach();
}
+
+ // This updated value allows us correctly decide if to keep_cache and use direct_io during
+ // FUSE_OPEN. Between the last lookup and this lookup, we might have deleted a cached
+ // transcoded file on the lower fs. A subsequent transcode at FUSE_READ should ensure we
+ // don't reuse any stale transcode page cache content.
+ node->SetTransformsComplete(transforms_complete);
}
TRACE_NODE(node, req);
@@ -1044,12 +1050,13 @@ static handle* create_handle_for_node(struct fuse* fuse, const string& path, int
bool redaction_needed = ri->isRedactionNeeded();
handle* handle = nullptr;
int transforms = node->GetTransforms();
+ bool transforms_complete = node->IsTransformsComplete();
if (transforms_uid > 0) {
CHECK(transforms);
}
if (fuse->passthrough) {
- *keep_cache = 1;
+ *keep_cache = transforms_complete;
// We only enabled passthrough iff these 2 conditions hold
// 1. Redaction is not needed
// 2. Node transforms are completed, e.g transcoding.
@@ -1058,10 +1065,9 @@ static handle* create_handle_for_node(struct fuse* fuse, const string& path, int
// arbitrary bytes the first time around. However, if we ensure that transforms are
// completed, then it's safe to use passthrough. Additionally, transcoded nodes never
// require redaction so (2) implies (1)
- handle = new struct handle(
- fd, ri, true /* cached */,
- !redaction_needed && node->IsTransformsComplete() /* passthrough */, uid,
- transforms_uid);
+ handle = new struct handle(fd, ri, true /* cached */,
+ !redaction_needed && transforms_complete /* passthrough */, uid,
+ transforms_uid);
} else {
// Without fuse->passthrough, we don't want to use the FUSE VFS cache in two cases:
// 1. When redaction is needed because app A with EXIF access might access
@@ -1087,7 +1093,7 @@ static handle* create_handle_for_node(struct fuse* fuse, const string& path, int
// Purges stale page cache before open
*keep_cache = 0;
} else {
- *keep_cache = 1;
+ *keep_cache = transforms_complete;
}
handle = new struct handle(fd, ri, !direct_io /* cached */, false /* passthrough */, uid,
transforms_uid);
@@ -1280,7 +1286,7 @@ static void pf_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
fuse_reply_err(req, EFAULT);
return;
}
- node->SetTransformsComplete();
+ node->SetTransformsComplete(true);
}
fuse->fadviser.Record(h->fd, size);
diff --git a/jni/node-inl.h b/jni/node-inl.h
index 9b30e8742..e531a0a2b 100644
--- a/jni/node-inl.h
+++ b/jni/node-inl.h
@@ -285,7 +285,9 @@ class node {
return transforms_complete_.load(std::memory_order_acquire);
}
- void SetTransformsComplete() { transforms_complete_.store(true, std::memory_order_release); }
+ void SetTransformsComplete(bool complete) {
+ transforms_complete_.store(complete, std::memory_order_release);
+ }
node* GetParent() const {
std::lock_guard<std::recursive_mutex> guard(*lock_);
diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java
index b20e6daf4..035d3e758 100644
--- a/src/com/android/providers/media/MediaProvider.java
+++ b/src/com/android/providers/media/MediaProvider.java
@@ -1474,7 +1474,7 @@ public class MediaProvider extends ContentProvider {
if (transformsReason > 0) {
ioPath = mTranscodeHelper.getIoPath(path, uid);
- transformsComplete = false;
+ transformsComplete = mTranscodeHelper.isTranscodeFileCached(path, ioPath);
transforms = FLAG_TRANSFORM_TRANSCODING;
}
}