blob: 8fb3b960315fc4f5f32374bb0733a3938c6086c5 [file] [log] [blame]
Tom Marshall292bd232019-01-04 14:37:31 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 * Copyright (C) 2019 The LineageOS Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "PublicVolume.h"
19#include <volume_manager/ResponseCode.h>
20#include <volume_manager/VolumeManager.h>
21#include "Utils.h"
22#include "fs/Exfat.h"
23#include "fs/Ext4.h"
24#include "fs/F2fs.h"
25#include "fs/Ntfs.h"
26#include "fs/Vfat.h"
27
28#include <android-base/logging.h>
29#include <android-base/stringprintf.h>
30#include <cutils/fs.h>
31#include <private/android_filesystem_config.h>
32
33#include <fcntl.h>
34#include <stdlib.h>
35#include <sys/mount.h>
36#include <sys/stat.h>
37#include <sys/sysmacros.h>
38#include <sys/types.h>
39#include <sys/wait.h>
40
41using android::base::StringPrintf;
42
43namespace android {
44namespace volmgr {
45
46PublicVolume::PublicVolume(dev_t device, const std::string& nickname,
47 const std::string& fstype /* = "" */,
48 const std::string& mntopts /* = "" */)
49 : VolumeBase(Type::kPublic), mDevice(device), mFsType(fstype), mMntOpts(mntopts) {
50 setId(StringPrintf("public:%u_%u", major(device), minor(device)));
51 setPartLabel(nickname);
52 mDevPath = StringPrintf("/dev/block/volmgr/%s", getId().c_str());
53}
54
55PublicVolume::~PublicVolume() {}
56
57status_t PublicVolume::readMetadata() {
58 std::string label;
59 status_t res = ReadMetadataUntrusted(mDevPath, mFsType, mFsUuid, label);
60 if (!label.empty()) {
61 setPartLabel(label);
62 }
63 VolumeManager::Instance()->notifyEvent(ResponseCode::VolumeFsTypeChanged, mFsType);
64 VolumeManager::Instance()->notifyEvent(ResponseCode::VolumeFsUuidChanged, mFsUuid);
65 return res;
66}
67
68status_t PublicVolume::doCreate() {
69 status_t res = CreateDeviceNode(mDevPath, mDevice);
70 if (res != OK) {
71 return res;
72 }
73 readMetadata();
74
75 // Use UUID as stable name, if available
76 std::string stableName = getId();
77 if (!mFsUuid.empty()) {
78 stableName = mFsUuid;
79 }
80 setPath(StringPrintf("/storage/%s", stableName.c_str()));
81
82 return OK;
83}
84
85status_t PublicVolume::doDestroy() {
86 return DestroyDeviceNode(mDevPath);
87}
88
89status_t PublicVolume::doMount() {
90 if (!IsFilesystemSupported(mFsType)) {
91 LOG(ERROR) << getId() << " unsupported filesystem " << mFsType;
92 return -EIO;
93 }
94
95 if (fs_prepare_dir(getPath().c_str(), 0700, AID_ROOT, AID_ROOT)) {
96 PLOG(ERROR) << getId() << " failed to create mount points";
97 return -errno;
98 }
99
100 int ret = 0;
101 if (mFsType == "exfat") {
102 ret = exfat::Mount(mDevPath, getPath(), AID_MEDIA_RW, AID_MEDIA_RW, 0007);
103 } else if (mFsType == "ext4") {
104 ret = ext4::Mount(mDevPath, getPath(), false, false, true, mMntOpts, false, true);
105 } else if (mFsType == "f2fs") {
106 ret = f2fs::Mount(mDevPath, getPath(), mMntOpts, false, true);
107 } else if (mFsType == "ntfs") {
108 ret =
109 ntfs::Mount(mDevPath, getPath(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW, 0007);
110 } else if (mFsType == "vfat") {
111 ret = vfat::Mount(mDevPath, getPath(), false, false, false, AID_MEDIA_RW, AID_MEDIA_RW,
112 0007, true);
113 } else {
114 ret = ::mount(mDevPath.c_str(), getPath().c_str(), mFsType.c_str(), 0, nullptr);
115 }
116 if (ret) {
117 PLOG(ERROR) << getId() << " failed to mount " << mDevPath;
118 return -EIO;
119 }
120
121 return OK;
122}
123
124status_t PublicVolume::doUnmount(bool detach /* = false */) {
125 ForceUnmount(getPath(), detach);
126
127 rmdir(getPath().c_str());
128
129 return OK;
130}
131
132} // namespace volmgr
133} // namespace android