daemon: GC remove-unused-links phase uses 'statx' when available.
authorLudovic Courtès <ludo@gnu.org>
Tue, 26 Nov 2019 22:35:24 +0000 (23:35 +0100)
committerLudovic Courtès <ludo@gnu.org>
Tue, 26 Nov 2019 23:03:03 +0000 (00:03 +0100)
* config-daemon.ac: Check for 'statx'.
* nix/libstore/gc.cc (LocalStore::removeUnusedLinks) [HAVE_STATX]: Use
'statx' instead of 'lstat'.

config-daemon.ac
nix/libstore/gc.cc

index 848e1e5..50ead35 100644 (file)
@@ -91,8 +91,9 @@ if test "x$guix_build_daemon" = "xyes"; then
   dnl sched_setaffinity: to improve RPC locality.
   dnl statvfs: to detect disk-full conditions.
   dnl strsignal: for error reporting.
+  dnl statx: fine-grain 'stat' call, new in glibc 2.28.
   AC_CHECK_FUNCS([lutimes lchown posix_fallocate sched_setaffinity \
-     statvfs nanosleep strsignal])
+     statvfs nanosleep strsignal statx])
 
   dnl Check whether the store optimiser can optimise symlinks.
   AC_MSG_CHECKING([whether it is possible to create a link to a symlink])
index 7976ff7..29b75aa 100644 (file)
@@ -570,8 +570,17 @@ void LocalStore::removeUnusedLinks(const GCState & state)
         if (name == "." || name == "..") continue;
         Path path = linksDir + "/" + name;
 
+#ifdef HAVE_STATX
+# define st_size stx_size
+# define st_nlink stx_nlink
+       struct statx st;
+       if (statx(AT_FDCWD, path.c_str(),
+                 AT_SYMLINK_NOFOLLOW | AT_STATX_DONT_SYNC,
+                 STATX_SIZE | STATX_NLINK, &st) == -1)
+#else
         struct stat st;
         if (lstat(path.c_str(), &st) == -1)
+#endif
             throw SysError(format("statting `%1%'") % path);
 
         if (st.st_nlink != 1) {
@@ -586,6 +595,8 @@ void LocalStore::removeUnusedLinks(const GCState & state)
             throw SysError(format("deleting `%1%'") % path);
 
         state.results.bytesFreed += st.st_size;
+#undef st_size
+#undef st_nlink
     }
 
     struct stat st;