Whamcloud - gitweb
misc/mk_hugefiles: simplify get_partition_start()
authorEric Biggers <ebiggers@google.com>
Sat, 21 Jan 2023 20:32:23 +0000 (12:32 -0800)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 27 Jan 2023 17:38:31 +0000 (12:38 -0500)
search_sysfs_block() is causing -Wformat-truncation warnings.  These
could be fixed by checking the return value of snprintf(), instead of
doing buggy checks like 'strlen(p_de->d_name) > SYSFS_PATH_LEN -
strlen(path) - 32', which has an integer underflow bug.

However, the only purpose of search_sysfs_block() is to find the sysfs
directory for a block device by device number.  That can trivially be
done using /sys/dev/block/$major:$minor.  So just do that instead.  Also
make get_partition_start() explicitly Linux-only, as it has never worked
anywhere else.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
include/mingw/sys/sysmacros.h
misc/mk_hugefiles.c

index 18fcaaa..a790cb2 100644 (file)
@@ -1,11 +1,5 @@
-
 #pragma once
 
-/*
- * Fall back to Linux's definitions of makedev and major are needed.
- * The search_sysfs_block() function is highly unlikely to work on
- * non-Linux systems anyway.
- */
 #ifndef makedev
 #define makedev(maj, min) (((maj) << 8) + (min))
-#endif
\ No newline at end of file
+#endif
index 0280b41..3caaf1b 100644 (file)
@@ -2,13 +2,8 @@
  * mk_hugefiles.c -- create huge files
  */
 
-#define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX in Solaris */
-#define _BSD_SOURCE      /* for makedev() and major() */
-#define _DEFAULT_SOURCE          /* since glibc 2.20 _BSD_SOURCE is deprecated */
-
 #include "config.h"
 #include <stdio.h>
-#include <stdarg.h>
 #include <string.h>
 #include <strings.h>
 #include <fcntl.h>
@@ -68,141 +63,30 @@ static char *fn_buf;
 static char *fn_numbuf;
 int zero_hugefile = 1;
 
-#define SYSFS_PATH_LEN 300
-typedef char sysfs_path_t[SYSFS_PATH_LEN];
-
-#ifndef HAVE_SNPRINTF
-/*
- * We are very careful to avoid needing to worry about buffer
- * overflows, so we don't really need to use snprintf() except as an
- * additional safety check.  So if snprintf() is not present, it's
- * safe to fall back to vsprintf().  This provides portability since
- * vsprintf() is guaranteed by C89, while snprintf() is only
- * guaranteed by C99 --- which for example, Microsoft Visual Studio
- * has *still* not bothered to implement.  :-/  (Not that I expect
- * mke2fs to be ported to MS Visual Studio any time soon, but
- * libext2fs *does* get built on Microsoft platforms, and we might
- * want to move this into libext2fs some day.)
- */
-static int my_snprintf(char *str, size_t size, const char *format, ...)
-{
-       va_list ap;
-       int ret;
-
-       va_start(ap, format);
-       ret = vsprintf(str, format, ap);
-       va_end(ap);
-       return ret;
-}
-
-#define snprintf my_snprintf
-#endif
-
-/*
- * Fall back to Linux's definitions of makedev and major are needed.
- * The search_sysfs_block() function is highly unlikely to work on
- * non-Linux systems anyway.
- */
-#ifndef makedev
-#define makedev(maj, min) (((maj) << 8) + (min))
-#endif
-
-static char *search_sysfs_block(dev_t devno, sysfs_path_t ret_path)
-{
-       struct dirent   *de, *p_de;
-       DIR             *dir = NULL, *p_dir = NULL;
-       FILE            *f;
-       sysfs_path_t    path, p_path;
-       unsigned int    major, minor;
-       char            *ret = ret_path;
-
-       ret_path[0] = 0;
-       if ((dir = opendir("/sys/block")) == NULL)
-               return NULL;
-       while ((de = readdir(dir)) != NULL) {
-               if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
-                   strlen(de->d_name) > sizeof(path)-32)
-                       continue;
-               snprintf(path, SYSFS_PATH_LEN,
-                        "/sys/block/%s/dev", de->d_name);
-               f = fopen(path, "r");
-               if (f &&
-                   (fscanf(f, "%u:%u", &major, &minor) == 2)) {
-                       fclose(f); f = NULL;
-                       if (makedev(major, minor) == devno) {
-                               snprintf(ret_path, SYSFS_PATH_LEN,
-                                        "/sys/block/%s", de->d_name);
-                               goto success;
-                       }
-#ifdef major
-                       if (major(devno) != major)
-                               continue;
-#endif
-               }
-               if (f)
-                       fclose(f);
-
-               snprintf(path, SYSFS_PATH_LEN, "/sys/block/%s", de->d_name);
-
-               if (p_dir)
-                       closedir(p_dir);
-               if ((p_dir = opendir(path)) == NULL)
-                       continue;
-               while ((p_de = readdir(p_dir)) != NULL) {
-                       if (!strcmp(p_de->d_name, ".") ||
-                           !strcmp(p_de->d_name, "..") ||
-                           (strlen(p_de->d_name) >
-                            SYSFS_PATH_LEN - strlen(path) - 32))
-                               continue;
-                       snprintf(p_path, SYSFS_PATH_LEN, "%s/%s/dev",
-                                path, p_de->d_name);
-
-                       f = fopen(p_path, "r");
-                       if (f &&
-                           (fscanf(f, "%u:%u", &major, &minor) == 2) &&
-                           (((major << 8) + minor) == devno)) {
-                               fclose(f);
-                               snprintf(ret_path, SYSFS_PATH_LEN, "%s/%s",
-                                        path, p_de->d_name);
-                               goto success;
-                       }
-                       if (f)
-                               fclose(f);
-               }
-       }
-       ret = NULL;
-success:
-       if (dir)
-               closedir(dir);
-       if (p_dir)
-               closedir(p_dir);
-       return ret;
-}
-
-static blk64_t get_partition_start(const char *device_name)
+static blk64_t
+get_partition_start(const char *device_name EXT2FS_ATTR((unused)))
 {
+#ifdef __linux__
        unsigned long long start;
-       sysfs_path_t    path;
+       char            path[128];
        struct stat     st;
        FILE            *f;
-       char            *cp;
        int             n;
 
        if ((stat(device_name, &st) < 0) || !S_ISBLK(st.st_mode))
                return 0;
 
-       cp = search_sysfs_block(st.st_rdev, path);
-       if (!cp)
-               return 0;
-       if (strlen(path) > SYSFS_PATH_LEN - sizeof("/start"))
-               return 0;
-       strcat(path, "/start");
+       sprintf(path, "/sys/dev/block/%d:%d/start",
+               major(st.st_rdev), minor(st.st_rdev));
        f = fopen(path, "r");
        if (!f)
                return 0;
        n = fscanf(f, "%llu", &start);
        fclose(f);
        return (n == 1) ? start : 0;
+#else
+       return 0;
+#endif
 }
 
 static errcode_t create_directory(ext2_filsys fs, char *dir,