From bc48b4de78a8d9b2567019deb9c8653968a4433e Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Sat, 24 Jul 2021 01:13:28 -0700 Subject: [PATCH] Allow consumers of `XmlFile` to disable `fsync(2)` (#5599) * Allowing consumers of XmlFile to disable fsync(2). * Stop using Unix-specific terminology * Jesse feels that this would be more natural as a constructor parameter * Place Javadoc on constructor to make warning visible to callers --- core/src/main/java/hudson/XmlFile.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/hudson/XmlFile.java b/core/src/main/java/hudson/XmlFile.java index d203806906..e11afae675 100644 --- a/core/src/main/java/hudson/XmlFile.java +++ b/core/src/main/java/hudson/XmlFile.java @@ -33,6 +33,8 @@ import hudson.diagnosis.OldDataMonitor; import hudson.model.Descriptor; import hudson.util.AtomicFileWriter; import hudson.util.XStream2; +import java.nio.channels.FileChannel; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.InvalidPathException; import org.xml.sax.Attributes; @@ -118,6 +120,7 @@ import org.apache.commons.io.IOUtils; public final class XmlFile { private final XStream xs; private final File file; + private final boolean force; private static final Map beingWritten = Collections.synchronizedMap(new IdentityHashMap<>()); private static final ThreadLocal writing = new ThreadLocal<>(); @@ -126,8 +129,18 @@ public final class XmlFile { } public XmlFile(XStream xs, File file) { + this(xs, file, true); + } + + /** + * @param force Whether or not to flush the page cache to the storage device with {@link + * FileChannel#force} (i.e., {@code fsync}} or {@code FlushFileBuffers}) before this method + * returns. If you set this to {@code false}, you will lose data integrity. + */ + public XmlFile(XStream xs, File file, boolean force) { this.xs = xs; this.file = file; + this.force = force; } public File getFile() { @@ -186,7 +199,9 @@ public final class XmlFile { public void write( Object o ) throws IOException { mkdirs(); - AtomicFileWriter w = new AtomicFileWriter(file); + AtomicFileWriter w = force + ? new AtomicFileWriter(file) + : new AtomicFileWriter(file.toPath(), StandardCharsets.UTF_8, false, false); try { w.write("\n"); beingWritten.put(o, null);