Skip to content

Instantly share code, notes, and snippets.

@xiaolu
Last active April 27, 2017 14:21
Show Gist options
  • Save xiaolu/6856146 to your computer and use it in GitHub Desktop.
Save xiaolu/6856146 to your computer and use it in GitHub Desktop.
Use exfat modules for mount.
diff --git a/Android.mk b/Android.mk
index 26c441e..5d11f24 100644
--- a/Android.mk
+++ b/Android.mk
@@ -28,6 +28,10 @@ ifneq ($(TARGET_USE_CUSTOM_SECOND_LUN_NUM),)
common_cflags += -DCUSTOM_SECOND_LUN_NUM=$(TARGET_USE_CUSTOM_SECOND_LUN_NUM)
endif
+ifneq ($(KERNEL_EXFAT_MODULE_NAME),)
+ common_cflags += -DEXFAT_MODULE_NAME=\"$(KERNEL_EXFAT_MODULE_NAME)\"
+endif
+
common_cflags += -Werror
common_src_files := \
diff --git a/Exfat.cpp b/Exfat.cpp
index 7bb7d44..cc2c917 100644
--- a/Exfat.cpp
+++ b/Exfat.cpp
@@ -45,7 +45,9 @@
static char EXFAT_FSCK[] = HELPER_PATH "fsck.exfat";
static char EXFAT_MKFS[] = HELPER_PATH "mkfs.exfat";
static char EXFAT_MOUNT[] = HELPER_PATH "mount.exfat";
-
+#ifdef EXFAT_MODULE_NAME
+extern "C" int mount(const char *, const char *, const char *, unsigned long, const void *);
+#endif
int Exfat::doMount(const char *fsPath, const char *mountPoint,
bool ro, bool remount, bool executable,
int ownerUid, int ownerGid, int permMask) {
@@ -54,18 +56,17 @@ int Exfat::doMount(const char *fsPath, const char *mountPoint,
char mountData[255];
const char *args[6];
int status;
-
if (access(EXFAT_MOUNT, X_OK)) {
SLOGE("Unable to mount, exFAT FUSE helper not found!");
return rc;
}
+#ifndef EXFAT_MODULE_NAME
sprintf(mountData,
"noatime,nodev,nosuid,dirsync,uid=%d,gid=%d,fmask=%o,dmask=%o,%s,%s",
ownerUid, ownerGid, permMask, permMask,
(executable ? "exec" : "noexec"),
(ro ? "ro" : "rw"));
-
args[0] = EXFAT_MOUNT;
args[1] = "-o";
args[2] = mountData;
@@ -77,12 +78,30 @@ int Exfat::doMount(const char *fsPath, const char *mountPoint,
rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
true);
+#else
+ unsigned long flags;
+ flags = MS_NOATIME | MS_NODEV | MS_NOSUID | MS_DIRSYNC;
+
+ flags |= (executable ? 0 : MS_NOEXEC);
+ flags |= (ro ? MS_RDONLY : 0);
+ flags |= (remount ? MS_REMOUNT : 0);
+
+ sprintf(mountData,
+ "uid=%d,gid=%d,fmask=%o,dmask=%o",
+ ownerUid, ownerGid, permMask, permMask);
+ rc = mount(fsPath, mountPoint, EXFAT_MODULE_NAME, flags, mountData);
+#endif
if (rc && errno == EROFS) {
SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath);
+#ifndef EXFAT_MODULE_NAME
strcat(mountData, ",ro");
rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
true);
+#else
+ flags |= MS_RDONLY;
+ rc = mount(fsPath, mountPoint, EXFAT_MODULE_NAME, flags, mountData);
+#endif
}
return rc;
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
index 8a74872..3695dfc 100644
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -1257,6 +1257,8 @@ static const char *LUN_FILES[] = {
#endif
/* Only andriod0 exists, but the %d in there is a hack to satisfy the
format string and also give a not found error when %d > 0 */
+ "/sys/devices/platform/msm_hsusb/gadget/lun0/file",
+ "/sys/class/android_usb/android0/f_mass_storage/lun0/file",
"/sys/class/android_usb/android%d/f_mass_storage/lun/file",
NULL
};
LOCAL_PATH:= $(call my-dir)
ifneq ($(BOARD_VOLD_MAX_PARTITIONS),)
common_cflags += -DVOLD_MAX_PARTITIONS=$(BOARD_VOLD_MAX_PARTITIONS)
endif
ifeq ($(BOARD_VOLD_EMMC_SHARES_DEV_MAJOR), true)
common_cflags += -DVOLD_EMMC_SHARES_DEV_MAJOR
endif
ifeq ($(BOARD_VOLD_DISC_HAS_MULTIPLE_MAJORS), true)
common_cflags += -DVOLD_DISC_HAS_MULTIPLE_MAJORS
endif
ifneq ($(TARGET_FUSE_SDCARD_UID),)
common_cflags += -DFUSE_SDCARD_UID=$(TARGET_FUSE_SDCARD_UID)
endif
ifneq ($(TARGET_FUSE_SDCARD_GID),)
common_cflags += -DFUSE_SDCARD_GID=$(TARGET_FUSE_SDCARD_GID)
endif
ifneq ($(TARGET_USE_CUSTOM_LUN_FILE_PATH),)
common_cflags += -DCUSTOM_LUN_FILE=\"$(TARGET_USE_CUSTOM_LUN_FILE_PATH)\"
endif
ifneq ($(TARGET_USE_CUSTOM_SECOND_LUN_NUM),)
common_cflags += -DCUSTOM_SECOND_LUN_NUM=$(TARGET_USE_CUSTOM_SECOND_LUN_NUM)
endif
ifneq ($(KERNEL_EXFAT_MODULE_NAME),)
common_cflags += -DEXFAT_MODULE_NAME=\"$(KERNEL_EXFAT_MODULE_NAME)\"
endif
common_cflags += -Werror
common_src_files := \
VolumeManager.cpp \
CommandListener.cpp \
VoldCommand.cpp \
NetlinkManager.cpp \
NetlinkHandler.cpp \
Volume.cpp \
DirectVolume.cpp \
Process.cpp \
Ext4.cpp \
Fat.cpp \
Ntfs.cpp \
Exfat.cpp \
Loop.cpp \
Devmapper.cpp \
ResponseCode.cpp \
cryptfs.c \
main.cpp
extra_src_files := \
Xwarp.cpp \
fstrim.c \
common_c_includes := \
$(KERNEL_HEADERS) \
system/extras/ext4_utils \
external/openssl/include \
external/e2fsprogs/lib \
system/core/fs_mgr/include \
system/core/logwrapper/include
common_libraries := \
libsysutils \
libcutils \
liblog \
libdiskconfig \
libext2_blkid \
liblogwrap
common_static_libraries := \
libfs_mgr \
libpower
include $(CLEAR_VARS)
LOCAL_MODULE := libvold
LOCAL_SRC_FILES := $(common_src_files) $(extra_src_files)
LOCAL_C_INCLUDES := $(common_c_includes)
LOCAL_SHARED_LIBRARIES := $(common_libraries) libcrypto
LOCAL_CFLAGS := $(common_cflags)
LOCAL_MODULE_TAGS := eng tests
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= vold
LOCAL_SRC_FILES := vold.c
LOCAL_C_INCLUDES := $(common_c_includes)
LOCAL_CFLAGS := $(common_cflags)
LOCAL_SHARED_LIBRARIES := $(common_libraries) libcrypto
LOCAL_STATIC_LIBRARIES := libvold $(common_static_libraries)
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= vdc.c
LOCAL_MODULE:= vdc
LOCAL_C_INCLUDES := $(KERNEL_HEADERS)
LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := libcutils
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE:= libminivold
LOCAL_SRC_FILES := $(common_src_files)
LOCAL_C_INCLUDES := $(common_c_includes)
LOCAL_CFLAGS := $(common_cflags) -DMINIVOLD -DHELPER_PATH=\"/sbin/\"
LOCAL_MODULE_TAGS := optional
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:= minivold
LOCAL_SRC_FILES := vold.c
LOCAL_C_INCLUDES := $(common_c_includes)
LOCAL_CFLAGS := $(common_cflags) -DMINIVOLD
LOCAL_STATIC_LIBRARIES := libminivold
LOCAL_STATIC_LIBRARIES += libc libstdc++
LOCAL_STATIC_LIBRARIES += $(common_libraries) $(common_static_libraries)
LOCAL_STATIC_LIBRARIES += libcrypto_static libext2_uuid
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES
LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)/sbin
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
/*
* Copyright (C) 2012 The Android Open Source Project
* Copyright (C) 2013 The CyanogenMod 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/wait.h>
#include <linux/kdev_t.h>
#include <logwrap/logwrap.h>
#include "VoldUtil.h"
#define LOG_TAG "Vold"
#include <cutils/log.h>
#include <cutils/properties.h>
#include "Exfat.h"
static char EXFAT_FSCK[] = HELPER_PATH "fsck.exfat";
static char EXFAT_MKFS[] = HELPER_PATH "mkfs.exfat";
static char EXFAT_MOUNT[] = HELPER_PATH "mount.exfat";
#ifdef EXFAT_MODULE_NAME
extern "C" int mount(const char *, const char *, const char *, unsigned long, const void *);
#endif
int Exfat::doMount(const char *fsPath, const char *mountPoint,
bool ro, bool remount, bool executable,
int ownerUid, int ownerGid, int permMask) {
int rc = -1;
char mountData[255];
const char *args[6];
int status;
if (access(EXFAT_MOUNT, X_OK)) {
SLOGE("Unable to mount, exFAT FUSE helper not found!");
return rc;
}
#ifndef EXFAT_MODULE_NAME
sprintf(mountData,
"noatime,nodev,nosuid,dirsync,uid=%d,gid=%d,fmask=%o,dmask=%o,%s,%s",
ownerUid, ownerGid, permMask, permMask,
(executable ? "exec" : "noexec"),
(ro ? "ro" : "rw"));
args[0] = EXFAT_MOUNT;
args[1] = "-o";
args[2] = mountData;
args[3] = fsPath;
args[4] = mountPoint;
args[5] = NULL;
SLOGW("Executing exFAT mount (%s) -> (%s)", fsPath, mountPoint);
rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
true);
#else
unsigned long flags;
flags = MS_NOATIME | MS_NODEV | MS_NOSUID | MS_DIRSYNC;
flags |= (executable ? 0 : MS_NOEXEC);
flags |= (ro ? MS_RDONLY : 0);
flags |= (remount ? MS_REMOUNT : 0);
sprintf(mountData,
"uid=%d,gid=%d,fmask=%o,dmask=%o",
ownerUid, ownerGid, permMask, permMask);
rc = mount(fsPath, mountPoint, EXFAT_MODULE_NAME, flags, mountData);
#endif
if (rc && errno == EROFS) {
SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath);
#ifndef EXFAT_MODULE_NAME
strcat(mountData, ",ro");
rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
true);
#else
flags |= MS_RDONLY;
rc = mount(fsPath, mountPoint, EXFAT_MODULE_NAME, flags, mountData);
#endif
}
return rc;
}
int Exfat::check(const char *fsPath) {
bool rw = true;
int rc = -1;
int status;
if (access(EXFAT_FSCK, X_OK)) {
SLOGW("Skipping fs checks, exfatfsck not found.\n");
return 0;
}
do {
const char *args[3];
args[0] = EXFAT_FSCK;
args[1] = fsPath;
args[2] = NULL;
rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
true);
switch(rc) {
case 0:
SLOGI("exFAT filesystem check completed OK.\n");
return 0;
case 1:
SLOGI("exFAT filesystem check completed, errors corrected OK.\n");
return 0;
case 2:
SLOGE("exFAT filesystem check completed, errors corrected, need reboot.\n");
return 0;
case 4:
SLOGE("exFAT filesystem errors left uncorrected.\n");
return 0;
case 8:
SLOGE("exfatfsck operational error.\n");
errno = EIO;
return -1;
default:
SLOGE("exFAT filesystem check failed (unknown exit code %d).\n", rc);
errno = EIO;
return -1;
}
} while (0);
return 0;
}
int Exfat::format(const char *fsPath) {
int fd;
const char *args[3];
int rc = -1;
int status;
if (access(EXFAT_MKFS, X_OK)) {
SLOGE("Unable to format, mkexfatfs not found.");
return -1;
}
args[0] = EXFAT_MKFS;
args[1] = fsPath;
args[2] = NULL;
rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
true);
if (rc == 0) {
SLOGI("Filesystem (exFAT) formatted OK");
return 0;
} else {
SLOGE("Format (exFAT) failed (unknown exit code %d)", rc);
errno = EIO;
return -1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment