You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2015/11/30 11:24:23 UTC
svn commit: r1717223 [26/50] - in /subversion/branches/ra-git: ./ build/
build/ac-macros/ build/generator/ build/generator/templates/
contrib/hook-scripts/ notes/ notes/api-errata/1.9/ notes/move-tracking/
subversion/ subversion/bindings/ctypes-python/...
Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/tree.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/tree.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/tree.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/tree.h Mon Nov 30 10:24:16 2015
@@ -20,10 +20,11 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS_TREE_H
-#define SVN_LIBSVN_FS_TREE_H
+#ifndef SVN_LIBSVN_FS_X_TREE_H
+#define SVN_LIBSVN_FS_X_TREE_H
#include "fs.h"
+#include "dag.h"
#ifdef __cplusplus
extern "C" {
@@ -31,9 +32,13 @@ extern "C" {
-/* In RESULT_POOL, create an instance of a DAG node 1st level cache. */
-svn_fs_x__dag_cache_t*
-svn_fs_x__create_dag_cache(apr_pool_t *result_pool);
+/* Return the transaction ID to a given transaction ROOT. */
+svn_fs_x__txn_id_t
+svn_fs_x__root_txn_id(svn_fs_root_t *root);
+
+/* Return the change set to a given ROOT. */
+svn_fs_x__change_set_t
+svn_fs_x__root_change_set(svn_fs_root_t *root);
/* Set *ROOT_P to the root directory of revision REV in filesystem FS.
Allocate the structure in POOL. */
@@ -109,4 +114,4 @@ svn_fs_x__info_config_files(apr_array_he
}
#endif /* __cplusplus */
-#endif /* SVN_LIBSVN_FS_TREE_H */
+#endif /* SVN_LIBSVN_FS_X_TREE_H */
Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/util.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/util.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/util.c Mon Nov 30 10:24:16 2015
@@ -110,11 +110,17 @@ svn_fs_x__path_current(svn_fs_t *fs,
}
const char *
+svn_fs_x__path_next(svn_fs_t *fs,
+ apr_pool_t *result_pool)
+{
+ return svn_dirent_join(fs->path, PATH_NEXT, result_pool);
+}
+
+const char *
svn_fs_x__path_txn_current(svn_fs_t *fs,
apr_pool_t *result_pool)
{
- return svn_dirent_join(fs->path, PATH_TXN_CURRENT,
- result_pool);
+ return svn_dirent_join(fs->path, PATH_TXN_CURRENT, result_pool);
}
const char *
@@ -147,14 +153,12 @@ svn_fs_x__path_revprop_generation(svn_fs
/* Return the full path of the file FILENAME within revision REV's shard in
* FS. If FILENAME is NULL, return the shard directory directory itself.
- * REVPROPS indicates the parent of the shard parent folder ("revprops" or
- * "revs"). PACKED says whether we want the packed shard's name.
+ * PACKED says whether we want the packed shard's name.
*
* Allocate the result in RESULT_POOL.
*/static const char*
construct_shard_sub_path(svn_fs_t *fs,
svn_revnum_t rev,
- svn_boolean_t revprops,
svn_boolean_t packed,
const char *filename,
apr_pool_t *result_pool)
@@ -162,9 +166,6 @@ construct_shard_sub_path(svn_fs_t *fs,
svn_fs_x__data_t *ffd = fs->fsap_data;
char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_PACKED_SHARD)] = { 0 };
- /* Select the appropriate parent path constant. */
- const char *parent = revprops ? PATH_REVPROPS_DIR : PATH_REVS_DIR;
-
/* String containing the shard number. */
apr_size_t len = svn__i64toa(buffer, rev / ffd->max_files_per_dir);
@@ -173,7 +174,7 @@ construct_shard_sub_path(svn_fs_t *fs,
strncpy(buffer + len, PATH_EXT_PACKED_SHARD, sizeof(buffer) - len - 1);
/* This will also work for NULL FILENAME as well. */
- return svn_dirent_join_many(result_pool, fs->path, parent, buffer,
+ return svn_dirent_join_many(result_pool, fs->path, PATH_REVS_DIR, buffer,
filename, SVN_VA_NULL);
}
@@ -184,15 +185,15 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs,
apr_pool_t *result_pool)
{
assert(svn_fs_x__is_packed_rev(fs, rev));
- return construct_shard_sub_path(fs, rev, FALSE, TRUE, kind, result_pool);
+ return construct_shard_sub_path(fs, rev, TRUE, kind, result_pool);
}
const char *
-svn_fs_x__path_rev_shard(svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool)
+svn_fs_x__path_shard(svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *result_pool)
{
- return construct_shard_sub_path(fs, rev, FALSE, FALSE, NULL, result_pool);
+ return construct_shard_sub_path(fs, rev, FALSE, NULL, result_pool);
}
const char *
@@ -200,11 +201,12 @@ svn_fs_x__path_rev(svn_fs_t *fs,
svn_revnum_t rev,
apr_pool_t *result_pool)
{
- char buffer[SVN_INT64_BUFFER_SIZE];
- svn__i64toa(buffer, rev);
+ char buffer[SVN_INT64_BUFFER_SIZE + 1];
+ buffer[0] = 'r';
+ svn__i64toa(buffer + 1, rev);
assert(! svn_fs_x__is_packed_rev(fs, rev));
- return construct_shard_sub_path(fs, rev, FALSE, FALSE, buffer, result_pool);
+ return construct_shard_sub_path(fs, rev, FALSE, buffer, result_pool);
}
const char *
@@ -218,19 +220,11 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs
}
const char *
-svn_fs_x__path_revprops_shard(svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool)
-{
- return construct_shard_sub_path(fs, rev, TRUE, FALSE, NULL, result_pool);
-}
-
-const char *
-svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
+svn_fs_x__path_pack_shard(svn_fs_t *fs,
svn_revnum_t rev,
apr_pool_t *result_pool)
{
- return construct_shard_sub_path(fs, rev, TRUE, TRUE, NULL, result_pool);
+ return construct_shard_sub_path(fs, rev, TRUE, NULL, result_pool);
}
const char *
@@ -238,11 +232,17 @@ svn_fs_x__path_revprops(svn_fs_t *fs,
svn_revnum_t rev,
apr_pool_t *result_pool)
{
- char buffer[SVN_INT64_BUFFER_SIZE];
- svn__i64toa(buffer, rev);
+ char buffer[SVN_INT64_BUFFER_SIZE + 1];
+ buffer[0] = 'p';
+ svn__i64toa(buffer + 1, rev);
assert(! svn_fs_x__is_packed_revprop(fs, rev));
- return construct_shard_sub_path(fs, rev, TRUE, FALSE, buffer, result_pool);
+
+ /* Revprops for packed r0 are not packed, yet stored in the packed shard.
+ Hence, the second flag must check for packed _rev_ - not revprop. */
+ return construct_shard_sub_path(fs, rev,
+ svn_fs_x__is_packed_rev(fs, rev) /* sic! */,
+ buffer, result_pool);
}
const char *
@@ -340,14 +340,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
return construct_txn_path(fs, txn_id, PATH_TXN_PROPS, result_pool);
}
-const char *
-svn_fs_x__path_txn_props_final(svn_fs_t *fs,
- svn_fs_x__txn_id_t txn_id,
- apr_pool_t *result_pool)
-{
- return construct_txn_path(fs, txn_id, PATH_TXN_PROPS_FINAL, result_pool);
-}
-
const char*
svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
svn_fs_x__txn_id_t txn_id,
@@ -550,8 +542,9 @@ svn_fs_x__write_min_unpacked_rev(svn_fs_
final_path = svn_fs_x__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 */, TRUE,
+ scratch_pool));
return SVN_NO_ERROR;
}
@@ -583,17 +576,28 @@ svn_fs_x__write_current(svn_fs_t *fs,
{
char *buf;
const char *tmp_name, *name;
+ apr_file_t *file;
/* Now we can just write out this line. */
buf = apr_psprintf(scratch_pool, "%ld\n", rev);
name = svn_fs_x__path_current(fs, scratch_pool);
- SVN_ERR(svn_io_write_unique(&tmp_name,
- svn_dirent_dirname(name, scratch_pool),
- buf, strlen(buf),
- svn_io_file_del_none, scratch_pool));
+ tmp_name = svn_fs_x__path_next(fs, scratch_pool);
+
+ SVN_ERR(svn_io_file_open(&file, tmp_name,
+ APR_WRITE | APR_CREATE | APR_BUFFERED,
+ APR_OS_DEFAULT, scratch_pool));
+ SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL,
+ scratch_pool));
+ SVN_ERR(svn_io_file_close(file, scratch_pool));
+
+ /* Copying permissions is a no-op on WIN32. */
+ SVN_ERR(svn_io_copy_perms(name, tmp_name, scratch_pool));
- return svn_fs_x__move_into_place(tmp_name, name, name, scratch_pool);
+ /* Move the file into place. */
+ SVN_ERR(svn_io_file_rename2(tmp_name, name, TRUE, scratch_pool));
+
+ return SVN_NO_ERROR;
}
@@ -711,66 +715,33 @@ svn_fs_x__read_number_from_stream(apr_in
return SVN_NO_ERROR;
}
-
-/* Move a file into place from OLD_FILENAME in the transactions
- directory to its final location NEW_FILENAME in the repository. On
- Unix, match the permissions of the new file to the permissions of
- PERMS_REFERENCE. Temporary allocations are from SCRATCH_POOL.
-
- This function almost duplicates svn_io_file_move(), but it tries to
- guarantee a flush. */
svn_error_t *
svn_fs_x__move_into_place(const char *old_filename,
const char *new_filename,
const char *perms_reference,
+ svn_fs_x__batch_fsync_t *batch,
apr_pool_t *scratch_pool)
{
- svn_error_t *err;
-
+ /* Copying permissions is a no-op on WIN32. */
SVN_ERR(svn_io_copy_perms(perms_reference, old_filename, scratch_pool));
+ /* We use specific 'fsyncing move' Win32 API calls on Windows while the
+ * directory update fsync is POSIX-only. Moreover, there tend to be only
+ * a few moved files (1 or 2) per batch.
+ *
+ * Therefore, we use the platform-optimized "immediate" fsyncs on all
+ * non-POSIX platforms and the "scheduled" fsyncs on POSIX only.
+ */
+#if defined(SVN_ON_POSIX)
/* Move the file into place. */
- err = svn_io_file_rename(old_filename, new_filename, scratch_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,
- scratch_pool));
-
- /* Flush the target of the copy to disk. */
- SVN_ERR(svn_io_file_open(&file, new_filename, APR_READ,
- APR_OS_DEFAULT, scratch_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, scratch_pool));
- SVN_ERR(svn_io_file_close(file, scratch_pool));
- }
- if (err)
- return svn_error_trace(err);
+ SVN_ERR(svn_io_file_rename2(old_filename, new_filename, FALSE,
+ scratch_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, scratch_pool);
- SVN_ERR(svn_io_file_open(&file, dirname, APR_READ, APR_OS_DEFAULT,
- scratch_pool));
- SVN_ERR(svn_io_file_flush_to_disk(file, scratch_pool));
- SVN_ERR(svn_io_file_close(file, scratch_pool));
- }
+ /* Schedule for synchronization. */
+ SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, new_filename, scratch_pool));
+#else
+ SVN_ERR(svn_io_file_rename2(old_filename, new_filename, TRUE,
+ scratch_pool));
#endif
return SVN_NO_ERROR;
Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/util.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/util.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/util.h Mon Nov 30 10:24:16 2015
@@ -20,11 +20,12 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__UTIL_H
-#define SVN_LIBSVN_FS__UTIL_H
+#ifndef SVN_LIBSVN_FS_X_UTIL_H
+#define SVN_LIBSVN_FS_X_UTIL_H
#include "svn_fs.h"
#include "id.h"
+#include "batch_fsync.h"
/* Functions for dealing with recoverable errors on mutable files
*
@@ -102,6 +103,12 @@ const char *
svn_fs_x__path_current(svn_fs_t *fs,
apr_pool_t *result_pool);
+/* Return the path to the 'next' file in FS.
+ Perform allocation in RESULT_POOL. */
+const char *
+svn_fs_x__path_next(svn_fs_t *fs,
+ apr_pool_t *result_pool);
+
/* Return the full path of the "uuid" file in FS.
* The result will be allocated in RESULT_POOL.
*/
@@ -158,9 +165,9 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs,
* revision REV in FS. Allocate the result in RESULT_POOL.
*/
const char *
-svn_fs_x__path_rev_shard(svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool);
+svn_fs_x__path_shard(svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *result_pool);
/* Return the full path of the non-packed rev file containing revision REV
* in FS. Allocate the result in RESULT_POOL.
@@ -183,23 +190,13 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs
svn_revnum_t rev,
apr_pool_t *result_pool);
-/* Return the full path of the revision properties shard directory that
- * will contain the properties of revision REV in FS.
- * Allocate the result in RESULT_POOL.
- */
-const char *
-svn_fs_x__path_revprops_shard(svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool);
-
-/* Return the full path of the revision properties pack shard directory
- * that will contain the packed properties of revision REV in FS.
- * Allocate the result in RESULT_POOL.
+/* Return the full path of the pack shard directory that will contain the
+ * packed revision REV in FS. Allocate the result in RESULT_POOL.
*/
const char *
-svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
- svn_revnum_t rev,
- apr_pool_t *result_pool);
+svn_fs_x__path_pack_shard(svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *result_pool);
/* Return the full path of the non-packed revision properties file that
* contains the props for revision REV in FS.
@@ -287,15 +284,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
svn_fs_x__txn_id_t txn_id,
apr_pool_t *result_pool);
-/* Return the path of the file containing the "final" transaction
- * properties for the transaction identified by TXN_ID in FS.
- * The result will be allocated in RESULT_POOL.
- */
-const char *
-svn_fs_x__path_txn_props_final(svn_fs_t *fs,
- svn_fs_x__txn_id_t txn_id,
- apr_pool_t *result_pool);
-
/* Return the path of the file containing the node and copy ID counters for
* the transaction identified by TXN_ID in FS.
* The result will be allocated in RESULT_POOL.
@@ -460,10 +448,12 @@ svn_fs_x__read_number_from_stream(apr_in
svn_stream_t *stream,
apr_pool_t *scratch_pool);
-/* Move a file into place from OLD_FILENAME in the transactions
- directory to its final location NEW_FILENAME in the repository. On
- Unix, match the permissions of the new file to the permissions of
- PERMS_REFERENCE. Temporary allocations are from SCRATCH_POOL.
+/* Move a file into place from temporary OLD_FILENAME to its final
+ location NEW_FILENAME, which must be on to the same volume. Schedule
+ any necessary fsync calls in BATCH. On Unix, match the permissions
+ of the new file to the permissions of PERMS_REFERENCE.
+
+ Temporary allocations are from SCRATCH_POOL.
This function almost duplicates svn_io_file_move(), but it tries to
guarantee a flush. */
@@ -471,6 +461,7 @@ svn_error_t *
svn_fs_x__move_into_place(const char *old_filename,
const char *new_filename,
const char *perms_reference,
+ svn_fs_x__batch_fsync_t *batch,
apr_pool_t *scratch_pool);
#endif
Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/verify.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/verify.c Mon Nov 30 10:24:16 2015
@@ -27,6 +27,7 @@
#include "cached_data.h"
#include "rep-cache.h"
+#include "revprops.h"
#include "util.h"
#include "index.h"
@@ -141,30 +142,27 @@ verify_rep_cache(svn_fs_t *fs,
* indedx NAME in the error message. Supports cancellation with CANCEL_FUNC
* and CANCEL_BATON. SCRATCH_POOL is for temporary allocations. */
static svn_error_t *
-verify_index_checksum(apr_file_t *file,
+verify_index_checksum(svn_fs_x__revision_file_t *file,
const char *name,
- apr_off_t start,
- apr_off_t end,
- svn_checksum_t *expected,
+ svn_fs_x__index_info_t *index_info,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
unsigned char buffer[SVN__STREAM_CHUNK_SIZE];
- apr_off_t size = end - start;
+ apr_off_t size = index_info->end - index_info->start;
svn_checksum_t *actual;
svn_checksum_ctx_t *context
= svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
/* Calculate the index checksum. */
- SVN_ERR(svn_io_file_seek(file, APR_SET, &start, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(file, NULL, index_info->start));
while (size > 0)
{
apr_size_t to_read = size > sizeof(buffer)
? sizeof(buffer)
: (apr_size_t)size;
- SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read));
SVN_ERR(svn_checksum_update(context, buffer, to_read));
size -= to_read;
@@ -175,12 +173,13 @@ verify_index_checksum(apr_file_t *file,
SVN_ERR(svn_checksum_final(&actual, context, scratch_pool));
/* Verify that it matches the expected checksum. */
- if (!svn_checksum_match(expected, actual))
+ if (!svn_checksum_match(index_info->checksum, actual))
{
const char *file_name;
- SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
- SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool,
+ SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
+ SVN_ERR(svn_checksum_mismatch_err(index_info->checksum, actual,
+ scratch_pool,
_("%s checksum mismatch in file %s"),
name, file_name));
}
@@ -201,20 +200,18 @@ verify_index_checksums(svn_fs_t *fs,
apr_pool_t *scratch_pool)
{
svn_fs_x__revision_file_t *rev_file;
+ svn_fs_x__index_info_t l2p_index_info;
+ svn_fs_x__index_info_t p2l_index_info;
/* Open the rev / pack file and read the footer */
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start,
- scratch_pool, scratch_pool));
- SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
+ SVN_ERR(svn_fs_x__rev_file_p2l_info(&p2l_index_info, rev_file));
/* Verify the index contents against the checksum from the footer. */
- SVN_ERR(verify_index_checksum(rev_file->file, "L2P index",
- rev_file->l2p_offset, rev_file->p2l_offset,
- rev_file->l2p_checksum,
+ SVN_ERR(verify_index_checksum(rev_file, "L2P index", &l2p_index_info,
cancel_func, cancel_baton, scratch_pool));
- SVN_ERR(verify_index_checksum(rev_file->file, "P2L index",
- rev_file->p2l_offset, rev_file->footer_offset,
- rev_file->p2l_checksum,
+ SVN_ERR(verify_index_checksum(rev_file, "P2L index", &p2l_index_info,
cancel_func, cancel_baton, scratch_pool));
/* Done. */
@@ -242,8 +239,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
/* common file access structure */
svn_fs_x__revision_file_t *rev_file;
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
- iterpool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
/* determine the range of items to check for each revision */
SVN_ERR(svn_fs_x__l2p_get_max_ids(&max_ids, fs, start, count, scratch_pool,
@@ -334,8 +330,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
/* common file access structure */
svn_fs_x__revision_file_t *rev_file;
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
- iterpool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
/* get the size of the rev / pack file as covered by the P2L index */
SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start,
@@ -424,7 +419,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
* exceed STREAM_THRESHOLD. Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
-expect_buffer_nul(apr_file_t *file,
+expect_buffer_nul(svn_fs_x__revision_file_t *file,
apr_off_t size,
apr_pool_t *scratch_pool)
{
@@ -439,8 +434,7 @@ expect_buffer_nul(apr_file_t *file,
/* read the whole data block; error out on failure */
data.chunks[(size - 1)/ sizeof(apr_uint64_t)] = 0;
- SVN_ERR(svn_io_file_read_full2(file, data.buffer, size, NULL, NULL,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_read(file, data.buffer, size));
/* chunky check */
for (i = 0; i < size / sizeof(apr_uint64_t); ++i)
@@ -454,8 +448,8 @@ expect_buffer_nul(apr_file_t *file,
const char *file_name;
apr_off_t offset;
- SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
- SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_offset(&offset, file));
offset -= size - i;
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
@@ -472,7 +466,7 @@ expect_buffer_nul(apr_file_t *file,
* Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
-read_all_nul(apr_file_t *file,
+read_all_nul(svn_fs_x__revision_file_t *file,
apr_off_t size,
apr_pool_t *scratch_pool)
{
@@ -490,7 +484,7 @@ read_all_nul(apr_file_t *file,
* in error message. Allocate temporary data in SCRATCH_POOL.
*/
static svn_error_t *
-expected_checksum(apr_file_t *file,
+expected_checksum(svn_fs_x__revision_file_t *file,
svn_fs_x__p2l_entry_t *entry,
apr_uint32_t actual,
apr_pool_t *scratch_pool)
@@ -499,8 +493,7 @@ expected_checksum(apr_file_t *file,
{
const char *file_name;
- SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
- SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
_("Checksum mismatch in item at offset %s of "
"length %s bytes in file %s"),
@@ -517,15 +510,14 @@ expected_checksum(apr_file_t *file,
* exceed STREAM_THRESHOLD. Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
-expected_buffered_checksum(apr_file_t *file,
+expected_buffered_checksum(svn_fs_x__revision_file_t *file,
svn_fs_x__p2l_entry_t *entry,
apr_pool_t *scratch_pool)
{
unsigned char buffer[STREAM_THRESHOLD];
SVN_ERR_ASSERT(entry->size <= STREAM_THRESHOLD);
- SVN_ERR(svn_io_file_read_full2(file, buffer, (apr_size_t)entry->size,
- NULL, NULL, scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_read(file, buffer, (apr_size_t)entry->size));
SVN_ERR(expected_checksum(file, entry,
svn__fnv1a_32x4(buffer, (apr_size_t)entry->size),
scratch_pool));
@@ -538,7 +530,7 @@ expected_buffered_checksum(apr_file_t *f
* Use SCRATCH_POOL for temporary allocations.
*/
static svn_error_t *
-expected_streamed_checksum(apr_file_t *file,
+expected_streamed_checksum(svn_fs_x__revision_file_t *file,
svn_fs_x__p2l_entry_t *entry,
apr_pool_t *scratch_pool)
{
@@ -553,8 +545,7 @@ expected_streamed_checksum(apr_file_t *f
apr_size_t to_read = size > sizeof(buffer)
? sizeof(buffer)
: (apr_size_t)size;
- SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read));
SVN_ERR(svn_checksum_update(context, buffer, to_read));
size -= to_read;
}
@@ -588,28 +579,27 @@ compare_p2l_to_rev(svn_fs_t *fs,
apr_off_t max_offset;
apr_off_t offset = 0;
svn_fs_x__revision_file_t *rev_file;
+ svn_fs_x__index_info_t l2p_index_info;
/* open the pack / rev file that is covered by the p2l index */
- SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
- iterpool));
+ SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
/* check file size vs. range covered by index */
- SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+ SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start,
scratch_pool));
- if (rev_file->l2p_offset != max_offset)
+ if (l2p_index_info.start != max_offset)
return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL,
_("File size of %s for revision r%ld does "
"not match p2l index size of %s"),
apr_off_t_toa(scratch_pool,
- rev_file->l2p_offset),
+ l2p_index_info.start),
start,
apr_off_t_toa(scratch_pool,
max_offset));
- SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, NULL, 0,
- scratch_pool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, 0));
/* for all offsets in the file, get the P2L index entries and check
them against the L2P index */
@@ -627,8 +617,7 @@ compare_p2l_to_rev(svn_fs_t *fs,
/* The above might have moved the file pointer.
* Ensure we actually start reading at OFFSET. */
- SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size,
- NULL, offset, iterpool));
+ SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset));
/* process all entries (and later continue with the next block) */
for (i = 0; i < entries->nelts; ++i)
@@ -661,15 +650,15 @@ compare_p2l_to_rev(svn_fs_t *fs,
{
/* skip filler entry at the end of the p2l index */
if (entry->offset != max_offset)
- SVN_ERR(read_all_nul(rev_file->file, entry->size, iterpool));
+ SVN_ERR(read_all_nul(rev_file, entry->size, iterpool));
}
else
{
if (entry->size < STREAM_THRESHOLD)
- SVN_ERR(expected_buffered_checksum(rev_file->file, entry,
+ SVN_ERR(expected_buffered_checksum(rev_file, entry,
iterpool));
else
- SVN_ERR(expected_streamed_checksum(rev_file->file, entry,
+ SVN_ERR(expected_streamed_checksum(rev_file, entry,
iterpool));
}
@@ -703,6 +692,10 @@ verify_revprops(svn_fs_t *fs,
svn_revnum_t revision;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ /* Invalidate the revprop generation once.
+ * Use the cache inside the loop to speed up packed revprop access. */
+ svn_fs_x__invalidate_revprop_generation(fs);
+
for (revision = start; revision < end; ++revision)
{
svn_string_t *date;
@@ -713,7 +706,7 @@ verify_revprops(svn_fs_t *fs,
/* Access the svn:date revprop.
* This implies parsing all revprops for that revision. */
SVN_ERR(svn_fs_x__revision_prop(&date, fs, revision,
- SVN_PROP_REVISION_DATE,
+ SVN_PROP_REVISION_DATE, FALSE,
iterpool, iterpool));
/* The time stamp is the only revprop that, if given, needs to
@@ -790,8 +783,15 @@ verify_metadata_consistency(svn_fs_t *fs
/* concurrent packing is one of the reasons why verification may fail.
Make sure, we operate on up-to-date information. */
if (err)
- SVN_ERR(svn_fs_x__read_min_unpacked_rev(&ffd->min_unpacked_rev,
- fs, scratch_pool));
+ {
+ svn_error_t *err2
+ = svn_fs_x__read_min_unpacked_rev(&ffd->min_unpacked_rev,
+ fs, scratch_pool);
+
+ /* Be careful to not leak ERR. */
+ if (err2)
+ return svn_error_trace(svn_error_compose_create(err, err2));
+ }
/* retry the whole shard if it got packed in the meantime */
if (err && count != svn_fs_x__pack_size(fs, revision))
@@ -824,14 +824,14 @@ svn_fs_x__verify(svn_fs_t *fs,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
- svn_fs_x__data_t *ffd = fs->fsap_data;
- svn_revnum_t youngest = ffd->youngest_rev_cache; /* cache is current */
-
/* Input validation. */
if (! SVN_IS_VALID_REVNUM(start))
start = 0;
if (! SVN_IS_VALID_REVNUM(end))
- end = youngest;
+ {
+ SVN_ERR(svn_fs_x__youngest_rev(&end, fs, scratch_pool));
+ }
+
SVN_ERR(svn_fs_x__ensure_revision_exists(start, fs, scratch_pool));
SVN_ERR(svn_fs_x__ensure_revision_exists(end, fs, scratch_pool));
Modified: subversion/branches/ra-git/subversion/libsvn_fs_x/verify.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_fs_x/verify.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_fs_x/verify.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_fs_x/verify.h Mon Nov 30 10:24:16 2015
@@ -1,4 +1,4 @@
-/* verify.h : verification interface of the native filesystem layer
+/* verify.h : verification interface of the FSX filesystem
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,8 @@
* ====================================================================
*/
-#ifndef SVN_LIBSVN_FS__VERIFY_H
-#define SVN_LIBSVN_FS__VERIFY_H
+#ifndef SVN_LIBSVN_FS_X_VERIFY_H
+#define SVN_LIBSVN_FS_X_VERIFY_H
#include "fs.h"
Modified: subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.c Mon Nov 30 10:24:16 2015
@@ -152,7 +152,7 @@ load_ra_module(svn_ra__init_func_t *func
const char *compat_funcname;
apr_status_t status;
- libname = apr_psprintf(pool, "libsvn_ra_%s-%d.so.%d",
+ libname = apr_psprintf(pool, "libsvn_ra_%s-" SVN_DSO_SUFFIX_FMT,
ra_name, SVN_VER_MAJOR, SVN_SOVERSION);
funcname = apr_psprintf(pool, "svn_ra_%s__init", ra_name);
compat_funcname = apr_psprintf(pool, "svn_ra_%s_init", ra_name);
@@ -275,6 +275,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
apr_pool_t *pool)
{
apr_pool_t *sesspool = svn_pool_create(pool);
+ apr_pool_t *scratch_pool = svn_pool_create(sesspool);
svn_ra_session_t *session;
const struct ra_lib_defn *defn;
const svn_ra__vtable_t *vtable = NULL;
@@ -284,6 +285,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
#ifdef CHOOSABLE_DAV_MODULE
const char *http_library = DEFAULT_HTTP_LIBRARY;
#endif
+ svn_auth_baton_t *auth_baton;
/* Initialize the return variable. */
*session_p = NULL;
@@ -299,8 +301,12 @@ svn_error_t *svn_ra_open4(svn_ra_session
repos_URL);
if (callbacks->auth_baton)
- SVN_ERR(svn_auth__apply_config_for_server(callbacks->auth_baton, config,
- repos_URI.hostname, sesspool));
+ SVN_ERR(svn_auth__make_session_auth(&auth_baton,
+ callbacks->auth_baton, config,
+ repos_URI.hostname,
+ sesspool, scratch_pool));
+ else
+ auth_baton = NULL;
#ifdef CHOOSABLE_DAV_MODULE
if (config)
@@ -353,16 +359,16 @@ svn_error_t *svn_ra_open4(svn_ra_session
if (! initfunc)
SVN_ERR(load_ra_module(&initfunc, NULL, defn->ra_name,
- sesspool));
+ scratch_pool));
if (! initfunc)
/* Library not found. */
continue;
- SVN_ERR(initfunc(svn_ra_version(), &vtable, sesspool));
+ SVN_ERR(initfunc(svn_ra_version(), &vtable, scratch_pool));
SVN_ERR(check_ra_version(vtable->get_version(), scheme));
- if (! has_scheme_of(vtable->get_schemes(sesspool), repos_URL))
+ if (! has_scheme_of(vtable->get_schemes(scratch_pool), repos_URL))
/* Library doesn't support the scheme at runtime. */
continue;
@@ -386,10 +392,12 @@ svn_error_t *svn_ra_open4(svn_ra_session
/* Ask the library to open the session. */
err = vtable->open_session(session, corrected_url_p,
repos_URL,
- callbacks, callback_baton, config, sesspool);
+ callbacks, callback_baton, auth_baton,
+ config, sesspool, scratch_pool);
if (err)
{
+ svn_pool_destroy(sesspool); /* Includes scratch_pool */
if (err->apr_err == SVN_ERR_RA_SESSION_URL_MISMATCH)
return svn_error_trace(err);
@@ -407,7 +415,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
{
/* *session_p = NULL; */
*corrected_url_p = apr_pstrdup(pool, *corrected_url_p);
- svn_pool_destroy(sesspool);
+ svn_pool_destroy(sesspool); /* Includes scratch_pool */
return SVN_NO_ERROR;
}
@@ -421,7 +429,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
{
/* Duplicate the uuid as it is allocated in sesspool */
repository_uuid = apr_pstrdup(pool, repository_uuid);
- svn_pool_destroy(sesspool);
+ svn_pool_destroy(sesspool); /* includes scratch_pool */
return svn_error_createf(SVN_ERR_RA_UUID_MISMATCH, NULL,
_("Repository UUID '%s' doesn't match "
"expected UUID '%s'"),
@@ -429,6 +437,7 @@ svn_error_t *svn_ra_open4(svn_ra_session
}
}
+ svn_pool_destroy(scratch_pool);
*session_p = session;
return SVN_NO_ERROR;
}
@@ -953,6 +962,7 @@ svn_error_t *svn_ra_get_locations(svn_ra
{
svn_error_t *err;
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(peg_revision));
SVN_ERR_ASSERT(svn_relpath_is_canonical(path));
err = session->vtable->get_locations(session, locations, path,
peg_revision, location_revisions, pool);
@@ -1120,6 +1130,8 @@ svn_error_t *svn_ra_replay(svn_ra_sessio
void *edit_baton,
apr_pool_t *pool)
{
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision)
+ && SVN_IS_VALID_REVNUM(low_water_mark));
return session->vtable->replay(session, revision, low_water_mark,
text_deltas, editor, edit_baton, pool);
}
@@ -1187,7 +1199,14 @@ svn_ra_replay_range(svn_ra_session_t *se
void *replay_baton,
apr_pool_t *pool)
{
- svn_error_t *err =
+ svn_error_t *err;
+
+ SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(start_revision)
+ && SVN_IS_VALID_REVNUM(end_revision)
+ && start_revision <= end_revision
+ && SVN_IS_VALID_REVNUM(low_water_mark));
+
+ err =
session->vtable->replay_range(session, start_revision, end_revision,
low_water_mark, text_deltas,
revstart_func, revfinish_func,
Modified: subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra/ra_loader.h Mon Nov 30 10:24:16 2015
@@ -61,8 +61,10 @@ typedef struct svn_ra__vtable_t {
const char *session_URL,
const svn_ra_callbacks2_t *callbacks,
void *callback_baton,
+ svn_auth_baton_t *auth_baton,
apr_hash_t *config,
- apr_pool_t *pool);
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
/* Backs svn_ra_dup_session */
svn_error_t * (*dup_session)(svn_ra_session_t *new_session,
svn_ra_session_t *old_session,
Modified: subversion/branches/ra-git/subversion/libsvn_ra/wrapper_template.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra/wrapper_template.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra/wrapper_template.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra/wrapper_template.h Mon Nov 30 10:24:16 2015
@@ -91,7 +91,9 @@ static svn_error_t *compat_open(void **s
callbacks2->progress_baton = NULL;
SVN_ERR(VTBL.open_session(sess, &session_url, repos_URL,
- callbacks2, callback_baton, config, sesspool));
+ callbacks2, callback_baton,
+ callbacks ? callbacks->auth_baton : NULL,
+ config, sesspool, sesspool));
if (strcmp(repos_URL, session_url) != 0)
{
Modified: subversion/branches/ra-git/subversion/libsvn_ra_local/ra_local.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_local/ra_local.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_local/ra_local.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_local/ra_local.h Mon Nov 30 10:24:16 2015
@@ -63,6 +63,9 @@ typedef struct svn_ra_local__session_bat
const svn_ra_callbacks2_t *callbacks;
void *callback_baton;
+ /* Slave auth baton */
+ svn_auth_baton_t *auth_baton;
+
const char *useragent;
} svn_ra_local__session_baton_t;
Modified: subversion/branches/ra-git/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_local/ra_plugin.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_local/ra_plugin.c Mon Nov 30 10:24:16 2015
@@ -41,6 +41,7 @@
#include "private/svn_repos_private.h"
#include "private/svn_fspath.h"
#include "private/svn_atomic.h"
+#include "private/svn_subr_private.h"
#define APR_WANT_STRFUNC
#include <apr_want.h>
@@ -86,7 +87,7 @@ get_username(svn_ra_session_t *session,
{
/* Get a username somehow, so we have some svn:author property to
attach to a commit. */
- if (sess->callbacks->auth_baton)
+ if (sess->auth_baton)
{
void *creds;
svn_auth_cred_username_t *username_creds;
@@ -95,7 +96,7 @@ get_username(svn_ra_session_t *session,
SVN_ERR(svn_auth_first_credentials(&creds, &iterstate,
SVN_AUTH_CRED_USERNAME,
sess->uuid, /* realmstring */
- sess->callbacks->auth_baton,
+ sess->auth_baton,
scratch_pool));
/* No point in calling next_creds(), since that assumes that the
@@ -551,13 +552,16 @@ svn_ra_local__open(svn_ra_session_t *ses
const char *repos_URL,
const svn_ra_callbacks2_t *callbacks,
void *callback_baton,
+ svn_auth_baton_t *auth_baton,
apr_hash_t *config,
- apr_pool_t *pool)
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
{
const char *client_string;
svn_ra_local__session_baton_t *sess;
const char *fs_path;
static volatile svn_atomic_t cache_init_state = 0;
+ apr_pool_t *pool = result_pool;
/* Initialise the FSFS memory cache size. We can only do this once
so one CONFIG will win the race and all others will be ignored
@@ -572,6 +576,7 @@ svn_ra_local__open(svn_ra_session_t *ses
sess = apr_pcalloc(pool, sizeof(*sess));
sess->callbacks = callbacks;
sess->callback_baton = callback_baton;
+ sess->auth_baton = auth_baton;
/* Look through the URL, figure out which part points to the
repository, and which part is the path *within* the
@@ -1305,7 +1310,6 @@ svn_ra_local__get_dir(svn_ra_session_t *
apr_hash_t *entries;
apr_hash_index_t *hi;
svn_ra_local__session_baton_t *sess = session->priv;
- apr_pool_t *subpool;
const char *abs_path = svn_fspath__join(sess->fs_path->data, path, pool);
/* Open the revision's root. */
@@ -1321,29 +1325,28 @@ svn_ra_local__get_dir(svn_ra_session_t *
if (dirents)
{
+ apr_pool_t *iterpool = svn_pool_create(pool);
/* Get the dir's entries. */
SVN_ERR(svn_fs_dir_entries(&entries, root, abs_path, pool));
/* Loop over the fs dirents, and build a hash of general
svn_dirent_t's. */
*dirents = apr_hash_make(pool);
- subpool = svn_pool_create(pool);
for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi))
{
const void *key;
void *val;
- apr_hash_t *prophash;
const char *datestring, *entryname, *fullpath;
svn_fs_dirent_t *fs_entry;
svn_dirent_t *entry = svn_dirent_create(pool);
- svn_pool_clear(subpool);
+ svn_pool_clear(iterpool);
apr_hash_this(hi, &key, NULL, &val);
entryname = (const char *) key;
fs_entry = (svn_fs_dirent_t *) val;
- fullpath = svn_dirent_join(abs_path, entryname, subpool);
+ fullpath = svn_dirent_join(abs_path, entryname, iterpool);
if (dirent_fields & SVN_DIRENT_KIND)
{
@@ -1358,15 +1361,15 @@ svn_ra_local__get_dir(svn_ra_session_t *
entry->size = 0;
else
SVN_ERR(svn_fs_file_length(&(entry->size), root,
- fullpath, subpool));
+ fullpath, iterpool));
}
if (dirent_fields & SVN_DIRENT_HAS_PROPS)
{
/* has_props? */
- SVN_ERR(svn_fs_node_proplist(&prophash, root, fullpath,
- subpool));
- entry->has_props = (apr_hash_count(prophash) != 0);
+ SVN_ERR(svn_fs_node_has_props(&entry->has_props,
+ root, fullpath,
+ iterpool));
}
if ((dirent_fields & SVN_DIRENT_TIME)
@@ -1377,7 +1380,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
SVN_ERR(svn_repos_get_committed_info(&(entry->created_rev),
&datestring,
&(entry->last_author),
- root, fullpath, subpool));
+ root, fullpath, iterpool));
if (datestring)
SVN_ERR(svn_time_from_cstring(&(entry->time), datestring,
pool));
@@ -1388,7 +1391,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
/* Store. */
svn_hash_sets(*dirents, entryname, entry);
}
- svn_pool_destroy(subpool);
+ svn_pool_destroy(iterpool);
}
/* Handle props if requested. */
@@ -1692,23 +1695,13 @@ svn_ra_local__get_inherited_props(svn_ra
apr_pool_t *scratch_pool)
{
svn_fs_root_t *root;
- svn_revnum_t youngest_rev;
svn_ra_local__session_baton_t *sess = session->priv;
const char *abs_path = svn_fspath__join(sess->fs_path->data, path,
scratch_pool);
svn_node_kind_t node_kind;
/* Open the revision's root. */
- if (! SVN_IS_VALID_REVNUM(revision))
- {
- SVN_ERR(svn_fs_youngest_rev(&youngest_rev, sess->fs, scratch_pool));
- SVN_ERR(svn_fs_revision_root(&root, sess->fs, youngest_rev,
- scratch_pool));
- }
- else
- {
- SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, scratch_pool));
- }
+ SVN_ERR(svn_fs_revision_root(&root, sess->fs, revision, scratch_pool));
SVN_ERR(svn_fs_check_path(&node_kind, root, abs_path, scratch_pool));
if (node_kind == svn_node_none)
@@ -1876,8 +1869,8 @@ svn_ra_local__init(const svn_version_t *
SVN_ERR(svn_ver_check_list2(ra_local_version(), checklist, svn_ver_equal));
#ifndef SVN_LIBSVN_CLIENT_LINKS_RA_LOCAL
- /* This assumes that POOL was the pool used to load the dso. */
- SVN_ERR(svn_fs_initialize(pool));
+ /* This means the library was loaded as a DSO, so use the DSO pool. */
+ SVN_ERR(svn_fs_initialize(svn_dso__pool()));
#endif
*vtable = &ra_local_vtable;
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/commit.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/commit.c Mon Nov 30 10:24:16 2015
@@ -71,6 +71,7 @@ typedef struct commit_context_t {
const char *checked_in_url; /* checked-in root to base CHECKOUTs from */
const char *vcc_url; /* vcc url */
+ int open_batons; /* Number of open batons */
} commit_context_t;
#define USING_HTTPV2_COMMIT_SUPPORT(commit_ctx) ((commit_ctx)->txn_url != NULL)
@@ -117,9 +118,6 @@ typedef struct dir_context_t {
HTTP v2, for PROPPATCH in HTTP v2). */
const char *url;
- /* How many pending changes we have left in this directory. */
- unsigned int ref_count;
-
/* Is this directory being added? (Otherwise, just opened.) */
svn_boolean_t added;
@@ -843,6 +841,7 @@ proppatch_resource(svn_ra_serf__session_
handler->body_delegate = create_proppatch_body;
handler->body_delegate_baton = proppatch;
+ handler->body_type = "text/xml";
handler->response_handler = svn_ra_serf__handle_multistatus_only;
handler->response_baton = handler;
@@ -1258,6 +1257,8 @@ open_root(void *edit_baton,
const char *proppatch_target = NULL;
apr_pool_t *scratch_pool = svn_pool_create(dir_pool);
+ commit_ctx->open_batons++;
+
if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(commit_ctx->session))
{
post_response_ctx_t *prc;
@@ -1533,6 +1534,8 @@ add_directory(const char *path,
dir->name = svn_relpath_basename(dir->relpath, NULL);
dir->prop_changes = apr_hash_make(dir->pool);
+ dir->commit_ctx->open_batons++;
+
if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
{
dir->url = svn_path_url_add_component2(parent->commit_ctx->txn_root_url,
@@ -1623,6 +1626,8 @@ open_directory(const char *path,
dir->name = svn_relpath_basename(dir->relpath, NULL);
dir->prop_changes = apr_hash_make(dir->pool);
+ dir->commit_ctx->open_batons++;
+
if (USING_HTTPV2_COMMIT_SUPPORT(dir->commit_ctx))
{
dir->url = svn_path_url_add_component2(parent->commit_ctx->txn_root_url,
@@ -1701,6 +1706,8 @@ close_directory(void *dir_baton,
proppatch_ctx, dir->pool));
}
+ dir->commit_ctx->open_batons--;
+
return SVN_NO_ERROR;
}
@@ -1720,8 +1727,6 @@ add_file(const char *path,
new_file = apr_pcalloc(file_pool, sizeof(*new_file));
new_file->pool = file_pool;
- dir->ref_count++;
-
new_file->parent_dir = dir;
new_file->commit_ctx = dir->commit_ctx;
new_file->relpath = apr_pstrdup(new_file->pool, path);
@@ -1732,6 +1737,8 @@ add_file(const char *path,
new_file->copy_revision = copy_revision;
new_file->prop_changes = apr_hash_make(new_file->pool);
+ dir->commit_ctx->open_batons++;
+
/* Ensure that the file doesn't exist by doing a HEAD on the
resource. If we're using HTTP v2, we'll just look into the
transaction root tree for this thing. */
@@ -1842,8 +1849,6 @@ open_file(const char *path,
new_file = apr_pcalloc(file_pool, sizeof(*new_file));
new_file->pool = file_pool;
- parent->ref_count++;
-
new_file->parent_dir = parent;
new_file->commit_ctx = parent->commit_ctx;
new_file->relpath = apr_pstrdup(new_file->pool, path);
@@ -1852,6 +1857,8 @@ open_file(const char *path,
new_file->base_revision = base_revision;
new_file->prop_changes = apr_hash_make(new_file->pool);
+ parent->commit_ctx->open_batons++;
+
if (USING_HTTPV2_COMMIT_SUPPORT(parent->commit_ctx))
{
new_file->url = svn_path_url_add_component2(parent->commit_ctx->txn_root_url,
@@ -1895,6 +1902,8 @@ apply_textdelta(void *file_baton,
void **handler_baton)
{
file_context_t *ctx = file_baton;
+ int svndiff_version;
+ int compression_level;
/* Store the stream in a temporary file; we'll give it to serf when we
* close this file.
@@ -1903,13 +1912,45 @@ apply_textdelta(void *file_baton,
* writing to a temporary file (ugh). A special svn stream serf bucket
* that returns EAGAIN until we receive the done call? But, when
* would we run through the serf context? Grr.
+ *
+ * BH: If you wait to a specific event... why not use that event to
+ * trigger the operation?
+ * Having a request (body) bucket return EAGAIN until done stalls
+ * the entire HTTP pipeline after writing the first part of the
+ * request. It is not like we can interrupt some part of a request
+ * and continue later. Or somebody else must use tempfiles and
+ * always assume that clients work this bad... as it only knows
+ * for sure after the request is completely available.
*/
ctx->stream = svn_stream_lazyopen_create(delayed_commit_stream_open,
ctx, FALSE, ctx->pool);
- svn_txdelta_to_svndiff3(handler, handler_baton, ctx->stream, 0,
- SVN_DELTA_COMPRESSION_LEVEL_DEFAULT, pool);
+ if (ctx->commit_ctx->session->supports_svndiff1 &&
+ ctx->commit_ctx->session->using_compression)
+ {
+ /* Use compressed svndiff1 format, if possible. */
+ svndiff_version = 1;
+ compression_level = SVN_DELTA_COMPRESSION_LEVEL_DEFAULT;
+ }
+ else
+ {
+ /* Difference between svndiff formats 0 and 1 that format 1 allows
+ * compression. Uncompressed svndiff0 should also be slightly more
+ * effective if the compression is not required at all.
+ *
+ * If the server cannot handle svndiff1, or compression is disabled
+ * with the 'http-compression = no' client configuration option, fall
+ * back to uncompressed svndiff0 format. As a bonus, users can force
+ * the usage of the uncompressed format by setting the corresponding
+ * client configuration option, if they want to.
+ */
+ svndiff_version = 0;
+ compression_level = SVN_DELTA_COMPRESSION_LEVEL_NONE;
+ }
+
+ svn_txdelta_to_svndiff3(handler, handler_baton, ctx->stream,
+ svndiff_version, compression_level, pool);
if (base_checksum)
ctx->base_checksum = apr_pstrdup(ctx->pool, base_checksum);
@@ -2014,6 +2055,8 @@ close_file(void *file_baton,
proppatch, scratch_pool));
}
+ ctx->commit_ctx->open_batons--;
+
return SVN_NO_ERROR;
}
@@ -2027,6 +2070,11 @@ close_edit(void *edit_baton,
const svn_commit_info_t *commit_info;
svn_error_t *err = NULL;
+ if (ctx->open_batons > 0)
+ return svn_error_create(
+ SVN_ERR_FS_INCORRECT_EDITOR_COMPLETION, NULL,
+ _("Closing editor with directories or files open"));
+
/* MERGE our activity */
SVN_ERR(svn_ra_serf__run_merge(&commit_info,
ctx->session,
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/eagain_bucket.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/eagain_bucket.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/eagain_bucket.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/eagain_bucket.c Mon Nov 30 10:24:16 2015
@@ -66,7 +66,7 @@ eagain_bucket_read(serf_bucket_t *bucket
return APR_EAGAIN;
}
-
+#if !SERF_VERSION_AT_LEAST(1, 4, 0)
static apr_status_t
eagain_bucket_readline(serf_bucket_t *bucket,
int acceptable,
@@ -79,6 +79,7 @@ eagain_bucket_readline(serf_bucket_t *bu
"Not implemented."));
return APR_ENOTIMPL;
}
+#endif
static apr_status_t
@@ -98,7 +99,11 @@ eagain_bucket_peek(serf_bucket_t *bucket
static const serf_bucket_type_t delay_bucket_vtable = {
"BUF-EAGAIN",
eagain_bucket_read,
+#if SERF_VERSION_AT_LEAST(1, 4, 0)
+ serf_default_readline,
+#else
eagain_bucket_readline,
+#endif
serf_default_read_iovec,
serf_default_read_for_sendfile,
serf_default_read_bucket,
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/get_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/get_file.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/get_file.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/get_file.c Mon Nov 30 10:24:16 2015
@@ -321,17 +321,19 @@ svn_ra_serf__get_file(svn_ra_session_t *
svn_stream_t *stream,
svn_revnum_t *fetched_rev,
apr_hash_t **props,
- apr_pool_t *pool)
+ apr_pool_t *result_pool)
{
svn_ra_serf__session_t *session = ra_session->priv;
const char *fetch_url;
const svn_ra_serf__dav_props_t *which_props;
svn_ra_serf__handler_t *propfind_handler;
+ apr_pool_t *scratch_pool = svn_pool_create(result_pool);
struct file_prop_baton_t fb;
/* Fetch properties. */
- fetch_url = svn_path_url_add_component2(session->session_url.path, path, pool);
+ fetch_url = svn_path_url_add_component2(session->session_url.path, path,
+ scratch_pool);
/* The simple case is if we want HEAD - then a GET on the fetch_url is fine.
*
@@ -343,7 +345,7 @@ svn_ra_serf__get_file(svn_ra_session_t *
SVN_ERR(svn_ra_serf__get_stable_url(&fetch_url, fetched_rev,
session,
fetch_url, revision,
- pool, pool));
+ scratch_pool, scratch_pool));
revision = SVN_INVALID_REVNUM;
}
/* REVISION is always SVN_INVALID_REVNUM */
@@ -356,8 +358,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
else
which_props = check_path_props;
- fb.result_pool = pool;
- fb.props = props ? apr_hash_make(pool) : NULL;
+ fb.result_pool = result_pool;
+ fb.props = props ? apr_hash_make(result_pool) : NULL;
fb.kind = svn_node_unknown;
fb.sha1_checksum = NULL;
@@ -365,9 +367,9 @@ svn_ra_serf__get_file(svn_ra_session_t *
fetch_url, SVN_INVALID_REVNUM,
"0", which_props,
get_file_prop_cb, &fb,
- pool));
+ scratch_pool));
- SVN_ERR(svn_ra_serf__context_run_one(propfind_handler, pool));
+ SVN_ERR(svn_ra_serf__context_run_one(propfind_handler, scratch_pool));
/* Verify that resource type is not collection. */
if (fb.kind != svn_node_file)
@@ -382,7 +384,8 @@ svn_ra_serf__get_file(svn_ra_session_t *
if (stream)
{
svn_boolean_t found;
- SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream, pool));
+ SVN_ERR(try_get_wc_contents(&found, session, fb.sha1_checksum, stream,
+ scratch_pool));
/* No contents found in the WC, let's fetch from server. */
if (!found)
@@ -391,11 +394,11 @@ svn_ra_serf__get_file(svn_ra_session_t *
svn_ra_serf__handler_t *handler;
/* Create the fetch context. */
- stream_ctx = apr_pcalloc(pool, sizeof(*stream_ctx));
+ stream_ctx = apr_pcalloc(scratch_pool, sizeof(*stream_ctx));
stream_ctx->result_stream = stream;
stream_ctx->using_compression = session->using_compression;
- handler = svn_ra_serf__create_handler(session, pool);
+ handler = svn_ra_serf__create_handler(session, scratch_pool);
handler->method = "GET";
handler->path = fetch_url;
@@ -414,12 +417,14 @@ svn_ra_serf__get_file(svn_ra_session_t *
stream_ctx->handler = handler;
- SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
+ SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
if (handler->sline.code != 200)
return svn_error_trace(svn_ra_serf__unexpected_status(handler));
}
}
+ svn_pool_destroy(scratch_pool);
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocations.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocations.c Mon Nov 30 10:24:16 2015
@@ -193,9 +193,8 @@ svn_ra_serf__get_locations(svn_ra_sessio
SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
- SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
- handler->path,
- handler->location));
+ if (handler->sline.code != 200)
+ SVN_ERR(svn_ra_serf__unexpected_status(handler));
return SVN_NO_ERROR;
}
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocationsegments.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/getlocationsegments.c Mon Nov 30 10:24:16 2015
@@ -196,12 +196,8 @@ svn_ra_serf__get_location_segments(svn_r
err = svn_ra_serf__context_run_one(handler, pool);
- if (!err)
- {
- err = svn_ra_serf__error_on_status(handler->sline,
- handler->path,
- handler->location);
- }
+ if (!err && handler->sline.code != 200)
+ err = svn_ra_serf__unexpected_status(handler);
if (err && (err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE))
return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, err, NULL);
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/lock.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/lock.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/lock.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/lock.c Mon Nov 30 10:24:16 2015
@@ -267,10 +267,9 @@ run_locks(svn_ra_serf__session_t *sess,
/* ### Authz can also lead to 403. */
err = svn_error_createf(SVN_ERR_FS_LOCK_OWNER_MISMATCH,
NULL,
- _("Unlock of '%s' failed (%d %s)"),
- ctx->path,
- ctx->handler->sline.code,
- ctx->handler->sline.reason);
+ _("Not authorized to perform lock "
+ "operation on '%s'"),
+ ctx->path);
break;
case 405:
err = svn_error_createf(SVN_ERR_FS_OUT_OF_DATE,
@@ -282,15 +281,23 @@ run_locks(svn_ra_serf__session_t *sess,
ctx->handler->sline.reason);
break;
case 423:
- err = svn_error_createf(SVN_ERR_FS_PATH_ALREADY_LOCKED,
- NULL,
- _("Path '%s' already locked "
- "(%d %s)"),
- ctx->path,
- ctx->handler->sline.code,
- ctx->handler->sline.reason);
+ if (server_err
+ && SVN_ERROR_IN_CATEGORY(server_err->apr_err,
+ SVN_ERR_FS_CATEGORY_START))
+ {
+ err = NULL;
+ }
+ else
+ err = svn_error_createf(SVN_ERR_FS_PATH_ALREADY_LOCKED,
+ NULL,
+ _("Path '%s' already locked "
+ "(%d %s)"),
+ ctx->path,
+ ctx->handler->sline.code,
+ ctx->handler->sline.reason);
break;
+ case 404:
case 409:
case 500:
if (server_err)
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/log.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/log.c Mon Nov 30 10:24:16 2015
@@ -272,7 +272,7 @@ log_closed(svn_ra_serf__xml_estate_t *xe
svn_log_entry_t *log_entry;
const char *rev_str;
- if (log_ctx->limit && (log_ctx->nest_level == 0)
+ if ((log_ctx->limit > 0) && (log_ctx->nest_level == 0)
&& (++log_ctx->count > log_ctx->limit))
{
return SVN_NO_ERROR;
@@ -598,8 +598,8 @@ svn_ra_serf__get_log(svn_ra_session_t *r
SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
- return svn_error_trace(
- svn_ra_serf__error_on_status(handler->sline,
- req_url,
- handler->location));
+ if (handler->sline.code != 200)
+ SVN_ERR(svn_ra_serf__unexpected_status(handler));
+
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/merge.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/merge.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/merge.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/merge.c Mon Nov 30 10:24:16 2015
@@ -427,6 +427,7 @@ svn_ra_serf__run_merge(const svn_commit_
handler->path = merge_ctx->merge_url;
handler->body_delegate = create_merge_body;
handler->body_delegate_baton = merge_ctx;
+ handler->body_type = "text/xml";
handler->header_delegate = setup_merge_headers;
handler->header_delegate_baton = merge_ctx;
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/mergeinfo.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/mergeinfo.c Mon Nov 30 10:24:16 2015
@@ -228,8 +228,8 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
SVN_ERR(svn_ra_serf__context_run_one(handler, pool));
- SVN_ERR(svn_ra_serf__error_on_status(handler->sline, handler->path,
- handler->location));
+ if (handler->sline.code != 200)
+ SVN_ERR(svn_ra_serf__unexpected_status(handler));
if (apr_hash_count(mergeinfo_ctx->result_catalog))
*catalog = mergeinfo_ctx->result_catalog;
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/multistatus.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/multistatus.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/multistatus.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/multistatus.c Mon Nov 30 10:24:16 2015
@@ -315,7 +315,7 @@ multistatus_closed(svn_ra_serf__xml_esta
svn_ra_serf__xml_note(xes, MS_RESPONSE, "errcode", errcode);
break;
case MS_RESPONSE:
- if ((status = svn_hash_gets(attrs, "status")) != NULL)
+ if ((status = svn_hash__get_cstring(attrs, "status", NULL)) != NULL)
{
error_item_t *item;
@@ -369,7 +369,7 @@ multistatus_closed(svn_ra_serf__xml_esta
break;
case MS_PROPSTAT:
- if ((status = svn_hash_gets(attrs, "status")) != NULL)
+ if ((status = svn_hash__get_cstring(attrs, "status", NULL)) != NULL)
{
apr_hash_t *response_attrs;
error_item_t *item;
@@ -428,7 +428,8 @@ multistatus_closed(svn_ra_serf__xml_esta
item->http_status = server_error->handler->sline.code;
/* Do we have a mod_dav specific message? */
- item->message = svn_hash_gets(attrs, "human-readable");
+ item->message = svn_hash__get_cstring(attrs, "human-readable",
+ NULL);
if (item->message)
{
@@ -442,9 +443,6 @@ multistatus_closed(svn_ra_serf__xml_esta
item->message = apr_pstrdup(server_error->pool, item->message);
}
- else
- item->message = apr_pstrdup(server_error->pool,
- svn_hash_gets(attrs, "description"));
APR_ARRAY_PUSH(server_error->items, error_item_t *) = item;
@@ -709,7 +707,16 @@ svn_ra_serf__handle_server_error(svn_ra_
clear the error and return - allowing serf to wait for more data.
*/
if (!err || SERF_BUCKET_READ_ERROR(err->apr_err))
- return svn_error_trace(err);
+ {
+ /* Perhaps we already parsed some server generated message. Let's pass
+ all information we can get.*/
+ if (err)
+ err = svn_error_compose_create(
+ svn_ra_serf__server_error_create(handler, scratch_pool),
+ err);
+
+ return svn_error_trace(err);
+ }
if (!APR_STATUS_IS_EOF(err->apr_err))
{
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/options.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/options.c Mon Nov 30 10:24:16 2015
@@ -226,6 +226,12 @@ capabilities_headers_iterator_callback(v
{
session->supports_rev_rsrc_replay = TRUE;
}
+ if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_SVNDIFF1, vals))
+ {
+ /* Use compressed svndiff1 format for servers that properly
+ advertise this capability (Subversion 1.10 and greater). */
+ session->supports_svndiff1 = TRUE;
+ }
}
/* SVN-specific headers -- if present, server supports HTTP protocol v2 */
@@ -243,6 +249,21 @@ capabilities_headers_iterator_callback(v
apr_hash_set(session->supported_posts, "create-txn", 10, (void *)1);
}
+ /* Use compressed svndiff1 format for servers that speak HTTPv2,
+ in addition to servers that send SVN_DAV_NS_DAV_SVN_SVNDIFF1.
+
+ Apache HTTPd + mod_dav_svn servers support svndiff1, beginning
+ from Subversion 1.4, but they do not advertise this capability.
+ Compressing data can have a noticeable impact if the connection
+ is slow, and we want to use it even for existing servers, so we
+ send svndiff1 data to every HTTPv2 server (Subversion 1.7 and
+ greater).
+
+ The reasoning behind enabling it with HTTPv2 is that if the user
+ is stuck with the old Subversion's HTTPv1 protocol, she probably
+ doesn't really care about performance. */
+ session->supports_svndiff1 = TRUE;
+
if (svn_cstring_casecmp(key, SVN_DAV_ROOT_URI_HEADER) == 0)
{
session->repos_root = session->session_url;
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/property.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/property.c Mon Nov 30 10:24:16 2015
@@ -390,6 +390,26 @@ create_propfind_body(serf_bucket_t **bkt
requested_allprop = TRUE;
}
+ prop++;
+ }
+
+ tmp = SERF_BUCKET_SIMPLE_STRING_LEN(PROPFIND_HEADER,
+ sizeof(PROPFIND_HEADER)-1,
+ alloc);
+ serf_bucket_aggregate_append(body_bkt, tmp);
+
+ /* If we're not doing an allprop, add <prop> tags. */
+ if (!requested_allprop)
+ {
+ tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<prop>",
+ sizeof("<prop>")-1,
+ alloc);
+ serf_bucket_aggregate_append(body_bkt, tmp);
+ }
+
+ prop = ctx->find_props;
+ while (prop && prop->xmlns)
+ {
/* <*propname* xmlns="*propns*" /> */
tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, alloc);
serf_bucket_aggregate_append(body_bkt, tmp);
@@ -412,21 +432,6 @@ create_propfind_body(serf_bucket_t **bkt
prop++;
}
- /* If we're not doing an allprop, add <prop> tags. */
- if (!requested_allprop)
- {
- tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<prop>",
- sizeof("<prop>")-1,
- alloc);
- serf_bucket_aggregate_prepend(body_bkt, tmp);
- }
-
- tmp = SERF_BUCKET_SIMPLE_STRING_LEN(PROPFIND_HEADER,
- sizeof(PROPFIND_HEADER)-1,
- alloc);
-
- serf_bucket_aggregate_prepend(body_bkt, tmp);
-
if (!requested_allprop)
{
tmp = SERF_BUCKET_SIMPLE_STRING_LEN("</prop>",
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/ra_serf.h?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/ra_serf.h Mon Nov 30 10:24:16 2015
@@ -114,7 +114,7 @@ struct svn_ra_serf__session_t {
/* Are we using ssl */
svn_boolean_t using_ssl;
- /* Should we ask for compressed responses? */
+ /* Should we use compression for network transmissions? */
svn_boolean_t using_compression;
/* The user agent string */
@@ -137,6 +137,10 @@ struct svn_ra_serf__session_t {
HTTP/1.0. Thus, we cannot send chunked requests. */
svn_boolean_t http10;
+ /* We are talking to the server via http/2. Responses of scheduled
+ requests may come in any order */
+ svn_boolean_t http20;
+
/* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
svn_boolean_t using_chunked_requests;
@@ -154,6 +158,7 @@ struct svn_ra_serf__session_t {
/* Callback functions to get info from WC */
const svn_ra_callbacks2_t *wc_callbacks;
void *wc_callback_baton;
+ svn_auth_baton_t *auth_baton;
/* Callback function to send progress info to the client */
svn_ra_progress_notify_func_t progress_func;
@@ -254,6 +259,9 @@ struct svn_ra_serf__session_t {
/* Indicates whether the server supports issuing replay REPORTs
against rev resources (children of `rev_stub', elsestruct). */
svn_boolean_t supports_rev_rsrc_replay;
+
+ /* Indicates whether the server can understand svndiff version 1. */
+ svn_boolean_t supports_svndiff1;
};
#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
@@ -1514,6 +1522,11 @@ svn_ra_serf__error_on_status(serf_status
svn_error_t *
svn_ra_serf__unexpected_status(svn_ra_serf__handler_t *handler);
+/* Make sure handler is no longer scheduled on its connection. Resetting
+ the connection if necessary */
+void
+svn_ra_serf__unschedule_handler(svn_ra_serf__handler_t *handler);
+
/* ###? */
svn_error_t *
@@ -1544,6 +1557,17 @@ svn_ra_serf__create_bucket_with_eagain(c
apr_size_t len,
serf_bucket_alloc_t *allocator);
+/* Parse a given URL_STR, fill in all supplied fields of URI
+ * structure.
+ *
+ * This function is a compatibility wrapper around apr_uri_parse().
+ * Different apr-util versions set apr_uri_t.path to either NULL or ""
+ * for root paths, and serf expects to see "/". This function always
+ * sets URI.path to "/" for these paths. */
+svn_error_t *
+svn_ra_serf__uri_parse(apr_uri_t *uri,
+ const char *url_str,
+ apr_pool_t *result_pool);
#if defined(SVN_DEBUG)
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/replay.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/replay.c Mon Nov 30 10:24:16 2015
@@ -427,10 +427,11 @@ replay_closed(svn_ra_serf__xml_estate_t
{
struct replay_node_t *node = ctx->current_node;
- if (! node || ! node->file || ! node->stream)
+ if (! node || ! node->file)
return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
- SVN_ERR(svn_stream_close(node->stream));
+ if (node->stream)
+ SVN_ERR(svn_stream_close(node->stream));
node->stream = NULL;
}
@@ -565,10 +566,10 @@ svn_ra_serf__replay(svn_ra_session_t *ra
SVN_ERR(svn_ra_serf__context_run_one(handler, scratch_pool));
- return svn_error_trace(
- svn_ra_serf__error_on_status(handler->sline,
- handler->path,
- handler->location));
+ if (handler->sline.code != 200)
+ SVN_ERR(svn_ra_serf__unexpected_status(handler));
+
+ return SVN_NO_ERROR;
}
/* The maximum number of outstanding requests at any time. When this
@@ -646,9 +647,28 @@ svn_ra_serf__replay_range(svn_ra_session
int active_reports = 0;
const char *include_path;
svn_boolean_t done;
+ apr_pool_t *subpool = svn_pool_create(scratch_pool);
+
+ if (session->http20) {
+ /* ### Auch... this doesn't work yet...
+
+ This code relies on responses coming in in an exact order, while
+ http2 does everything to deliver responses as fast as possible.
+
+ With http/1.1 we were quite lucky that this worked, as serf doesn't
+ promise in order delivery.... (Please do not use authz with keys
+ that expire)
+
+ For now fall back to the legacy callback in libsvn_ra that is
+ used by all the other ra layers as workaround.
+
+ ### TODO: Optimize
+ */
+ return svn_error_create(SVN_ERR_RA_NOT_IMPLEMENTED, NULL, NULL);
+ }
SVN_ERR(svn_ra_serf__report_resource(&report_target, session,
- scratch_pool));
+ subpool));
/* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
aimed at the session URL. But that's incorrect -- these reports
@@ -671,7 +691,7 @@ svn_ra_serf__replay_range(svn_ra_session
{
SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
session->session_url.path,
- session, scratch_pool));
+ session, subpool));
}
else
{
@@ -689,7 +709,7 @@ svn_ra_serf__replay_range(svn_ra_session
{
struct revision_report_t *rev_ctx;
svn_ra_serf__handler_t *handler;
- apr_pool_t *rev_pool = svn_pool_create(scratch_pool);
+ apr_pool_t *rev_pool = svn_pool_create(subpool);
svn_ra_serf__xml_context_t *xmlctx;
const char *replay_target;
@@ -756,6 +776,7 @@ svn_ra_serf__replay_range(svn_ra_session
handler->path = replay_target;
handler->body_delegate = create_replay_body;
handler->body_delegate_baton = rev_ctx;
+ handler->body_type = "text/xml";
handler->done_delegate = replay_done;
handler->done_delegate_baton = rev_ctx;
@@ -769,13 +790,23 @@ svn_ra_serf__replay_range(svn_ra_session
/* Run the serf loop. */
done = FALSE;
- SVN_ERR(svn_ra_serf__context_run_wait(&done, session, scratch_pool));
+ {
+ svn_error_t *err = svn_ra_serf__context_run_wait(&done, session,
+ subpool);
+
+ if (err)
+ {
+ svn_pool_destroy(subpool); /* Unregister all requests! */
+ return svn_error_trace(err);
+ }
+ }
/* The done handler of reports decrements active_reports when a report
is done. This same handler reports (fatal) report errors, so we can
just loop here. */
}
+ svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
#undef MAX_OUTSTANDING_REQUESTS
Modified: subversion/branches/ra-git/subversion/libsvn_ra_serf/sb_bucket.c
URL: http://svn.apache.org/viewvc/subversion/branches/ra-git/subversion/libsvn_ra_serf/sb_bucket.c?rev=1717223&r1=1717222&r2=1717223&view=diff
==============================================================================
--- subversion/branches/ra-git/subversion/libsvn_ra_serf/sb_bucket.c (original)
+++ subversion/branches/ra-git/subversion/libsvn_ra_serf/sb_bucket.c Mon Nov 30 10:24:16 2015
@@ -117,7 +117,7 @@ sb_bucket_read(serf_bucket_t *bucket, ap
return *data == NULL ? APR_EOF : APR_SUCCESS;
}
-
+#if !SERF_VERSION_AT_LEAST(1, 4, 0)
static apr_status_t
sb_bucket_readline(serf_bucket_t *bucket, int acceptable,
int *found,
@@ -128,6 +128,7 @@ sb_bucket_readline(serf_bucket_t *bucket
"Not implemented."));
return APR_ENOTIMPL;
}
+#endif
static apr_status_t
@@ -159,7 +160,11 @@ sb_bucket_peek(serf_bucket_t *bucket,
static const serf_bucket_type_t sb_bucket_vtable = {
"SPILLBUF",
sb_bucket_read,
+#if SERF_VERSION_AT_LEAST(1, 4, 0)
+ serf_default_readline,
+#else
sb_bucket_readline,
+#endif
serf_default_read_iovec,
serf_default_read_for_sendfile,
serf_default_read_bucket,