From: Tobias Jakobi Date: Wed, 28 Sep 2016 17:28:03 +0000 (+0200) Subject: libf2fs: increase robustness when called on root device X-Git-Tag: v1.8.0~58 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e5b3ec89eec84e9d073788e6169b464169305026;p=platform%2Fupstream%2Ff2fs-tools.git libf2fs: increase robustness when called on root device On some systems '/proc/mounts' contains the entry '/dev/root' as alias for the root device, while that alias doesn't actually exist as symlink in /dev. /proc/mounts: /dev/root / f2fs rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6 0 0 mount: /dev/mmcblk1p1 on / type f2fs (rw,noatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6) If the root device is mounted RO, and we try to scan it, via 'fsck.f2fs /dev/mmcblk1p1', then fsck.f2fs exits because it can't find the entry in /proc/mounts. Try harder to identify the root device of the system first, and in case we are operating on it, check also for '/dev/root' in mounts. Signed-off-by: Tobias Jakobi Signed-off-by: Jaegeuk Kim --- diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index 19ce250..bfe9b3f 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -279,6 +279,7 @@ struct f2fs_configuration { int32_t dump_fd; char *device_name; char *extension_list; + const char *rootdev_name; int dbg_lv; int trim; int func; diff --git a/lib/libf2fs.c b/lib/libf2fs.c index 2284a78..6140452 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -485,6 +486,53 @@ int f2fs_crc_valid(u_int32_t blk_crc, void *buf, int len) } /* + * try to identify the root device + */ +const char *get_rootdev() +{ + struct stat sb; + int fd, ret; + char buf[32]; + char *uevent, *ptr; + + static char rootdev[PATH_MAX + 1]; + + if (stat("/", &sb) == -1) + return NULL; + + snprintf(buf, 32, "/sys/dev/block/%u:%u/uevent", + major(sb.st_dev), minor(sb.st_dev)); + + fd = open(buf, O_RDONLY); + + if (fd < 0) + return NULL; + + ret = lseek(fd, (off_t)0, SEEK_END); + (void)lseek(fd, (off_t)0, SEEK_SET); + + if (ret == -1) { + close(fd); + return NULL; + } + + uevent = malloc(ret + 1); + uevent[ret] = '\0'; + + ret = read(fd, uevent, ret); + close(fd); + + ptr = strstr(uevent, "DEVNAME"); + if (!ptr) + return NULL; + + ret = sscanf(ptr, "DEVNAME=%s\n", buf); + snprintf(rootdev, PATH_MAX + 1, "/dev/%s", buf); + + return rootdev; +} + +/* * device information */ void f2fs_init_configuration(void) @@ -493,6 +541,7 @@ void f2fs_init_configuration(void) c.sector_size = DEFAULT_SECTOR_SIZE; c.sectors_per_blk = DEFAULT_SECTORS_PER_BLOCK; c.blks_per_seg = DEFAULT_BLOCKS_PER_SEGMENT; + c.rootdev_name = get_rootdev(); /* calculated by overprovision ratio */ c.reserved_segments = 0; @@ -532,8 +581,12 @@ static int is_mounted(const char *mpt, const char *device) int f2fs_dev_is_umounted(void) { struct stat st_buf; + int is_rootdev = 0; int ret = 0; + if (c.rootdev_name && !strcmp(c.device_name, c.rootdev_name)) + is_rootdev = 1; + /* * try with /proc/mounts fist to detect RDONLY. * f2fs_stop_checkpoint makes RO in /proc/mounts while RW in /etc/mtab. @@ -551,6 +604,19 @@ int f2fs_dev_is_umounted(void) } /* + * If we are supposed to operate on the root device, then + * also check the mounts for '/dev/root', which sometimes + * functions as an alias for the root device. + */ + if (is_rootdev) { + ret = is_mounted("/proc/mounts", "/dev/root"); + if (ret) { + MSG(0, "Info: 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. */