From 03e31332a38f0f812836bec92dab5fe5f313d48e Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Fri, 31 May 2019 13:22:34 +0100 Subject: [PATCH] Close /dev/fuse FD before calling onClosed This works around a deadlock when a bridge that is about to be closed is reused for a new call to openFile. The call to open() ends up holding the vold lock, waiting for appfuse to respond. The appfuse event loop calls onClosed(), which ends up calling vold.unmountAppFuse(), which cannot get the lock. Closing this file descriptor causes any current calls to open() on its mount path to fail with either ECONNABORTED or ENOTCONN, allowing the event loop to make progress, call onClosed() and unmount the path. Note that the failed call to open() will result in a retry, which will create a new appfuse bridge. This is not ideal but not a new problem -- the common case here is that that each call to openProxyFileDescriptor creates a new bridge. This should ideally be improved. Bug: 132344997 Test: flick through info of photos with location info attached Change-Id: I878e5cf86f18c5233f8505f52eb9db076bd72d01 Merged-In: I878e5cf86f18c5233f8505f52eb9db076bd72d01 --- libappfuse/FuseBridgeLoop.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc index ac94e6917..f1ca4463e 100644 --- a/libappfuse/FuseBridgeLoop.cc +++ b/libappfuse/FuseBridgeLoop.cc @@ -353,8 +353,8 @@ bool FuseBridgeLoop::ProcessEventLocked(const std::unordered_setIsClosing()) { const int mount_id = entry->mount_id(); - callback->OnClosed(mount_id); bridges_.erase(mount_id); + callback->OnClosed(mount_id); if (bridges_.size() == 0) { // All bridges are now closed. return false;