You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by br...@apache.org on 2020/11/12 08:54:27 UTC
svn commit: r1883340 - in /apr/apr/trunk: file_io/unix/readwrite.c
test/testfile.c
Author: brane
Date: Thu Nov 12 08:54:27 2020
New Revision: 1883340
URL: http://svn.apache.org/viewvc?rev=1883340&view=rev
Log:
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.: https://github.com/vim/vim/pull/4025
Modified:
apr/apr/trunk/file_io/unix/readwrite.c
apr/apr/trunk/test/testfile.c
Modified: apr/apr/trunk/file_io/unix/readwrite.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/file_io/unix/readwrite.c?rev=1883340&r1=1883339&r2=1883340&view=diff
==============================================================================
--- apr/apr/trunk/file_io/unix/readwrite.c (original)
+++ apr/apr/trunk/file_io/unix/readwrite.c Thu Nov 12 08:54:27 2020
@@ -466,6 +466,7 @@ APR_DECLARE(apr_status_t) apr_file_sync(
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);
@@ -479,12 +480,17 @@ APR_DECLARE(apr_status_t) apr_file_datas
}
#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();
}
Modified: apr/apr/trunk/test/testfile.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/testfile.c?rev=1883340&r1=1883339&r2=1883340&view=diff
==============================================================================
--- apr/apr/trunk/test/testfile.c (original)
+++ apr/apr/trunk/test/testfile.c Thu Nov 12 08:54:27 2020
@@ -2207,6 +2207,41 @@ static void test_read_buffered_seek(abts
apr_file_remove(fname, p);
}
+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)
@@ -2270,6 +2305,8 @@ abts_suite *testfile(abts_suite *suite)
abts_run_test(suite, test_read_buffered_spanning_over_bufsize, NULL);
abts_run_test(suite, test_single_byte_reads_buffered, NULL);
abts_run_test(suite, test_read_buffered_seek, NULL);
+ abts_run_test(suite, test_datasync_on_file, NULL);
+ abts_run_test(suite, test_datasync_on_stream, NULL);
return suite;
}