Skip to content

Commit 2292092

Browse files
committed
Backport r1883340:
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
1 parent c19ce40 commit 2292092

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

file_io/unix/readwrite.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ APR_DECLARE(apr_status_t) apr_file_sync(apr_file_t *thefile)
373373
APR_DECLARE(apr_status_t) apr_file_datasync(apr_file_t *thefile)
374374
{
375375
apr_status_t rv = APR_SUCCESS;
376+
int os_status = 0;
376377

377378
file_lock(thefile);
378379

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

388389
#ifdef HAVE_FDATASYNC
389-
if (fdatasync(thefile->filedes)) {
390+
os_status = fdatasync(thefile->filedes);
390391
#elif defined(F_FULLFSYNC)
391-
if (fcntl(thefile->filedes, F_FULLFSYNC)) {
392+
os_status = fcntl(thefile->filedes, F_FULLFSYNC);
393+
if (os_status) {
394+
/* Fall back to fsync() if the device doesn't support F_FULLFSYNC. */
395+
os_status = fsync(thefile->filedes);
396+
}
392397
#else
393-
if (fsync(thefile->filedes)) {
398+
os_status = fsync(thefile->filedes);
394399
#endif
400+
if (os_status) {
395401
rv = apr_get_os_error();
396402
}
397403

test/testfile.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,41 @@ static void test_xthread(abts_case *tc, void *data)
12191219
apr_file_close(f);
12201220
}
12211221

1222+
static void test_datasync_on_file(abts_case *tc, void *data)
1223+
{
1224+
apr_status_t rv;
1225+
apr_file_t *f;
1226+
const char *fname = DIRNAME "/testtest_datasync.dat";
1227+
apr_size_t bytes_written;
1228+
1229+
apr_file_remove(fname, p);
1230+
1231+
rv = apr_file_open(&f, fname, APR_FOPEN_CREATE | APR_FOPEN_WRITE,
1232+
APR_FPROT_OS_DEFAULT, p);
1233+
APR_ASSERT_SUCCESS(tc, "open test file for writing", rv);
1234+
rv = apr_file_write_full(f, "abcdef", 6, &bytes_written);
1235+
APR_ASSERT_SUCCESS(tc, "write to file", rv);
1236+
rv = apr_file_datasync(f);
1237+
APR_ASSERT_SUCCESS(tc, "sync file contents", rv);
1238+
apr_file_close(f);
1239+
1240+
apr_file_remove(fname, p);
1241+
}
1242+
1243+
static void test_datasync_on_stream(abts_case *tc, void *data)
1244+
{
1245+
apr_status_t rv;
1246+
apr_file_t *f;
1247+
apr_size_t bytes_written;
1248+
1249+
rv = apr_file_open_stdout(&f, p);
1250+
APR_ASSERT_SUCCESS(tc, "open stdout", rv);
1251+
rv = apr_file_write_full(f, "abcdef\b\b\b\b\b\b\b", 12, &bytes_written);
1252+
APR_ASSERT_SUCCESS(tc, "write to stdout", rv);
1253+
rv = apr_file_datasync(f);
1254+
APR_ASSERT_SUCCESS(tc, "sync stdout", rv);
1255+
}
1256+
12221257
abts_suite *testfile(abts_suite *suite)
12231258
{
12241259
suite = ADD_SUITE(suite)
@@ -1263,6 +1298,8 @@ abts_suite *testfile(abts_suite *suite)
12631298
abts_run_test(suite, test_fail_read_flush, NULL);
12641299
abts_run_test(suite, test_buffer_set_get, NULL);
12651300
abts_run_test(suite, test_xthread, NULL);
1301+
abts_run_test(suite, test_datasync_on_file, NULL);
1302+
abts_run_test(suite, test_datasync_on_stream, NULL);
12661303

12671304
return suite;
12681305
}

0 commit comments

Comments
 (0)