]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
depmod: use array for dependency output
authorTobias Stoeckmann <tobias@stoeckmann.org>
Fri, 18 Oct 2024 15:23:17 +0000 (17:23 +0200)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Tue, 22 Oct 2024 16:52:48 +0000 (11:52 -0500)
The shared/array implementation is already used within depmod, but not
for dependency output. Adding it here reduces the amount of custom code
in depmod, simplifies auditing, reduces binary size, and has the nice
benefit of slightly faster runtime due to memory reusage.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Link: https://github.com/kmod-project/kmod/pull/193
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
tools/depmod.c

index a3f9801ff7a2225c1cc6c91bf51ce98e30246f2e..cbac467cd27c9e3a8c6f7a64f224710603bc7d85 100644 (file)
@@ -1995,70 +1995,39 @@ static int depmod_load(struct depmod *depmod)
        return 0;
 }
 
-static size_t mod_count_all_dependencies(const struct mod *mod)
-{
-       size_t i, count = 0;
-       for (i = 0; i < mod->deps.count; i++) {
-               const struct mod *d = mod->deps.array[i];
-               count += 1 + mod_count_all_dependencies(d);
-       }
-       return count;
-}
-
-static int mod_fill_all_unique_dependencies(const struct mod *mod,
-                                           const struct mod **deps, size_t n_deps,
-                                           size_t *last)
+static int mod_fill_all_unique_dependencies(const struct mod *mod, struct array *deps)
 {
        size_t i;
        int err = 0;
+
        for (i = 0; i < mod->deps.count; i++) {
                const struct mod *d = mod->deps.array[i];
-               size_t j;
-               uint8_t exists = 0;
 
-               for (j = 0; j < *last; j++) {
-                       if (deps[j] == d) {
-                               exists = 1;
-                               break;
+               err = array_append_unique(deps, d);
+               if (err < 0) {
+                       if (err == -EEXIST) {
+                               err = 0;
+                               continue;
                        }
+                       return err;
                }
 
-               if (exists)
-                       continue;
-
-               if (*last >= n_deps)
-                       return -ENOSPC;
-               deps[*last] = d;
-               (*last)++;
-               err = mod_fill_all_unique_dependencies(d, deps, n_deps, last);
+               err = mod_fill_all_unique_dependencies(d, deps);
                if (err < 0)
                        break;
        }
        return err;
 }
 
-static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod,
-                                                         size_t *n_deps)
+static bool mod_get_all_sorted_dependencies(const struct mod *mod, struct array *deps)
 {
-       const struct mod **deps;
-       size_t last = 0;
-
-       *n_deps = mod_count_all_dependencies(mod);
-       if (*n_deps == 0)
-               return NULL;
-
-       deps = malloc(sizeof(struct mod *) * (*n_deps));
-       if (deps == NULL)
-               return NULL;
-
-       if (mod_fill_all_unique_dependencies(mod, deps, *n_deps, &last) < 0) {
-               free(deps);
-               return NULL;
-       }
+       deps->count = 0;
+       if (mod_fill_all_unique_dependencies(mod, deps) < 0)
+               return false;
 
-       qsort(deps, last, sizeof(struct mod *), dep_cmp);
-       *n_deps = last;
-       return deps;
+       if (deps->count > 1)
+               array_sort(deps, dep_cmp);
+       return true;
 }
 
 static inline const char *mod_get_compressed_path(const struct mod *mod)
@@ -2071,32 +2040,34 @@ static inline const char *mod_get_compressed_path(const struct mod *mod)
 static int output_deps(struct depmod *depmod, FILE *out)
 {
        size_t i;
+       struct array deps;
+
+       array_init(&deps, 64);
 
        for (i = 0; i < depmod->modules.count; i++) {
-               const struct mod **deps, *mod = depmod->modules.array[i];
+               const struct mod *mod = depmod->modules.array[i];
                const char *p = mod_get_compressed_path(mod);
-               size_t j, n_deps;
+               size_t j;
 
                fprintf(out, "%s:", p);
 
                if (mod->deps.count == 0)
                        goto end;
 
-               deps = mod_get_all_sorted_dependencies(mod, &n_deps);
-               if (deps == NULL) {
+               if (!mod_get_all_sorted_dependencies(mod, &deps)) {
                        ERR("could not get all sorted dependencies of %s\n", p);
                        goto end;
                }
 
-               for (j = 0; j < n_deps; j++) {
-                       const struct mod *d = deps[j];
+               for (j = 0; j < deps.count; j++) {
+                       const struct mod *d = deps.array[j];
                        fprintf(out, " %s", mod_get_compressed_path(d));
                }
-               free(deps);
 end:
                putc('\n', out);
        }
 
+       array_free_array(&deps);
        return 0;
 }
 
@@ -2104,6 +2075,7 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
 {
        struct index_node *idx;
        size_t i;
+       struct array array;
 
        if (out == stdout)
                return 0;
@@ -2112,28 +2084,28 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
        if (idx == NULL)
                return -ENOMEM;
 
+       array_init(&array, 64);
+
        for (i = 0; i < depmod->modules.count; i++) {
-               const struct mod **deps, *mod = depmod->modules.array[i];
+               const struct mod *mod = depmod->modules.array[i];
                const char *p = mod_get_compressed_path(mod);
                char *line;
-               size_t j, n_deps, linepos, linelen, slen;
+               size_t j, linepos, linelen, slen;
                int duplicate;
 
-               deps = mod_get_all_sorted_dependencies(mod, &n_deps);
-               if (deps == NULL && n_deps > 0) {
+               if (!mod_get_all_sorted_dependencies(mod, &array)) {
                        ERR("could not get all sorted dependencies of %s\n", p);
                        continue;
                }
 
                linelen = strlen(p) + 1;
-               for (j = 0; j < n_deps; j++) {
-                       const struct mod *d = deps[j];
+               for (j = 0; j < array.count; j++) {
+                       const struct mod *d = array.array[j];
                        linelen += 1 + strlen(mod_get_compressed_path(d));
                }
 
                line = malloc(linelen + 1);
                if (line == NULL) {
-                       free(deps);
                        ERR("modules.deps.bin: out of memory\n");
                        continue;
                }
@@ -2145,8 +2117,8 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
                line[linepos] = ':';
                linepos++;
 
-               for (j = 0; j < n_deps; j++) {
-                       const struct mod *d = deps[j];
+               for (j = 0; j < array.count; j++) {
+                       const struct mod *d = array.array[j];
                        const char *dp;
 
                        line[linepos] = ' ';
@@ -2163,9 +2135,9 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
                if (duplicate && depmod->cfg->warn_dups)
                        WRN("duplicate module deps:\n%s\n", line);
                free(line);
-               free(deps);
        }
 
+       array_free_array(&array);
        index_write(idx, out);
        index_destroy(idx);