1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

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.
This commit is contained in:
Zdenek Kabelac 2021-02-27 17:09:38 +01:00
parent 9dd759c6b1
commit fa64c51428

View 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 (!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;
}
if (!(path = _join(dir, dirent[n]->d_name)))
return_0;
_collapse_slashes(path);
r &= _insert(path, NULL, 1, 0);
free(path);
free(dirent[n]);
}
for (n = 0; n < dirent_count; n++)
free(dirent[n]);
free(dirent);
}
setlocale(LC_COLLATE, "");
return r;
}