Skip to content

Instantly share code, notes, and snippets.

@checko
Created February 21, 2013 03:12
Show Gist options
  • Save checko/5001745 to your computer and use it in GitHub Desktop.
Save checko/5001745 to your computer and use it in GitHub Desktop.
some source code from Cyanogen Mod 7. Vold. add support for exfat
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