From c60814348645c367fecd82d9036dd6e4f52013e2 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 16 Jun 2020 13:07:42 -0700 Subject: [PATCH] Maintain the fuse buffer pool keyed by inode instead of threadId. In order to save memory, FuseAppLoop maintains a buffer pool to use when dispatching the read/write requests. Currently, it uses the threadId of the ProxyFileDescriptorCallback as the key for this buffer pool and this can result in an issue when a caller creates multiple ProxyFileDescriptors with ProxyFileDescriptorCallbacks running on the same thread. When this happens, it is possible that a buffer is reused before a read/write request which was using it earlier has been handled and would result in data from read/write requests on different fds getting mixed up. Bug: 158568683 Test: atest --test-mapping apex/blobstore Change-Id: Iaffd54f4430ecb3778f01c80f5a1684ac448f8dc --- .../com/android/internal/os/FuseAppLoop.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java index ab0cc3093b6dc..2393036b5a389 100644 --- a/core/java/com/android/internal/os/FuseAppLoop.java +++ b/core/java/com/android/internal/os/FuseAppLoop.java @@ -210,7 +210,7 @@ public class FuseAppLoop implements Handler.Callback { if (mInstance != 0) { native_replySimple(mInstance, unique, FUSE_OK); } - mBytesMap.stopUsing(entry.getThreadId()); + mBytesMap.stopUsing(inode); recycleLocked(args); } break; @@ -270,7 +270,7 @@ public class FuseAppLoop implements Handler.Callback { if (mInstance != 0) { native_replyOpen(mInstance, unique, /* fh */ inode); entry.opened = true; - return mBytesMap.startUsing(entry.getThreadId()); + return mBytesMap.startUsing(inode); } } catch (ErrnoException error) { replySimpleLocked(unique, getError(error)); @@ -354,27 +354,27 @@ public class FuseAppLoop implements Handler.Callback { } /** - * Map between Thread ID and byte buffer. + * Map between inode and byte buffer. */ private static class BytesMap { final Map mEntries = new HashMap<>(); - byte[] startUsing(long threadId) { - BytesMapEntry entry = mEntries.get(threadId); + byte[] startUsing(long inode) { + BytesMapEntry entry = mEntries.get(inode); if (entry == null) { entry = new BytesMapEntry(); - mEntries.put(threadId, entry); + mEntries.put(inode, entry); } entry.counter++; return entry.bytes; } - void stopUsing(long threadId) { - final BytesMapEntry entry = mEntries.get(threadId); + void stopUsing(long inode) { + final BytesMapEntry entry = mEntries.get(inode); Objects.requireNonNull(entry); entry.counter--; if (entry.counter <= 0) { - mEntries.remove(threadId); + mEntries.remove(inode); } }