[Libguestfs] [nbdkit PATCH 3/4] file: Use dirent.dt_type for speed

Eric Blake eblake at redhat.com
Fri Aug 7 02:23:47 UTC 2020


No need to fstatat() when .d_type is reliable.  However, as it is not
portable, I've done this as a separate patch.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 configure.ac        |  1 +
 plugins/file/file.c | 21 ++++++++++++++-------
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/configure.ac b/configure.ac
index 28f4a3cd..8074a470 100644
--- a/configure.ac
+++ b/configure.ac
@@ -323,6 +323,7 @@ AC_CHECK_FUNCS([\
 	pipe2 \
 	ppoll \
 	posix_fadvise])
+AC_CHECK_MEMBERS([struct dirent.d_type], [], [], [[#include <dirent.h>]])

 dnl Check whether printf("%m") works
 AC_CACHE_CHECK([whether the printf family supports %m],
diff --git a/plugins/file/file.c b/plugins/file/file.c
index 4afcad11..445d5686 100644
--- a/plugins/file/file.c
+++ b/plugins/file/file.c
@@ -184,13 +184,20 @@ static int file_list_exports (int readonly, int default_only,
   }
   errno = 0;
   while ((entry = readdir (dir)) != NULL) {
-    /* TODO: Optimize with d_type and/or statx when present? */
-    if (fstatat (fd, entry->d_name, &sb, 0) == 0 &&
-        (S_ISREG (sb.st_mode) || S_ISBLK (sb.st_mode))) {
-      if (nbdkit_add_export (exports, entry->d_name, NULL) == -1) {
-        close (fd);
-        return -1;
-      }
+    int r = -1;
+#if HAVE_STRUCT_DIRENT_D_TYPE
+    if (entry->d_type == DT_BLK || entry->d_type == DT_REG)
+      r = 1;
+    else if (entry->d_type != DT_LNK && entry->d_type != DT_UNKNOWN)
+      r = 0;
+#endif
+    /* TODO: when chasing symlinks, is statx any nicer than fstatat? */
+    if (r < 0 && fstatat (fd, entry->d_name, &sb, 0) == 0 &&
+        (S_ISREG (sb.st_mode) || S_ISBLK (sb.st_mode)))
+      r = 1;
+    if (r == 1 && nbdkit_add_export (exports, entry->d_name, NULL) == -1) {
+      close (fd);
+      return -1;
     }
     errno = 0;
   }
-- 
2.28.0




More information about the Libguestfs mailing list