summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java21
1 files changed, 20 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 15fc2dc15d02..f6835feeea16 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3651,7 +3651,26 @@ class StorageManagerService extends IStorageManager.Stub
Watchdog.getInstance().pauseWatchingMonitorsFor(
SLOW_OPERATION_WATCHDOG_TIMEOUT_MS, "#close might be slow");
if (mMounted) {
- mVold.unmountAppFuse(uid, mountId);
+ BackgroundThread.getHandler().post(() -> {
+ try {
+ // We need to run the unmount on a separate thread to
+ // prevent a possible deadlock, where:
+ // 1. AppFuseThread (this thread) tries to call into vold
+ // 2. the vold lock is held by another thread, which called:
+ // mVold.openAppFuseFile()
+ // as part of that call, vold calls open() on the
+ // underlying file, which is a call that needs to be
+ // handled by the AppFuseThread, which is stuck waiting
+ // for the vold lock (see 1.)
+ // It is safe to do the unmount asynchronously, because the mount
+ // path we use is never reused during the current boot cycle;
+ // see mNextAppFuseName. Also,we have anyway stopped serving
+ // requests at this point.
+ mVold.unmountAppFuse(uid, mountId);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ });
mMounted = false;
}
}