You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/06/30 03:03:14 UTC

svn commit: r1498045 [4/8] - in /subversion/branches/fsfs-format7: ./ build/ build/generator/ build/generator/templates/ notes/tree-conflicts/ subversion/bindings/cxxhl/include/ subversion/bindings/cxxhl/include/svncxxhl/ subversion/bindings/cxxhl/src/...

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_base/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_base/fs.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_base/fs.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_base/fs.c Sun Jun 30 01:03:10 2013
@@ -898,7 +898,13 @@ base_open_for_recovery(svn_fs_t *fs, con
 }
 
 static svn_error_t *
-base_upgrade(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+base_upgrade(svn_fs_t *fs,
+             const char *path,
+             svn_fs_upgrade_notify_t notify_func,
+             void *notify_baton,
+             svn_cancel_func_t cancel_func,
+             void *cancel_baton,
+             apr_pool_t *pool,
              apr_pool_t *common_pool)
 {
   const char *version_file_path;
@@ -921,6 +927,9 @@ base_upgrade(svn_fs_t *fs, const char *p
   /* Bump the format file's stored version number. */
   SVN_ERR(svn_io_write_version_file(version_file_path,
                                     SVN_FS_BASE__FORMAT_NUMBER, pool));
+  if (notify_func)
+    SVN_ERR(notify_func(notify_baton, SVN_FS_BASE__FORMAT_NUMBER,
+                        svn_fs_upgrade_format_bumped, pool));
 
   /* Check and see if we need to record the "bump" revision. */
   if (old_format_number < SVN_FS_BASE__MIN_FORWARD_DELTAS_FORMAT)

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_base/tree.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_base/tree.c Sun Jun 30 01:03:10 2013
@@ -4828,6 +4828,13 @@ base_node_origin_rev(svn_revnum_t *revis
      prev_location() does below will work. */
   path = svn_fs__canonicalize_abspath(path, pool);
 
+  /* Special-case the root node (for performance reasons) */
+  if (strcmp(path, "/") == 0)
+    {
+      *revision = 0;
+      return SVN_NO_ERROR;
+    }
+
   /* If we have support for the node-origins table, we'll try to use
      it. */
   if (bfd->format >= SVN_FS_BASE__MIN_NODE_ORIGINS_FORMAT)

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/cached_data.c Sun Jun 30 01:03:10 2013
@@ -1554,7 +1554,6 @@ get_combined_window(svn_stringbuf_t **re
 {
   apr_pool_t *pool, *new_pool, *window_pool;
   int i;
-  svn_txdelta_window_t *window;
   apr_array_header_t *windows;
   svn_stringbuf_t *source, *buf = rb->base_window;
   rep_state_t *rs;
@@ -1567,6 +1566,8 @@ get_combined_window(svn_stringbuf_t **re
   windows = apr_array_make(window_pool, 0, sizeof(svn_txdelta_window_t *));
   for (i = 0; i < rb->rs_list->nelts; ++i)
     {
+      svn_txdelta_window_t *window;
+
       rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
       SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool));
 
@@ -1582,6 +1583,7 @@ get_combined_window(svn_stringbuf_t **re
   pool = svn_pool_create(rb->pool);
   for (--i; i >= 0; --i)
     {
+      svn_txdelta_window_t *window;
 
       rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
       window = APR_ARRAY_IDX(windows, i, svn_txdelta_window_t *);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs.c Sun Jun 30 01:03:10 2013
@@ -295,7 +295,13 @@ fs_open_for_recovery(svn_fs_t *fs,
 
 /* This implements the fs_library_vtable_t.upgrade_fs() API. */
 static svn_error_t *
-fs_upgrade(svn_fs_t *fs, const char *path, apr_pool_t *pool,
+fs_upgrade(svn_fs_t *fs,
+           const char *path,
+           svn_fs_upgrade_notify_t notify_func,
+           void *notify_baton,
+           svn_cancel_func_t cancel_func,
+           void *cancel_baton,
+           apr_pool_t *pool,
            apr_pool_t *common_pool)
 {
   SVN_ERR(svn_fs__check_fs(fs, FALSE));
@@ -303,7 +309,8 @@ fs_upgrade(svn_fs_t *fs, const char *pat
   SVN_ERR(svn_fs_fs__open(fs, path, pool));
   SVN_ERR(svn_fs_fs__initialize_caches(fs, pool));
   SVN_ERR(fs_serialized_init(fs, common_pool, pool));
-  return svn_fs_fs__upgrade(fs, pool);
+  return svn_fs_fs__upgrade(fs, notify_func, notify_baton,
+                            cancel_func, cancel_baton, pool);
 }
 
 static svn_error_t *

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.c Sun Jun 30 01:03:10 2013
@@ -598,14 +598,27 @@ create_file_ignore_eexist(const char *fi
   return svn_error_trace(err);
 }
 
+/* Baton type bridging svn_fs_fs__upgrade and upgrade_body carrying 
+ * parameters over between them. */
+struct upgrade_baton_t
+{
+  svn_fs_t *fs;
+  svn_fs_upgrade_notify_t notify_func;
+  void *notify_baton;
+  svn_cancel_func_t cancel_func;
+  void *cancel_baton;
+};
+
 static svn_error_t *
 upgrade_body(void *baton, apr_pool_t *pool)
 {
-  svn_fs_t *fs = baton;
+  struct upgrade_baton_t *upgrade_baton = baton;
+  svn_fs_t *fs = upgrade_baton->fs;
   fs_fs_data_t *ffd = fs->fsap_data;
   int format, max_files_per_dir;
   const char *format_path = path_format(fs, pool);
   svn_node_kind_t kind;
+  svn_boolean_t needs_revprop_shard_cleanup = FALSE;
 
   /* Read the FS format number and max-files-per-dir setting. */
   SVN_ERR(read_format(&format, &max_files_per_dir, format_path, pool));
@@ -657,24 +670,64 @@ upgrade_body(void *baton, apr_pool_t *po
   if (format < SVN_FS_FS__MIN_PACKED_FORMAT)
     SVN_ERR(svn_io_file_create(path_min_unpacked_rev(fs, pool), "0\n", pool));
 
-  /* If the file system supports revision packing but not revprop packing,
-     pack the revprops up to the point that revision data has been packed. */
+  /* If the file system supports revision packing but not revprop packing
+     *and* the FS has been sharded, pack the revprops up to the point that
+     revision data has been packed.  However, keep the non-packed revprop
+     files around until after the format bump */
   if (   format >= SVN_FS_FS__MIN_PACKED_FORMAT
-      && format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
-    SVN_ERR(upgrade_pack_revprops(fs, pool));
+      && format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT
+      && max_files_per_dir > 0)
+    {
+      needs_revprop_shard_cleanup = TRUE;
+      SVN_ERR(upgrade_pack_revprops(fs,
+                                    upgrade_baton->notify_func,
+                                    upgrade_baton->notify_baton,
+                                    upgrade_baton->cancel_func,
+                                    upgrade_baton->cancel_baton,
+                                    pool));
+    }
 
   /* Bump the format file. */
 
   ffd->format = SVN_FS_FS__FORMAT_NUMBER;
   ffd->max_files_per_dir = max_files_per_dir;
-  return svn_fs_fs__write_format(fs, TRUE, pool);
+  SVN_ERR(svn_fs_fs__write_format(fs, TRUE, pool));
+  if (upgrade_baton->notify_func)
+    SVN_ERR(upgrade_baton->notify_func(upgrade_baton->notify_baton,
+                                       SVN_FS_FS__FORMAT_NUMBER,
+                                       svn_fs_upgrade_format_bumped,
+                                       pool));
+
+  /* Now, it is safe to remove the redundant revprop files. */
+  if (needs_revprop_shard_cleanup)
+    SVN_ERR(upgrade_cleanup_pack_revprops(fs,
+                                          upgrade_baton->notify_func,
+                                          upgrade_baton->notify_baton,
+                                          upgrade_baton->cancel_func,
+                                          upgrade_baton->cancel_baton,
+                                          pool));
+
+  /* Done */
+  return SVN_NO_ERROR;
 }
 
 
 svn_error_t *
-svn_fs_fs__upgrade(svn_fs_t *fs, apr_pool_t *pool)
-{
-  return svn_fs_fs__with_write_lock(fs, upgrade_body, (void *)fs, pool);
+svn_fs_fs__upgrade(svn_fs_t *fs,
+                   svn_fs_upgrade_notify_t notify_func,
+                   void *notify_baton,
+                   svn_cancel_func_t cancel_func,
+                   void *cancel_baton,
+                   apr_pool_t *pool)
+{
+  struct upgrade_baton_t baton;
+  baton.fs = fs;
+  baton.notify_func = notify_func;
+  baton.notify_baton = notify_baton;
+  baton.cancel_func = cancel_func;
+  baton.cancel_baton = cancel_baton;
+  
+  return svn_fs_fs__with_write_lock(fs, upgrade_body, (void *)&baton, pool);
 }
 
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/fs_fs.h Sun Jun 30 01:03:10 2013
@@ -34,8 +34,15 @@ svn_error_t *svn_fs_fs__open(svn_fs_t *f
                              const char *path,
                              apr_pool_t *pool);
 
-/* Upgrade the fsfs filesystem FS.  Use POOL for temporary allocations. */
+/* Upgrade the fsfs filesystem FS.  Indicate progress via the optional
+ * NOTIFY_FUNC callback using NOTIFY_BATON.  The optional CANCEL_FUNC
+ * will periodically be called with CANCEL_BATON to allow for preemption.
+ * Use POOL for temporary allocations. */
 svn_error_t *svn_fs_fs__upgrade(svn_fs_t *fs,
+                                svn_fs_upgrade_notify_t notify_func,
+                                void *notify_baton,
+                                svn_cancel_func_t cancel_func,
+                                void *cancel_baton,
                                 apr_pool_t *pool);
 
 /* Set *YOUNGEST to the youngest revision in filesystem FS.  Do any

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/pack.c Sun Jun 30 01:03:10 2013
@@ -2339,13 +2339,31 @@ pack_shard(const char *revs_dir,
                             pool));
   ffd->min_unpacked_rev = (svn_revnum_t)((shard + 1) * max_files_per_dir);
 
-  /* Finally, remove the existing shard directories. */
+  /* Finally, remove the existing shard directories.
+   * For revprops, clean up older obsolete shards as well as they might
+   * have been left over from an interrupted FS upgrade. */
   SVN_ERR(svn_io_remove_dir2(rev_shard_path, TRUE,
                              cancel_func, cancel_baton, pool));
   if (revsprops_dir)
-    SVN_ERR(delete_revprops_shard(revprops_shard_path,
-                                  shard, max_files_per_dir,
-                                  cancel_func, cancel_baton, pool));
+    {
+      svn_node_kind_t kind = svn_node_dir;
+      apr_int64_t to_cleanup = shard;
+      do
+        {
+          SVN_ERR(delete_revprops_shard(revprops_shard_path,
+                                        to_cleanup, max_files_per_dir,
+                                        cancel_func, cancel_baton, pool));
+
+          /* If the previous shard exists, clean it up as well.
+             Don't try to clean up shard 0 as it we can't tell quickly
+             whether it actually needs cleaning up. */
+          revprops_shard_path = svn_dirent_join(revsprops_dir,
+                      apr_psprintf(pool, "%" APR_INT64_T_FMT, --to_cleanup),
+                      pool);
+          SVN_ERR(svn_io_check_path(revprops_shard_path, &kind, pool));
+        }
+      while (kind == svn_node_dir && to_cleanup > 0);
+    }
 
   /* Notify caller we're starting to pack this shard. */
   if (notify_func)

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.c Sun Jun 30 01:03:10 2013
@@ -48,11 +48,12 @@
 #define ATOMIC_REVPROP_TIMEOUT    "rev-prop-timeout"
 #define ATOMIC_REVPROP_NAMESPACE  "rev-prop-atomics"
 
-/* In the filesystem FS, pack all revprop shards up to min_unpacked_rev.
- * Use SCRATCH_POOL for temporary allocations.
- */
 svn_error_t *
 upgrade_pack_revprops(svn_fs_t *fs,
+                      svn_fs_upgrade_notify_t notify_func,
+                      void *notify_baton,
+                      svn_cancel_func_t cancel_func,
+                      void *cancel_baton,
                       apr_pool_t *scratch_pool)
 {
   fs_fs_data_t *ffd = fs->fsap_data;
@@ -85,10 +86,37 @@ upgrade_pack_revprops(svn_fs_t *fs,
                                   shard, ffd->max_files_per_dir,
                                   (int)(0.9 * ffd->revprop_pack_size),
                                   compression_level,
-                                  NULL, NULL, iterpool));
+                                  cancel_func, cancel_baton, iterpool));
+      if (notify_func)
+        SVN_ERR(notify_func(notify_baton, shard,
+                            svn_fs_upgrade_pack_revprops, iterpool));
+
       svn_pool_clear(iterpool);
     }
 
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+upgrade_cleanup_pack_revprops(svn_fs_t *fs,
+                              svn_fs_upgrade_notify_t notify_func,
+                              void *notify_baton,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
+                              apr_pool_t *scratch_pool)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  const char *revprops_shard_path;
+  apr_int64_t shard;
+  apr_int64_t first_unpacked_shard
+    =  ffd->min_unpacked_rev / ffd->max_files_per_dir;
+
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  const char *revsprops_dir = svn_dirent_join(fs->path, PATH_REVPROPS_DIR,
+                                              scratch_pool);
+  
   /* delete the non-packed revprops shards afterwards */
   for (shard = 0; shard < first_unpacked_shard; ++shard)
     {
@@ -97,7 +125,11 @@ upgrade_pack_revprops(svn_fs_t *fs,
                        iterpool);
       SVN_ERR(delete_revprops_shard(revprops_shard_path,
                                     shard, ffd->max_files_per_dir,
-                                    NULL, NULL, iterpool));
+                                    cancel_func, cancel_baton, iterpool));
+      if (notify_func)
+        SVN_ERR(notify_func(notify_baton, shard,
+                            svn_fs_upgrade_cleanup_revprops, iterpool));
+
       svn_pool_clear(iterpool);
     }
 
@@ -290,15 +322,17 @@ ensure_revprop_timeout(svn_fs_t *fs)
 }
 
 /* Create an error object with the given MESSAGE and pass it to the
-   WARNING member of FS. */
+   WARNING member of FS. Clears UNDERLYING_ERR. */
 static void
 log_revprop_cache_init_warning(svn_fs_t *fs,
                                svn_error_t *underlying_err,
-                               const char *message)
+                               const char *message,
+                               apr_pool_t *pool)
 {
-  svn_error_t *err = svn_error_createf(SVN_ERR_FS_REVPROP_CACHE_INIT_FAILURE,
-                                       underlying_err,
-                                       message, fs->path);
+  svn_error_t *err = svn_error_createf(
+                       SVN_ERR_FS_REVPROP_CACHE_INIT_FAILURE,
+                       underlying_err, message,
+                       svn_dirent_local_style(fs->path, pool));
 
   if (fs->warning)
     (fs->warning)(fs->warning_baton, err);
@@ -327,7 +361,8 @@ has_revprop_cache(svn_fs_t *fs, apr_pool
       ffd->revprop_cache = NULL;
       log_revprop_cache_init_warning(fs, NULL,
                                      "Revprop caching for '%s' disabled"
-                                     " because it would be inefficient.");
+                                     " because it would be inefficient.",
+                                     pool);
 
       return FALSE;
     }
@@ -342,7 +377,8 @@ has_revprop_cache(svn_fs_t *fs, apr_pool
       log_revprop_cache_init_warning(fs, error,
                                      "Revprop caching for '%s' disabled "
                                      "because SHM infrastructure for revprop "
-                                     "caching failed to initialize.");
+                                     "caching failed to initialize.",
+                                     pool);
 
       return FALSE;
     }
@@ -363,9 +399,9 @@ typedef struct revprop_generation_fixup_
 /* If the revprop generation has an odd value, it means the original writer
    of the revprop got killed. We don't know whether that process as able
    to change the revprop data but we assume that it was. Therefore, we
-   increase the generation in that case to basically invalidate everyones
+   increase the generation in that case to basically invalidate everyone's
    cache content.
-   Execute this onlx while holding the write lock to the repo in baton->FFD.
+   Execute this only while holding the write lock to the repo in baton->FFD.
  */
 static svn_error_t *
 revprop_generation_fixup(void *void_baton,
@@ -699,7 +735,7 @@ parse_packed_revprops(svn_fs_t *fs,
    * length header to remove) */
   svn_stringbuf_t *compressed = revprops->packed_revprops;
   svn_stringbuf_t *uncompressed = svn_stringbuf_create_empty(pool);
-  SVN_ERR(svn__decompress(compressed, uncompressed, 0x1000000));
+  SVN_ERR(svn__decompress(compressed, uncompressed, APR_SIZE_MAX));
 
   /* read first revision number and number of revisions in the pack */
   stream = svn_stream_from_stringbuf(uncompressed, scratch_pool);
@@ -1526,7 +1562,8 @@ copy_revprops(const char *pack_file_dir,
   SVN_ERR(svn_stream_close(pack_stream));
 
   /* compress the content (or just store it for COMPRESSION_LEVEL 0) */
-  SVN_ERR(svn__compress(uncompressed, compressed, compression_level));
+  SVN_ERR(svn__compress(svn_stringbuf__morph_into_string(uncompressed),
+                        compressed, compression_level));
 
   /* write the pack file content to disk */
   stream = svn_stream_from_aprfile2(pack_file, FALSE, scratch_pool);
@@ -1585,6 +1622,9 @@ pack_revprops_shard(const char *pack_fil
   end_rev = (svn_revnum_t) ((shard + 1) * (max_files_per_dir) - 1);
   if (start_rev == 0)
     ++start_rev;
+    /* Special special case: if max_files_per_dir is 1, then at this point
+       start_rev == 1 and end_rev == 0 (!).  Fortunately, everything just
+       works. */
 
   /* initialize the revprop size info */
   sizes = apr_array_make(scratch_pool, max_files_per_dir, sizeof(apr_off_t));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/revprops.h Sun Jun 30 01:03:10 2013
@@ -34,12 +34,41 @@ svn_error_t *
 cleanup_revprop_namespace(svn_fs_t *fs);
 
 /* In the filesystem FS, pack all revprop shards up to min_unpacked_rev.
- * Use SCRATCH_POOL for temporary allocations.
+ * 
+ * NOTE: Keep the old non-packed shards around until after the format bump.
+ * Otherwise, re-running upgrade will drop the packed revprop shard but
+ * have no unpacked data anymore.  Call upgrade_cleanup_pack_revprops after
+ * the bump.
+ * 
+ * NOTIFY_FUNC and NOTIFY_BATON as well as CANCEL_FUNC and CANCEL_BATON are
+ * used in the usual way.  Temporary allocations are done in SCRATCH_POOL.
  */
 svn_error_t *
 upgrade_pack_revprops(svn_fs_t *fs,
+                      svn_fs_upgrade_notify_t notify_func,
+                      void *notify_baton,
+                      svn_cancel_func_t cancel_func,
+                      void *cancel_baton,
                       apr_pool_t *scratch_pool);
 
+/* In the filesystem FS, remove all non-packed revprop shards up to
+ * min_unpacked_rev.  Temporary allocations are done in SCRATCH_POOL.
+ * 
+ * NOTIFY_FUNC and NOTIFY_BATON as well as CANCEL_FUNC and CANCEL_BATON are
+ * used in the usual way.  Cancellation is supported in the sense that we
+ * will cleanly abort the operation.  However, there will be remnant shards
+ * that must be removed manually.
+ *
+ * See upgrade_pack_revprops for more info.
+ */
+svn_error_t *
+upgrade_cleanup_pack_revprops(svn_fs_t *fs,
+                              svn_fs_upgrade_notify_t notify_func,
+                              void *notify_baton,
+                              svn_cancel_func_t cancel_func,
+                              void *cancel_baton,
+                              apr_pool_t *scratch_pool);
+
 /* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
  *
  * Allocations will be done in POOL.

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/transaction.c Sun Jun 30 01:03:10 2013
@@ -1738,7 +1738,12 @@ choose_delta_base(representation_t **rep
                   svn_boolean_t props,
                   apr_pool_t *pool)
 {
+  /* The zero-based index (counting from the "oldest" end), along NODEREVs line
+   * predecessors, of the node-rev we will use as delta base. */
   int count;
+  /* The length of the linear part of a delta chain.  (Delta chains use
+   * skip-delta bits for the high-order bits and are linear in the low-order
+   * bits.) */
   int walk;
   node_revision_t *base;
   fs_fs_data_t *ffd = fs->fsap_data;
@@ -1793,6 +1798,8 @@ choose_delta_base(representation_t **rep
        * Please note that copied nodes - such as branch directories - will
        * look the same (false positive) while reps shared within the same
        * revision will not be caught (false negative).
+       *
+       * Message-ID: <CA...@mail.gmail.com>
        */
       base_revision = svn_fs_fs__id_rev(base->id);
       if (props)
@@ -1810,7 +1817,7 @@ choose_delta_base(representation_t **rep
   /* return a suitable base representation */
   *rep = props ? base->prop_rep : base->data_rep;
 
-  /* if we encountered a shared rep, it's parent chain may be different
+  /* if we encountered a shared rep, its parent chain may be different
    * from the node-rev parent chain. */
   if (*rep && maybe_shared_rep)
     {
@@ -1823,7 +1830,6 @@ choose_delta_base(representation_t **rep
         *rep = NULL;
     }
 
-  /* verify that the reps don't form a degenerated '*/
   return SVN_NO_ERROR;
 }
 
@@ -1941,7 +1947,7 @@ rep_write_get_baton(struct rep_write_bat
   return SVN_NO_ERROR;
 }
 
-/* For the hash REP->SHA1, try to find an already existing representation
+/* For REP->SHA1_CHECKSUM, try to find an already existing representation
    in FS and return it in *OUT_REP.  If no such representation exists or
    if rep sharing has been disabled for FS, NULL will be returned.  Since
    there may be new duplicate representations within the same uncommitted

Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c Sun Jun 30 01:03:10 2013
@@ -144,7 +144,7 @@ typedef struct cache_entry_t
 {
   /* hash value derived from PATH, REVISION.
      Used to short-circuit failed lookups. */
-  long int hash_value;
+  apr_uint32_t hash_value;
 
   /* revision to which the NODE belongs */
   svn_revnum_t revision;
@@ -333,7 +333,12 @@ cache_lookup( fs_fs_dag_cache_t *cache
 {
   apr_size_t i, bucket_index;
   apr_size_t path_len = strlen(path);
-  long int hash_value = revision;
+  apr_uint32_t hash_value = (apr_uint32_t)revision;
+
+#if SVN_UNALIGNED_ACCESS_IS_OK
+  /* "randomizing" / distributing factor used in our hash function */
+  const apr_uint32_t factor = 0xd1f3da69;
+#endif
 
   /* optimistic lookup: hit the same bucket again? */
   cache_entry_t *result = &cache->buckets[cache->last_hit];
@@ -346,11 +351,25 @@ cache_lookup( fs_fs_dag_cache_t *cache
 
   /* need to do a full lookup.  Calculate the hash value
      (HASH_VALUE has been initialized to REVISION). */
-  for (i = 0; i + 4 <= path_len; i += 4)
-    hash_value = hash_value * 0xd1f3da69 + *(const apr_uint32_t*)(path + i);
+  i = 0;
+#if SVN_UNALIGNED_ACCESS_IS_OK
+  /* We relax the dependency chain between iterations by processing
+     two chunks from the input per hash_value self-multiplication.
+     The HASH_VALUE update latency is now 1 MUL latency + 1 ADD latency
+     per 2 chunks instead of 1 chunk.
+   */
+  for (; i + 8 <= path_len; i += 8)
+    hash_value = hash_value * factor * factor
+               + (  *(const apr_uint32_t*)(path + i) * factor
+                  + *(const apr_uint32_t*)(path + i + 4));
+#endif
 
   for (; i < path_len; ++i)
-    hash_value = hash_value * 33 + path[i];
+    /* Help GCC to minimize the HASH_VALUE update latency by splitting the
+       MUL 33 of the naive implementation: h = h * 33 + path[i].  This
+       shortens the dependency chain from 1 shift + 2 ADDs to 1 shift + 1 ADD.
+     */
+    hash_value = hash_value * 32 + (hash_value + (unsigned char)path[i]);
 
   bucket_index = hash_value + (hash_value >> 16);
   bucket_index = (bucket_index + (bucket_index >> 8)) % BUCKET_COUNT;
@@ -3349,6 +3368,14 @@ fs_node_origin_rev(svn_revnum_t *revisio
       return SVN_NO_ERROR;
     }
 
+  /* The root node always has ID 0, created in revision 0 and will never
+     use the new-style ID format. */
+  if (strcmp(node_id, "0") == 0)
+    {
+      *revision = 0;
+      return SVN_NO_ERROR;
+    }
+
   /* OK, it's an old-style ID?  Maybe it's cached. */
   SVN_ERR(svn_fs_fs__get_node_origin(&cached_origin_id,
                                      fs,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c Sun Jun 30 01:03:10 2013
@@ -1030,6 +1030,13 @@ svn_error_t *svn_ra_get_file_revs2(svn_r
   if (include_merged_revisions)
     SVN_ERR(svn_ra__assert_mergeinfo_capable_server(session, NULL, pool));
 
+  if (start > end)
+    SVN_ERR(
+     svn_ra__assert_capable_server(session,
+                                   SVN_RA_CAPABILITY_GET_FILE_REVS_REVERSE,
+                                   NULL,
+                                   pool));
+
   err = session->vtable->get_file_revs(session, path, start, end,
                                        include_merged_revisions,
                                        handler, handler_baton, pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/util.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/util.c Sun Jun 30 01:03:10 2013
@@ -69,6 +69,31 @@ svn_ra__assert_mergeinfo_capable_server(
   return SVN_NO_ERROR;
 }
 
+svn_error_t *
+svn_ra__assert_capable_server(svn_ra_session_t *ra_session,
+                              const char *capability,
+                              const char *path_or_url,
+                              apr_pool_t *pool)
+{
+  if (!strcmp(capability, SVN_RA_CAPABILITY_MERGEINFO))
+    return svn_ra__assert_mergeinfo_capable_server(ra_session, path_or_url,
+                                                   pool);
+
+  else
+    {
+      svn_boolean_t has;
+      SVN_ERR(svn_ra_has_capability(ra_session, &has, capability, pool));
+      if (! has)
+        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                               _("The '%s' feature is not supported by '%s'"),
+                               capability,
+                               svn_path_is_url(path_or_url)
+                                  ? path_or_url
+                                  : svn_dirent_local_style(path_or_url, pool));
+    }
+  return SVN_NO_ERROR;
+}
+
 /* Does ERR mean "the current value of the revprop isn't equal to
    the *OLD_VALUE_P you gave me"?
  */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/blame.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/blame.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/blame.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/blame.c Sun Jun 30 01:03:10 2013
@@ -332,6 +332,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   svn_ra_serf__xml_context_t *xmlctx;
   const char *req_url;
   svn_error_t *err;
+  svn_revnum_t peg_rev;
 
   blame_ctx = apr_pcalloc(pool, sizeof(*blame_ctx));
   blame_ctx->pool = pool;
@@ -342,9 +343,16 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   blame_ctx->end = end;
   blame_ctx->include_merged_revisions = include_merged_revisions;
 
+  /* Since Subversion 1.8 we allow retrieving blames backwards. So we can't
+     just unconditionally use end_rev as the peg revision as before */
+  if (end > start)
+    peg_rev = end;
+  else
+    peg_rev = start;
+
   SVN_ERR(svn_ra_serf__get_stable_url(&req_url, NULL /* latest_revnum */,
                                       session, NULL /* conn */,
-                                      NULL /* url */, end,
+                                      NULL /* url */, peg_rev,
                                       pool, pool));
 
   xmlctx = svn_ra_serf__xml_context_create(blame_ttable,
@@ -366,7 +374,7 @@ svn_ra_serf__get_file_revs(svn_ra_sessio
   err = svn_ra_serf__context_run_one(handler, pool);
 
   err = svn_error_compose_create(
-            svn_ra_serf__error_on_status(handler->sline.code,
+            svn_ra_serf__error_on_status(handler->sline,
                                          handler->path,
                                          handler->location),
             err);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c Sun Jun 30 01:03:10 2013
@@ -223,7 +223,7 @@ return_response_err(svn_ra_serf__handler
   /* Try to return one of the standard errors for 301, 404, etc.,
      then look for an error embedded in the response.  */
   return svn_error_compose_create(svn_ra_serf__error_on_status(
-                                    handler->sline.code,
+                                    handler->sline,
                                     handler->path,
                                     handler->location),
                                   err);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getdate.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getdate.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getdate.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getdate.c Sun Jun 30 01:03:10 2013
@@ -131,6 +131,7 @@ svn_ra_serf__get_dated_revision(svn_ra_s
   svn_ra_serf__handler_t *handler;
   svn_ra_serf__xml_context_t *xmlctx;
   const char *report_target;
+  svn_error_t *err;
 
   date_ctx = apr_palloc(pool, sizeof(*date_ctx));
   date_ctx->time = tm;
@@ -155,7 +156,15 @@ svn_ra_serf__get_dated_revision(svn_ra_s
 
   *date_ctx->revision = SVN_INVALID_REVNUM;
 
-  /* ### use svn_ra_serf__error_on_status() ?  */
+  err = svn_ra_serf__context_run_one(handler, pool);
 
-  return svn_error_trace(svn_ra_serf__context_run_one(handler, pool));
+  SVN_ERR(svn_error_compose_create(
+              svn_ra_serf__error_on_status(handler->sline,
+                                           report_target,
+                                           handler->location),
+              err));
+
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*revision));
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocations.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocations.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocations.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocations.c Sun Jun 30 01:03:10 2013
@@ -192,7 +192,7 @@ svn_ra_serf__get_locations(svn_ra_sessio
   err = svn_ra_serf__context_run_one(handler, pool);
 
   SVN_ERR(svn_error_compose_create(
-              svn_ra_serf__error_on_status(handler->sline.code,
+              svn_ra_serf__error_on_status(handler->sline,
                                            req_url,
                                            handler->location),
               err));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocationsegments.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocationsegments.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocationsegments.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocationsegments.c Sun Jun 30 01:03:10 2013
@@ -194,7 +194,7 @@ svn_ra_serf__get_location_segments(svn_r
   err = svn_ra_serf__context_run_one(handler, pool);
 
   err = svn_error_compose_create(
-         svn_ra_serf__error_on_status(handler->sline.code,
+         svn_ra_serf__error_on_status(handler->sline,
                                       handler->path,
                                       handler->location),
          err);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocks.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocks.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocks.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/getlocks.c Sun Jun 30 01:03:10 2013
@@ -266,7 +266,7 @@ svn_ra_serf__get_locks(svn_ra_session_t 
      have existed earlier (E.g. 'svn ls http://s/svn/trunk/file@1' */
   if (handler->sline.code != 404)
     {
-      SVN_ERR(svn_ra_serf__error_on_status(handler->sline.code,
+      SVN_ERR(svn_ra_serf__error_on_status(handler->sline,
                                            handler->path,
                                            handler->location));
     }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/inherited_props.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/inherited_props.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/inherited_props.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/inherited_props.c Sun Jun 30 01:03:10 2013
@@ -41,7 +41,7 @@
 
 /* The current state of our XML parsing. */
 typedef enum iprops_state_e {
-  NONE = 0,
+  INITIAL = 0,
   IPROPS_REPORT,
   IPROPS_ITEM,
   IPROPS_PATH,
@@ -61,18 +61,12 @@ typedef struct iprops_context_t {
   /* The repository's root URL. */
   const char *repos_root_url;
 
-  /* Current CDATA values*/
-  svn_stringbuf_t *curr_path;
+  /* Current property name */
   svn_stringbuf_t *curr_propname;
-  svn_stringbuf_t *curr_propval;
-  const char *curr_prop_val_encoding;
 
   /* Current element in IPROPS. */
   svn_prop_inherited_item_t *curr_iprop;
 
-  /* Serf context completion flag for svn_ra_serf__context_run_wait() */
-  svn_boolean_t done;
-
   /* Path we are finding inherited properties for.  This is relative to
      the RA session passed to svn_ra_serf__get_inherited_props. */
   const char *path;
@@ -80,162 +74,121 @@ typedef struct iprops_context_t {
   svn_revnum_t revision;
 } iprops_context_t;
 
+#define S_ SVN_XML_NAMESPACE
+static const svn_ra_serf__xml_transition_t iprops_table[] = {
+  { INITIAL, S_, SVN_DAV__INHERITED_PROPS_REPORT, IPROPS_REPORT,
+    FALSE, { NULL }, FALSE },
+
+  { IPROPS_REPORT, S_, SVN_DAV__IPROP_ITEM, IPROPS_ITEM,
+    FALSE, { NULL }, TRUE },
+
+  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PATH, IPROPS_PATH,
+    TRUE, { NULL }, TRUE },
+
+  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPNAME, IPROPS_PROPNAME,
+    TRUE, { NULL }, TRUE },
+
+  { IPROPS_ITEM, S_, SVN_DAV__IPROP_PROPVAL, IPROPS_PROPVAL,
+    TRUE, { "?V:encoding", NULL }, TRUE },
+
+  { 0 }
+};
+
+/* Conforms to svn_ra_serf__xml_opened_t */
 static svn_error_t *
-start_element(svn_ra_serf__xml_parser_t *parser,
-              svn_ra_serf__dav_props_t name,
-              const char **attrs,
+iprops_opened(svn_ra_serf__xml_estate_t *xes,
+              void *baton,
+              int entered_state,
+              const svn_ra_serf__dav_props_t *tag,
               apr_pool_t *scratch_pool)
 {
-  iprops_context_t *iprops_ctx = parser->user_data;
-  iprops_state_e state;
+  iprops_context_t *iprops_ctx = baton;
 
-  state = parser->state->current_state;
-  if (state == NONE
-      && strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
+  if (entered_state == IPROPS_ITEM)
     {
-      svn_ra_serf__xml_push_state(parser, IPROPS_REPORT);
-    }
-  else if (state == IPROPS_REPORT &&
-           strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
-    {
-      svn_stringbuf_setempty(iprops_ctx->curr_path);
       svn_stringbuf_setempty(iprops_ctx->curr_propname);
-      svn_stringbuf_setempty(iprops_ctx->curr_propval);
-      iprops_ctx->curr_prop_val_encoding = NULL;
-      iprops_ctx->curr_iprop = NULL;
-      svn_ra_serf__xml_push_state(parser, IPROPS_ITEM);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
-    {
-      const char *prop_val_encoding = svn_xml_get_attr_value("encoding",
-                                                             attrs);
-      iprops_ctx->curr_prop_val_encoding = apr_pstrdup(iprops_ctx->pool,
-                                                       prop_val_encoding);
-      svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, IPROPS_PATH);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, IPROPS_PROPNAME);
-    }
-  else if (state == IPROPS_ITEM &&
-           strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
-    {
-      svn_ra_serf__xml_push_state(parser, IPROPS_PROPVAL);
-    }
 
+      iprops_ctx->curr_iprop = apr_pcalloc(iprops_ctx->pool,
+                                           sizeof(*iprops_ctx->curr_iprop));
+
+      iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
+    }
   return SVN_NO_ERROR;
 }
 
+/* Conforms to svn_ra_serf__xml_closed_t  */
 static svn_error_t *
-end_element(svn_ra_serf__xml_parser_t *parser,
-            svn_ra_serf__dav_props_t name,
-            apr_pool_t *scratch_pool)
+iprops_closed(svn_ra_serf__xml_estate_t *xes,
+              void *baton,
+              int leaving_state,
+              const svn_string_t *cdata,
+              apr_hash_t *attrs,
+              apr_pool_t *scratch_pool)
 {
-  iprops_context_t *iprops_ctx = parser->user_data;
-  iprops_state_e state;
-
-  state = parser->state->current_state;
+  iprops_context_t *iprops_ctx = baton;
 
-    if (state == IPROPS_REPORT &&
-      strcmp(name.name, SVN_DAV__INHERITED_PROPS_REPORT) == 0)
+  if (leaving_state == IPROPS_ITEM)
     {
-      svn_ra_serf__xml_pop_state(parser);
+      APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
+        iprops_ctx->curr_iprop;
+
+      iprops_ctx->curr_iprop = NULL;
     }
-  else if (state == IPROPS_PATH
-           && strcmp(name.name, SVN_DAV__IPROP_PATH) == 0)
+  else if (leaving_state == IPROPS_PATH)
     {
-      iprops_ctx->curr_iprop = apr_palloc(
-        iprops_ctx->pool, sizeof(svn_prop_inherited_item_t));
+      /* Every <iprop-item> has a single <iprop-path> */
+      if (iprops_ctx->curr_iprop->path_or_url)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
 
       iprops_ctx->curr_iprop->path_or_url =
         svn_path_url_add_component2(iprops_ctx->repos_root_url,
-                                    iprops_ctx->curr_path->data,
+                                    cdata->data,
                                     iprops_ctx->pool);
-      iprops_ctx->curr_iprop->prop_hash = apr_hash_make(iprops_ctx->pool);
-      svn_ra_serf__xml_pop_state(parser);
     }
-  else if (state == IPROPS_PROPVAL
-           && strcmp(name.name, SVN_DAV__IPROP_PROPVAL) == 0)
+  else if (leaving_state == IPROPS_PROPNAME)
     {
-      const svn_string_t *prop_val;
+      if (iprops_ctx->curr_propname->len)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
 
-      if (iprops_ctx->curr_prop_val_encoding)
-        {
-          svn_string_t encoded_prop_val;
+      /* Store propname for value */
+      svn_stringbuf_set(iprops_ctx->curr_propname, cdata->data);
+    }
+  else if (leaving_state == IPROPS_PROPVAL)
+    {
+      const char *encoding;
+      const svn_string_t *val_str;
+
+      if (! iprops_ctx->curr_propname->len)
+        return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+
+      encoding = svn_hash_gets(attrs, "V:encoding");
 
-          if (strcmp(iprops_ctx->curr_prop_val_encoding, "base64") != 0)
-            return svn_error_create(SVN_ERR_XML_MALFORMED, NULL, NULL);
+      if (encoding)
+        {
+          if (strcmp(encoding, "base64") != 0)
+            return svn_error_createf(SVN_ERR_XML_MALFORMED,
+                                     NULL,
+                                     _("Got unrecognized encoding '%s'"),
+                                     encoding);
 
-          encoded_prop_val.data = iprops_ctx->curr_propval->data;
-          encoded_prop_val.len = iprops_ctx->curr_propval->len;
-          prop_val = svn_base64_decode_string(&encoded_prop_val,
-                                              iprops_ctx->pool);
+          /* Decode into the right pool.  */
+          val_str = svn_base64_decode_string(cdata, iprops_ctx->pool);
         }
       else
         {
-          prop_val = svn_string_create_from_buf(iprops_ctx->curr_propval,
-                                                iprops_ctx->pool);
+          /* Copy into the right pool.  */
+          val_str = svn_string_dup(cdata, iprops_ctx->pool);
         }
 
       svn_hash_sets(iprops_ctx->curr_iprop->prop_hash,
                     apr_pstrdup(iprops_ctx->pool,
                                 iprops_ctx->curr_propname->data),
-                    prop_val);
-      /* Clear current propname and propval in the event there are
-         multiple properties on the current path. */
+                    val_str);
+      /* Clear current propname. */
       svn_stringbuf_setempty(iprops_ctx->curr_propname);
-      svn_stringbuf_setempty(iprops_ctx->curr_propval);
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == IPROPS_PROPNAME
-           && strcmp(name.name, SVN_DAV__IPROP_PROPNAME) == 0)
-    {
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  else if (state == IPROPS_ITEM
-           && strcmp(name.name, SVN_DAV__IPROP_ITEM) == 0)
-    {
-      APR_ARRAY_PUSH(iprops_ctx->iprops, svn_prop_inherited_item_t *) =
-        iprops_ctx->curr_iprop;
-      svn_ra_serf__xml_pop_state(parser);
-    }
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-cdata_handler(svn_ra_serf__xml_parser_t *parser,
-              const char *data,
-              apr_size_t len,
-              apr_pool_t *scratch_pool)
-{
-  iprops_context_t *iprops_ctx = parser->user_data;
-  iprops_state_e state = parser->state->current_state;
-
-  switch (state)
-    {
-    case IPROPS_PATH:
-      svn_stringbuf_appendbytes(iprops_ctx->curr_path, data, len);
-      break;
-
-    case IPROPS_PROPNAME:
-      svn_stringbuf_appendbytes(iprops_ctx->curr_propname, data, len);
-      break;
-
-    case IPROPS_PROPVAL:
-      svn_stringbuf_appendbytes(iprops_ctx->curr_propval, data, len);
-      break;
-
-    default:
-      break;
     }
+  else
+    SVN_ERR_MALFUNCTION(); /* Invalid transition table */
 
   return SVN_NO_ERROR;
 }
@@ -281,7 +234,7 @@ svn_ra_serf__get_inherited_props(svn_ra_
   iprops_context_t *iprops_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
-  svn_ra_serf__xml_parser_t *parser_ctx;
+  svn_ra_serf__xml_context_t *xmlctx;
   const char *req_url;
 
   SVN_ERR(svn_ra_serf__get_stable_url(&req_url,
@@ -295,19 +248,20 @@ svn_ra_serf__get_inherited_props(svn_ra_
   SVN_ERR_ASSERT(session->repos_root_str);
 
   iprops_ctx = apr_pcalloc(scratch_pool, sizeof(*iprops_ctx));
-  iprops_ctx->done = FALSE;
   iprops_ctx->repos_root_url = session->repos_root_str;
   iprops_ctx->pool = result_pool;
-  iprops_ctx->curr_path = svn_stringbuf_create_empty(scratch_pool);
   iprops_ctx->curr_propname = svn_stringbuf_create_empty(scratch_pool);
-  iprops_ctx->curr_propval = svn_stringbuf_create_empty(scratch_pool);
   iprops_ctx->curr_iprop = NULL;
   iprops_ctx->iprops = apr_array_make(result_pool, 1,
                                        sizeof(svn_prop_inherited_item_t *));
   iprops_ctx->path = path;
   iprops_ctx->revision = revision;
 
-  handler = apr_pcalloc(scratch_pool, sizeof(*handler));
+  xmlctx = svn_ra_serf__xml_context_create(iprops_table,
+                                           iprops_opened, iprops_closed, NULL,
+                                           iprops_ctx,
+                                           scratch_pool);
+  handler = svn_ra_serf__create_expat_handler(xmlctx, scratch_pool);
 
   handler->method = "REPORT";
   handler->path = req_url;
@@ -318,27 +272,14 @@ svn_ra_serf__get_inherited_props(svn_ra_
   handler->body_type = "text/xml";
   handler->handler_pool = scratch_pool;
 
-  parser_ctx = apr_pcalloc(scratch_pool, sizeof(*parser_ctx));
-
-  parser_ctx->pool = scratch_pool;
-  parser_ctx->user_data = iprops_ctx;
-  parser_ctx->start = start_element;
-  parser_ctx->end = end_element;
-  parser_ctx->cdata = cdata_handler;
-  parser_ctx->done = &iprops_ctx->done;
-
-  handler->response_handler = svn_ra_serf__handle_xml_parser;
-  handler->response_baton = parser_ctx;
-
   err = svn_ra_serf__context_run_one(handler, scratch_pool);
   SVN_ERR(svn_error_compose_create(
-                    svn_ra_serf__error_on_status(handler->sline.code,
+                    svn_ra_serf__error_on_status(handler->sline,
                                                  handler->path,
                                                  handler->location),
                     err));
 
-  if (iprops_ctx->done)
-    *iprops = iprops_ctx->iprops;
+  *iprops = iprops_ctx->iprops;
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/log.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/log.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/log.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/log.c Sun Jun 30 01:03:10 2013
@@ -595,7 +595,7 @@ svn_ra_serf__get_log(svn_ra_session_t *r
   err = svn_ra_serf__context_run_one(handler, pool);
 
   SVN_ERR(svn_error_compose_create(
-              svn_ra_serf__error_on_status(handler->sline.code,
+              svn_ra_serf__error_on_status(handler->sline,
                                            req_url,
                                            handler->location),
               err));

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/mergeinfo.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/mergeinfo.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/mergeinfo.c Sun Jun 30 01:03:10 2013
@@ -191,7 +191,7 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
                            svn_boolean_t include_descendants,
                            apr_pool_t *pool)
 {
-  svn_error_t *err, *err2;
+  svn_error_t *err;
   mergeinfo_context_t *mergeinfo_ctx;
   svn_ra_serf__session_t *session = ra_session->priv;
   svn_ra_serf__handler_t *handler;
@@ -229,15 +229,10 @@ svn_ra_serf__get_mergeinfo(svn_ra_sessio
 
   err = svn_ra_serf__context_run_one(handler, pool);
 
-  err2 = svn_ra_serf__error_on_status(handler->sline.code, handler->path,
-                                      handler->location);
-  if (err2)
-    {
-      svn_error_clear(err);
-      return err2;
-    }
-
-  SVN_ERR(err);
+  SVN_ERR(svn_error_compose_create(
+                svn_ra_serf__error_on_status(handler->sline, handler->path,
+                                             handler->location),
+                err));
 
   if (handler->done && apr_hash_count(mergeinfo_ctx->result_catalog))
     *catalog = mergeinfo_ctx->result_catalog;

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c Sun Jun 30 01:03:10 2013
@@ -436,11 +436,12 @@ svn_ra_serf__v2_get_youngest_revnum(svn_
 
   SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
   SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
-  SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
+  SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline,
                                        opt_ctx->handler->path,
                                        opt_ctx->handler->location));
 
   *youngest = opt_ctx->youngest_rev;
+  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(*youngest));
 
   return SVN_NO_ERROR;
 }
@@ -460,7 +461,7 @@ svn_ra_serf__v1_get_activity_collection(
   SVN_ERR(create_options_req(&opt_ctx, session, conn, scratch_pool));
   SVN_ERR(svn_ra_serf__context_run_one(opt_ctx->handler, scratch_pool));
 
-  SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
+  SVN_ERR(svn_ra_serf__error_on_status(opt_ctx->handler->sline,
                                        opt_ctx->handler->path,
                                        opt_ctx->handler->location));
 
@@ -499,7 +500,7 @@ svn_ra_serf__exchange_capabilities(svn_r
     }
 
   SVN_ERR(svn_error_compose_create(
-              svn_ra_serf__error_on_status(opt_ctx->handler->sline.code,
+              svn_ra_serf__error_on_status(opt_ctx->handler->sline,
                                            serf_sess->session_url.path,
                                            opt_ctx->handler->location),
               err));
@@ -517,6 +518,74 @@ svn_ra_serf__exchange_capabilities(svn_r
 }
 
 
+static svn_error_t *
+create_simple_options_body(serf_bucket_t **body_bkt,
+                           void *baton,
+                           serf_bucket_alloc_t *alloc,
+                           apr_pool_t *pool)
+{
+  serf_bucket_t *body;
+  serf_bucket_t *s;
+
+  body = serf_bucket_aggregate_create(alloc);
+  svn_ra_serf__add_xml_header_buckets(body, alloc);
+
+  s = SERF_BUCKET_SIMPLE_STRING("<D:options xmlns:D=\"DAV:\" />", alloc);
+  serf_bucket_aggregate_append(body, s);
+
+  *body_bkt = body;
+  return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
+                         apr_pool_t *scratch_pool)
+{
+  svn_ra_serf__handler_t *handler;
+  svn_error_t *err;
+
+  handler = apr_pcalloc(scratch_pool, sizeof(*handler));
+  handler->handler_pool = scratch_pool;
+  handler->method = "OPTIONS";
+  handler->path = serf_sess->session_url.path;
+  handler->conn = serf_sess->conns[0];
+  handler->session = serf_sess;
+
+  /* We don't care about the response body, so discard it.  */
+  handler->response_handler = svn_ra_serf__handle_discard_body;
+
+  /* We need a simple body, in order to send it in chunked format.  */
+  handler->body_delegate = create_simple_options_body;
+
+  /* No special headers.  */
+
+  err = svn_ra_serf__context_run_one(handler, scratch_pool);
+  if (err)
+    {
+      /* Some versions of nginx in reverse proxy mode will return 411. They want
+         a Content-Length header, rather than chunked requests. We can keep other
+         HTTP/1.1 features, but will disable the chunking.  */
+      if (handler->sline.code == 411)
+        {
+          serf_sess->using_chunked_requests = FALSE;
+
+          svn_error_clear(err);
+          return SVN_NO_ERROR;
+        }
+
+      return svn_error_trace(
+        svn_error_compose_create(
+          svn_ra_serf__error_on_status(handler->sline,
+                                       serf_sess->session_url.path,
+                                       handler->location),
+          err));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
 svn_ra_serf__has_capability(svn_ra_session_t *ra_session,
                             svn_boolean_t *has,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c Sun Jun 30 01:03:10 2013
@@ -635,7 +635,7 @@ svn_ra_serf__wait_for_props(svn_ra_serf_
 
   err = svn_ra_serf__context_run_one(handler, scratch_pool);
 
-  err2 = svn_ra_serf__error_on_status(handler->sline.code,
+  err2 = svn_ra_serf__error_on_status(handler->sline,
                                       handler->path,
                                       handler->location);
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h Sun Jun 30 01:03:10 2013
@@ -144,6 +144,9 @@ struct svn_ra_serf__session_t {
      HTTP/1.0. Thus, we cannot send chunked requests.  */
   svn_boolean_t http10;
 
+  /* Should we use Transfer-Encoding: chunked for HTTP/1.1 servers. */
+  svn_boolean_t using_chunked_requests;
+
   /* Our Version-Controlled-Configuration; may be NULL until we know it. */
   const char *vcc_url;
 
@@ -186,7 +189,11 @@ struct svn_ra_serf__session_t {
   const char *activity_collection_url;
 
   /* Are we using a proxy? */
-  int using_proxy;
+  svn_boolean_t using_proxy;
+
+  /* Should we be careful with this proxy? (some have insufficient support that
+     we need to work around).  */
+  svn_boolean_t busted_proxy;
 
   const char *proxy_username;
   const char *proxy_password;
@@ -1334,6 +1341,14 @@ svn_ra_serf__run_merge(const svn_commit_
 
 /** OPTIONS-related functions **/
 
+/* When running with a proxy, we may need to detect and correct for problems.
+   This probing function will send a simple OPTIONS request to detect problems
+   with the connection.  */
+svn_error_t *
+svn_ra_serf__probe_proxy(svn_ra_serf__session_t *serf_sess,
+                         apr_pool_t *scratch_pool);
+
+
 /* On HTTPv2 connections, run an OPTIONS request over CONN to fetch the
    current youngest revnum, returning it in *YOUNGEST.
 
@@ -1744,7 +1759,7 @@ svn_ra_serf__credentials_callback(char *
  * where it necessary.
  */
 svn_error_t *
-svn_ra_serf__error_on_status(int status_code,
+svn_ra_serf__error_on_status(serf_status_line sline,
                              const char *path,
                              const char *location);
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c Sun Jun 30 01:03:10 2013
@@ -696,7 +696,7 @@ svn_ra_serf__replay(svn_ra_session_t *ra
   err = svn_ra_serf__context_run_wait(&replay_ctx->done, session, pool);
 
   SVN_ERR(svn_error_compose_create(
-              svn_ra_serf__error_on_status(handler->sline.code,
+              svn_ra_serf__error_on_status(handler->sline,
                                            handler->path,
                                            handler->location),
               err));
@@ -905,7 +905,7 @@ svn_ra_serf__replay_range(svn_ra_session
           svn_ra_serf__handler_t *done_handler = ctx->report_handler;
 
           done_list = done_list->next;
-          SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline.code,
+          SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline,
                                                done_handler->path,
                                                done_handler->location));
           svn_pool_destroy(ctx->src_rev_pool);

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c Sun Jun 30 01:03:10 2013
@@ -225,6 +225,12 @@ load_config(svn_ra_serf__session_t *sess
                                SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
                                SVN_CONFIG_DEFAULT_OPTION_HTTP_MAX_CONNECTIONS));
 
+  /* Is this proxy potentially busted? Do we need to take special care?  */
+  SVN_ERR(svn_config_get_bool(config, &session->busted_proxy,
+                              SVN_CONFIG_SECTION_GLOBAL,
+                              SVN_CONFIG_OPTION_BUSTED_PROXY,
+                              FALSE));
+
   if (config)
     server_group = svn_config_find_group(config,
                                          session->session_url.hostname,
@@ -281,6 +287,13 @@ load_config(svn_ra_serf__session_t *sess
                                    server_group,
                                    SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
                                    session->max_connections));
+
+      /* Do we need to take care with this proxy?  */
+      SVN_ERR(svn_config_get_bool(
+               config, &session->busted_proxy,
+               server_group,
+               SVN_CONFIG_OPTION_BUSTED_PROXY,
+               session->busted_proxy));
     }
 
   /* Don't allow the http-max-connections value to be larger than our
@@ -392,6 +405,7 @@ svn_ra_serf__open(svn_ra_session_t *sess
   svn_ra_serf__session_t *serf_sess;
   apr_uri_t url;
   const char *client_string = NULL;
+  svn_error_t *err;
 
   if (corrected_url)
     *corrected_url = NULL;
@@ -441,6 +455,10 @@ svn_ra_serf__open(svn_ra_session_t *sess
      HTTP/1.1 is supported, we can upgrade. */
   serf_sess->http10 = TRUE;
 
+  /* If we switch to HTTP/1.1, then we will use chunked requests. We may disable
+     this, if we find an intervening proxy does not support chunked requests.  */
+  serf_sess->using_chunked_requests = TRUE;
+
   SVN_ERR(load_config(serf_sess, config, serf_sess->pool));
 
   serf_sess->conns[0] = apr_pcalloc(serf_sess->pool,
@@ -479,7 +497,21 @@ svn_ra_serf__open(svn_ra_session_t *sess
 
   session->priv = serf_sess;
 
-  return svn_ra_serf__exchange_capabilities(serf_sess, corrected_url, pool);
+  err = svn_ra_serf__exchange_capabilities(serf_sess, corrected_url, pool);
+
+  /* serf should produce a usable error code instead of APR_EGENERAL */
+  if (err && err->apr_err == APR_EGENERAL)
+    err = svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, err,
+                            _("Connection to '%s' failed"), session_URL);
+  SVN_ERR(err);
+
+  /* We have set up a useful connection. If we've been told there is possibly a
+     busted proxy in our path to the server AND we switched to HTTP/1.1 (chunked
+     requests), then probe for problems in any proxy.  */
+  if (serf_sess->busted_proxy && !serf_sess->http10)
+    SVN_ERR(svn_ra_serf__probe_proxy(serf_sess, pool));
+
+  return SVN_NO_ERROR;
 }
 
 /* Implements svn_ra__vtable_t.reparent(). */

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c Sun Jun 30 01:03:10 2013
@@ -1268,7 +1268,7 @@ handle_stream(serf_request_t *request,
   /* ### new field. make sure we didn't miss some initialization.  */
   SVN_ERR_ASSERT(fetch_ctx->handler != NULL);
 
-  err = svn_ra_serf__error_on_status(fetch_ctx->handler->sline.code,
+  err = svn_ra_serf__error_on_status(fetch_ctx->handler->sline,
                                      fetch_ctx->info->name,
                                      fetch_ctx->handler->location);
   if (err)
@@ -2739,7 +2739,7 @@ setup_update_report_headers(serf_bucket_
   if (report->sess->using_compression)
     {
       serf_bucket_headers_setn(headers, "Accept-Encoding",
-                               "gzip;svndiff1;q=0.9,svndiff;q=0.8");
+                               "gzip,svndiff1;q=0.9,svndiff;q=0.8");
     }
   else
     {
@@ -2891,7 +2891,7 @@ finish_report(void *report_baton,
         {
           return svn_error_trace(
                     svn_error_compose_create(
-                        svn_ra_serf__error_on_status(handler->sline.code,
+                        svn_ra_serf__error_on_status(handler->sline,
                                                      handler->path,
                                                      handler->location),
                         err));
@@ -3250,6 +3250,14 @@ make_update_reporter(svn_ra_session_t *r
              supports inlining properties in update editor report. */
           if (sess->supports_inline_props)
             {
+              /* NOTE: both inlined properties and server->allows_bulk_update
+                 (flag SVN_DAV_ALLOW_BULK_UPDATES) were added in 1.8.0, so
+                 this code is never reached with a released version of
+                 mod_dav_svn.
+
+                 Basically by default a 1.8.0 client connecting to a 1.7.x or
+                 older server will always use bulk updates. */
+
               /* Inline props supported: do not use bulk updates. */
               use_bulk_updates = FALSE;
             }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c Sun Jun 30 01:03:10 2013
@@ -641,8 +641,9 @@ setup_serf_req(serf_request_t *request,
   serf_bucket_alloc_t *allocator = serf_request_get_alloc(request);
 
   svn_spillbuf_t *buf;
+  svn_boolean_t set_CL = session->http10 || !session->using_chunked_requests;
 
-  if (session->http10 && body_bkt != NULL)
+  if (set_CL && body_bkt != NULL)
     {
       /* Ugh. Use HTTP/1.0 to talk to the server because we don't know if
          it speaks HTTP/1.1 (and thus, chunked requests), or because the
@@ -670,7 +671,7 @@ setup_serf_req(serf_request_t *request,
 
   /* Set the Content-Length value. This will also trigger an HTTP/1.0
      request (rather than the default chunked request).  */
-  if (session->http10)
+  if (set_CL)
     {
       if (body_bkt == NULL)
         serf_bucket_request_set_CL(*req_bkt, 0);
@@ -2386,17 +2387,17 @@ svn_ra_serf__report_resource(const char 
 }
 
 svn_error_t *
-svn_ra_serf__error_on_status(int status_code,
+svn_ra_serf__error_on_status(serf_status_line sline,
                              const char *path,
                              const char *location)
 {
-  switch(status_code)
+  switch(sline.code)
     {
       case 301:
       case 302:
       case 307:
         return svn_error_createf(SVN_ERR_RA_DAV_RELOCATED, NULL,
-                                 (status_code == 301)
+                                 (sline.code == 301)
                                  ? _("Repository moved permanently to '%s';"
                                      " please relocate")
                                  : _("Repository moved temporarily to '%s';"
@@ -2411,8 +2412,18 @@ svn_ra_serf__error_on_status(int status_
       case 423:
         return svn_error_createf(SVN_ERR_FS_NO_LOCK_TOKEN, NULL,
                                  _("'%s': no lock token available"), path);
+
+      case 411:
+        return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                                _("DAV request failed: "
+                                  "Content length required"));
     }
 
+  if (sline.code >= 300)
+    return svn_error_createf(SVN_ERR_RA_DAV_REQUEST_FAILED, NULL,
+                             _("Unexpected HTTP status %d '%s' on '%s'\n"),
+                             sline.code, sline.reason, path);
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/commit.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/commit.c Sun Jun 30 01:03:10 2013
@@ -1120,15 +1120,15 @@ static svn_error_t *
 alter_file_cb(void *baton,
               const char *relpath,
               svn_revnum_t revision,
-              apr_hash_t *props,
               const svn_checksum_t *checksum,
               svn_stream_t *contents,
+              apr_hash_t *props,
               apr_pool_t *scratch_pool)
 {
   struct ev2_baton *eb = baton;
 
-  SVN_ERR(svn_editor_alter_file(eb->inner, relpath, revision, props,
-                                checksum, contents));
+  SVN_ERR(svn_editor_alter_file(eb->inner, relpath, revision,
+                                checksum, contents, props));
   return SVN_NO_ERROR;
 }
 
@@ -1138,14 +1138,14 @@ static svn_error_t *
 alter_symlink_cb(void *baton,
                  const char *relpath,
                  svn_revnum_t revision,
-                 apr_hash_t *props,
                  const char *target,
+                 apr_hash_t *props,
                  apr_pool_t *scratch_pool)
 {
   struct ev2_baton *eb = baton;
 
-  SVN_ERR(svn_editor_alter_symlink(eb->inner, relpath, revision, props,
-                                   target));
+  SVN_ERR(svn_editor_alter_symlink(eb->inner, relpath, revision,
+                                   target, props));
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/deprecated.c Sun Jun 30 01:03:10 2013
@@ -727,6 +727,27 @@ svn_repos_dump_fs2(svn_repos_t *repos,
 }
 
 svn_error_t *
+svn_repos_verify_fs2(svn_repos_t *repos,
+                     svn_revnum_t start_rev,
+                     svn_revnum_t end_rev,
+                     svn_repos_notify_func_t notify_func,
+                     void *notify_baton,
+                     svn_cancel_func_t cancel_func,
+                     void *cancel_baton,
+                     apr_pool_t *pool)
+{
+  return svn_error_trace(svn_repos_verify_fs3(repos,
+                                              start_rev,
+                                              end_rev,
+                                              FALSE,
+                                              notify_func,
+                                              notify_baton,
+                                              cancel_func,
+                                              cancel_baton,
+                                              pool));
+}
+
+svn_error_t *
 svn_repos_verify_fs(svn_repos_t *repos,
                     svn_stream_t *feedback_stream,
                     svn_revnum_t start_rev,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/dump.c Sun Jun 30 01:03:10 2013
@@ -1332,6 +1332,71 @@ verify_close_directory(void *dir_baton,
   return close_directory(dir_baton, pool);
 }
 
+static void
+notify_verification_error(svn_revnum_t rev,
+                          svn_error_t *err,
+                          svn_repos_notify_func_t notify_func,
+                          void *notify_baton,
+                          apr_pool_t *pool)
+{
+  svn_repos_notify_t *notify_failure;
+
+  if (notify_func == NULL)
+    return;
+
+  notify_failure = svn_repos_notify_create(svn_repos_notify_failure, pool);
+  notify_failure->err = err;
+  notify_failure->revision = rev;
+  notify_func(notify_baton, notify_failure, pool);
+}
+
+/* Verify revision REV in file system FS. */
+static svn_error_t *
+verify_one_revision(svn_fs_t *fs,
+                    svn_revnum_t rev,
+                    svn_repos_notify_func_t notify_func,
+                    void *notify_baton,
+                    svn_revnum_t start_rev,
+                    svn_cancel_func_t cancel_func,
+                    void *cancel_baton,
+                    apr_pool_t *scratch_pool)
+{
+  const svn_delta_editor_t *dump_editor;
+  void *dump_edit_baton;
+  svn_fs_root_t *to_root;
+  apr_hash_t *props;
+  const svn_delta_editor_t *cancel_editor;
+  void *cancel_edit_baton;
+
+  /* Get cancellable dump editor, but with our close_directory handler.*/
+  SVN_ERR(get_dump_editor(&dump_editor, &dump_edit_baton,
+                          fs, rev, "",
+                          svn_stream_empty(scratch_pool),
+                          NULL, NULL,
+                          verify_close_directory,
+                          notify_func, notify_baton,
+                          start_rev,
+                          FALSE, TRUE, /* use_deltas, verify */
+                          scratch_pool));
+  SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton,
+                                            dump_editor, dump_edit_baton,
+                                            &cancel_editor,
+                                            &cancel_edit_baton,
+                                            scratch_pool));
+  SVN_ERR(svn_fs_revision_root(&to_root, fs, rev, scratch_pool));
+  SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
+                            cancel_editor, cancel_edit_baton,
+                            NULL, NULL, scratch_pool));
+ 
+  /* While our editor close_edit implementation is a no-op, we still
+     do this for completeness. */
+  SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, scratch_pool));
+ 
+  SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, scratch_pool));
+
+  return SVN_NO_ERROR;
+}
+
 /* Baton type used for forwarding notifications from FS API to REPOS API. */
 struct verify_fs2_notify_func_baton_t
 {
@@ -1359,9 +1424,10 @@ verify_fs2_notify_func(svn_revnum_t revi
 }
 
 svn_error_t *
-svn_repos_verify_fs2(svn_repos_t *repos,
+svn_repos_verify_fs3(svn_repos_t *repos,
                      svn_revnum_t start_rev,
                      svn_revnum_t end_rev,
+                     svn_boolean_t keep_going,
                      svn_repos_notify_func_t notify_func,
                      void *notify_baton,
                      svn_cancel_func_t cancel_func,
@@ -1375,6 +1441,8 @@ svn_repos_verify_fs2(svn_repos_t *repos,
   svn_repos_notify_t *notify;
   svn_fs_progress_notify_func_t verify_notify = NULL;
   struct verify_fs2_notify_func_baton_t *verify_notify_baton = NULL;
+  svn_error_t *err;
+  svn_boolean_t found_corruption = FALSE;
 
   /* Determine the current youngest revision of the filesystem. */
   SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
@@ -1403,7 +1471,6 @@ svn_repos_verify_fs2(svn_repos_t *repos,
     {
       notify = svn_repos_notify_create(svn_repos_notify_verify_rev_end,
                                        pool);
-
       verify_notify = verify_fs2_notify_func;
       verify_notify_baton = apr_palloc(pool, sizeof(*verify_notify_baton));
       verify_notify_baton->notify_func = notify_func;
@@ -1413,49 +1480,50 @@ svn_repos_verify_fs2(svn_repos_t *repos,
     }
 
   /* Verify global metadata and backend-specific data first. */
-  SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), svn_fs_config(fs, pool),
-                        start_rev, end_rev,
-                        verify_notify, verify_notify_baton,
-                        cancel_func, cancel_baton, pool));
+  err = svn_fs_verify(svn_fs_path(fs, pool), svn_fs_config(fs, pool),
+                      start_rev, end_rev,
+                      verify_notify, verify_notify_baton,
+                      cancel_func, cancel_baton, pool);
 
-  for (rev = start_rev; rev <= end_rev; rev++)
+  if (err && !keep_going)
     {
-      const svn_delta_editor_t *dump_editor;
-      void *dump_edit_baton;
-      const svn_delta_editor_t *cancel_editor;
-      void *cancel_edit_baton;
-      svn_fs_root_t *to_root;
-      apr_hash_t *props;
+      found_corruption = TRUE;
+      notify_verification_error(SVN_INVALID_REVNUM, err, notify_func,
+                                notify_baton, iterpool);
+      svn_error_clear(err);
+      return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL,
+                               _("Repository '%s' failed to verify"),
+                               svn_dirent_local_style(svn_repos_path(repos,
+                                                                     pool),
+                                                      pool));
+    }
+  else
+    {
+      if (err)
+        found_corruption = TRUE;
+      svn_error_clear(err);
+    }
 
+  for (rev = start_rev; rev <= end_rev; rev++)
+    {
       svn_pool_clear(iterpool);
 
-      /* Get cancellable dump editor, but with our close_directory handler. */
-      SVN_ERR(get_dump_editor(&dump_editor, &dump_edit_baton,
-                              fs, rev, "",
-                              svn_stream_empty(iterpool),
-                              NULL, NULL,
-                              verify_close_directory,
-                              notify_func, notify_baton,
-                              start_rev,
-                              FALSE, TRUE, /* use_deltas, verify */
-                              iterpool));
-      SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton,
-                                                dump_editor, dump_edit_baton,
-                                                &cancel_editor,
-                                                &cancel_edit_baton,
-                                                iterpool));
-
-      SVN_ERR(svn_fs_revision_root(&to_root, fs, rev, iterpool));
-      SVN_ERR(svn_fs_verify_root(to_root, iterpool));
-
-      SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE,
-                                cancel_editor, cancel_edit_baton,
-                                NULL, NULL, iterpool));
-      /* While our editor close_edit implementation is a no-op, we still
-         do this for completeness. */
-      SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, iterpool));
+      /* Wrapper function to catch the possible errors. */
+      err = verify_one_revision(fs, rev, notify_func, notify_baton, start_rev,
+                                cancel_func, cancel_baton, iterpool);
 
-      SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, iterpool));
+      if (err)
+        {
+          found_corruption = TRUE;
+          notify_verification_error(rev, err, notify_func, notify_baton,
+                                    iterpool);
+          svn_error_clear(err);
+
+          if (keep_going)
+            continue;
+          else
+            break;
+        }
 
       if (notify_func)
         {
@@ -1474,5 +1542,12 @@ svn_repos_verify_fs2(svn_repos_t *repos,
   /* Per-backend verification. */
   svn_pool_destroy(iterpool);
 
+  if (found_corruption)
+    return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL,
+                             _("Repository '%s' failed to verify"),
+                             svn_dirent_local_style(svn_repos_path(repos,
+                                                                   pool),
+                                                    pool));
+
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/fs-wrap.c Sun Jun 30 01:03:10 2013
@@ -172,6 +172,10 @@ svn_repos__validate_prop(const char *nam
 {
   svn_prop_kind_t kind = svn_property_kind2(name);
 
+  /* Allow deleting any property, even a property we don't allow to set. */
+  if (value == NULL)
+    return SVN_NO_ERROR;
+
   /* Disallow setting non-regular properties. */
   if (kind != svn_prop_regular_kind)
     return svn_error_createf

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/replay.c Sun Jun 30 01:03:10 2013
@@ -1457,8 +1457,8 @@ replay_node(svn_fs_root_t *root,
             }
 
           SVN_ERR(svn_editor_alter_file(editor, repos_relpath,
-                                        SVN_INVALID_REVNUM, props, checksum,
-                                        contents));
+                                        SVN_INVALID_REVNUM,
+                                        checksum, contents, props));
         }
 
       if (change->node_kind == svn_node_dir

Modified: subversion/branches/fsfs-format7/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_repos/repos.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_repos/repos.c Sun Jun 30 01:03:10 2013
@@ -1534,6 +1534,54 @@ svn_repos_open2(svn_repos_t **repos_p,
   return get_repos(repos_p, path, FALSE, FALSE, TRUE, fs_config, pool);
 }
 
+/* Baton used with fs_upgrade_notify, specifying the svn_repos layer
+ * notification parameters.
+ */
+struct fs_upgrade_notify_baton_t
+{
+  svn_repos_notify_func_t notify_func;
+  void *notify_baton;
+};
+
+/* Implements svn_fs_upgrade_notify_t as forwarding to a
+ * svn_repos_notify_func_t passed in a fs_upgrade_notify_baton_t* BATON.
+ */
+static svn_error_t *
+fs_upgrade_notify(void *baton,
+                  apr_uint64_t number,
+                  svn_fs_upgrade_notify_action_t action,
+                  apr_pool_t *pool)
+{
+  struct fs_upgrade_notify_baton_t *fs_baton = baton;
+
+  svn_repos_notify_t *notify = svn_repos_notify_create(
+                                svn_repos_notify_mutex_acquired, pool);
+  switch(action)
+    {
+      case svn_fs_upgrade_pack_revprops:
+        notify->shard = number;
+        notify->action = svn_repos_notify_pack_revprops;
+        break;
+
+      case svn_fs_upgrade_cleanup_revprops:
+        notify->shard = number;
+        notify->action = svn_repos_notify_cleanup_revprops;
+        break;
+
+      case svn_fs_upgrade_format_bumped:
+        notify->revision = number;
+        notify->action = svn_repos_notify_format_bumped;
+        break;
+
+      default:
+        /* unknown notification */
+        SVN_ERR_MALFUNCTION();
+    }
+
+  fs_baton->notify_func(fs_baton->notify_baton, notify, pool);
+
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_repos_upgrade2(const char *path,
@@ -1547,6 +1595,10 @@ svn_repos_upgrade2(const char *path,
   int format;
   apr_pool_t *subpool = svn_pool_create(pool);
 
+  struct fs_upgrade_notify_baton_t fs_notify_baton;
+  fs_notify_baton.notify_func = notify_func;
+  fs_notify_baton.notify_baton = notify_baton;
+
   /* Fetch a repository object; for the Berkeley DB backend, it is
      initialized with an EXCLUSIVE lock on the database.  This will at
      least prevent others from trying to read or write to it while we
@@ -1575,7 +1627,9 @@ svn_repos_upgrade2(const char *path,
   SVN_ERR(svn_io_write_version_file(format_path, format, subpool));
 
   /* Try to upgrade the filesystem. */
-  SVN_ERR(svn_fs_upgrade(repos->db_path, subpool));
+  SVN_ERR(svn_fs_upgrade2(repos->db_path,
+                          notify_func ? fs_upgrade_notify : NULL,
+                          &fs_notify_baton, NULL, NULL, subpool));
 
   /* Now overwrite our format file with the latest version. */
   SVN_ERR(svn_io_write_version_file(format_path, SVN_REPOS__FORMAT_NUMBER,

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/config_file.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/config_file.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/config_file.c Sun Jun 30 01:03:10 2013
@@ -810,6 +810,9 @@ svn_config_ensure(const char *config_dir
         "###   http-max-connections       Maximum number of parallel server" NL
         "###                              connections to use for any given"  NL
         "###                              HTTP operation."                   NL
+        "###   busted-proxy               The proxy may have some protocol"  NL
+        "###                              issues that Subversion needs to"   NL
+        "###                              detect and work around."           NL
         "###   neon-debug-mask            Debug mask for Neon HTTP library"  NL
         "###   ssl-authority-files        List of files, each of a trusted CA"
                                                                              NL

Modified: subversion/branches/fsfs-format7/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_subr/io.c?rev=1498045&r1=1498044&r2=1498045&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_subr/io.c Sun Jun 30 01:03:10 2013
@@ -3724,6 +3724,9 @@ svn_io_read_length_line(apr_file_t *file
       apr_size_t bytes_read = 0;
       char *eol;
 
+      if (to_read == 0)
+        break;
+
       /* read data block (or just a part of it) */
       SVN_ERR(svn_io_file_read_full2(file, buf, to_read,
                                      &bytes_read, &eof, pool));