diff options
author | Chao Yu <chao@kernel.org> | 2024-01-31 15:34:25 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2024-02-07 16:25:51 -0800 |
commit | 14197d546b9326035e038034a3f95937cb7b7d30 (patch) | |
tree | 2f04bf823579f0e2089a599a98fb3547b41d2f6c | |
parent | 96da467d9357f546dbab7bdb6d51283efd4d6ad3 (diff) | |
download | f2fs-tools-14197d546b9326035e038034a3f95937cb7b7d30.tar.gz |
f2fs-tools: fix to check loop device
Otherwise, mkfs/fsck can update backfile of moutned loop device.
1. mkfs.f2fs image
2. mount -o loop image /mnt/f2fs/
3. mkfs.f2fs image -f
Before:
...
Info: format successful
After:
...
Error: In use by loop device!
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | fsck/main.c | 4 | ||||
-rw-r--r-- | include/android_config.h | 2 | ||||
-rw-r--r-- | lib/libf2fs.c | 74 | ||||
-rw-r--r-- | mkfs/f2fs_format_main.c | 7 |
5 files changed, 74 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac index 123ddbb..21c6391 100644 --- a/configure.ac +++ b/configure.ac @@ -144,6 +144,8 @@ AC_CHECK_HEADERS(m4_flatten([ linux/fs.h linux/hdreg.h linux/limits.h + linux/loop.h + linux/major.h linux/posix_acl.h linux/types.h linux/xattr.h diff --git a/fsck/main.c b/fsck/main.c index 1affa72..c4d0956 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -1111,8 +1111,8 @@ int main(int argc, char **argv) f2fs_parse_options(argc, argv); - if (c.func != DUMP && f2fs_devs_are_umounted() < 0) { - if (errno == EBUSY) { + if (c.func != DUMP && (ret = f2fs_devs_are_umounted()) < 0) { + if (ret == -EBUSY) { ret = -1; if (c.func == FSCK) ret = FSCK_OPERATIONAL_ERROR; diff --git a/include/android_config.h b/include/android_config.h index da8abcb..05b686e 100644 --- a/include/android_config.h +++ b/include/android_config.h @@ -6,6 +6,8 @@ #define HAVE_FSYNC 1 #define HAVE_LINUX_HDREG_H 1 #define HAVE_LINUX_LIMITS_H 1 +#define HAVE_LINUX_LOOP_H 1 +#define HAVE_LINUX_MAJOR_H 1 #define HAVE_POSIX_ACL_H 1 #define HAVE_LINUX_TYPES_H 1 #define HAVE_LINUX_XATTR_H 1 diff --git a/lib/libf2fs.c b/lib/libf2fs.c index 13f2b07..5c6c5b7 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -19,6 +19,12 @@ #endif #include <time.h> #include <sys/stat.h> +#ifdef HAVE_LINUX_LOOP_H +#include <linux/loop.h> +#ifdef HAVE_LINUX_MAJOR_H +#include <linux/major.h> +#endif +#endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif @@ -756,7 +762,7 @@ int f2fs_dev_is_umounted(char *path) #ifdef _WIN32 return 0; #else - struct stat *st_buf; + struct stat st_buf; int is_rootdev = 0; int ret = 0; char *rootdev_name = get_rootdev(); @@ -807,32 +813,78 @@ int f2fs_dev_is_umounted(char *path) * If f2fs is umounted with -l, the process can still use * the file system. In this case, we should not format. */ - st_buf = malloc(sizeof(struct stat)); - ASSERT(st_buf); + if (stat(path, &st_buf)) { + MSG(0, "Info: stat failed errno:%d\n", errno); + return -1; + } - if (stat(path, st_buf) == 0 && S_ISBLK(st_buf->st_mode)) { + if (S_ISBLK(st_buf.st_mode)) { int fd = open(path, O_RDONLY | O_EXCL); if (fd >= 0) { close(fd); } else if (errno == EBUSY) { MSG(0, "\tError: In use by the system!\n"); - free(st_buf); - return -1; + return -EBUSY; } + } else if (S_ISREG(st_buf.st_mode)) { + /* check whether regular is backfile of loop device */ +#if defined(HAVE_LINUX_LOOP_H) && defined(HAVE_LINUX_MAJOR_H) + struct mntent *mnt; + struct stat st_loop; + FILE *f; + + f = setmntent("/proc/mounts", "r"); + + while ((mnt = getmntent(f)) != NULL) { + struct loop_info64 loopinfo = {0, }; + int loop_fd, err; + + if (mnt->mnt_fsname[0] != '/') + continue; + if (stat(mnt->mnt_fsname, &st_loop) != 0) + continue; + if (!S_ISBLK(st_loop.st_mode)) + continue; + if (major(st_loop.st_rdev) != LOOP_MAJOR) + continue; + + loop_fd = open(mnt->mnt_fsname, O_RDONLY); + if (loop_fd < 0) { + MSG(0, "Info: open %s failed errno:%d\n", + mnt->mnt_fsname, errno); + return -1; + } + + err = ioctl(loop_fd, LOOP_GET_STATUS64, &loopinfo); + close(loop_fd); + if (err < 0) { + MSG(0, "\tError: ioctl LOOP_GET_STATUS64 failed errno:%d!\n", + errno); + return -1; + } + + if (st_buf.st_dev == loopinfo.lo_device && + st_buf.st_ino == loopinfo.lo_inode) { + MSG(0, "\tError: In use by loop device!\n"); + return -EBUSY; + } + } +#endif } - free(st_buf); return ret; #endif } int f2fs_devs_are_umounted(void) { - int i; + int ret, i; - for (i = 0; i < c.ndevs; i++) - if (f2fs_dev_is_umounted((char *)c.devices[i].path)) - return -1; + for (i = 0; i < c.ndevs; i++) { + ret = f2fs_dev_is_umounted((char *)c.devices[i].path); + if (ret) + return ret; + } return 0; } diff --git a/mkfs/f2fs_format_main.c b/mkfs/f2fs_format_main.c index 4de517a..f3316f7 100644 --- a/mkfs/f2fs_format_main.c +++ b/mkfs/f2fs_format_main.c @@ -443,6 +443,8 @@ static int f2fs_check_overwrite(void) int main(int argc, char *argv[]) { + int ret; + f2fs_init_configuration(); f2fs_parse_options(argc, argv); @@ -451,8 +453,9 @@ int main(int argc, char *argv[]) c.func = MKFS; - if (f2fs_devs_are_umounted() < 0) { - if (errno != EBUSY) + ret = f2fs_devs_are_umounted(); + if (ret) { + if (ret != -EBUSY) MSG(0, "\tError: Not available on mounted device!\n"); goto err_format; } |