]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: unify nodev lists into global one
authorMasatake YAMATO <yamato@redhat.com>
Thu, 13 May 2021 20:24:21 +0000 (05:24 +0900)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Oct 2021 09:01:54 +0000 (11:01 +0200)
misc-utils/lsfd-file.c
misc-utils/lsfd.c
misc-utils/lsfd.h

index 1684d038da40c347c7fc6b7b5924326e6e98d184..762d759f1ea4ff894ecd2cc0fcae380c078f96f7 100644 (file)
@@ -227,8 +227,7 @@ static bool file_fill_column(struct proc *proc,
                break;
        case COL_DEVNAME:
                if (major(file->stat.st_dev) == 0) {
-                       const char *filesystem = get_nodev_filesystem(proc,
-                                                                     minor(file->stat.st_dev));
+                       const char *filesystem = get_nodev_filesystem(minor(file->stat.st_dev));
                        if (filesystem) {
                                xasprintf(&str, "nodev:%s", filesystem);
                                break;
index 3bb43ffc00c03035891988eea71badba221584c8..06accb14b3bcfc54b670d83686f4dcafdb615fd0 100644 (file)
@@ -52,6 +52,7 @@ static int kcmp(pid_t pid1, pid_t pid2, int type,
 #include "lsfd.h"
 
 static void fill_proc(struct proc *proc);
+static void add_nodev(unsigned long minor, const char *filesystem);
 
 /*
  * /proc/$pid/maps entries
@@ -72,6 +73,11 @@ struct nodev {
        char *filesystem;
 };
 
+struct nodev_table {
+#define NODEV_TABLE_SIZE 97
+       struct list_head tables[NODEV_TABLE_SIZE];
+} nodev_table;
+
 /*
  * Column related stuffs
  */
@@ -249,9 +255,16 @@ static void free_nodev(struct nodev *nodev)
        free(nodev);
 }
 
-static void free_nodevs(struct list_head *nodevs)
+static void initialize_nodevs(void)
+{
+       for (int i = 0; i < NODEV_TABLE_SIZE; i++)
+               INIT_LIST_HEAD(&nodev_table.tables[i]);
+}
+
+static void finalize_nodevs(void)
 {
-       list_free(nodevs, struct nodev, nodevs, free_nodev);
+       for (int i = 0; i < NODEV_TABLE_SIZE; i++)
+               list_free(&nodev_table.tables[i], struct nodev, nodevs, free_nodev);
 }
 
 static void free_proc(struct proc *proc)
@@ -259,7 +272,6 @@ static void free_proc(struct proc *proc)
        list_free(&proc->files, struct file, files, free_file);
 
        free(proc->command);
-       free_nodevs(&proc->nodevs);
        free(proc);
 }
 
@@ -723,13 +735,12 @@ static FILE *open_mountinfo(pid_t pid, pid_t tid)
        return fopenf("r", "/proc/%d/task/%d/mountinfo", pid, tid);
 }
 
-static void read_nodevs(struct list_head *nodevs_list, FILE *mountinfo_fp)
+static void add_nodevs(FILE *mountinfo_fp)
 {
        /* This can be very long.
           A line in mountinfo can have more than 3 paths. */
        char line[PATH_MAX * 3 + 256];
        while (fgets(line, sizeof(line), mountinfo_fp)) {
-               struct nodev *nodev;
                unsigned long major, minor;
                char filesystem[256];
 
@@ -744,8 +755,7 @@ static void read_nodevs(struct list_head *nodevs_list, FILE *mountinfo_fp)
                if (major != 0)
                        continue;
 
-               nodev = make_nodev(minor, filesystem);
-               list_add_tail(&nodev->nodevs, nodevs_list);
+               add_nodev(minor, filesystem);
        }
 }
 
@@ -754,7 +764,6 @@ static void fill_proc(struct proc *proc)
        FILE *mountinfo_fp;
 
        INIT_LIST_HEAD(&proc->files);
-       INIT_LIST_HEAD(&proc->nodevs);
 
        proc->command = proc_get_command_name(proc->pid);
        if (!proc->command)
@@ -773,7 +782,7 @@ static void fill_proc(struct proc *proc)
        mountinfo_fp = open_mountinfo(proc->leader->pid,
                                      proc->pid);
        if (mountinfo_fp) {
-               read_nodevs(&proc->nodevs, mountinfo_fp);
+               add_nodevs(mountinfo_fp);
                fclose(mountinfo_fp);
        }
 
@@ -913,7 +922,6 @@ int main(int argc, char *argv[])
        char *outarg = NULL;
 
        struct list_head procs;
-
        struct lsfd_control ctl = {};
 
        static const struct option longopts[] = {
@@ -996,6 +1004,7 @@ int main(int argc, char *argv[])
                        scols_column_set_json_type(cl, col->json_type);
        }
 
+       initialize_nodevs();
        initialize_classes();
 
        INIT_LIST_HEAD(&procs);
@@ -1006,6 +1015,7 @@ int main(int argc, char *argv[])
        delete(&procs, &ctl);
 
        finalize_classes();
+       finalize_nodevs();
 
        return 0;
 }
@@ -1064,17 +1074,6 @@ unsigned long add_name(struct name_manager *nm, const char *name)
        return e->id;
 }
 
-const char *get_nodev_filesystem(struct proc *proc, unsigned long minor)
-{
-       struct list_head *n;
-       list_for_each (n, &proc->nodevs) {
-               struct nodev *nodev = list_entry(n, struct nodev, nodevs);
-               if (nodev->minor == minor)
-                       return nodev->filesystem;
-       }
-       return NULL;
-}
-
 DIR *opendirf(const char *format, ...)
 {
        va_list ap;
@@ -1102,3 +1101,25 @@ FILE *fopenf(const char *mode, const char *format, ...)
 
        return fopen(path, mode);
 }
+
+static void add_nodev(unsigned long minor, const char *filesystem)
+{
+       if (get_nodev_filesystem(minor))
+               return;
+
+       struct nodev *nodev = make_nodev(minor, filesystem);
+       int slot = minor % NODEV_TABLE_SIZE;
+       list_add_tail(&nodev->nodevs, &nodev_table.tables[slot]);
+}
+
+const char *get_nodev_filesystem(unsigned long minor)
+{
+       struct list_head *n;
+       int slot = minor % NODEV_TABLE_SIZE;
+       list_for_each (n, &nodev_table.tables[slot]) {
+               struct nodev *nodev = list_entry(n, struct nodev, nodevs);
+               if (nodev->minor == minor)
+                       return nodev->filesystem;
+       }
+       return NULL;
+}
index 76911573c8a348458eb487d9d256d750c085333d..149808b3c60dcf97df0b02eeb44b8085cdf29a46 100644 (file)
@@ -108,7 +108,6 @@ struct proc {
        uid_t uid;
        struct list_head procs;
        struct list_head files;
-       struct list_head nodevs;
 };
 
 /*
@@ -192,6 +191,6 @@ unsigned long add_name(struct name_manager *nm, const char *name);
 const char *get_partition(dev_t dev);
 const char *get_chrdrv(unsigned long major);
 const char *get_miscdev(unsigned long minor);
-const char *get_nodev_filesystem(struct proc *proc, unsigned long minor);
+const char *get_nodev_filesystem(unsigned long minor);
 
 #endif /* UTIL_LINUX_LSFD_H */