]> sourceware.org Git - lvm2.git/commitdiff
dev-cache: optimize dir scanning
authorZdenek Kabelac <zkabelac@redhat.com>
Sat, 27 Feb 2021 16:09:38 +0000 (17:09 +0100)
committerZdenek Kabelac <zkabelac@redhat.com>
Tue, 2 Mar 2021 21:54:40 +0000 (22:54 +0100)
Use 'C' for alphasort - there is no need to use localized and slower
sorting for internal directory scanning.

Ensure on all code paths allocated dirent entries are released.

Optimize full path construction.

lib/device/dev-cache.c

index 21c9ef0eade4417f49a790b1b8469753e5e56d7f..bbf6ce833c20e530a1b7161adf0582d088647b67 100644 (file)
@@ -28,6 +28,7 @@
 #endif
 #include <unistd.h>
 #include <dirent.h>
+#include <locale.h>
 
 struct dev_iter {
        struct btree_iter *current;
@@ -809,16 +810,6 @@ static int _insert_dev(const char *path, dev_t d)
        return 0;
 }
 
-static char *_join(const char *dir, const char *name)
-{
-       size_t len = strlen(dir) + strlen(name) + 2;
-       char *r = malloc(len);
-       if (r)
-               snprintf(r, len, "%s/%s", dir, name);
-
-       return r;
-}
-
 /*
  * Get rid of extra slashes in the path string.
  */
@@ -845,27 +836,39 @@ static int _insert_dir(const char *dir)
 {
        int n, dirent_count, r = 1;
        struct dirent **dirent;
-       char *path;
+       char path[PATH_MAX];
+       size_t len;
+
+       if (!dm_strncpy(path, dir, sizeof(path) - 1)) {
+               log_debug_devs("Dir path %s is too long", path);
+               return 0;
+       }
+       _collapse_slashes(path);
+       len = strlen(path);
+       if (len && path[len - 1] != '/')
+               path[len++] = '/';
 
+       setlocale(LC_COLLATE, "C"); /* Avoid sorting by locales */
        dirent_count = scandir(dir, &dirent, NULL, alphasort);
        if (dirent_count > 0) {
                for (n = 0; n < dirent_count; n++) {
-                       if (dirent[n]->d_name[0] == '.') {
-                               free(dirent[n]);
+                       if (dirent[n]->d_name[0] == '.')
                                continue;
-                       }
 
-                       if (!(path = _join(dir, dirent[n]->d_name)))
-                               return_0;
+                       if (!dm_strncpy(path + len, dirent[n]->d_name, sizeof(path) - len)) {
+                               log_debug_devs("Path %s/%s is too long.", dir, dirent[n]->d_name);
+                               r = 0;
+                               continue;
+                       }
 
-                       _collapse_slashes(path);
                        r &= _insert(path, NULL, 1, 0);
-                       free(path);
+               }
 
+               for (n = 0; n < dirent_count; n++)
                        free(dirent[n]);
-               }
                free(dirent);
        }
+       setlocale(LC_COLLATE, "");
 
        return r;
 }
This page took 0.037205 seconds and 5 git commands to generate.