Only set quota project ID inheritance on app-private dirs.
Previously every directory on external storage had project ID quota
inheritance enabled; this means that if any new file/directory is
created under such a directory, it will inherit the project ID from the
parent. We use a default project ID of 1000 for generic directories, and
application-specific project IDs for app-specific directories.
MediaProvider is responsible for updating the quota type in the generic
directories, as it scans all files there. However, there is a problem
with this approach: if you move a file to a directory with project ID
inheritance set, and the project ID of that file differs from the
project ID of the dir, that results in an EXDEV error, and requires a
copy instead. For example, if /sdcard/DCIM/test.jpg has a project ID of
1003 (for images), and you try to move it to /sdcard/Pictures/test.jpg,
that would require a copy, because the project ID of /sdcard/Pictures is
1000.
While this is not a very common scenario, it's still better to avoid it.
Luckily we can - since MediaProvider anyway scans all files, it will set
the project ID on individual files correctly - there's no need to
inherit them.
We then only need to inherit quota in application-specific directories,
since in those directories the app can create files itself, and those
need to be tagged correctly.
This change enables that, by removing quota inheritance setting from the
top-level directory, and instead doing it for app-specific directories
instead.
Bug: 151078664
Test: atest StorageHostTest
atest com.android.tests.fused.host.FuseDaemonHostTest#testRenameAndReplaceFile
Change-Id: I38a057ec61cb627e39a3ff7ac58c7218dc251bdc
diff --git a/Utils.cpp b/Utils.cpp
index 82ad1f1..1e20d75 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -366,6 +366,15 @@
if (ret != 0) {
return ret;
}
+
+ if (!IsFilesystemSupported("sdcardfs")) {
+ // Set project ID inheritance, so that future subdirectories inherit the
+ // same project ID
+ ret = SetQuotaInherit(pathToCreate);
+ if (ret != 0) {
+ return ret;
+ }
+ }
}
depth++;