diff options
Diffstat (limited to 'subversion/libsvn_fs_fs/util.c')
-rw-r--r-- | subversion/libsvn_fs_fs/util.c | 93 |
1 files changed, 40 insertions, 53 deletions
diff --git a/subversion/libsvn_fs_fs/util.c b/subversion/libsvn_fs_fs/util.c index faa1e3d319b29..e191322480351 100644 --- a/subversion/libsvn_fs_fs/util.c +++ b/subversion/libsvn_fs_fs/util.c @@ -428,6 +428,7 @@ svn_fs_fs__write_min_unpacked_rev(svn_fs_t *fs, svn_revnum_t revnum, apr_pool_t *scratch_pool) { + fs_fs_data_t *ffd = fs->fsap_data; const char *final_path; char buf[SVN_INT64_BUFFER_SIZE]; apr_size_t len = svn__i64toa(buf, revnum); @@ -435,8 +436,9 @@ svn_fs_fs__write_min_unpacked_rev(svn_fs_t *fs, final_path = svn_fs_fs__path_min_unpacked_rev(fs, scratch_pool); - SVN_ERR(svn_io_write_atomic(final_path, buf, len + 1, - final_path /* copy_perms */, scratch_pool)); + SVN_ERR(svn_io_write_atomic2(final_path, buf, len + 1, + final_path /* copy_perms */, + ffd->flush_to_disk, scratch_pool)); return SVN_NO_ERROR; } @@ -517,8 +519,9 @@ svn_fs_fs__write_current(svn_fs_t *fs, } name = svn_fs_fs__path_current(fs, pool); - SVN_ERR(svn_io_write_atomic(name, buf, strlen(buf), - name /* copy_perms_path */, pool)); + SVN_ERR(svn_io_write_atomic2(name, buf, strlen(buf), + name /* copy_perms_path */, + ffd->flush_to_disk, pool)); return SVN_NO_ERROR; } @@ -565,22 +568,6 @@ svn_fs_fs__try_stringbuf_from_file(svn_stringbuf_t **content, } svn_error_t * -svn_fs_fs__get_file_offset(apr_off_t *offset_p, - apr_file_t *file, - apr_pool_t *pool) -{ - apr_off_t offset; - - /* Note that, for buffered files, one (possibly surprising) side-effect - of this call is to flush any unwritten data to disk. */ - offset = 0; - SVN_ERR(svn_io_file_seek(file, APR_CUR, &offset, pool)); - *offset_p = offset; - - return SVN_NO_ERROR; -} - -svn_error_t * svn_fs_fs__read_content(svn_stringbuf_t **content, const char *fname, apr_pool_t *pool) @@ -634,54 +621,54 @@ svn_error_t * svn_fs_fs__move_into_place(const char *old_filename, const char *new_filename, const char *perms_reference, + svn_boolean_t flush_to_disk, apr_pool_t *pool) { svn_error_t *err; + apr_file_t *file; + /* Copying permissions is a no-op on WIN32. */ SVN_ERR(svn_io_copy_perms(perms_reference, old_filename, pool)); /* Move the file into place. */ - err = svn_io_file_rename(old_filename, new_filename, pool); + err = svn_io_file_rename2(old_filename, new_filename, flush_to_disk, pool); if (err && APR_STATUS_IS_EXDEV(err->apr_err)) { - apr_file_t *file; - /* Can't rename across devices; fall back to copying. */ svn_error_clear(err); - err = SVN_NO_ERROR; SVN_ERR(svn_io_copy_file(old_filename, new_filename, TRUE, pool)); - /* Flush the target of the copy to disk. */ - SVN_ERR(svn_io_file_open(&file, new_filename, APR_READ, - APR_OS_DEFAULT, pool)); - /* ### BH: Does this really guarantee a flush of the data written - ### via a completely different handle on all operating systems? - ### - ### Maybe we should perform the copy ourselves instead of making - ### apr do that and flush the real handle? */ - SVN_ERR(svn_io_file_flush_to_disk(file, pool)); - SVN_ERR(svn_io_file_close(file, pool)); - } - if (err) - return svn_error_trace(err); + /* Flush the target of the copy to disk. + ### The code below is duplicates svn_io_file_rename2(), because + currently we don't have the svn_io_copy_file2() function with + a flush_to_disk argument. */ + if (flush_to_disk) + { + SVN_ERR(svn_io_file_open(&file, new_filename, APR_WRITE, + APR_OS_DEFAULT, pool)); + SVN_ERR(svn_io_file_flush_to_disk(file, pool)); + SVN_ERR(svn_io_file_close(file, pool)); + } -#ifdef __linux__ - { - /* Linux has the unusual feature that fsync() on a file is not - enough to ensure that a file's directory entries have been - flushed to disk; you have to fsync the directory as well. - On other operating systems, we'd only be asking for trouble - by trying to open and fsync a directory. */ - const char *dirname; - apr_file_t *file; - - dirname = svn_dirent_dirname(new_filename, pool); - SVN_ERR(svn_io_file_open(&file, dirname, APR_READ, APR_OS_DEFAULT, - pool)); - SVN_ERR(svn_io_file_flush_to_disk(file, pool)); - SVN_ERR(svn_io_file_close(file, pool)); - } +#ifdef SVN_ON_POSIX + if (flush_to_disk) + { + /* On POSIX, the file name is stored in the file's directory entry. + Hence, we need to fsync() that directory as well. + On other operating systems, we'd only be asking for trouble + by trying to open and fsync a directory. */ + const char *dirname; + + dirname = svn_dirent_dirname(new_filename, pool); + SVN_ERR(svn_io_file_open(&file, dirname, APR_READ, APR_OS_DEFAULT, + pool)); + SVN_ERR(svn_io_file_flush_to_disk(file, pool)); + SVN_ERR(svn_io_file_close(file, pool)); + } #endif + } + else if (err) + return svn_error_trace(err); return SVN_NO_ERROR; } |