diff options
Diffstat (limited to 'vold/volmgr_vfat.c')
-rw-r--r-- | vold/volmgr_vfat.c | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c new file mode 100644 index 0000000..1dc4c8d --- /dev/null +++ b/vold/volmgr_vfat.c @@ -0,0 +1,135 @@ + +/* + * Copyright (C) 2008 The Android Open Source 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 <errno.h> + +#include <sys/mount.h> + +#include "vold.h" +#include "volmgr.h" +#include "volmgr_vfat.h" +#include "logwrapper.h" + +#define VFAT_DEBUG 0 + +static char FSCK_MSDOS_PATH[] = "/system/bin/dosfsck"; + +int vfat_identify(blkdev_t *dev) +{ +#if VFAT_DEBUG + LOG_VOL("vfat_identify(%d:%d):", dev->major, dev->minor); +#endif + return 0; // XXX: Implement +} + +int vfat_check(blkdev_t *dev) +{ + int rc; + +#if VFAT_DEBUG + LOG_VOL("vfat_check(%d:%d):", dev->major, dev->minor); +#endif + + if (access(FSCK_MSDOS_PATH, X_OK)) { + LOGE("vfat_check(%d:%d): %s not found (skipping checks)", + dev->major, dev->minor, FSCK_MSDOS_PATH); + return 0; + } + +#ifdef VERIFY_PASS + char *args[7]; + args[0] = FSCK_MSDOS_PATH; + args[1] = "-v"; + args[2] = "-V"; + args[3] = "-w"; + args[4] = "-p"; + args[5] = blkdev_get_devpath(dev); + args[6] = NULL; + rc = logwrap(6, args); + free(args[5]); +#else + char *args[6]; + args[0] = FSCK_MSDOS_PATH; + args[1] = "-v"; + args[2] = "-w"; + args[3] = "-p"; + args[4] = blkdev_get_devpath(dev); + args[5] = NULL; + rc = logwrap(5, args); + free(args[4]); +#endif + + if (rc == 0) { + LOG_VOL("Filesystem check completed OK"); + return 0; + } else if (rc == 1) { + LOG_VOL("Filesystem check failed (general failure)"); + return -EINVAL; + } else if (rc == 2) { + LOG_VOL("Filesystem check failed (invalid usage)"); + return -EIO; + } else if (rc == 4) { + LOG_VOL("Filesystem check completed (errors fixed)"); + } else if (rc == 8) { + LOG_VOL("Filesystem check failed (not a FAT filesystem)"); + return -ENODATA; + } else { + LOG_VOL("Filesystem check failed (unknown exit code %d)", rc); + return -EIO; + } + return 0; +} + +int vfat_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode) +{ + int flags, rc; + char *devpath; + + devpath = blkdev_get_devpath(dev); + +#if VFAT_DEBUG + LOG_VOL("vfat_mount(%d:%d, %s, %d):", dev->major, dev->minor, vol->mount_point, safe_mode); +#endif + + flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC; + + if (safe_mode) + flags |= MS_SYNCHRONOUS; + if (vol->state == volstate_mounted) { + LOG_VOL("Remounting %d:%d on %s, safe mode %d", dev->major, + dev->minor, vol->mount_point, safe_mode); + flags |= MS_REMOUNT; + } + + rc = mount(devpath, vol->mount_point, "vfat", flags, + "utf8,uid=1000,gid=1000,fmask=711,dmask=700"); + + if (rc && errno == EROFS) { + LOGE("vfat_mount(%d:%d, %s): Read only filesystem - retrying mount RO", + dev->major, dev->minor, vol->mount_point); + flags |= MS_RDONLY; + rc = mount(devpath, vol->mount_point, "vfat", flags, + "utf8,uid=1000,gid=1000,fmask=711,dmask=700"); + } + +#if VFAT_DEBUG + LOG_VOL("vfat_mount(%s, %d:%d): mount rc = %d", dev->major,k dev->minor, + vol->mount_point, rc); +#endif + free (devpath); + return rc; +} |