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
gugelfrei
Martijn Coenen 4 years ago
parent 7de5377c89
commit 9171fcc984

@ -807,14 +807,6 @@ bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_
if (!prepare_dir(vendor_ce_path, 0771, AID_ROOT, AID_ROOT)) return false;
}
if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
// Setup quota project ID and inheritance policy
if (!IsFilesystemSupported("sdcardfs")) {
if (SetQuotaInherit(media_ce_path) != 0) return false;
if (SetQuotaProjectId(media_ce_path,
multiuser_get_uid(user_id, PROJECT_ID_EXT_DEFAULT)) != 0) {
return false;
}
}
if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;

@ -366,6 +366,15 @@ int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int
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++;

Loading…
Cancel
Save