Skip to content

Commit

Permalink
Backport r1883340:
Browse files Browse the repository at this point in the history
Follow up to r1790200: fall back to fsync() if F_FULLFSYNC is not supported
by the file descriptor, filesystem or underlying device.

See, e.g.: vim/vim#4025


git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.7.x@1883341 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
brainy committed Nov 12, 2020
1 parent c19ce40 commit 2292092
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
12 changes: 9 additions & 3 deletions file_io/unix/readwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ APR_DECLARE(apr_status_t) apr_file_sync(apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile)
{
apr_status_t rv = APR_SUCCESS;
int os_status = 0;

file_lock(thefile);

Expand All @@ -386,12 +387,17 @@ APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile)
}

#ifdef HAVE_FDATASYNC
if (fdatasync(thefile->filedes)) {
os_status = fdatasync(thefile->filedes);
#elif defined(F_FULLFSYNC)
if (fcntl(thefile->filedes, F_FULLFSYNC)) {
os_status = fcntl(thefile->filedes, F_FULLFSYNC);
if (os_status) {
/* Fall back to fsync() if the device doesn't support F_FULLFSYNC. */
os_status = fsync(thefile->filedes);
}
#else
if (fsync(thefile->filedes)) {
os_status = fsync(thefile->filedes);
#endif
if (os_status) {
rv = apr_get_os_error();
}

Expand Down
37 changes: 37 additions & 0 deletions test/testfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,41 @@ static void test_xthread(abts_case *tc, void *data)
apr_file_close(f);
}

static void test_datasync_on_file(abts_case *tc, void *data)
{
apr_status_t rv;
apr_file_t *f;
const char *fname = DIRNAME "/testtest_datasync.dat";
apr_size_t bytes_written;

apr_file_remove(fname, p);

rv = apr_file_open(&f, fname, APR_FOPEN_CREATE | APR_FOPEN_WRITE,
APR_FPROT_OS_DEFAULT, p);
APR_ASSERT_SUCCESS(tc, "open test file for writing", rv);
rv = apr_file_write_full(f, "abcdef", 6, &bytes_written);
APR_ASSERT_SUCCESS(tc, "write to file", rv);
rv = apr_file_datasync(f);
APR_ASSERT_SUCCESS(tc, "sync file contents", rv);
apr_file_close(f);

apr_file_remove(fname, p);
}

static void test_datasync_on_stream(abts_case *tc, void *data)
{
apr_status_t rv;
apr_file_t *f;
apr_size_t bytes_written;

rv = apr_file_open_stdout(&f, p);
APR_ASSERT_SUCCESS(tc, "open stdout", rv);
rv = apr_file_write_full(f, "abcdef\b\b\b\b\b\b\b", 12, &bytes_written);
APR_ASSERT_SUCCESS(tc, "write to stdout", rv);
rv = apr_file_datasync(f);
APR_ASSERT_SUCCESS(tc, "sync stdout", rv);
}

abts_suite *testfile(abts_suite *suite)
{
suite = ADD_SUITE(suite)
Expand Down Expand Up @@ -1263,6 +1298,8 @@ abts_suite *testfile(abts_suite *suite)
abts_run_test(suite, test_fail_read_flush, NULL);
abts_run_test(suite, test_buffer_set_get, NULL);
abts_run_test(suite, test_xthread, NULL);
abts_run_test(suite, test_datasync_on_file, NULL);
abts_run_test(suite, test_datasync_on_stream, NULL);

return suite;
}
Expand Down

0 comments on commit 2292092

Please sign in to comment.