libf2fs: check more conditions on mounted filesystem
authorJaegeuk Kim <jaegeuk.kim@samsung.com>
Fri, 2 Aug 2013 08:03:10 +0000 (17:03 +0900)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Fri, 2 Aug 2013 08:06:26 +0000 (17:06 +0900)
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@samsung.com>
fsck/main.c
include/f2fs_fs.h
lib/libf2fs.c
mkfs/f2fs_format.c

index 80db15d..a0144fc 100644 (file)
@@ -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 */
index d0fc79e..7081e5e 100644 (file)
@@ -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);
index b02072f..6947425 100644 (file)
@@ -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;
 }
 
index d60f990..5b017c7 100644 (file)
@@ -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)