Skip to content

Commit 5312621

Browse files
author
Edward Thomson
committed
git_futils_writebuffer: optionally fsync
Add a custom `O_FSYNC` bit (if it's not been defined by the operating system`) so that `git_futils_writebuffer` can optionally do an `fsync` when it's done writing. We call `fsync` ourselves, even on systems that define `O_FSYNC` because its definition is no guarantee of its actual support. Mac, for instance, defines it but doesn't support it in an `open(2)` call.
1 parent 1c2c0ae commit 5312621

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/fileops.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,16 @@ int git_futils_readbuffer(git_buf *buf, const char *path)
235235
int git_futils_writebuffer(
236236
const git_buf *buf, const char *path, int flags, mode_t mode)
237237
{
238-
int fd, error = 0;
238+
int fd, do_fsync = 0, error = 0;
239+
240+
if ((flags & O_FSYNC) != 0)
241+
do_fsync = 1;
242+
243+
flags &= ~O_FSYNC;
239244

240245
if (flags <= 0)
241246
flags = O_CREAT | O_TRUNC | O_WRONLY;
247+
242248
if (!mode)
243249
mode = GIT_FILEMODE_BLOB;
244250

@@ -253,6 +259,12 @@ int git_futils_writebuffer(
253259
return error;
254260
}
255261

262+
if (do_fsync && (error = p_fsync(fd)) < 0) {
263+
giterr_set(GITERR_OS, "could not fsync '%s'", path);
264+
p_close(fd);
265+
return error;
266+
}
267+
256268
if ((error = p_close(fd)) < 0)
257269
giterr_set(GITERR_OS, "error while closing '%s'", path);
258270

src/fileops.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ extern int git_futils_readbuffer_updated(
2525
git_buf *obj, const char *path, git_oid *checksum, int *updated);
2626
extern int git_futils_readbuffer_fd(git_buf *obj, git_file fd, size_t len);
2727

28+
/* Additional constants for `git_futils_writebuffer`'s `open_flags`. We
29+
* support these internally and they will be removed before the `open` call.
30+
*/
31+
#ifndef O_FSYNC
32+
# define O_FSYNC (1 << 31)
33+
#endif
34+
2835
extern int git_futils_writebuffer(
2936
const git_buf *buf, const char *path, int open_flags, mode_t mode);
3037

0 commit comments

Comments
 (0)