73e3010a25
With the way the FUSE mount point are currently setup for emulated volumes, there can be multiple paths that serve the same files on the lower filesystem; eg * /mnt/user/0/emulated/0/Android * /mnt/user/10/emulated/0/Android both refer to the same file on the lower filesystem: * /data/media/0/Android this is normally not a problem, because cross-user file access is not allowed, and so the FUSE daemon won't serve files for other users. With clone profiles this is no longer true however, as their volumes are accessible by each other. So, it can happen that an app running in clone profile 10 accesses "/mnt/user/10/emulated/0/Android", which would be served by the FUSE daemon for the user 10 filesystem. At the same time, an app running in the owner profile 0 accesses "mnt/user/0/emulated/0/Android", which would be served by the FUSE daemon for the user 0 filesystem. This can cause page cache inconsistencies, because multiple FUSE daemons can be running on top of the same entries in the lower filesystem. To prevent this, use bind mounts to make sure that cross-profile accesses actually end up in the FUSE daemon to which the volume belongs: "/mnt/user/10/emulated/0" is bind-mounted to "/mnt/user/0/emulated/0", and vice-versa. Bug: 228271997 Test: manual Change-Id: Iefcbc813670628b329a1a5d408b6126b84991e09
87 lines
2.6 KiB
C++
87 lines
2.6 KiB
C++
/*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_VOLD_EMULATED_VOLUME_H
|
|
#define ANDROID_VOLD_EMULATED_VOLUME_H
|
|
|
|
#include "VolumeBase.h"
|
|
|
|
#include <cutils/multiuser.h>
|
|
|
|
namespace android {
|
|
namespace vold {
|
|
|
|
/*
|
|
* Shared storage emulated on top of private storage.
|
|
*
|
|
* Knows how to spawn a sdcardfs daemon to synthesize permissions. ObbVolume
|
|
* can be stacked above it.
|
|
*
|
|
* This volume is always multi-user aware, but is only binds itself to
|
|
* users when its primary storage. This volume should never be presented
|
|
* as secondary storage, since we're strongly encouraging developers to
|
|
* store data local to their app.
|
|
*/
|
|
class EmulatedVolume : public VolumeBase {
|
|
public:
|
|
explicit EmulatedVolume(const std::string& rawPath, int userId);
|
|
EmulatedVolume(const std::string& rawPath, dev_t device, const std::string& fsUuid, int userId);
|
|
virtual ~EmulatedVolume();
|
|
std::string getRootPath() const override;
|
|
bool isFuseMounted() const { return mFuseMounted; }
|
|
|
|
protected:
|
|
status_t doMount() override;
|
|
status_t doUnmount() override;
|
|
|
|
private:
|
|
status_t unmountSdcardFs();
|
|
status_t mountFuseBindMounts();
|
|
status_t unmountFuseBindMounts();
|
|
|
|
status_t bindMountVolume(const EmulatedVolume& vol, std::list<std::string>& pathsToUnmount);
|
|
|
|
std::string getLabel() const;
|
|
std::string mRawPath;
|
|
std::string mLabel;
|
|
|
|
std::string mSdcardFsDefault;
|
|
std::string mSdcardFsRead;
|
|
std::string mSdcardFsWrite;
|
|
std::string mSdcardFsFull;
|
|
|
|
/* Whether we mounted FUSE for this volume */
|
|
bool mFuseMounted;
|
|
|
|
/* Whether the FUSE BPF feature is enabled */
|
|
bool mFuseBpfEnabled;
|
|
|
|
/* Whether to use sdcardfs for this volume */
|
|
bool mUseSdcardFs;
|
|
|
|
/* Whether to use app data isolation is enabled tor this volume */
|
|
bool mAppDataIsolationEnabled;
|
|
|
|
/* Location of bind mount for another profile that shares storage with us */
|
|
std::string mSharedStorageMountPath = "";
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(EmulatedVolume);
|
|
};
|
|
|
|
} // namespace vold
|
|
} // namespace android
|
|
|
|
#endif
|