summaryrefslogtreecommitdiffstats
path: root/fs_mgr
diff options
context:
space:
mode:
Diffstat (limited to 'fs_mgr')
-rw-r--r--fs_mgr/fs_mgr.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 0361ab8..e51c9cf 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -58,6 +58,12 @@ static struct flag_list mount_flags[] = {
{ "ro", MS_RDONLY },
{ "rw", 0 },
{ "remount", MS_REMOUNT },
+ { "bind", MS_BIND },
+ { "rec", MS_REC },
+ { "unbindable", MS_UNBINDABLE },
+ { "private", MS_PRIVATE },
+ { "slave", MS_SLAVE },
+ { "shared", MS_SHARED },
{ "defaults", 0 },
{ 0, 0 },
};
@@ -167,7 +173,7 @@ out:
* then return an empty buffer. This effectively ignores lines that are too long.
* On EOF, return null.
*/
-static char *getline(char *buf, int size, FILE *file)
+static char *fs_getline(char *buf, int size, FILE *file)
{
int cnt = 0;
int eof = 0;
@@ -241,7 +247,7 @@ static struct fstab_rec *read_fstab(char *fstab_path)
}
entries = 0;
- while (getline(line, sizeof(line), fstab_file)) {
+ while (fs_getline(line, sizeof(line), fstab_file)) {
/* if the last character is a newline, shorten the string by 1 byte */
len = strlen(line);
if (line[len - 1] == '\n') {
@@ -268,7 +274,7 @@ static struct fstab_rec *read_fstab(char *fstab_path)
fseek(fstab_file, 0, SEEK_SET);
cnt = 0;
- while (getline(line, sizeof(line), fstab_file)) {
+ while (fs_getline(line, sizeof(line), fstab_file)) {
/* if the last character is a newline, shorten the string by 1 byte */
len = strlen(line);
if (line[len - 1] == '\n') {
@@ -358,13 +364,34 @@ static void free_fstab(struct fstab_rec *fstab)
free(fstab);
}
-static void check_fs(char *blk_dev, char *type)
+static void check_fs(char *blk_dev, char *type, char *target)
{
pid_t pid;
int status;
+ int ret;
+ long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
+ char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro";
/* Check for the types of filesystems we know how to check */
if (!strcmp(type, "ext2") || !strcmp(type, "ext3") || !strcmp(type, "ext4")) {
+ /*
+ * First try to mount and unmount the filesystem. We do this because
+ * the kernel is more efficient than e2fsck in running the journal and
+ * processing orphaned inodes, and on at least one device with a
+ * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
+ * to do what the kernel does in about a second.
+ *
+ * After mounting and unmounting the filesystem, run e2fsck, and if an
+ * error is recorded in the filesystem superblock, e2fsck will do a full
+ * check. Otherwise, it does nothing. If the kernel cannot mount the
+ * filesytsem due to an error, e2fsck is still run to do a full check
+ * fix the filesystem.
+ */
+ ret = mount(blk_dev, target, type, tmpmnt_flags, tmpmnt_opts);
+ if (! ret) {
+ umount(target);
+ }
+
INFO("Running %s on %s\n", E2FSCK_BIN, blk_dev);
pid = fork();
if (pid > 0) {
@@ -434,7 +461,7 @@ int fs_mgr_mount_all(char *fstab_file)
}
if (fstab[i].fs_mgr_flags & MF_CHECK) {
- check_fs(fstab[i].blk_dev, fstab[i].type);
+ check_fs(fstab[i].blk_dev, fstab[i].type, fstab[i].mnt_point);
}
mret = mount(fstab[i].blk_dev, fstab[i].mnt_point, fstab[i].type,
@@ -496,11 +523,11 @@ int fs_mgr_do_mount(char *fstab_file, char *n_name, char *n_blk_dev, char *tmp_m
/* We found our match */
/* First check the filesystem if requested */
if (fstab[i].fs_mgr_flags & MF_WAIT) {
- wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT);
+ wait_for_file(n_blk_dev, WAIT_TIMEOUT);
}
if (fstab[i].fs_mgr_flags & MF_CHECK) {
- check_fs(fstab[i].blk_dev, fstab[i].type);
+ check_fs(n_blk_dev, fstab[i].type, fstab[i].mnt_point);
}
/* Now mount it where requested */