In the case of lazy umount, "umount -l", some processes are able to use the file system even if its mountpoint was disconnected. At this moment, we should not allow mkfs.f2fs. This patch adds this condition check. Signed-off-by: Jaegeuk Kim <jaegeuk.kim@xxxxxxxxxxx> --- fsck/main.c | 2 +- include/f2fs_fs.h | 2 +- lib/libf2fs.c | 60 +++++++++++++++++++++++++++++++++++++++--------------- mkfs/f2fs_format.c | 2 +- 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/fsck/main.c b/fsck/main.c index 80db15d..a0144fc 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -183,7 +183,7 @@ int main (int argc, char **argv) f2fs_parse_options(argc, argv); - if (f2fs_dev_is_mounted(&config) < 0) + if (f2fs_dev_is_umounted(&config) < 0) return -1; /* Get device */ diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index d0fc79e..7081e5e 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -641,7 +641,7 @@ extern u_int32_t f2fs_cal_crc32(u_int32_t, void *, int); extern int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len); extern void f2fs_init_configuration(struct f2fs_configuration *); -extern int f2fs_dev_is_mounted(struct f2fs_configuration *); +extern int f2fs_dev_is_umounted(struct f2fs_configuration *); extern int f2fs_get_device_info(struct f2fs_configuration *); extern int dev_read(void *, __u64, size_t); diff --git a/lib/libf2fs.c b/lib/libf2fs.c index b02072f..6947425 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -13,6 +13,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include <unistd.h> #include <fcntl.h> #include <mntent.h> @@ -365,31 +366,58 @@ void f2fs_init_configuration(struct f2fs_configuration *c) c->device_name = NULL; } -int f2fs_dev_is_mounted(struct f2fs_configuration *c) +static int is_mounted(const char *mpt, const char *device) { FILE *file = NULL; struct mntent *mnt = NULL; - file = setmntent(MOUNTED, "r"); - if (file == NULL) { - /* if failed due to /etc/mtab file not present - try with /proc/mounts */ - file = setmntent("/proc/mounts", "r"); - if (file == NULL) - return 0; - } + file = setmntent(mpt, "r"); + if (file == NULL) + return 0; - while (1) { - mnt = getmntent(file); - if (mnt == NULL) + while ((mnt = getmntent(file)) != NULL) { + if (!strcmp(device, mnt->mnt_fsname)) break; - if (!strcmp(c->device_name, mnt->mnt_fsname)) { - endmntent(file); - MSG(0, "\tError: Not available on mounted device!\n"); + } + endmntent(file); + return mnt ? 1 : 0; +} + +int f2fs_dev_is_umounted(struct f2fs_configuration *c) +{ + struct stat st_buf; + int ret = 0; + + ret = is_mounted(MOUNTED, c->device_name); + if (ret) { + MSG(0, "\tError: Not available on mounted device!\n"); + return -1; + } + + /* + * if failed due to /etc/mtab file not present + * try with /proc/mounts. + */ + ret = is_mounted("/proc/mounts", c->device_name); + if (ret) { + MSG(0, "\tError: Not available on mounted device!\n"); + return -1; + } + + /* + * If f2fs is umounted with -l, the process can still use + * the file system. In this case, we should not format. + */ + if (stat(c->device_name, &st_buf) == 0 && S_ISBLK(st_buf.st_mode)) { + int fd = open(c->device_name, O_RDONLY | O_EXCL); + + if (fd >= 0) { + close(fd); + } else if (errno == EBUSY) { + MSG(0, "\tError: In use by the system!\n"); return -1; } } - endmntent(file); return 0; } diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c index d60f990..5b017c7 100644 --- a/mkfs/f2fs_format.c +++ b/mkfs/f2fs_format.c @@ -998,7 +998,7 @@ int main(int argc, char *argv[]) f2fs_parse_options(argc, argv); - if (f2fs_dev_is_mounted(&config) < 0) + if (f2fs_dev_is_umounted(&config) < 0) return -1; if (f2fs_get_device_info(&config) < 0) -- 1.8.3.1.437.g0dbd812 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html