[lvm-devel] main - dev-cache: optimize dir scanning
Zdenek Kabelac
zkabelac at sourceware.org
Tue Mar 2 21:58:31 UTC 2021
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fa64c51428ca20e860bbe21338d916329b8aaf25
Commit: fa64c51428ca20e860bbe21338d916329b8aaf25
Parent: 9dd759c6b1c0e25e785485f823b09c59ef5b2583
Author: Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate: Sat Feb 27 17:09:38 2021 +0100
Committer: Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Tue Mar 2 22:54:40 2021 +0100
dev-cache: optimize dir scanning
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 | 41 ++++++++++++++++++++++-------------------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 21c9ef0ea..bbf6ce833 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -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;
}
More information about the lvm-devel
mailing list