Merge "[CloneProfile] Create user mount directory before creating bind mounts." into main
diff --git a/Utils.cpp b/Utils.cpp
index 696b0b4..a3db43e 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1562,15 +1562,9 @@
         return -1;
     }
 
-    // Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
-    // /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
-    // AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
-    // These bits should be consistent with what is set in zygote in
-    // com_android_internal_os_Zygote#MountEmulatedStorage on volume bind mount during app fork
-    result = PrepareDir(pre_fuse_path, 0710, user_id ? AID_ROOT : AID_SHELL,
-                             multiuser_get_uid(user_id, AID_EVERYBODY));
+    result = PrepareMountDirForUser(user_id);
     if (result != android::OK) {
-        PLOG(ERROR) << "Failed to prepare directory " << pre_fuse_path;
+        PLOG(ERROR) << "Failed to create Mount Directory for user " << user_id;
         return -1;
     }
 
@@ -1808,5 +1802,22 @@
     return enabled;
 }
 
+status_t PrepareMountDirForUser(userid_t user_id) {
+    std::string pre_fuse_path(StringPrintf("/mnt/user/%d", user_id));
+    LOG(INFO) << "Creating mount directory " << pre_fuse_path;
+    // Shell is neither AID_ROOT nor AID_EVERYBODY. Since it equally needs 'execute' access to
+    // /mnt/user/0 to 'adb shell ls /sdcard' for instance, we set the uid bit of /mnt/user/0 to
+    // AID_SHELL. This gives shell access along with apps running as group everybody (user 0 apps)
+    // These bits should be consistent with what is set in zygote in
+    // com_android_internal_os_Zygote#MountEmulatedStorage on volume bind mount during app fork
+    auto result = PrepareDir(pre_fuse_path, 0710, user_id ? AID_ROOT : AID_SHELL,
+                             multiuser_get_uid(user_id, AID_EVERYBODY));
+    if (result != android::OK) {
+        PLOG(ERROR) << "Failed to prepare directory " << pre_fuse_path;
+        return -1;
+    }
+    return result;
+}
+
 }  // namespace vold
 }  // namespace android
diff --git a/Utils.h b/Utils.h
index 690f79e..39723ec 100644
--- a/Utils.h
+++ b/Utils.h
@@ -219,6 +219,8 @@
 // referenced inside the current process via the virtual procfs symlink returned here.
 std::pair<android::base::unique_fd, std::string> OpenDirInProcfs(std::string_view path);
 
+status_t PrepareMountDirForUser(userid_t user_id);
+
 }  // namespace vold
 }  // namespace android
 
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index a1ac20d..2171717 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -473,6 +473,13 @@
                 // No need to bind if the user does not share storage with the mount owner
                 continue;
             }
+            // Create mount directory for the user as there is a chance that no other Volume is
+            // mounted for the user (ex: if the user is just started), so /mnt/user/user_id  does
+            // not exist yet.
+            auto mountDirStatus = android::vold::PrepareMountDirForUser(userId);
+            if (mountDirStatus != OK) {
+                LOG(ERROR) << "Failed to create Mount Directory for user " << userId;
+            }
             auto bindMountStatus = pvol->bindMountForUser(userId);
             if (bindMountStatus != OK) {
                 LOG(ERROR) << "Bind Mounting Public Volume: " << pvol << " for user: " << userId
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index e86d002..91b1ca2 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -269,6 +269,12 @@
             // No need to bind if the user does not share storage with the mount owner
             continue;
         }
+        // Create mount directory for the user as there is a chance that no other Volume is mounted
+        // for the user (ex: if the user is just started), so /mnt/user/user_id  does not exist yet.
+        auto mountDirStatus = PrepareMountDirForUser(started_user);
+        if (mountDirStatus != OK) {
+            LOG(ERROR) << "Failed to create Mount Directory for user " << started_user;
+        }
         auto bindMountStatus = bindMountForUser(started_user);
         if (bindMountStatus != OK) {
             LOG(ERROR) << "Bind Mounting Public Volume: " << stableName