From 76c235ffe37d6ad4640a4dd41a1a1f85b668b635 Mon Sep 17 00:00:00 2001 From: Tom Marshall Date: Thu, 5 Nov 2015 11:20:54 -0800 Subject: [PATCH] vold: Honor mount options for ext4/f2fs partitions * Save mount options and fstype for DiskPartition objects * Pass mount options and fstype to PublicVolume ctor * Pass mount options to ext4::Mount/f2fs:Mount * Use specified/default fstype if blkid fails This is trivially extensible for other fs types. [mikeioannina] Adapt for Pie and Q Change-Id: Ie5dd27f26a4a7129dd9efe6a7ad0a589928282a0 --- VolumeManager.cpp | 3 ++- VolumeManager.h | 12 ++++++++++-- fs/Ext4.cpp | 5 +++-- fs/Ext4.h | 2 +- fs/F2fs.cpp | 5 +++-- fs/F2fs.h | 2 +- main.cpp | 11 ++++++++++- model/Disk.cpp | 6 ++++-- model/Disk.h | 4 +++- model/DiskPartition.cpp | 9 ++++++--- model/DiskPartition.h | 7 ++++++- model/PrivateVolume.cpp | 2 +- model/PublicVolume.cpp | 9 ++++++--- model/PublicVolume.h | 5 ++++- 14 files changed, 60 insertions(+), 22 deletions(-) diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 6b06703..69f4b8b 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -245,7 +245,8 @@ void VolumeManager::handleBlockEvent(NetlinkEvent* evt) { source->getNickname(), flags) : new android::vold::DiskPartition(eventPath, device, source->getNickname(), flags, - source->getPartNum()); + source->getPartNum(), + source->getFsType(), source->getMntOpts()); handleDiskAdded(std::shared_ptr(disk)); break; } diff --git a/VolumeManager.h b/VolumeManager.h index 03ca6b1..8bb0a57 100644 --- a/VolumeManager.h +++ b/VolumeManager.h @@ -63,8 +63,12 @@ class VolumeManager { class DiskSource { public: - DiskSource(const std::string& sysPattern, const std::string& nickname, int partnum, int flags) - : mSysPattern(sysPattern), mNickname(nickname), mPartNum(partnum), mFlags(flags) {} + DiskSource(const std::string& sysPattern, const std::string& nickname, + int partnum, int flags, + const std::string& fstype, const std::string mntopts) + : mSysPattern(sysPattern), mNickname(nickname), + mPartNum(partnum), mFlags(flags), + mFsType(fstype), mMntOpts(mntopts) {} bool matches(const std::string& sysPath) { return !fnmatch(mSysPattern.c_str(), sysPath.c_str(), 0); @@ -73,12 +77,16 @@ class VolumeManager { const std::string& getNickname() const { return mNickname; } int getPartNum() const { return mPartNum; } int getFlags() const { return mFlags; } + const std::string& getFsType() { return mFsType; } + const std::string& getMntOpts() { return mMntOpts; } private: std::string mSysPattern; std::string mNickname; int mPartNum; int mFlags; + std::string mFsType; + std::string mMntOpts; }; void addDiskSource(const std::shared_ptr& diskSource); diff --git a/fs/Ext4.cpp b/fs/Ext4.cpp index e0f89a5..63882bc 100644 --- a/fs/Ext4.cpp +++ b/fs/Ext4.cpp @@ -123,12 +123,13 @@ status_t Check(const std::string& source, const std::string& target, bool truste } status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount, - bool executable) { + bool executable, const std::string& opts /* = "" */) { int rc; unsigned long flags; const char* c_source = source.c_str(); const char* c_target = target.c_str(); + const char* c_opts = opts.c_str(); flags = MS_NOATIME | MS_NODEV | MS_NOSUID | MS_DIRSYNC; @@ -136,7 +137,7 @@ status_t Mount(const std::string& source, const std::string& target, bool ro, bo flags |= (ro ? MS_RDONLY : 0); flags |= (remount ? MS_REMOUNT : 0); - rc = mount(c_source, c_target, "ext4", flags, NULL); + rc = mount(c_source, c_target, "ext4", flags, c_opts); if (rc && errno == EROFS) { LOG(ERROR) << source << " appears to be a read only filesystem - retrying mount RO"; diff --git a/fs/Ext4.h b/fs/Ext4.h index b458439..8643ed6 100644 --- a/fs/Ext4.h +++ b/fs/Ext4.h @@ -29,7 +29,7 @@ bool IsSupported(); status_t Check(const std::string& source, const std::string& target, bool trusted); status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount, - bool executable); + bool executable, const std::string& opts = ""); status_t Format(const std::string& source, unsigned long numSectors, const std::string& target); status_t Resize(const std::string& source, unsigned long numSectors); diff --git a/fs/F2fs.cpp b/fs/F2fs.cpp index 5bdfcaf..4ac33fd 100644 --- a/fs/F2fs.cpp +++ b/fs/F2fs.cpp @@ -50,12 +50,13 @@ status_t Check(const std::string& source, bool trusted) { return ForkExecvp(cmd, nullptr, trusted ? sFsckContext : sFsckUntrustedContext); } -status_t Mount(const std::string& source, const std::string& target) { +status_t Mount(const std::string& source, const std::string& target, const std::string& opts /* = "" */) { const char* c_source = source.c_str(); const char* c_target = target.c_str(); + const char* c_opts = opts.c_str(); unsigned long flags = MS_NOATIME | MS_NODEV | MS_NOSUID | MS_DIRSYNC; - int res = mount(c_source, c_target, "f2fs", flags, NULL); + int res = mount(c_source, c_target, "f2fs", flags, c_opts); if (res != 0) { PLOG(ERROR) << "Failed to mount " << source; if (errno == EROFS) { diff --git a/fs/F2fs.h b/fs/F2fs.h index eb34afa..227b8bb 100644 --- a/fs/F2fs.h +++ b/fs/F2fs.h @@ -28,7 +28,7 @@ namespace f2fs { bool IsSupported(); status_t Check(const std::string& source, bool trusted); -status_t Mount(const std::string& source, const std::string& target); +status_t Mount(const std::string& source, const std::string& target, const std::string& opts = ""); status_t Format(const std::string& source); } // namespace f2fs diff --git a/main.cpp b/main.cpp index c9fc41b..2ddb958 100644 --- a/main.cpp +++ b/main.cpp @@ -243,6 +243,14 @@ static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quot if (entry.fs_mgr_flags.vold_managed) { std::string sysPattern(entry.blk_device); + std::string fstype; + if (!entry.fs_type.empty()) { + fstype = entry.fs_type; + } + std::string mntopts; + if (!entry.fs_options.empty()) { + mntopts = entry.fs_options; + } std::string nickname(entry.label); int partnum = entry.partnum; int flags = 0; @@ -260,7 +268,8 @@ static int process_config(VolumeManager* vm, bool* has_adoptable, bool* has_quot } vm->addDiskSource(std::shared_ptr( - new VolumeManager::DiskSource(sysPattern, nickname, partnum, flags))); + new VolumeManager::DiskSource(sysPattern, nickname, partnum, flags, + fstype, mntopts))); } } return 0; diff --git a/model/Disk.cpp b/model/Disk.cpp index f0fa02e..d33d081 100644 --- a/model/Disk.cpp +++ b/model/Disk.cpp @@ -171,8 +171,10 @@ status_t Disk::destroy() { return OK; } -void Disk::createPublicVolume(dev_t device) { - auto vol = std::shared_ptr(new PublicVolume(device)); +void Disk::createPublicVolume(dev_t device, + const std::string& fstype /* = "" */, + const std::string& mntopts /* = "" */) { + auto vol = std::shared_ptr(new PublicVolume(device, fstype, mntopts)); if (mJustPartitioned) { LOG(DEBUG) << "Device just partitioned; silently formatting"; vol->setSilent(true); diff --git a/model/Disk.h b/model/Disk.h index b926ae2..8268a1e 100644 --- a/model/Disk.h +++ b/model/Disk.h @@ -116,7 +116,9 @@ class Disk { /* Flag that we need to skip first disk change events after partitioning*/ bool mSkipChange; - void createPublicVolume(dev_t device); + void createPublicVolume(dev_t device, + const std::string& fstype = "", + const std::string& mntopts = ""); void createPrivateVolume(dev_t device, const std::string& partGuid); void createStubVolume(); diff --git a/model/DiskPartition.cpp b/model/DiskPartition.cpp index 1cbcfbb..10b2f95 100644 --- a/model/DiskPartition.cpp +++ b/model/DiskPartition.cpp @@ -44,9 +44,12 @@ namespace android { namespace vold { DiskPartition::DiskPartition(const std::string& eventPath, dev_t device, - const std::string& nickname, int flags, int partnum) : + const std::string& nickname, int flags, int partnum, + const std::string& fstype /* = "" */, const std::string& mntopts /* = "" */) : Disk(eventPath, device, nickname, flags), - mPartNum(partnum) { + mPartNum(partnum), + mFsType(fstype), + mMntOpts(mntopts) { // Empty } @@ -60,7 +63,7 @@ status_t DiskPartition::create() { auto listener = VolumeManager::Instance()->getListener(); if (listener) listener->onDiskCreated(getId(), mFlags); dev_t partDevice = makedev(major(mDevice), minor(mDevice) + mPartNum); - createPublicVolume(partDevice); + createPublicVolume(partDevice, mFsType, mMntOpts); return OK; } diff --git a/model/DiskPartition.h b/model/DiskPartition.h index 274d6be..4c9ab08 100644 --- a/model/DiskPartition.h +++ b/model/DiskPartition.h @@ -31,7 +31,8 @@ class DiskPartition : public Disk { public: DiskPartition(const std::string& eventPath, dev_t device, const std::string& nickname, - int flags, int partnum); + int flags, int partnum, + const std::string& fstype = "", const std::string& mntopts = ""); virtual ~DiskPartition(); virtual status_t create(); @@ -44,6 +45,10 @@ public: private: /* Partition number */ int mPartNum; + /* Filesystem type */ + std::string mFsType; + /* Mount options */ + std::string mMntOpts; }; } // namespace vold diff --git a/model/PrivateVolume.cpp b/model/PrivateVolume.cpp index e983f77..50c0f63 100644 --- a/model/PrivateVolume.cpp +++ b/model/PrivateVolume.cpp @@ -177,7 +177,7 @@ status_t PrivateVolume::doMount() { return -EIO; } - if (f2fs::Mount(mDmDevPath, mPath)) { + if (f2fs::Mount(mDmDevPath, mPath, "")) { PLOG(ERROR) << getId() << " failed to mount"; return -EIO; } diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp index 82cf95f..6b37770 100644 --- a/model/PublicVolume.cpp +++ b/model/PublicVolume.cpp @@ -50,7 +50,10 @@ static const char* kSdcardFsPath = "/system/bin/sdcard"; static const char* kAsecPath = "/mnt/secure/asec"; -PublicVolume::PublicVolume(dev_t device) : VolumeBase(Type::kPublic), mDevice(device) { +PublicVolume::PublicVolume(dev_t device, const std::string& fstype /* = "" */, + const std::string& mntopts /* = "" */) + : VolumeBase(Type::kPublic), mDevice(device), + mFsType(fstype), mMntOpts(mntopts) { setId(StringPrintf("public:%u,%u", major(device), minor(device))); mDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str()); mFuseMounted = false; @@ -156,9 +159,9 @@ status_t PublicVolume::doMount() { ret = exfat::Mount(mDevPath, mRawPath, AID_ROOT, (isVisible ? AID_MEDIA_RW : AID_EXTERNAL_STORAGE), 0007); } else if (mFsType == "ext4") { - ret = ext4::Mount(mDevPath, mRawPath, false, false, true); + ret = ext4::Mount(mDevPath, mRawPath, false, false, true, mMntOpts); } else if (mFsType == "f2fs") { - ret = f2fs::Mount(mDevPath, mRawPath); + ret = f2fs::Mount(mDevPath, mRawPath, mMntOpts); } else if (mFsType == "ntfs") { ret = ntfs::Mount(mDevPath, mRawPath, AID_ROOT, (isVisible ? AID_MEDIA_RW : AID_EXTERNAL_STORAGE), 0007); diff --git a/model/PublicVolume.h b/model/PublicVolume.h index 3156b53..9235bad 100644 --- a/model/PublicVolume.h +++ b/model/PublicVolume.h @@ -39,7 +39,8 @@ namespace vold { */ class PublicVolume : public VolumeBase { public: - explicit PublicVolume(dev_t device); + explicit PublicVolume(dev_t device, const std::string& mntopts = "", + const std::string& fstype = ""); virtual ~PublicVolume(); protected: @@ -77,6 +78,8 @@ class PublicVolume : public VolumeBase { std::string mFsUuid; /* User-visible filesystem label */ std::string mFsLabel; + /* Mount options */ + std::string mMntOpts; DISALLOW_COPY_AND_ASSIGN(PublicVolume); };