summaryrefslogtreecommitdiff
path: root/src/libotutil/ot-unix-utils.h
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2012-08-27 11:53:06 -0400
committerColin Walters <walters@verbum.org>2012-08-27 15:35:40 -0400
commit2396608754060e9e7a68843b65e4d3b8f4a4b5f2 (patch)
tree25189d7c855400aa4f7dbf4a0699e6a7c4aa4704 /src/libotutil/ot-unix-utils.h
parent5038a1930f1779d5ba09cd24085ff6984eb052c5 (diff)
downloadostree-2396608754060e9e7a68843b65e4d3b8f4a4b5f2.tar.gz
repo: Call fdatasync() before adding objects to the repo
I run builds on my laptop, but it also crashes about 1/4 of the time while suspending. It's definitely undesrirable to get e.g. empty .dirtree objects because they corrupt builds. Concretely, I was getting empty contents committed for xorg-util-macros. Now, we used to write out temporary files using g_file_replace() which does a fsync() during close, but then switched to a more "manual" g_file_append_to(). We could switch back to g_file_replace(), but the problem is, we don't want to call fsync() on temporary files in the case where we already have the object. Attempting to add an object we already have is a *very* common case. This is both the old and new code sequence for the case where an object is already stored: open(temp, O_WRONLY) write() write() write() close() lstat(objects/3a/9fe332...) = 0 unlink(temp) In the *new* code, here's the case where an object *isn't* stored: open(temp, O_WRONLY) write() write() write() close() lstat(objects/3a/9fe332...) = -1 open(temp, O_RDONLY) fdatasync() close() rename(temp, objects/3a/9fe332) Compare with the *old* code path for when an object isn't stored: open(temp, O_WRONLY) write() write() write() close() lstat(objects/3a/9fe332...) = -1 link(temp, objects/3a/9fe332) unlink(temp) The problem with this is we really need to fdatasync(). Also doing just rename() instead of the weird link()/unlink() helps us express to the filesystem that we want atomic semantics. For example, BTRFS has special handling for rename().
Diffstat (limited to 'src/libotutil/ot-unix-utils.h')
-rw-r--r--src/libotutil/ot-unix-utils.h10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/libotutil/ot-unix-utils.h b/src/libotutil/ot-unix-utils.h
index 58dd59b5..2022dea8 100644
--- a/src/libotutil/ot-unix-utils.h
+++ b/src/libotutil/ot-unix-utils.h
@@ -49,6 +49,16 @@ gboolean ot_util_path_split_validate (const char *path, GPtrArray **out_componen
void ot_util_set_error_from_errno (GError **error, gint saved_errno);
+gboolean ot_unix_open (const char *path,
+ int flags,
+ mode_t mode,
+ int *out_fd,
+ GError **error);
+
+gboolean ot_unix_fdatasync (int fd, GError **error);
+
+gboolean ot_unix_close (int fd, GError **error);
+
G_END_DECLS
#endif