From 267dd987b1aec750f8839d1d8d8c2f80d9f1107e Mon Sep 17 00:00:00 2001 From: Peter Wagner Date: Mon, 1 Jul 2013 20:22:21 +0000 Subject: [PATCH] add option to check ext* partitions before mounting V3 UpdatesV2: Check for e2fsck before calling it. fix whitespace Updates V3: fix another whitespace This patch adds a new option called check_fs to /etc/config/fstab, if set to '1' every partition with ext* fs will be checked before it gets mounted. Signed-off-by: Peter Wagner with minor changes to http://patchwork.openwrt.org/patch/3791/ Signed-off-by: John Crispin --- block.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 4bbfeb0..d0fce7e 100644 --- a/block.c +++ b/block.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -57,7 +58,7 @@ struct mount { static struct vlist_tree mounts; static struct blob_buf b; static LIST_HEAD(devices); -static int anon_mount, anon_swap, auto_mount, auto_swap; +static int anon_mount, anon_swap, auto_mount, auto_swap, check_fs; static unsigned int delay_root; enum { @@ -66,6 +67,7 @@ enum { CFG_AUTO_MOUNT, CFG_AUTO_SWAP, CFG_DELAY_ROOT, + CFG_CHECK_FS, __CFG_MAX }; @@ -75,6 +77,7 @@ static const struct blobmsg_policy config_policy[__CFG_MAX] = { [CFG_AUTO_SWAP] = { .name = "auto_swap", .type = BLOBMSG_TYPE_INT32 }, [CFG_AUTO_MOUNT] = { .name = "auto_mount", .type = BLOBMSG_TYPE_INT32 }, [CFG_DELAY_ROOT] = { .name = "delay_root", .type = BLOBMSG_TYPE_INT32 }, + [CFG_CHECK_FS] = { .name = "check_fs", .type = BLOBMSG_TYPE_INT32 }, }; enum { @@ -221,6 +224,9 @@ static int global_add(struct uci_section *s) if (tb[CFG_DELAY_ROOT]) delay_root = blobmsg_get_u32(tb[CFG_DELAY_ROOT]); + if ((tb[CFG_CHECK_FS]) && blobmsg_get_u32(tb[CFG_CHECK_FS])) + check_fs = 1; + return 0; } @@ -431,6 +437,33 @@ static void mkdir_p(char *dir) } } +static void check_filesystem(struct blkid_struct_probe *pr) +{ + pid_t pid; + struct stat statbuf; + char *e2fsck = "/usr/sbin/e2fsck"; + + if (strncmp(pr->id->name, "ext", 3)) { + fprintf(stderr, "check_filesystem: %s is not supported\n", pr->id->name); + return; + } + + if (stat(e2fsck, &statbuf) < 0) + return; + + if (!(statbuf.st_mode & S_IXUSR)) + return; + + pid = fork(); + if (!pid) { + execl(e2fsck, e2fsck, "-p", pr->dev, NULL); + exit(-1); + } else if (pid > 0) { + int status; + waitpid(pid, &status, 0); + } +} + static int mount_device(struct blkid_struct_probe *pr, int hotplug) { struct mount *m; @@ -471,6 +504,10 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) target = _target; } mkdir_p(target); + + if (check_fs) + check_filesystem(pr); + err = mount(pr->dev, target, pr->id->name, 0, (m->options) ? (m->options) : ("")); if (err) fprintf(stderr, "mounting %s (%s) as %s failed (%d) - %s\n", @@ -484,6 +521,10 @@ static int mount_device(struct blkid_struct_probe *pr, int hotplug) snprintf(target, sizeof(target), "/mnt/%s", device); mkdir_p(target); + + if (check_fs) + check_filesystem(pr); + err = mount(pr->dev, target, pr->id->name, 0, ""); if (err) fprintf(stderr, "mounting %s (%s) as %s failed (%d) - %s\n", @@ -672,6 +713,9 @@ static int mount_extroot(char *cfg) path = overlay; mkdir_p(path); + if (check_fs) + check_filesystem(pr); + err = mount(pr->dev, path, pr->id->name, 0, (m->options) ? (m->options) : ("")); if (err) { @@ -771,8 +815,9 @@ static int main_detect(int argc, char **argv) printf("\toption\tanon_swap\t'0'\n"); printf("\toption\tanon_mount\t'0'\n"); printf("\toption\tauto_swap\t'1'\n"); - printf("\toption\tauto_mount\t'1'\n\n"); - printf("\toption\tdelay_root\t'0'\n\n"); + printf("\toption\tauto_mount\t'1'\n"); + printf("\toption\tdelay_root\t'0'\n"); + printf("\toption\tcheck_fs\t'0'\n\n"); list_for_each_entry(pr, &devices, list) print_block_uci(pr); -- 2.25.1