]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: optimize symlinks use
authorKarel Zak <kzak@redhat.com>
Thu, 30 Sep 2021 09:11:30 +0000 (11:11 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Oct 2021 09:01:54 +0000 (11:01 +0200)
Like the previous commit, this patch tries to reuse
/proc/#/{fd,ns,cwd,root} symlinks if possible. On my machine it
saves ~2000 stat() calls.

Signed-off-by: Karel Zak <kzak@redhat.com>
misc-utils/lsfd.c

index 5c4cb17c4c720a6db0301d21a66fdc93cd3b4bb3..f855f637cb4eb7d37ec6b8596127c0cd4030c4f9 100644 (file)
@@ -351,16 +351,27 @@ static struct file *collect_file_symlink(struct path_cxt *pc,
 {
        char sym[PATH_MAX] = { '\0' };
        struct stat sb;
-       struct file *f;
+       struct file *f, *prev;
 
-       if (ul_path_stat(pc, &sb, 0, name) < 0)
-               return NULL;
        if (ul_path_readlink(pc, sym, sizeof(sym), name) < 0)
                return NULL;
 
-       f = new_file(proc, stat2class(&sb));
+       /* The /proc/#/{fd,ns} often contains the same file (e.g. /dev/tty)
+        * more than once. Let's try to reuse the previous file if the real
+        * path is the same to save stat() call.
+        */
+       prev = list_last_entry(&proc->files, struct file, files);
+       if (prev && prev->name && strcmp(prev->name, sym) == 0) {
+               f = copy_file(prev);
+               f->association = assoc;
+       } else {
+               if (ul_path_stat(pc, &sb, 0, name) < 0)
+                       return NULL;
+
+               f = new_file(proc, stat2class(&sb));
+               file_set_path(f, &sb, sym, assoc);
+       }
 
-       file_set_path(f, &sb, sym, assoc);
        file_init_content(f);
 
        if (is_association(f, EXE))