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,