Created
February 21, 2013 03:12
-
-
Save checko/5001745 to your computer and use it in GitHub Desktop.
some source code from Cyanogen Mod 7. Vold.
add support for exfat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int Fat::check(const char *fsPath) { | |
bool rw = true; | |
SLOGI("Fat::check\n"); | |
if (access(FSCK_MSDOS_PATH, X_OK) || access(FSCK_EXT_PATH, X_OK)) { | |
SLOGW("Skipping fs checks\n"); | |
return 0; | |
} | |
int pass = 1; | |
int rc = 0; | |
do { | |
const char *args[5]; | |
enum { FS_OK, FS_FIXED, FS_MISMATCH, FS_ERROR } status = FS_ERROR; | |
args[0] = FSCK_EXT_PATH; | |
args[1] = "-p"; | |
args[2] = "-f"; | |
args[3] = fsPath; | |
args[4] = NULL; | |
rc = logwrap(4, args, 1); | |
if (rc == 0) { | |
// if rc is 0, the check was ok | |
// That means the FileSystem is EXT | |
fsType = 2; | |
status = FS_OK; | |
} else if (rc == 1) | |
status = FS_FIXED; | |
else if (rc == 8) | |
status = FS_MISMATCH; | |
else | |
status = FS_ERROR; | |
if (status == FS_MISMATCH) { | |
args[0] = FSCK_EXFAT_PATH; | |
args[1] = fsPath; | |
args[2] = NULL; | |
rc = logwrap(2,args,1); | |
if (rc == 0) { | |
// check OK, FileSystem is ExFAT | |
fsType = 3; | |
status = FS_OK; | |
}else{ | |
status = FS_MISMATCH; | |
} | |
} | |
if (status == FS_MISMATCH) { // not EXT, let's try FAT | |
args[0] = FSCK_MSDOS_PATH; | |
args[1] = "-p"; | |
args[2] = "-f"; | |
args[3] = fsPath; | |
args[4] = NULL; | |
rc = logwrap(4, args, 1); | |
if (rc == 0) { | |
// if rc is 0, the check was ok | |
// That means the FileSystem is FAT | |
fsType = 1; | |
status = FS_OK; | |
} else if (rc == 2) | |
status = FS_MISMATCH; | |
else if (rc == 4) | |
status = FS_FIXED; | |
else | |
status = FS_ERROR; | |
} | |
switch(status) { | |
case FS_OK: | |
SLOGI("Filesystem check completed OK"); | |
// TODO: Remove this print. | |
const char *fsTypePrint; | |
if (fsType == 1) | |
fsTypePrint = "VFAT"; | |
else if (fsType == 2) | |
fsTypePrint = "EXT"; | |
else if (fsType == 3) | |
fsTypePrint = "EXFAT"; | |
F else | |
fsTypePrint = "Unknown"; | |
SLOGI("Filesystem type is: %s", fsTypePrint); | |
return 0; | |
case FS_MISMATCH: | |
SLOGW("Filesystem check failed (not a FAT or EXT filesystem)"); | |
errno = ENODATA; | |
return -1; | |
case FS_FIXED: | |
if (pass++ <= 3) { | |
SLOGW("Filesystem modified - rechecking (pass %d)", | |
pass); | |
continue; | |
} | |
SLOGE("Failing check after too many rechecks"); | |
errno = EIO; | |
return -1; | |
default: | |
SLOGE("Filesystem check failed (unknown exit code %d)", rc); | |
errno = EIO; | |
return -1; | |
} | |
} while (0); | |
return 0; | |
} | |
int Fat::doMount(const char *fsPath, const char *mountPoint, | |
bool ro, bool remount, bool executable, | |
int ownerUid, int ownerGid, int permMask, bool createLost) { | |
int rc; | |
unsigned long flags; | |
char mountData[255]; | |
const char *mntFSType; | |
flags = MS_NODEV | MS_NOSUID | MS_DIRSYNC; | |
flags |= (executable ? 0 : MS_NOEXEC); | |
flags |= (ro ? MS_RDONLY : 0); | |
flags |= (remount ? MS_REMOUNT : 0); | |
/* | |
* 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; | |
} | |
if (fsType == 2) { | |
sprintf(mountData, "noauto_da_alloc"); | |
mntFSType = "ext4"; | |
rc = mount(fsPath, mountPoint, mntFSType, flags, mountData); | |
} else if (fsType == 3) { | |
const char *args[5]; | |
args[0] = "/system/bin/mount.exfat-fuse"; | |
args[1] = fsPath; | |
args[2] = mountPoint; | |
args[3] = NULL; | |
rc = logwrap(3,args,1); | |
} else { | |
sprintf(mountData, | |
"utf8,uid=%d,gid=%d,fmask=%o,dmask=%o,shortname=mixed", | |
ownerUid, ownerGid, permMask, permMask); | |
mntFSType = "vfat"; | |
rc = mount(fsPath, mountPoint, mntFSType, flags, mountData); | |
} | |
if (rc && errno == EROFS) { | |
SLOGE("%s appears to be a read only filesystem - retrying mount RO", fsPath); | |
flags |= MS_RDONLY; | |
rc = mount(fsPath, mountPoint, mntFSType, flags, mountData); | |
} | |
if (rc == 0 && createLost && fsType == 1) { | |
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment