Sfoglia il codice sorgente

dpkg: On Linux initiate writeback of unpacked files ASAP

To avoid performance degradation on filesystems with "allocate on
flush" semantics (like xfs, ubifs, hfs+, and ext4 without nodelalloc),
start writing back each file once it has finished being extracted.
This doesn't actually wait for the write to finish; it just starts
the writeback.

The sync_file_range() call has been available since Linux 2.6.17.
On non-Linux systems we can skip it.

Closes: #605009

Suggested-by: Ted Ts'o <tytso@mit.edu>
Based-on-patch-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Guillem Jover <guillem@debian.org>
Guillem Jover 15 anni fa
parent
commit
203c99b0dd
2 ha cambiato i file con 14 aggiunte e 0 eliminazioni
  1. 3 0
      debian/changelog
  2. 11 0
      src/archives.c

+ 3 - 0
debian/changelog

@@ -4,6 +4,9 @@ dpkg (1.15.8.7) UNRELEASED; urgency=low
   * Defer symlink renames so that there's never a point were a symlink
     is broken, this is particularly important for shared libraries.
     Closes: #605536
+  * On Linux use sync_file_range() to initiate asynchronous writeback
+    of just unpacked files. Suggested by Ted Ts'o <tytso@mit.edu>.
+    Thanks to Jonathan Nieder <jrnieder@gmail.com>. Closes: #605009
 
   [ Updated manpage translations ]
   * French (Christian Perrier).

+ 11 - 0
src/archives.c

@@ -82,6 +82,14 @@ static int safe_read(int fd, void *buf, int len)
   return have;
 }
 
+static inline void
+fd_writeback_init(int fd)
+{
+#if defined(SYNC_FILE_RANGE_WRITE)
+  sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
+#endif
+}
+
 static struct obstack tar_obs;
 static bool tarobs_init = false;
 
@@ -687,6 +695,9 @@ tarobject(void *ctx, struct tar_entry *ti)
     if (r > 0)
       if (safe_read(tc->backendpipe, databuf, TARBLKSZ - r) == -1)
         ohshite(_("error reading from dpkg-deb pipe"));
+
+    fd_writeback_init(fd);
+
     if (nifd->namenode->statoverride) 
       debug(dbg_eachfile, "tarobject ... stat override, uid=%d, gid=%d, mode=%04o",
 			  nifd->namenode->statoverride->uid,