[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH 2/4] dpkg: On Linux finish writeback before fsync



The second sync_file_range() call, with the operation
SYNC_FILE_RANGE_WAIT_BEFORE, will block until the previously initiated
writeback has completed.  This basically ensures that the delayed
allocation has been resolved; that is, the data blocks have been
allocated and written, and the inode updated (in memory), but not
necessarily pushed out to disk.

Ted suggests finishing writeback for all files before calling fsync,
so later fdatasync can become no-ops, minimizing the number of
(costly) jbd2 commits.  And we should probably do that.  To make
bisecting for performance easier, let's try this simpler step first.

Suggested-and-explained-by: Ted Ts'o <tytso@mit.edu>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 src/archives.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/src/archives.c b/src/archives.c
index d423f45..17e8c89 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -80,6 +80,20 @@ begin_writeback(int fd)
 }
 #endif
 
+#ifdef SYNC_FILE_RANGE_WAIT_BEFORE
+static int
+finish_writeback(int fd)
+{
+  return sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE);
+}
+#else
+static int
+finish_writeback(int fd)
+{
+  return 0;
+}
+#endif
+
 /**
  * Special routine to handle partial reads from the tarfile.
  */
@@ -900,6 +914,8 @@ tar_deferred_extract(struct fileinlist *files, struct pkginfo *pkg)
       fd = open(fnamenewvb.buf, O_WRONLY);
       if (fd < 0)
         ohshite(_("unable to open '%.255s'"), fnamenewvb.buf);
+      if (finish_writeback(fd))
+        ohshite(_("unable to write out file '%.255s'"), fnamenewvb.buf);
       if (fsync(fd))
         ohshite(_("unable to sync file '%.255s'"), fnamenewvb.buf);
       if (close(fd))
-- 
1.7.2.3


Reply to: