/* * Copyright (C) 2008 The Android Open Source Project * Copyright (C) 2012 Freescale Semiconductor, Inc. * * 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. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LOG_TAG "Vold" #include #include #include "Ntfs.h" static char NTFS_FIX_PATH[] = "/system/bin/ntfsfix"; static char NTFS_MOUNT_PATH[] = "/system/bin/ntfs-3g"; extern "C" int logwrap(int argc, const char **argv, int background); int Ntfs::check(const char *fsPath) { if (access(NTFS_FIX_PATH, X_OK)) { SLOGW("Skipping fs checks\n"); return 0; } int rc = 0; const char *args[4]; /* we first use -n to do ntfs detection */ args[0] = NTFS_FIX_PATH; args[1] = "-n"; args[2] = fsPath; args[3] = NULL; rc = logwrap(3, args, 1); if (rc) { errno = ENODATA; return -1; } SLOGI("Ntfs filesystem existed"); /* do the real fix */ /* redo the ntfsfix without -n to fix problems */ args[1] = fsPath; args[2] = NULL; rc = logwrap(2, args, 1); if (rc) { errno = EIO; SLOGE("Filesystem check failed (unknown exit code %d)", rc); return -1; } SLOGI("Ntfs filesystem check completed OK"); return 0; } int Ntfs::doMount(const char *fsPath, const char *mountPoint, bool ro, bool remount, bool executable, int ownerUid, int ownerGid, int permMask, bool createLost) { int rc; char mountData[255]; const char *args[6]; /* * Note: This is a temporary hack. If the sampling profiler is enabled, * we make the SD card world-writable so any process can write snapshots. * * TODO: Remove this code once we have a drop box in system_server. */ char value[PROPERTY_VALUE_MAX]; property_get("persist.sampling_profiler", value, ""); if (value[0] == '1') { SLOGW("The SD card is world-writable because the" " 'persist.sampling_profiler' system property is set to '1'."); permMask = 0; } sprintf(mountData, "utf8,uid=%d,gid=%d,fmask=%o,dmask=%o," "shortname=mixed,nodev,nosuid,dirsync", ownerUid, ownerGid, permMask, permMask); if (!executable) strcat(mountData, ",noexec"); if (ro) strcat(mountData, ",ro"); if (remount) strcat(mountData, ",remount"); SLOGD("Mounting ntfs with options:%s\n", mountData); args[0] = NTFS_MOUNT_PATH; args[1] = "-o"; args[2] = mountData; args[3] = fsPath; args[4] = mountPoint; args[5] = NULL; rc = logwrap(5, args, 1); if (rc && errno == EROFS) { SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath); strcat(mountData, ",ro"); rc = logwrap(5, args, 1); } if (rc == 0 && createLost) { char *lost_path; asprintf(&lost_path, "%s/LOST.DIR", mountPoint); if (access(lost_path, F_OK)) { /* * Create a LOST.DIR in the root so we have somewhere to put * lost cluster chains (fsck_msdos doesn't currently do this) */ if (mkdir(lost_path, 0755)) { SLOGE("Unable to create LOST.DIR (%s)", strerror(errno)); } } free(lost_path); } return rc; }