blob: 395664a35ea5d2e2aab9fdb50e9c6d1d14de74a7 [file] [log] [blame]
Tom Marshall55220ba2019-01-04 14:37:31 -08001/*
2 * Copyright (C) 2008 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 <dirent.h>
19#include <errno.h>
20#include <fcntl.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include <linux/fs.h>
27#include <sys/ioctl.h>
28#include <sys/mman.h>
29#include <sys/mount.h>
30#include <sys/stat.h>
31#include <sys/types.h>
32#include <sys/wait.h>
33
34#include <linux/kdev_t.h>
35
36#define LOG_TAG "Vold"
37
38#include <android-base/logging.h>
39#include <android-base/stringprintf.h>
40#include <cutils/log.h>
41#include <cutils/properties.h>
42#include <selinux/selinux.h>
43
44#include <logwrap/logwrap.h>
45
46#include "Utils.h"
47#include "Vfat.h"
48
49using android::base::StringPrintf;
50
51namespace android {
52namespace volmgr {
53namespace vfat {
54
55status_t Mount(const std::string& source, const std::string& target, bool ro, bool remount,
56 bool executable, int ownerUid, int ownerGid, int permMask, bool createLost) {
57 int rc;
58 unsigned long flags;
59 char mountData[255];
60
61 const char* c_source = source.c_str();
62 const char* c_target = target.c_str();
63
64 flags = MS_NODEV | MS_NOSUID | MS_DIRSYNC | MS_NOATIME;
65
66 flags |= (executable ? 0 : MS_NOEXEC);
67 flags |= (ro ? MS_RDONLY : 0);
68 flags |= (remount ? MS_REMOUNT : 0);
69
70 snprintf(mountData, sizeof(mountData), "utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed",
71 ownerUid, ownerGid, permMask, permMask);
72
73 rc = mount(c_source, c_target, "vfat", flags, mountData);
74
75 if (rc && errno == EROFS) {
76 SLOGE("%s appears to be a read only filesystem - retrying mount RO", c_source);
77 flags |= MS_RDONLY;
78 rc = mount(c_source, c_target, "vfat", flags, mountData);
79 }
80
81 if (rc == 0 && createLost) {
82 char* lost_path;
83 asprintf(&lost_path, "%s/LOST.DIR", c_target);
84 if (access(lost_path, F_OK)) {
85 /*
86 * Create a LOST.DIR in the root so we have somewhere to put
87 * lost cluster chains (fsck_msdos doesn't currently do this)
88 */
89 if (mkdir(lost_path, 0755)) {
90 SLOGE("Unable to create LOST.DIR (%s)", strerror(errno));
91 }
92 }
93 free(lost_path);
94 }
95
96 return rc;
97}
98
99} // namespace vfat
100} // namespace volmgr
101} // namespace android