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 2014/10/30 04:02:06 UTC

svn commit: r1635377 [1/2] - in /subversion/trunk/subversion/libsvn_fs_x: ./ cached_data.c cached_data.h dag.c low_level.c low_level.h pack.c transaction.c tree.c

Author: stefan2
Date: Thu Oct 30 03:02:05 2014
New Revision: 1635377

URL: http://svn.apache.org/r1635377
Log:
Sync FSX with FSFS:
Merge revisions r1604802, r1604824, r1604836, r1604902, r1604911,
r1604925, r1605060, r1605065, r1605068, r1605071, r1605072 and r1605073
from libsvn_fs_fs.  Fix the usual text conflicts caused by reordered code
and renamed functions in FSX.

This ports dual pool paradigm introduction in the lower data access layer
to FSX.

Modified:
    subversion/trunk/subversion/libsvn_fs_x/   (props changed)
    subversion/trunk/subversion/libsvn_fs_x/cached_data.c
    subversion/trunk/subversion/libsvn_fs_x/cached_data.h
    subversion/trunk/subversion/libsvn_fs_x/dag.c
    subversion/trunk/subversion/libsvn_fs_x/low_level.c
    subversion/trunk/subversion/libsvn_fs_x/low_level.h
    subversion/trunk/subversion/libsvn_fs_x/pack.c
    subversion/trunk/subversion/libsvn_fs_x/transaction.c
    subversion/trunk/subversion/libsvn_fs_x/tree.c

Propchange: subversion/trunk/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/libsvn_fs_fs:r1604802,1604824,1604836,1604902,1604911,1604925,1605060,1605065,1605068,1605071-1605073

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.c?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.c Thu Oct 30 03:02:05 2014
@@ -270,7 +270,8 @@ static svn_error_t *
 get_node_revision_body(node_revision_t **noderev_p,
                        svn_fs_t *fs,
                        const svn_fs_id_t *id,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
   svn_boolean_t is_cached = FALSE;
@@ -283,8 +284,10 @@ get_node_revision_body(node_revision_t *
       /* This is a transaction node-rev.  Its storage logic is very
          different from that of rev / pack files. */
       err = svn_io_file_open(&file,
-                             svn_fs_x__path_txn_node_rev(fs, id, pool),
-                             APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
+                             svn_fs_x__path_txn_node_rev(fs, id,
+                                                         scratch_pool),
+                             APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
+                             scratch_pool);
       if (err)
         {
           if (APR_STATUS_IS_ENOENT(err->apr_err))
@@ -299,8 +302,8 @@ get_node_revision_body(node_revision_t *
       SVN_ERR(svn_fs_x__read_noderev(noderev_p,
                                      svn_stream_from_aprfile2(file,
                                                               FALSE,
-                                                              pool),
-                                     pool));
+                                                              scratch_pool),
+                                     result_pool, scratch_pool));
     }
   else
     {
@@ -312,7 +315,7 @@ get_node_revision_body(node_revision_t *
       pair_cache_key_t key;
 
       SVN_ERR(svn_fs_x__open_pack_or_rev_file(&revision_file, fs, revision,
-                                              pool));
+                                              scratch_pool));
 
       /* First, try a noderevs container cache lookup. */
       if (   svn_fs_x__is_packed_rev(fs, revision)
@@ -321,14 +324,14 @@ get_node_revision_body(node_revision_t *
           apr_off_t offset;
           apr_uint32_t sub_item;
           SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, revision_file,
-                                        noderev_id, pool));
+                                        noderev_id, scratch_pool));
           key.revision = svn_fs_x__packed_base_rev(fs, revision);
           key.second = offset;
 
           SVN_ERR(svn_cache__get_partial((void **)noderev_p, &is_cached,
                                          ffd->noderevs_container_cache, &key, 
                                          svn_fs_x__noderevs_get_func,
-                                         &sub_item, pool));
+                                         &sub_item, result_pool));
           if (is_cached)
             return SVN_NO_ERROR;
         }
@@ -344,21 +347,22 @@ get_node_revision_body(node_revision_t *
                                  &is_cached,
                                  ffd->node_revision_cache,
                                  &key,
-                                 pool));
+                                 result_pool));
           if (is_cached)
             return SVN_NO_ERROR;
         }
 
-      /* someone needs to read the data from this file: */
-      err = open_and_seek_revision(&revision_file, fs, noderev_id, pool);
+      /* read the data from disk */
+      SVN_ERR(open_and_seek_revision(&revision_file, fs, noderev_id,
+                                     scratch_pool));
 
       /* block-read will parse the whole block and will also return
-          the one noderev that we need right now. */
+         the one noderev that we need right now. */
       SVN_ERR(block_read((void **)noderev_p, fs,
                          noderev_id,
                          revision_file,
-                         pool,
-                         pool));
+                         result_pool,
+                         scratch_pool));
       SVN_ERR(svn_fs_x__close_revision_file(revision_file));
     }
 
@@ -369,21 +373,23 @@ svn_error_t *
 svn_fs_x__get_node_revision(node_revision_t **noderev_p,
                             svn_fs_t *fs,
                             const svn_fs_id_t *id,
-                            apr_pool_t *pool)
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool)
 {
   const svn_fs_x__id_part_t *noderev_id = svn_fs_x__id_noderev_id(id);
 
-  svn_error_t *err = get_node_revision_body(noderev_p, fs, id, pool);
+  svn_error_t *err = get_node_revision_body(noderev_p, fs, id,
+                                            result_pool, scratch_pool);
   if (err && err->apr_err == SVN_ERR_FS_CORRUPT)
     {
-      svn_string_t *id_string = svn_fs_x__id_unparse(id, pool);
+      svn_string_t *id_string = svn_fs_x__id_unparse(id, scratch_pool);
       return svn_error_createf(SVN_ERR_FS_CORRUPT, err,
                                "Corrupt node-revision '%s'",
                                id_string->data);
     }
 
   SVN_ERR(dgb__log_access(fs, noderev_id, *noderev_p,
-                          SVN_FS_X__ITEM_TYPE_NODEREV, pool));
+                          SVN_FS_X__ITEM_TYPE_NODEREV, scratch_pool));
 
   return svn_error_trace(err);
 }
@@ -436,7 +442,7 @@ svn_fs_x__get_mergeinfo_count(apr_int64_
 #endif
 
   /* fallback to the naive implementation handling all edge cases */
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool));
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool, pool));
   *count = noderev->mergeinfo_count;
 
   return SVN_NO_ERROR;
@@ -447,10 +453,11 @@ svn_error_t *
 svn_fs_x__rev_get_root(svn_fs_id_t **root_id_p,
                        svn_fs_t *fs,
                        svn_revnum_t rev,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
-  SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, pool));
-  *root_id_p = svn_fs_x__id_create_root(rev, pool);
+  SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
+  *root_id_p = svn_fs_x__id_create_root(rev, result_pool);
 
   return SVN_NO_ERROR;
 }
@@ -589,10 +596,11 @@ create_rep_state_body(rep_state_t **rep_
                       shared_file_t **shared_file,
                       representation_t *rep,
                       svn_fs_t *fs,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   fs_x_data_t *ffd = fs->fsap_data;
-  rep_state_t *rs = apr_pcalloc(pool, sizeof(*rs));
+  rep_state_t *rs = apr_pcalloc(result_pool, sizeof(*rs));
   svn_fs_x__rep_header_t *rh;
   svn_boolean_t is_cached = FALSE;
   svn_revnum_t revision = svn_fs_x__get_revnum(rep->id.change_set);
@@ -649,7 +657,7 @@ create_rep_state_body(rep_state_t **rep_
   /* cache lookup, i.e. skip reading the rep header if possible */
   if (ffd->rep_header_cache && SVN_IS_VALID_REVNUM(revision))
     SVN_ERR(svn_cache__get((void **) &rh, &is_cached,
-                           ffd->rep_header_cache, &key, pool));
+                           ffd->rep_header_cache, &key, result_pool));
 
   /* initialize the (shared) FILE member in RS */
   if (reuse_shared_file)
@@ -658,9 +666,9 @@ create_rep_state_body(rep_state_t **rep_
     }
   else
     {
-      shared_file_t *file = apr_pcalloc(pool, sizeof(*file));
+      shared_file_t *file = apr_pcalloc(result_pool, sizeof(*file));
       file->revision = revision;
-      file->pool = pool;
+      file->pool = result_pool;
       file->fs = fs;
       rs->sfile = file;
 
@@ -686,7 +694,6 @@ create_rep_state_body(rep_state_t **rep_
           SVN_ERR_ASSERT(sub_item == 0);
           rs->sfile = *shared_file;
           SVN_ERR(auto_open_shared_file(rs->sfile));
-          SVN_ERR(rs_aligned_seek(rs, NULL, offset, pool));
         }
       else
         {
@@ -694,27 +701,29 @@ create_rep_state_body(rep_state_t **rep_
            * an in-txn file.
            */
           SVN_ERR(open_and_seek_representation(&rs->sfile->rfile, fs, rep,
-                                               pool));
+                                               result_pool));
         }
 
       if (SVN_IS_VALID_REVNUM(revision))
         {
           SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs,
-                                        rs->sfile->rfile, &rep->id, pool));
+                                        rs->sfile->rfile, &rep->id,
+                                        scratch_pool));
 
           /* is rep stored in some star-deltified container? */
           if (sub_item == 0)
             {
               svn_fs_x__p2l_entry_t *entry;
               SVN_ERR(svn_fs_x__p2l_entry_lookup(&entry, fs, rs->sfile->rfile,
-                                                 revision, offset, pool));
+                                                 revision, offset,
+                                                 scratch_pool));
               in_container = entry->type == SVN_FS_X__ITEM_TYPE_REPS_CONT;
             }
 
           if (in_container)
             {
               /* construct a container rep header */
-              *rep_header = apr_pcalloc(pool, sizeof(**rep_header));
+              *rep_header = apr_pcalloc(result_pool, sizeof(**rep_header));
               (*rep_header)->type = svn_fs_x__rep_container;
 
               /* exit to caller */
@@ -722,25 +731,27 @@ create_rep_state_body(rep_state_t **rep_
               return SVN_NO_ERROR;
             }
 
-          SVN_ERR(rs_aligned_seek(rs, NULL, offset, pool));
+          SVN_ERR(rs_aligned_seek(rs, NULL, offset, scratch_pool));
         }
 
-      SVN_ERR(svn_fs_x__read_rep_header(&rh, rs->sfile->rfile->stream, pool));
-      SVN_ERR(get_file_offset(&rs->start, rs, pool));
+      SVN_ERR(svn_fs_x__read_rep_header(&rh, rs->sfile->rfile->stream,
+                                        result_pool, scratch_pool));
+      SVN_ERR(get_file_offset(&rs->start, rs, result_pool));
 
       /* populate the cache if appropriate */
       if (SVN_IS_VALID_REVNUM(revision))
         {
-          SVN_ERR(block_read(NULL, fs, &rs->rep_id, rs->sfile->rfile, pool,
-                             pool));
+          SVN_ERR(block_read(NULL, fs, &rs->rep_id, rs->sfile->rfile,
+                             result_pool, scratch_pool));
           if (ffd->rep_header_cache)
-            SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh, pool));
+            SVN_ERR(svn_cache__set(ffd->rep_header_cache, &key, rh,
+                                   scratch_pool));
         }
     }
 
   /* finalize */
   SVN_ERR(dgb__log_access(fs, &rs->rep_id, rh, SVN_FS_X__ITEM_TYPE_ANY_REP,
-                          pool));
+                          scratch_pool));
 
   rs->header_size = rh->header_size;
   *rep_state = rs;
@@ -771,14 +782,14 @@ create_rep_state(rep_state_t **rep_state
                  shared_file_t **shared_file,
                  representation_t *rep,
                  svn_fs_t *fs,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   svn_error_t *err = create_rep_state_body(rep_state, rep_header,
-                                           shared_file, rep, fs, pool);
+                                           shared_file, rep, fs,
+                                           result_pool, scratch_pool);
   if (err && err->apr_err == SVN_ERR_FS_CORRUPT)
     {
-      fs_x_data_t *ffd = fs->fsap_data;
-
       /* ### This always returns "-1" for transaction reps, because
          ### this particular bit of code doesn't know if the rep is
          ### stored in the protorev or in the mutable area (for props
@@ -790,7 +801,8 @@ create_rep_state(rep_state_t **rep_state
                                "Corrupt representation '%s'",
                                rep
                                ? svn_fs_x__unparse_representation
-                                   (rep, ffd->format, TRUE, pool)->data
+                                   (rep, TRUE, scratch_pool,
+                                    scratch_pool)->data
                                : "(null)");
     }
   /* ### Call representation_string() ? */
@@ -888,6 +900,7 @@ svn_fs_x__rep_chain_length(int *chain_le
                                     &file_hint,
                                     &base_rep,
                                     fs,
+                                    iterpool,
                                     iterpool));
 
       base_rep.id.change_set
@@ -1047,9 +1060,14 @@ get_cached_window_sizes_func(void **out,
   return SVN_NO_ERROR;
 }
 
-/* Return the packed & expanded sizes of the window addressed by RS.  If the
- * window cannot be found in the window cache, set *IS_CACHED to FALSE.
- * Otherwise, set it to TRUE and return the data in *SIZES, allocated in POOL.
+/* Read the WINDOW_P number CHUNK_INDEX for the representation given in
+ * rep state RS from the current FSFS session's cache.  This will be a
+ * no-op and IS_CACHED will be set to FALSE if no cache has been given.
+ * If a cache is available IS_CACHED will inform the caller about the
+ * success of the lookup. Allocations of the window in will be made
+ * from RESULT_POOL. Use SCRATCH_POOL for temporary allocations.
+ *
+ * If the information could be found, put RS to CHUNK_INDEX.
  */
 static svn_error_t *
 get_cached_window_sizes(window_sizes_t **sizes,
@@ -1082,7 +1100,8 @@ get_cached_window(svn_txdelta_window_t *
                   rep_state_t *rs,
                   int chunk_index,
                   svn_boolean_t *is_cached,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   if (! rs->window_cache)
     {
@@ -1100,7 +1119,7 @@ get_cached_window(svn_txdelta_window_t *
                              is_cached,
                              rs->window_cache,
                              &key,
-                             pool));
+                             result_pool));
 
       if (*is_cached)
         {
@@ -1223,19 +1242,23 @@ build_rep_list(apr_array_header_t **list
   svn_fs_x__rep_header_t *rep_header;
   svn_boolean_t is_cached = FALSE;
   shared_file_t *shared_file = NULL;
+  apr_pool_t *iterpool = svn_pool_create(pool);
 
   *list = apr_array_make(pool, 1, sizeof(rep_state_t *));
   rep = *first_rep;
 
   /* for the top-level rep, we need the rep_args */
-  SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file, &rep, fs, pool));
+  SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file, &rep, fs, pool,
+                           iterpool));
 
   while (1)
     {
+      svn_pool_clear(iterpool);
+
       /* fetch state, if that has not been done already */
       if (!rs)
         SVN_ERR(create_rep_state(&rs, &rep_header, &shared_file,
-                                 &rep, fs, pool));
+                                 &rep, fs, pool, iterpool));
 
       /* for txn reps and containered reps, there won't be a cached
        * combined window */
@@ -1251,14 +1274,14 @@ build_rep_list(apr_array_header_t **list
           rs->current = 0;
           rs->size = (*window_p)->len;
           *src_state = rs;
-          return SVN_NO_ERROR;
+          break;
         }
 
       if (rep_header->type == svn_fs_x__rep_container)
         {
           /* This is a container item, so just return the current rep_state. */
           *src_state = rs;
-          return SVN_NO_ERROR;
+          break;
         }
 
       /* Push this rep onto the list.  If it's self-compressed, we're done. */
@@ -1266,7 +1289,7 @@ build_rep_list(apr_array_header_t **list
       if (rep_header->type == svn_fs_x__rep_self_delta)
         {
           *src_state = NULL;
-          return SVN_NO_ERROR;
+          break;
         }
 
       rep.id.change_set
@@ -1276,6 +1299,9 @@ build_rep_list(apr_array_header_t **list
 
       rs = NULL;
     }
+  svn_pool_destroy(iterpool);
+
+  return SVN_NO_ERROR;
 }
 
 
@@ -1321,7 +1347,8 @@ rep_read_get_baton(struct rep_read_baton
    window into *NWIN. */
 static svn_error_t *
 read_delta_window(svn_txdelta_window_t **nwin, int this_chunk,
-                  rep_state_t *rs, apr_pool_t *pool)
+                  rep_state_t *rs, apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   svn_boolean_t is_cached;
   apr_off_t start_offset;
@@ -1331,10 +1358,11 @@ read_delta_window(svn_txdelta_window_t *
   SVN_ERR_ASSERT(rs->chunk_index <= this_chunk);
 
   SVN_ERR(dgb__log_access(rs->sfile->fs, &rs->rep_id, NULL,
-                          SVN_FS_X__ITEM_TYPE_ANY_REP, pool));
+                          SVN_FS_X__ITEM_TYPE_ANY_REP, scratch_pool));
 
   /* Read the next window.  But first, try to find it in the cache. */
-  SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
+  SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached,
+                            result_pool, scratch_pool));
   if (is_cached)
     return SVN_NO_ERROR;
 
@@ -1349,33 +1377,34 @@ read_delta_window(svn_txdelta_window_t *
       && rs->window_cache)
     {
       SVN_ERR(block_read(NULL, rs->sfile->fs, &rs->rep_id,
-                         rs->sfile->rfile, pool, pool));
+                         rs->sfile->rfile, result_pool, scratch_pool));
 
       /* reading the whole block probably also provided us with the
          desired txdelta window */
-      SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached, pool));
+      SVN_ERR(get_cached_window(nwin, rs, this_chunk, &is_cached,
+                                result_pool, scratch_pool));
       if (is_cached)
         return SVN_NO_ERROR;
     }
 
   /* data is still not cached -> we need to read it.
      Make sure we have all the necessary info. */
-  SVN_ERR(auto_set_start_offset(rs, pool));
-  SVN_ERR(auto_read_diff_version(rs, pool));
+  SVN_ERR(auto_set_start_offset(rs, scratch_pool));
+  SVN_ERR(auto_read_diff_version(rs, scratch_pool));
 
   /* RS->FILE may be shared between RS instances -> make sure we point
    * to the right data. */
   start_offset = rs->start + rs->current;
-  SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, pool));
+  SVN_ERR(rs_aligned_seek(rs, NULL, start_offset, scratch_pool));
 
   /* Skip windows to reach the current chunk if we aren't there yet. */
-  iterpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
   while (rs->chunk_index < this_chunk)
     {
       apr_file_t *file = rs->sfile->rfile->file;
       svn_pool_clear(iterpool);
 
-      SVN_ERR(svn_txdelta_skip_svndiff_window(file, rs->ver, pool));
+      SVN_ERR(svn_txdelta_skip_svndiff_window(file, rs->ver, iterpool));
       rs->chunk_index++;
       SVN_ERR(svn_fs_x__get_file_offset(&start_offset, file, iterpool));
 
@@ -1390,8 +1419,8 @@ read_delta_window(svn_txdelta_window_t *
 
   /* Actually read the next window. */
   SVN_ERR(svn_txdelta_read_svndiff_window(nwin, rs->sfile->rfile->stream,
-                                          rs->ver, pool));
-  SVN_ERR(get_file_offset(&end_offset, rs, pool));
+                                          rs->ver, result_pool));
+  SVN_ERR(get_file_offset(&end_offset, rs, scratch_pool));
   rs->current = end_offset - rs->start;
   if (rs->current > rs->size)
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
@@ -1401,7 +1430,7 @@ read_delta_window(svn_txdelta_window_t *
   /* the window has not been cached before, thus cache it now
    * (if caching is used for them at all) */
   if (svn_fs_x__is_revision(rs->rep_id.change_set))
-    SVN_ERR(set_cached_window(*nwin, rs, start_offset, pool));
+    SVN_ERR(set_cached_window(*nwin, rs, start_offset, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1411,7 +1440,8 @@ static svn_error_t *
 read_container_window(svn_stringbuf_t **nwin,
                       rep_state_t *rs,
                       apr_size_t size,
-                      apr_pool_t *pool)
+                      apr_pool_t *result_pool,
+                      apr_pool_t *scratch_pool)
 {
   svn_fs_x__rep_extractor_t *extractor = NULL;
   svn_fs_t *fs = rs->sfile->fs;
@@ -1419,7 +1449,7 @@ read_container_window(svn_stringbuf_t **
   pair_cache_key_t key;
   svn_revnum_t revision = svn_fs_x__get_revnum(rs->rep_id.change_set);
 
-  SVN_ERR(auto_set_start_offset(rs, pool));
+  SVN_ERR(auto_set_start_offset(rs, scratch_pool));
   key.revision = svn_fs_x__packed_base_rev(fs, revision);
   key.second = rs->start;
 
@@ -1434,7 +1464,7 @@ read_container_window(svn_stringbuf_t **
       SVN_ERR(svn_cache__get_partial((void**)&extractor, &is_cached,
                                      ffd->reps_container_cache, &key,
                                      svn_fs_x__reps_get_func, &baton,
-                                     pool));
+                                     result_pool));
     }
 
   /* read from disk, if necessary */
@@ -1442,11 +1472,11 @@ read_container_window(svn_stringbuf_t **
     {
       SVN_ERR(auto_open_shared_file(rs->sfile));
       SVN_ERR(block_read((void **)&extractor, fs, &rs->rep_id,
-                         rs->sfile->rfile, pool, pool));
+                         rs->sfile->rfile, result_pool, scratch_pool));
     }
 
   SVN_ERR(svn_fs_x__extractor_drive(nwin, extractor, rs->current, size,
-                                    pool, pool));
+                                    result_pool, scratch_pool));
 
   /* Update RS. */
   rs->current += (apr_off_t)size;
@@ -1466,6 +1496,7 @@ get_combined_window(svn_stringbuf_t **re
   apr_array_header_t *windows;
   svn_stringbuf_t *source, *buf = rb->base_window;
   rep_state_t *rs;
+  apr_pool_t *iterpool;
 
   /* Read all windows that we need to combine. This is fine because
      the size of each window is relatively small (100kB) and skip-
@@ -1473,12 +1504,16 @@ get_combined_window(svn_stringbuf_t **re
      Stop early if one of them does not depend on its predecessors. */
   window_pool = svn_pool_create(rb->pool);
   windows = apr_array_make(window_pool, 0, sizeof(svn_txdelta_window_t *));
+  iterpool = svn_pool_create(rb->pool);
   for (i = 0; i < rb->rs_list->nelts; ++i)
     {
       svn_txdelta_window_t *window;
 
+      svn_pool_clear(iterpool);
+
       rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
-      SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool));
+      SVN_ERR(read_delta_window(&window, rb->chunk_index, rs, window_pool,
+                                iterpool));
 
       APR_ARRAY_PUSH(windows, svn_txdelta_window_t *) = window;
       if (window->src_ops == 0)
@@ -1494,6 +1529,8 @@ get_combined_window(svn_stringbuf_t **re
     {
       svn_txdelta_window_t *window;
 
+      svn_pool_clear(iterpool);
+
       rs = APR_ARRAY_IDX(rb->rs_list, i, rep_state_t *);
       window = APR_ARRAY_IDX(windows, i, svn_txdelta_window_t *);
 
@@ -1504,7 +1541,7 @@ get_combined_window(svn_stringbuf_t **re
       source = buf;
       if (source == NULL && rb->src_state != NULL)
         SVN_ERR(read_container_window(&source, rb->src_state,
-                                      window->sview_len, pool));
+                                      window->sview_len, pool, iterpool));
 
       /* Combine this window with the current one. */
       new_pool = svn_pool_create(rb->pool);
@@ -1531,6 +1568,7 @@ get_combined_window(svn_stringbuf_t **re
       svn_pool_destroy(pool);
       pool = new_pool;
     }
+  svn_pool_destroy(iterpool);
 
   svn_pool_destroy(window_pool);
 
@@ -1700,7 +1738,7 @@ read_rep_header(svn_fs_x__rep_header_t *
         return SVN_NO_ERROR;
     }
 
-  SVN_ERR(svn_fs_x__read_rep_header(rep_header, stream, pool));
+  SVN_ERR(svn_fs_x__read_rep_header(rep_header, stream, pool, pool));
 
   if (ffd->rep_header_cache)
     SVN_ERR(svn_cache__set(ffd->rep_header_cache, key, *rep_header, pool));
@@ -1767,7 +1805,7 @@ get_contents_from_windows(struct rep_rea
            * the delta rep size _before_ putting the data into a
            * a container. */
           SVN_ERR(read_container_window(&rb->base_window, rs,
-                                        rb->len, rb->pool));
+                                        rb->len, rb->pool, rb->pool));
           rs->current -= rb->base_window->len;
         }
 
@@ -2239,14 +2277,18 @@ delta_read_next_window(svn_txdelta_windo
                        apr_pool_t *pool)
 {
   struct delta_read_baton *drb = baton;
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   *window = NULL;
   if (drb->rs->current < drb->rs->size)
     {
-      SVN_ERR(read_delta_window(window, drb->rs->chunk_index, drb->rs, pool));
+      SVN_ERR(read_delta_window(window, drb->rs->chunk_index, drb->rs, pool,
+                                scratch_pool));
       drb->rs->chunk_index++;
     }
 
+  svn_pool_destroy(scratch_pool);
+
   return SVN_NO_ERROR;
 }
 
@@ -2294,7 +2336,7 @@ svn_fs_x__get_file_delta_stream(svn_txde
     {
       /* Read target's base rep if any. */
       SVN_ERR(create_rep_state(&rep_state, &rep_header, NULL,
-                                target->data_rep, fs, pool));
+                                target->data_rep, fs, pool, pool));
 
       /* Try a shortcut: if the target is stored as a delta against the source,
          then just use that delta. */
@@ -2899,7 +2941,7 @@ block_read_changes(apr_array_header_t **
 
   /* read changes from revision file */
 
-  SVN_ERR(svn_fs_x__read_changes(changes, stream, result_pool));
+  SVN_ERR(svn_fs_x__read_changes(changes, stream, result_pool, scratch_pool));
 
   /* cache for future reference */
 
@@ -2991,7 +3033,8 @@ block_read_noderev(node_revision_t **nod
 
   /* read node rev from revision file */
 
-  SVN_ERR(svn_fs_x__read_noderev(noderev_p, stream, result_pool));
+  SVN_ERR(svn_fs_x__read_noderev(noderev_p, stream, result_pool,
+                                 scratch_pool));
 
   /* Workaround issue #4031: is-fresh-txn-root in revision files. */
   (*noderev_p)->is_fresh_txn_root = FALSE;

Modified: subversion/trunk/subversion/libsvn_fs_x/cached_data.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/cached_data.h?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/cached_data.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/cached_data.h Thu Oct 30 03:02:05 2014
@@ -37,7 +37,8 @@ svn_error_t *
 svn_fs_x__get_node_revision(node_revision_t **noderev_p,
                             svn_fs_t *fs,
                             const svn_fs_id_t *id,
-                            apr_pool_t *pool);
+                            apr_pool_t *result_pool,
+                            apr_pool_t *scratch_pool);
 
 /* Set *COUNT to the value of the mergeinfo_count member of the node-
    revision for the node ID in FS.  Do any allocations in POOL. */
@@ -53,7 +54,8 @@ svn_error_t *
 svn_fs_x__rev_get_root(svn_fs_id_t **root_id,
                        svn_fs_t *fs,
                        svn_revnum_t rev,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool);
 
 /* Verify that representation REP in FS can be accessed.
    Do any allocations in POOL. */

Modified: subversion/trunk/subversion/libsvn_fs_x/dag.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/dag.c?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/dag.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/dag.c Thu Oct 30 03:02:05 2014
@@ -160,10 +160,13 @@ get_node_revision(node_revision_t **node
   if (! node->node_revision)
     {
       node_revision_t *noderev;
+      apr_pool_t *scratch_pool = svn_pool_create(node->node_pool);
 
       SVN_ERR(svn_fs_x__get_node_revision(&noderev, node->fs,
-                                          node->id, node->node_pool));
+                                          node->id, node->node_pool,
+                                          scratch_pool));
       node->node_revision = noderev;
+      svn_pool_destroy(scratch_pool);
     }
 
   /* Now NODE->node_revision is set.  */
@@ -613,7 +616,7 @@ svn_fs_x__dag_revision_root(dag_node_t *
   /* Construct the node. */
   new_node = apr_pcalloc(pool, sizeof(*new_node));
   new_node->fs = fs;
-  SVN_ERR(svn_fs_x__rev_get_root(&new_node->id, fs, rev, pool));
+  SVN_ERR(svn_fs_x__rev_get_root(&new_node->id, fs, rev, pool, pool));
 
   /* Grab the contents so we can inspect the node's kind and created path. */
   new_node->node_pool = pool;

Modified: subversion/trunk/subversion/libsvn_fs_x/low_level.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/low_level.c?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/low_level.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/low_level.c Thu Oct 30 03:02:05 2014
@@ -152,9 +152,9 @@ svn_fs_x__parse_revision_trailer(apr_off
 svn_stringbuf_t *
 svn_fs_x__unparse_revision_trailer(apr_off_t root_offset,
                                    apr_off_t changes_offset,
-                                   apr_pool_t *pool)
+                                   apr_pool_t *result_pool)
 {
-  return svn_stringbuf_createf(pool,
+  return svn_stringbuf_createf(result_pool,
                                "%" APR_OFF_T_FMT " %" APR_OFF_T_FMT "\n",
                                root_offset,
                                changes_offset);
@@ -188,9 +188,9 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
 svn_stringbuf_t *
 svn_fs_x__unparse_footer(apr_off_t l2p_offset,
                          apr_off_t p2l_offset,
-                         apr_pool_t *pool)
+                         apr_pool_t *result_pool)
 {
-  return svn_stringbuf_createf(pool,
+  return svn_stringbuf_createf(result_pool,
                                "%" APR_OFF_T_FMT " %" APR_OFF_T_FMT,
                                l2p_offset,
                                p2l_offset);
@@ -199,13 +199,13 @@ svn_fs_x__unparse_footer(apr_off_t l2p_o
 /* Given a revision file FILE that has been pre-positioned at the
    beginning of a Node-Rev header block, read in that header block and
    store it in the apr_hash_t HEADERS.  All allocations will be from
-   POOL. */
+   RESULT_POOL. */
 static svn_error_t *
 read_header_block(apr_hash_t **headers,
                   svn_stream_t *stream,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool)
 {
-  *headers = svn_hash__make(pool);
+  *headers = svn_hash__make(result_pool);
 
   while (1)
     {
@@ -215,7 +215,8 @@ read_header_block(apr_hash_t **headers,
       apr_ssize_t name_len;
       svn_boolean_t eof;
 
-      SVN_ERR(svn_stream_readline(stream, &header_str, "\n", &eof, pool));
+      SVN_ERR(svn_stream_readline(stream, &header_str, "\n", &eof,
+                                  result_pool));
 
       if (eof || header_str->len == 0)
         break; /* end of header block */
@@ -262,7 +263,8 @@ read_header_block(apr_hash_t **headers,
 svn_error_t *
 svn_fs_x__parse_representation(representation_t **rep_p,
                                svn_stringbuf_t *text,
-                               apr_pool_t *pool)
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool)
 {
   representation_t *rep;
   char *str;
@@ -270,7 +272,7 @@ svn_fs_x__parse_representation(represent
   char *string = text->data;
   svn_checksum_t *checksum;
 
-  rep = apr_pcalloc(pool, sizeof(*rep));
+  rep = apr_pcalloc(result_pool, sizeof(*rep));
   *rep_p = rep;
 
   str = svn_cstring_tokenize(" ", &string);
@@ -319,7 +321,8 @@ svn_fs_x__parse_representation(represent
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in node-rev"));
 
-  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_md5, str, pool));
+  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_md5, str,
+                                 scratch_pool));
   if (checksum)
     memcpy(rep->md5_digest, checksum->digest, sizeof(rep->md5_digest));
 
@@ -333,7 +336,8 @@ svn_fs_x__parse_representation(represent
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Malformed text representation offset line in node-rev"));
 
-  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str, pool));
+  SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str,
+                                 scratch_pool));
   rep->has_sha1 = checksum != NULL;
   if (checksum)
     memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest));
@@ -347,17 +351,22 @@ static svn_error_t *
 read_rep_offsets(representation_t **rep_p,
                  char *string,
                  const svn_fs_id_t *noderev_id,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool,
+                 apr_pool_t *scratch_pool)
 {
   svn_error_t *err
     = svn_fs_x__parse_representation(rep_p,
-                                     svn_stringbuf_create_wrap(string, pool),
-                                     pool);
+                                     svn_stringbuf_create_wrap(string,
+                                                               scratch_pool),
+                                     result_pool,
+                                     scratch_pool);
   if (err)
     {
-      const svn_string_t *id_unparsed = svn_fs_x__id_unparse(noderev_id, pool);
+      const svn_string_t *id_unparsed;
       const char *where;
-      where = apr_psprintf(pool,
+
+      id_unparsed = svn_fs_x__id_unparse(noderev_id, scratch_pool);
+      where = apr_psprintf(scratch_pool,
                            _("While reading representation offsets "
                              "for node-revision '%s':"),
                            noderev_id ? id_unparsed->data : "(null)");
@@ -423,27 +432,28 @@ auto_unescape_path(const char *path,
 svn_error_t *
 svn_fs_x__read_noderev(node_revision_t **noderev_p,
                        svn_stream_t *stream,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   apr_hash_t *headers;
   node_revision_t *noderev;
   char *value;
   const char *noderev_id;
 
-  SVN_ERR(read_header_block(&headers, stream, pool));
+  SVN_ERR(read_header_block(&headers, stream, scratch_pool));
 
-  noderev = apr_pcalloc(pool, sizeof(*noderev));
+  noderev = apr_pcalloc(result_pool, sizeof(*noderev));
 
   /* Read the node-rev id. */
   value = svn_hash_gets(headers, HEADER_ID);
   if (value == NULL)
-      /* ### More information: filename/offset coordinates */
-      return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
-                              _("Missing id field in node-rev"));
+     /* ### More information: filename/offset coordinates */
+     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
+                             _("Missing id field in node-rev"));
 
   SVN_ERR(svn_stream_close(stream));
 
-  noderev->id = svn_fs_x__id_parse(value, strlen(value), pool);
+  noderev->id = svn_fs_x__id_parse(value, strlen(value), result_pool);
   noderev_id = value; /* for error messages later */
 
   /* Read the type. */
@@ -473,7 +483,7 @@ svn_fs_x__read_noderev(node_revision_t *
   if (value)
     {
       SVN_ERR(read_rep_offsets(&noderev->prop_rep, value,
-                               noderev->id, pool));
+                               noderev->id, result_pool, scratch_pool));
     }
 
   /* Get the data location. */
@@ -481,7 +491,7 @@ svn_fs_x__read_noderev(node_revision_t *
   if (value)
     {
       SVN_ERR(read_rep_offsets(&noderev->data_rep, value,
-                               noderev->id, pool));
+                               noderev->id, result_pool, scratch_pool));
     }
 
   /* Get the created path. */
@@ -494,13 +504,16 @@ svn_fs_x__read_noderev(node_revision_t *
     }
   else
     {
-      noderev->created_path = auto_unescape_path(value, pool);
+      noderev->created_path = auto_unescape_path(apr_pstrdup(result_pool,
+                                                              value),
+                                                 result_pool);
     }
 
   /* Get the predecessor ID. */
   value = svn_hash_gets(headers, HEADER_PRED);
   if (value)
-    noderev->predecessor_id = svn_fs_x__id_parse(value, strlen(value), pool);
+    noderev->predecessor_id = svn_fs_x__id_parse(value, strlen(value),
+                                                 result_pool);
 
   /* Get the copyroot. */
   value = svn_hash_gets(headers, HEADER_COPYROOT);
@@ -525,7 +538,9 @@ svn_fs_x__read_noderev(node_revision_t *
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                  _("Malformed copyroot line in node-rev '%s'"),
                                  noderev_id);
-      noderev->copyroot_path = auto_unescape_path(value, pool);
+      noderev->copyroot_path = auto_unescape_path(apr_pstrdup(result_pool,
+                                                              value),
+                                                  result_pool);
     }
 
   /* Get the copyfrom. */
@@ -549,7 +564,9 @@ svn_fs_x__read_noderev(node_revision_t *
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                  _("Malformed copyfrom line in node-rev '%s'"),
                                  noderev_id);
-      noderev->copyfrom_path = auto_unescape_path(value, pool);
+      noderev->copyfrom_path = auto_unescape_path(apr_pstrdup(result_pool,
+                                                              value),
+                                                  result_pool);
     }
 
   /* Get whether this is a fresh txn root. */
@@ -574,13 +591,13 @@ svn_fs_x__read_noderev(node_revision_t *
 
 /* Return a textual representation of the DIGEST of given KIND.
  * If IS_NULL is TRUE, no digest is available.
- * Use POOL for allocations.
+ * Allocate the result in RESULT_POOL.
  */
 static const char *
 format_digest(const unsigned char *digest,
               svn_checksum_kind_t kind,
               svn_boolean_t is_null,
-              apr_pool_t *pool)
+              apr_pool_t *result_pool)
 {
   svn_checksum_t checksum;
   checksum.digest = digest;
@@ -589,92 +606,96 @@ format_digest(const unsigned char *diges
   if (is_null)
     return "(null)";
 
-  return svn_checksum_to_cstring_display(&checksum, pool);
+  return svn_checksum_to_cstring_display(&checksum, result_pool);
 }
 
 svn_stringbuf_t *
 svn_fs_x__unparse_representation(representation_t *rep,
-                                 int format,
                                  svn_boolean_t mutable_rep_truncated,
-                                 apr_pool_t *pool)
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
 {
   if (!rep->has_sha1)
     return svn_stringbuf_createf
-            (pool,
+            (result_pool,
              "%" APR_INT64_T_FMT " %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT
              " %" SVN_FILESIZE_T_FMT " %s",
              rep->id.change_set, rep->id.number, rep->size,
              rep->expanded_size,
-             format_digest(rep->md5_digest, svn_checksum_md5, FALSE, pool));
+             format_digest(rep->md5_digest, svn_checksum_md5, FALSE,
+                           scratch_pool));
 
   return svn_stringbuf_createf
-          (pool,
+          (result_pool,
            "%" APR_INT64_T_FMT " %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT
            " %" SVN_FILESIZE_T_FMT " %s %s",
            rep->id.change_set, rep->id.number, rep->size,
            rep->expanded_size,
-           format_digest(rep->md5_digest, svn_checksum_md5, FALSE, pool),
+           format_digest(rep->md5_digest, svn_checksum_md5,
+                         FALSE, scratch_pool),
            format_digest(rep->sha1_digest, svn_checksum_sha1,
-                         !rep->has_sha1, pool));
+                         !rep->has_sha1, scratch_pool));
 }
 
 
 svn_error_t *
 svn_fs_x__write_noderev(svn_stream_t *outfile,
                         node_revision_t *noderev,
-                        int format,
-                        apr_pool_t *pool)
+                        apr_pool_t *scratch_pool)
 {
-  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_ID ": %s\n",
-                            svn_fs_x__id_unparse(noderev->id, pool)->data));
+  SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_ID ": %s\n",
+                            svn_fs_x__id_unparse(noderev->id,
+                                                 scratch_pool)->data));
 
-  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_TYPE ": %s\n",
+  SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_TYPE ": %s\n",
                             (noderev->kind == svn_node_file) ?
                             SVN_FS_X__KIND_FILE : SVN_FS_X__KIND_DIR));
 
   if (noderev->predecessor_id)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_PRED ": %s\n",
+    SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_PRED ": %s\n",
                               svn_fs_x__id_unparse(noderev->predecessor_id,
-                                                   pool)->data));
+                                                   scratch_pool)->data));
 
-  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COUNT ": %d\n",
+  SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_COUNT ": %d\n",
                             noderev->predecessor_count));
 
   if (noderev->data_rep)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_TEXT ": %s\n",
+    SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_TEXT ": %s\n",
                               svn_fs_x__unparse_representation
                                 (noderev->data_rep,
-                                 format,
                                  noderev->kind == svn_node_dir,
-                                 pool)->data));
+                                 scratch_pool, scratch_pool)->data));
 
   if (noderev->prop_rep)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_PROPS ": %s\n",
+    SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_PROPS ": %s\n",
                               svn_fs_x__unparse_representation
-                                (noderev->prop_rep, format,
-                                 TRUE, pool)->data));
+                                (noderev->prop_rep,
+                                 TRUE, scratch_pool, scratch_pool)->data));
 
-  SVN_ERR(svn_stream_printf(outfile, pool, HEADER_CPATH ": %s\n",
-                            auto_escape_path(noderev->created_path, pool)));
+  SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_CPATH ": %s\n",
+                            auto_escape_path(noderev->created_path,
+                                             scratch_pool)));
 
   if (noderev->copyfrom_path)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COPYFROM ": %ld"
+    SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_COPYFROM ": %ld"
                               " %s\n",
                               noderev->copyfrom_rev,
-                              auto_escape_path(noderev->copyfrom_path, pool)));
+                              auto_escape_path(noderev->copyfrom_path,
+                                               scratch_pool)));
 
   if ((noderev->copyroot_rev != svn_fs_x__id_rev(noderev->id)) ||
       (strcmp(noderev->copyroot_path, noderev->created_path) != 0))
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_COPYROOT ": %ld"
+    SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_COPYROOT ": %ld"
                               " %s\n",
                               noderev->copyroot_rev,
-                              auto_escape_path(noderev->copyroot_path, pool)));
+                              auto_escape_path(noderev->copyroot_path,
+                                               scratch_pool)));
 
   if (noderev->is_fresh_txn_root)
     SVN_ERR(svn_stream_puts(outfile, HEADER_FRESHTXNRT ": y\n"));
 
   if (noderev->mergeinfo_count > 0)
-    SVN_ERR(svn_stream_printf(outfile, pool, HEADER_MINFO_CNT ": %"
+    SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_MINFO_CNT ": %"
                               APR_INT64_T_FMT "\n",
                               noderev->mergeinfo_count));
 
@@ -687,16 +708,17 @@ svn_fs_x__write_noderev(svn_stream_t *ou
 svn_error_t *
 svn_fs_x__read_rep_header(svn_fs_x__rep_header_t **header,
                           svn_stream_t *stream,
-                          apr_pool_t *pool)
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool)
 {
   svn_stringbuf_t *buffer;
   char *str, *last_str;
   apr_int64_t val;
   svn_boolean_t eol = FALSE;
 
-  SVN_ERR(svn_stream_readline(stream, &buffer, "\n", &eol, pool));
+  SVN_ERR(svn_stream_readline(stream, &buffer, "\n", &eol, scratch_pool));
 
-  *header = apr_pcalloc(pool, sizeof(**header));
+  *header = apr_pcalloc(result_pool, sizeof(**header));
   (*header)->header_size = buffer->len + 1;
   if (strcmp(buffer->data, REP_DELTA) == 0)
     {
@@ -740,7 +762,7 @@ svn_fs_x__read_rep_header(svn_fs_x__rep_
 svn_error_t *
 svn_fs_x__write_rep_header(svn_fs_x__rep_header_t *header,
                            svn_stream_t *stream,
-                           apr_pool_t *pool)
+                           apr_pool_t *scratch_pool)
 {
   const char *text;
   
@@ -751,8 +773,8 @@ svn_fs_x__write_rep_header(svn_fs_x__rep
         break;
 
       default:
-        text = apr_psprintf(pool, REP_DELTA " %ld %" APR_OFF_T_FMT " %"
-                            SVN_FILESIZE_T_FMT "\n",
+        text = apr_psprintf(scratch_pool, REP_DELTA " %ld %" APR_OFF_T_FMT
+                                          " %" SVN_FILESIZE_T_FMT "\n",
                             header->base_revision, header->base_item_index,
                             header->base_length);
     }
@@ -948,20 +970,22 @@ read_change(change_t **change_p,
 svn_error_t *
 svn_fs_x__read_changes(apr_array_header_t **changes,
                        svn_stream_t *stream,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
   change_t *change;
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_pool_t *iterpool;
 
   /* pre-allocate enough room for most change lists
      (will be auto-expanded as necessary) */
-  *changes = apr_array_make(pool, 30, sizeof(change_t *));
+  *changes = apr_array_make(result_pool, 30, sizeof(change_t *));
 
-  SVN_ERR(read_change(&change, stream, pool, iterpool));
+  SVN_ERR(read_change(&change, stream, result_pool, scratch_pool));
+  iterpool = svn_pool_create(scratch_pool);
   while (change)
     {
       APR_ARRAY_PUSH(*changes, change_t*) = change;
-      SVN_ERR(read_change(&change, stream, pool, iterpool));
+      SVN_ERR(read_change(&change, stream, result_pool, iterpool));
       svn_pool_clear(iterpool);
     }
   svn_pool_destroy(iterpool);
@@ -974,12 +998,12 @@ svn_fs_x__read_changes_incrementally(svn
                                      svn_fs_x__change_receiver_t
                                        change_receiver,
                                      void *change_receiver_baton,
-                                     apr_pool_t *pool)
+                                     apr_pool_t *scratch_pool)
 {
   change_t *change;
   apr_pool_t *iterpool;
 
-  iterpool = svn_pool_create(pool);
+  iterpool = svn_pool_create(scratch_pool);
   do
     {
       svn_pool_clear(iterpool);
@@ -996,12 +1020,12 @@ svn_fs_x__read_changes_incrementally(svn
 
 /* Write a single change entry, path PATH, change CHANGE, and copyfrom
    string COPYFROM, into the file specified by FILE.  All temporary
-   allocations are in POOL. */
+   allocations are in SCRATCH_POOL. */
 static svn_error_t *
 write_change_entry(svn_stream_t *stream,
                    const char *path,
                    svn_fs_path_change2_t *change,
-                   apr_pool_t *pool)
+                   apr_pool_t *scratch_pool)
 {
   const char *idstr;
   const char *change_string = NULL;
@@ -1033,29 +1057,31 @@ write_change_entry(svn_stream_t *stream,
     }
 
   if (change->node_rev_id)
-    idstr = svn_fs_x__id_unparse(change->node_rev_id, pool)->data;
+    idstr = svn_fs_x__id_unparse(change->node_rev_id, scratch_pool)->data;
   else
     idstr = ACTION_RESET;
 
   SVN_ERR_ASSERT(change->node_kind == svn_node_dir
-                  || change->node_kind == svn_node_file);
-  kind_string = apr_psprintf(pool, "-%s",
-                              change->node_kind == svn_node_dir
-                              ? SVN_FS_X__KIND_DIR
-                              : SVN_FS_X__KIND_FILE);
-  buf = svn_stringbuf_createf(pool, "%s %s%s %s %s %s %s\n",
+                 || change->node_kind == svn_node_file);
+  kind_string = apr_psprintf(scratch_pool, "-%s",
+                             change->node_kind == svn_node_dir
+                             ? SVN_FS_X__KIND_DIR
+                             : SVN_FS_X__KIND_FILE);
+
+  buf = svn_stringbuf_createf(scratch_pool, "%s %s%s %s %s %s %s\n",
                               idstr, change_string, kind_string,
                               change->text_mod ? FLAG_TRUE : FLAG_FALSE,
                               change->prop_mod ? FLAG_TRUE : FLAG_FALSE,
                               change->mergeinfo_mod == svn_tristate_true
                                                ? FLAG_TRUE : FLAG_FALSE,
-                              auto_escape_path(path, pool));
+                              auto_escape_path(path, scratch_pool));
 
   if (SVN_IS_VALID_REVNUM(change->copyfrom_rev))
     {
-      svn_stringbuf_appendcstr(buf, apr_psprintf(pool, "%ld %s",
-                             change->copyfrom_rev,
-                             auto_escape_path(change->copyfrom_path, pool)));
+      svn_stringbuf_appendcstr(buf, apr_psprintf(scratch_pool, "%ld %s",
+                               change->copyfrom_rev,
+                               auto_escape_path(change->copyfrom_path,
+                                                scratch_pool)));
     }
 
   svn_stringbuf_appendbyte(buf, '\n');
@@ -1070,9 +1096,9 @@ svn_fs_x__write_changes(svn_stream_t *st
                         svn_fs_t *fs,
                         apr_hash_t *changes,
                         svn_boolean_t terminate_list,
-                        apr_pool_t *pool)
+                        apr_pool_t *scratch_pool)
 {
-  apr_pool_t *iterpool = svn_pool_create(pool);
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
   apr_array_header_t *sorted_changed_paths;
   int i;
 
@@ -1080,7 +1106,8 @@ svn_fs_x__write_changes(svn_stream_t *st
      that the final file is deterministic and repeatable, however the
      rest of the FSX code doesn't require any particular order here. */
   sorted_changed_paths = svn_sort__hash(changes,
-                                        svn_sort_compare_items_lexically, pool);
+                                        svn_sort_compare_items_lexically,
+                                        scratch_pool);
 
   /* Write all items to disk in the new order. */
   for (i = 0; i < sorted_changed_paths->nelts; ++i)
@@ -1099,7 +1126,7 @@ svn_fs_x__write_changes(svn_stream_t *st
 
   if (terminate_list)
     svn_stream_puts(stream, "\n");
-  
+
   svn_pool_destroy(iterpool);
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/libsvn_fs_x/low_level.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/low_level.h?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/low_level.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/low_level.h Thu Oct 30 03:02:05 2014
@@ -52,12 +52,12 @@ svn_fs_x__parse_revision_trailer(apr_off
 
 /* Given the offset of the root noderev in ROOT_OFFSET and the offset of
  * the changed paths list in CHANGES_OFFSET,  return the corresponding
- * revision's trailer.  Allocate it in POOL.
+ * revision's trailer.  Allocate it in RESULT_POOL.
  */
 svn_stringbuf_t *
 svn_fs_x__unparse_revision_trailer(apr_off_t root_offset,
                                    apr_off_t changes_offset,
-                                   apr_pool_t *pool);
+                                   apr_pool_t *result_pool);
 
 /* Given the FSX revision / pack FOOTER, parse it destructively
  * and return the start offsets of the index data in *L2P_OFFSET and
@@ -74,46 +74,47 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of
 
 /* Given the offset of the L2P index data in L2P_OFFSET and the offset of
  * the P2L index data in P2L_OFFSET,  return the corresponding format 7+
- * revision / pack file footer.  Allocate it in POOL.
+ * revision / pack file footer.  Allocate it in RESULT_POOL.
  */
 svn_stringbuf_t *
 svn_fs_x__unparse_footer(apr_off_t l2p_offset,
                          apr_off_t p2l_offset,
-                         apr_pool_t *pool);
+                         apr_pool_t *result_pool);
 
 /* Parse the description of a representation from TEXT and store it
-   into *REP_P.  Allocate *REP_P in POOL. */
+   into *REP_P.  TEXT will be invalidated by this call.  Allocate *REP_P in
+   RESULT_POOL and use SCRATCH_POOL for temporaries. */
 svn_error_t *
 svn_fs_x__parse_representation(representation_t **rep_p,
                                svn_stringbuf_t *text,
-                               apr_pool_t *pool);
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool);
 
-/* Return a formatted string, compatible with filesystem format FORMAT,
-   that represents the location of representation REP.  If
-   MUTABLE_REP_TRUNCATED is given, the rep is for props or dir contents,
-   and only a "-1" revision number will be given for a mutable rep.
-   If MAY_BE_CORRUPT is true, guard for NULL when constructing the string.
-   Perform the allocation from POOL.  */
+/* Return a formatted string that represents the location of representation
+ * REP.  If MUTABLE_REP_TRUNCATED is given, the rep is for props or dir
+ * contents, and only a "-1" revision number will be given for a mutable rep.
+ * If MAY_BE_CORRUPT is true, guard for NULL when constructing the string.
+ * Allocate the result in RESULT_POOL and temporaries in SCRATCH_POOL. */
 svn_stringbuf_t *
 svn_fs_x__unparse_representation(representation_t *rep,
-                                 int format,
                                  svn_boolean_t mutable_rep_truncated,
-                                 apr_pool_t *pool);
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool);
 
 /* Read a node-revision from STREAM. Set *NODEREV to the new structure,
-   allocated in POOL. */
+   allocated in RESULT_POOL. */
 svn_error_t *
 svn_fs_x__read_noderev(node_revision_t **noderev,
                        svn_stream_t *stream,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool);
 
-/* Write the node-revision NODEREV into the stream OUTFILE, compatible with
-   filesystem format FORMAT.  Temporary allocations are from POOL. */
+/* Write the node-revision NODEREV into the stream OUTFILE.
+   Temporary allocations are from SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__write_noderev(svn_stream_t *outfile,
                         node_revision_t *noderev,
-                        int format,
-                        apr_pool_t *pool);
+                        apr_pool_t *scratch_pool);
 
 /* This type enumerates all forms of representations that we support. */
 typedef enum svn_fs_x__rep_type_t
@@ -154,34 +155,41 @@ typedef struct svn_fs_x__rep_header_t
   apr_size_t header_size;
 } svn_fs_x__rep_header_t;
 
-/* Read the next line from file FILE and parse it as a text
-   representation entry.  Return the parsed entry in *REP_ARGS_P.
-   Perform all allocations in POOL. */
+/* Read the next line from STREAM and parse it as a text
+   representation header.  Return the parsed entry in *HEADER, allocated
+   in RESULT_POOL. Perform temporary allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__read_rep_header(svn_fs_x__rep_header_t **header,
                           svn_stream_t *stream,
-                          apr_pool_t *pool);
+                          apr_pool_t *result_pool,
+                          apr_pool_t *scratch_pool);
 
-/* Write the representation HEADER to STREAM.  Use POOL for allocations. */
+/* Write the representation HEADER to STREAM. 
+ * Use SCRATCH_POOL for allocations. */
 svn_error_t *
 svn_fs_x__write_rep_header(svn_fs_x__rep_header_t *header,
                            svn_stream_t *stream,
-                           apr_pool_t *pool);
+                           apr_pool_t *scratch_pool);
 
-/* Read all the changes from STREAM and store them in *CHANGES.  Do all
-   allocations in POOL. */
+/* Read all the changes from STREAM and store them in *CHANGES,
+   allocated in RESULT_POOL. Do temporary allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__read_changes(apr_array_header_t **changes,
                        svn_stream_t *stream,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool);
 
+/* Callback function used by svn_fs_fs__read_changes_incrementally(),
+ * asking the receiver to process to process CHANGE using BATON.  CHANGE
+ * and SCRATCH_POOL will not be valid beyond the current callback invocation.
+ */
 typedef svn_error_t *(*svn_fs_x__change_receiver_t)(
   void *baton,
   change_t *change,
   apr_pool_t *scratch_pool);
 
 /* Read all the changes from STREAM and invoke CHANGE_RECEIVER on each change.
-   Do all allocations in POOL. */
+   Do all allocations in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__read_changes_incrementally(svn_stream_t *stream,
                                      svn_fs_x__change_receiver_t
@@ -193,14 +201,14 @@ svn_fs_x__read_changes_incrementally(svn
    output stream STREAM.  You may call this function multiple time on
    the same stream but the last call should set TERMINATE_LIST to write
    an extra empty line that marks the end of the changed paths list.
-   Perform temporary allocations in POOL.
+   Perform temporary allocations in SCRATCH_POOL.
  */
 svn_error_t *
 svn_fs_x__write_changes(svn_stream_t *stream,
                         svn_fs_t *fs,
                         apr_hash_t *changes,
                         svn_boolean_t terminate_list,
-                        apr_pool_t *pool);
+                        apr_pool_t *scratch_pool);
 
 #ifdef __cplusplus
 }

Modified: subversion/trunk/subversion/libsvn_fs_x/pack.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/pack.c?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/pack.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/pack.c Thu Oct 30 03:02:05 2014
@@ -571,7 +571,8 @@ copy_rep_to_temp(pack_context_t *context
   add_item_rep_mapping(context, entry);
 
   /* read & parse the representation header */
-  SVN_ERR(svn_fs_x__read_rep_header(&rep_header, rev_file->stream, pool));
+  SVN_ERR(svn_fs_x__read_rep_header(&rep_header, rev_file->stream, pool,
+                                    pool));
 
   /* if the representation is a delta against some other rep, link the two */
   if (   rep_header->type == svn_fs_x__rep_delta
@@ -681,7 +682,7 @@ copy_node_to_temp(pack_context_t *contex
   apr_off_t source_offset = entry->offset;
 
   /* read & parse noderev */
-  SVN_ERR(svn_fs_x__read_noderev(&noderev, rev_file->stream, pool));
+  SVN_ERR(svn_fs_x__read_noderev(&noderev, rev_file->stream, pool, pool));
 
   /* create a copy of ENTRY, make it point to the copy destination and
    * store it in CONTEXT */
@@ -1195,7 +1196,7 @@ store_nodes(pack_context_t *context,
 
       /* item will fit into the block. */
       SVN_ERR(svn_io_file_seek(temp_file, APR_SET, &entry->offset, iterpool));
-      SVN_ERR(svn_fs_x__read_noderev(&noderev, stream, iterpool));
+      SVN_ERR(svn_fs_x__read_noderev(&noderev, stream, iterpool, iterpool));
       svn_fs_x__noderevs_add(*container, noderev);
 
       container_size += entry->size;
@@ -1645,7 +1646,7 @@ write_changes_containers(pack_context_t 
        * the container */
       SVN_ERR(svn_io_file_seek(temp_file, APR_SET, &entry->offset,
                                iterpool));
-      SVN_ERR(svn_fs_x__read_changes(&changes, temp_stream, iterpool));
+      SVN_ERR(svn_fs_x__read_changes(&changes, temp_stream, pool, iterpool));
       SVN_ERR(svn_fs_x__changes_append_list(&list_index, container, changes));
       SVN_ERR_ASSERT(list_index == sub_items->nelts);
       block_left -= estimated_size;

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1635377&r1=1635376&r2=1635377&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Thu Oct 30 03:02:05 2014
@@ -751,7 +751,6 @@ svn_fs_x__put_node_revision(svn_fs_t *fs
                             svn_boolean_t fresh_txn_root,
                             apr_pool_t *pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
   apr_file_t *noderev_file;
 
   noderev->is_fresh_txn_root = fresh_txn_root;
@@ -768,7 +767,7 @@ svn_fs_x__put_node_revision(svn_fs_t *fs
 
   SVN_ERR(svn_fs_x__write_noderev(svn_stream_from_aprfile2(noderev_file, TRUE,
                                                            pool),
-                                  noderev, ffd->format, pool));
+                                  noderev, pool));
 
   SVN_ERR(svn_io_file_close(noderev_file, pool));
 
@@ -777,12 +776,12 @@ svn_fs_x__put_node_revision(svn_fs_t *fs
 
 /* For the in-transaction NODEREV within FS, write the sha1->rep mapping
  * file in the respective transaction, if rep sharing has been enabled etc.
- * Use POOL for temporary allocations.
+ * Use SCATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 store_sha1_rep_mapping(svn_fs_t *fs,
                        node_revision_t *noderev,
-                       apr_pool_t *pool)
+                       apr_pool_t *scratch_pool)
 {
   fs_x_data_t *ffd = fs->fsap_data;
 
@@ -797,20 +796,21 @@ store_sha1_rep_mapping(svn_fs_t *fs,
         = svn_fs_x__get_txn_id(noderev->data_rep->id.change_set);
       const char *file_name
         = svn_fs_x__path_txn_sha1(fs, txn_id,
-                                  noderev->data_rep->sha1_digest, pool);
+                                  noderev->data_rep->sha1_digest,
+                                  scratch_pool);
       svn_stringbuf_t *rep_string
         = svn_fs_x__unparse_representation(noderev->data_rep,
-                                           ffd->format,
                                            (noderev->kind == svn_node_dir),
-                                           pool);
+                                           scratch_pool, scratch_pool);
+
       SVN_ERR(svn_io_file_open(&rep_file, file_name,
                                APR_WRITE | APR_CREATE | APR_TRUNCATE
-                               | APR_BUFFERED, APR_OS_DEFAULT, pool));
+                               | APR_BUFFERED, APR_OS_DEFAULT, scratch_pool));
 
       SVN_ERR(svn_io_file_write_full(rep_file, rep_string->data,
-                                     rep_string->len, NULL, pool));
+                                     rep_string->len, NULL, scratch_pool));
 
-      SVN_ERR(svn_io_file_close(rep_file, pool));
+      SVN_ERR(svn_io_file_close(rep_file, scratch_pool));
     }
 
   return SVN_NO_ERROR;
@@ -1158,7 +1158,7 @@ create_new_txn_noderev_from_rev(svn_fs_t
 {
   node_revision_t *noderev;
 
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, src, pool));
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, src, pool, pool));
 
   /* This must be a root node. */
   SVN_ERR_ASSERT(   svn_fs_x__id_node_id(noderev->id)->number == 0
@@ -1276,7 +1276,7 @@ svn_fs_x__create_txn(svn_fs_txn_t **txn_
   *txn_p = txn;
 
   /* Create a new root node for this transaction. */
-  SVN_ERR(svn_fs_x__rev_get_root(&root_id, fs, rev, pool));
+  SVN_ERR(svn_fs_x__rev_get_root(&root_id, fs, rev, pool, pool));
   SVN_ERR(create_new_txn_noderev_from_rev(fs, ftd->txn_id, root_id, pool));
 
   /* Create an empty rev file. */
@@ -1427,7 +1427,7 @@ svn_fs_x__get_txn(transaction_t **txn_p,
   SVN_ERR(get_txn_proplist(txn->proplist, fs, txn_id, pool));
   root_id = svn_fs_x__id_txn_create_root(txn_id, pool);
 
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, root_id, pool));
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, root_id, pool, pool));
 
   txn->root_id = svn_fs_x__id_copy(noderev->id, pool);
   txn->base_id = svn_fs_x__id_copy(noderev->predecessor_id, pool);
@@ -1872,9 +1872,11 @@ struct rep_write_baton
   /* Receives the low-level checksum when closing REP_STREAM. */
   apr_uint32_t fnv1a_checksum;
 
-  apr_pool_t *pool;
+  /* Local / scratch pool, available for temporary allocations. */
+  apr_pool_t *scratch_pool;
 
-  apr_pool_t *parent_pool;
+  /* Outer / result pool. */
+  apr_pool_t *result_pool;
 };
 
 /* Handler for the write method of the representation writable stream.
@@ -1906,13 +1908,17 @@ shards_spanned(int *spanned,
 {
   fs_x_data_t *ffd = fs->fsap_data;
   int shard_size = ffd->max_files_per_dir ? ffd->max_files_per_dir : 1;
+  apr_pool_t *iterpool;
 
   int count = walk ? 1 : 0; /* The start of a walk already touches a shard. */
   svn_revnum_t shard, last_shard = ffd->youngest_rev_cache / shard_size;
+  iterpool = svn_pool_create(pool);
   while (walk-- && noderev->predecessor_count)
     {
+      svn_pool_clear(iterpool);
       SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs,
-                                          noderev->predecessor_id, pool));
+                                          noderev->predecessor_id, pool,
+                                          iterpool));
       shard = svn_fs_x__id_rev(noderev->id) / shard_size;
       if (shard != last_shard)
         {
@@ -1920,6 +1926,7 @@ shards_spanned(int *spanned,
           last_shard = shard;
         }
     }
+  svn_pool_destroy(iterpool);
 
   *spanned = count;
   return SVN_NO_ERROR;
@@ -1946,6 +1953,7 @@ choose_delta_base(representation_t **rep
   int walk;
   node_revision_t *base;
   fs_x_data_t *ffd = fs->fsap_data;
+  apr_pool_t *iterpool;
 
   /* If we have no predecessors, or that one is empty, then use the empty
    * stream as a base. */
@@ -1992,9 +2000,15 @@ choose_delta_base(representation_t **rep
      if noderev has ten predecessors and we want the eighth file rev,
      walk back two predecessors.) */
   base = noderev;
+  iterpool = svn_pool_create(pool);
   while ((count++) < noderev->predecessor_count)
-    SVN_ERR(svn_fs_x__get_node_revision(&base, fs,
-                                        base->predecessor_id, pool));
+    {
+      svn_pool_clear(iterpool);
+      SVN_ERR(svn_fs_x__get_node_revision(&base, fs,
+                                          base->predecessor_id, pool,
+                                          iterpool));
+    }
+  svn_pool_destroy(iterpool);
 
   /* return a suitable base representation */
   *rep = props ? base->prop_rep : base->data_rep;
@@ -2052,8 +2066,9 @@ rep_write_cleanup(void *data)
   struct rep_write_baton *b = data;
 
   /* Truncate and close the protorevfile. */
-  err = svn_io_file_trunc(b->file, b->rep_offset, b->pool);
-  err = svn_error_compose_create(err, svn_io_file_close(b->file, b->pool));
+  err = svn_io_file_trunc(b->file, b->rep_offset, b->scratch_pool);
+  err = svn_error_compose_create(err, svn_io_file_close(b->file,
+                                                        b->scratch_pool));
 
   /* Remove our lock regardless of any preceding errors so that the
      being_written flag is always removed and stays consistent with the
@@ -2061,8 +2076,8 @@ rep_write_cleanup(void *data)
      going away. */
   err = svn_error_compose_create(err,
                                  unlock_proto_rev(b->fs,
-                                                  svn_fs_x__id_txn_id(b->noderev->id),
-                                                  b->lockcookie, b->pool));
+                                     svn_fs_x__id_txn_id(b->noderev->id),
+                                     b->lockcookie, b->scratch_pool));
   if (err)
     {
       apr_status_t rc = err->apr_err;
@@ -2099,27 +2114,29 @@ rep_write_get_baton(struct rep_write_bat
   b->md5_checksum_ctx = svn_checksum_ctx_create(svn_checksum_md5, pool);
 
   b->fs = fs;
-  b->parent_pool = pool;
-  b->pool = svn_pool_create(pool);
+  b->result_pool = pool;
+  b->scratch_pool = svn_pool_create(pool);
   b->rep_size = 0;
   b->noderev = noderev;
 
   /* Open the prototype rev file and seek to its end. */
   SVN_ERR(get_writable_proto_rev(&file, &b->lockcookie,
                                  fs, svn_fs_x__id_txn_id(noderev->id),
-                                 b->pool));
+                                 b->scratch_pool));
 
   b->file = file;
   b->rep_stream = svn_checksum__wrap_write_stream_fnv1a_32x4(
                               &b->fnv1a_checksum,
-                              svn_stream_from_aprfile2(file, TRUE, b->pool),
-                              b->pool);
+                              svn_stream_from_aprfile2(file, TRUE,
+                                                       b->scratch_pool),
+                              b->scratch_pool);
 
-  SVN_ERR(svn_fs_x__get_file_offset(&b->rep_offset, file, b->pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&b->rep_offset, file, b->scratch_pool));
 
   /* Get the base for this delta. */
-  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, FALSE, b->pool));
-  SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, TRUE, b->pool));
+  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, FALSE, b->scratch_pool));
+  SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, TRUE,
+                                 b->scratch_pool));
 
   /* Write out the rep header. */
   if (base_rep)
@@ -2133,24 +2150,27 @@ rep_write_get_baton(struct rep_write_bat
     {
       header.type = svn_fs_x__rep_self_delta;
     }
-  SVN_ERR(svn_fs_x__write_rep_header(&header, b->rep_stream, b->pool));
+  SVN_ERR(svn_fs_x__write_rep_header(&header, b->rep_stream,
+                                      b->scratch_pool));
 
   /* Now determine the offset of the actual svndiff data. */
-  SVN_ERR(svn_fs_x__get_file_offset(&b->delta_start, file, b->pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&b->delta_start, file,
+                                    b->scratch_pool));
 
   /* Cleanup in case something goes wrong. */
-  apr_pool_cleanup_register(b->pool, b, rep_write_cleanup,
+  apr_pool_cleanup_register(b->scratch_pool, b, rep_write_cleanup,
                             apr_pool_cleanup_null);
 
   /* Prepare to write the svndiff data. */
   svn_txdelta_to_svndiff3(&wh,
                           &whb,
-                          svn_stream_disown(b->rep_stream, b->pool),
+                          svn_stream_disown(b->rep_stream, b->result_pool),
                           diff_version,
                           ffd->delta_compression_level,
                           pool);
 
-  b->delta_stream = svn_txdelta_target_push(wh, whb, source, b->pool);
+  b->delta_stream = svn_txdelta_target_push(wh, whb, source,
+                                            b->result_pool);
 
   *wb_p = b;
 
@@ -2163,15 +2183,16 @@ rep_write_get_baton(struct rep_write_bat
    there may be new duplicate representations within the same uncommitted
    revision, those can be passed in REPS_HASH (maps a sha1 digest onto
    representation_t*), otherwise pass in NULL for REPS_HASH.
-   POOL will be used for allocations. The lifetime of the returned rep is
-   limited by both, POOL and REP lifetime.
+   Use RESULT_POOL for *OLD_REP  allocations and SCRATCH_POOL for temporaries.
+   The lifetime of *OLD_REP is limited by both, RESULT_POOL and REP lifetime.
  */
 static svn_error_t *
 get_shared_rep(representation_t **old_rep,
                svn_fs_t *fs,
                representation_t *rep,
                apr_hash_t *reps_hash,
-               apr_pool_t *pool)
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
   fs_x_data_t *ffd = fs->fsap_data;
@@ -2195,12 +2216,12 @@ get_shared_rep(representation_t **old_re
       svn_checksum_t checksum;
       checksum.digest = rep->sha1_digest;
       checksum.kind = svn_checksum_sha1;
-      err = svn_fs_x__get_rep_reference(old_rep, fs, &checksum, pool);
+      err = svn_fs_x__get_rep_reference(old_rep, fs, &checksum, result_pool);
       /* ### Other error codes that we shouldn't mask out? */
       if (err == SVN_NO_ERROR)
         {
           if (*old_rep)
-            SVN_ERR(svn_fs_x__check_rep(*old_rep, fs, pool));
+            SVN_ERR(svn_fs_x__check_rep(*old_rep, fs, scratch_pool));
         }
       else if (err->apr_err == SVN_ERR_FS_CORRUPT
                || SVN_ERROR_IN_CATEGORY(err->apr_err,
@@ -2235,17 +2256,19 @@ get_shared_rep(representation_t **old_re
       const char *file_name
         = svn_fs_x__path_txn_sha1(fs,
                                   svn_fs_x__get_txn_id(rep->id.change_set),
-                                  rep->sha1_digest, pool);
+                                  rep->sha1_digest, scratch_pool);
 
       /* in our txn, is there a rep file named with the wanted SHA1?
          If so, read it and use that rep.
        */
-      SVN_ERR(svn_io_check_path(file_name, &kind, pool));
+      SVN_ERR(svn_io_check_path(file_name, &kind, scratch_pool));
       if (kind == svn_node_file)
         {
           svn_stringbuf_t *rep_string;
-          SVN_ERR(svn_stringbuf_from_file2(&rep_string, file_name, pool));
-          SVN_ERR(svn_fs_x__parse_representation(old_rep, rep_string, pool));
+          SVN_ERR(svn_stringbuf_from_file2(&rep_string, file_name,
+                                           scratch_pool));
+          SVN_ERR(svn_fs_x__parse_representation(old_rep, rep_string,
+                                                 result_pool, scratch_pool));
         }
     }
 
@@ -2292,14 +2315,14 @@ rep_write_contents_close(void *baton)
   apr_off_t offset;
   apr_int64_t txn_id;
 
-  rep = apr_pcalloc(b->parent_pool, sizeof(*rep));
+  rep = apr_pcalloc(b->result_pool, sizeof(*rep));
 
   /* Close our delta stream so the last bits of svndiff are written
      out. */
   SVN_ERR(svn_stream_close(b->delta_stream));
 
   /* Determine the length of the svndiff data. */
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->scratch_pool));
   rep->size = offset - b->delta_start;
 
   /* Fill in the rest of the representation field. */
@@ -2309,16 +2332,17 @@ rep_write_contents_close(void *baton)
 
   /* Finalize the checksum. */
   SVN_ERR(digests_final(rep, b->md5_checksum_ctx, b->sha1_checksum_ctx,
-                        b->parent_pool));
+                        b->result_pool));
 
   /* Check and see if we already have a representation somewhere that's
      identical to the one we just wrote out. */
-  SVN_ERR(get_shared_rep(&old_rep, b->fs, rep, NULL, b->parent_pool));
+  SVN_ERR(get_shared_rep(&old_rep, b->fs, rep, NULL, b->result_pool,
+                         b->scratch_pool));
 
   if (old_rep)
     {
       /* We need to erase from the protorev the data we just wrote. */
-      SVN_ERR(svn_io_file_trunc(b->file, b->rep_offset, b->pool));
+      SVN_ERR(svn_io_file_trunc(b->file, b->rep_offset, b->scratch_pool));
 
       /* Use the old rep for this content. */
       b->noderev->data_rep = old_rep;
@@ -2327,9 +2351,10 @@ rep_write_contents_close(void *baton)
     {
       /* Write out our cosmetic end marker. */
       SVN_ERR(svn_stream_puts(b->rep_stream, "ENDREP\n"));
-      SVN_ERR(allocate_item_index(&rep->id.number, b->fs, txn_id, b->pool));
+      SVN_ERR(allocate_item_index(&rep->id.number, b->fs, txn_id,
+                                  b->scratch_pool));
       SVN_ERR(store_l2p_index_entry(b->fs, txn_id, b->rep_offset,
-                                    rep->id.number, b->pool));
+                                    rep->id.number, b->scratch_pool));
 
       b->noderev->data_rep = rep;
     }
@@ -2337,11 +2362,11 @@ rep_write_contents_close(void *baton)
   SVN_ERR(svn_stream_close(b->rep_stream));
 
   /* Remove cleanup callback. */
-  apr_pool_cleanup_kill(b->pool, b, rep_write_cleanup);
+  apr_pool_cleanup_kill(b->scratch_pool, b, rep_write_cleanup);
 
   /* Write out the new node-rev information. */
   SVN_ERR(svn_fs_x__put_node_revision(b->fs, b->noderev->id, b->noderev,
-                                      FALSE, b->pool));
+                                      FALSE, b->scratch_pool));
   if (!old_rep)
     {
       svn_fs_x__p2l_entry_t entry;
@@ -2350,20 +2375,20 @@ rep_write_contents_close(void *baton)
       noderev_id.number = rep->id.number;
 
       entry.offset = b->rep_offset;
-      SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->pool));
+      SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->scratch_pool));
       entry.size = offset - b->rep_offset;
       entry.type = SVN_FS_X__ITEM_TYPE_FILE_REP;
       entry.item_count = 1;
       entry.items = &noderev_id;
       entry.fnv1_checksum = b->fnv1a_checksum;
 
-      SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->pool));
-      SVN_ERR(store_p2l_index_entry(b->fs, txn_id, &entry, b->pool));
+      SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->scratch_pool));
+      SVN_ERR(store_p2l_index_entry(b->fs, txn_id, &entry, b->scratch_pool));
     }
 
-  SVN_ERR(svn_io_file_close(b->file, b->pool));
-  SVN_ERR(unlock_proto_rev(b->fs, txn_id, b->lockcookie, b->pool));
-  svn_pool_destroy(b->pool);
+  SVN_ERR(svn_io_file_close(b->file, b->scratch_pool));
+  SVN_ERR(unlock_proto_rev(b->fs, txn_id, b->lockcookie, b->scratch_pool));
+  svn_pool_destroy(b->scratch_pool);
 
   return SVN_NO_ERROR;
 }
@@ -2552,7 +2577,8 @@ write_directory_to_stream(svn_stream_t *
    If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_*_PROPS, assume
    that we want to a props representation as the base for our delta.
    If FINAL_REVISION is not SVN_INVALID_REVNUM, use it to determine whether
-   to write to the proto-index files.  Perform temporary allocations in POOL.
+   to write to the proto-index files.
+   Perform temporary allocations in SCRATCH_POOL.
  */
 static svn_error_t *
 write_container_delta_rep(representation_t *rep,
@@ -2565,7 +2591,7 @@ write_container_delta_rep(representation
                           apr_hash_t *reps_hash,
                           int item_type,
                           svn_revnum_t final_revision,
-                          apr_pool_t *pool)
+                          apr_pool_t *scratch_pool)
 {
   fs_x_data_t *ffd = fs->fsap_data;
   svn_txdelta_window_handler_t diff_wh;
@@ -2589,10 +2615,10 @@ write_container_delta_rep(representation
                         || (item_type == SVN_FS_X__ITEM_TYPE_DIR_PROPS);
 
   /* Get the base for this delta. */
-  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, is_props, pool));
-  SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, FALSE, pool));
+  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, is_props, scratch_pool));
+  SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, FALSE, scratch_pool));
 
-  SVN_ERR(svn_fs_x__get_file_offset(&offset, file, pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
 
   /* Write out the rep header. */
   if (base_rep)
@@ -2609,45 +2635,48 @@ write_container_delta_rep(representation
 
   file_stream = svn_checksum__wrap_write_stream_fnv1a_32x4(
                                   &entry.fnv1_checksum,
-                                  svn_stream_from_aprfile2(file, TRUE, pool),
-                                  pool);
-  SVN_ERR(svn_fs_x__write_rep_header(&header, file_stream, pool));
-  SVN_ERR(svn_fs_x__get_file_offset(&delta_start, file, pool));
+                                  svn_stream_from_aprfile2(file, TRUE,
+                                                           scratch_pool),
+                                  scratch_pool);
+  SVN_ERR(svn_fs_x__write_rep_header(&header, file_stream, scratch_pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&delta_start, file, scratch_pool));
 
   /* Prepare to write the svndiff data. */
   svn_txdelta_to_svndiff3(&diff_wh,
                           &diff_whb,
-                          svn_stream_disown(file_stream, pool),
+                          svn_stream_disown(file_stream, scratch_pool),
                           diff_version,
                           ffd->delta_compression_level,
-                          pool);
+                          scratch_pool);
 
-  whb = apr_pcalloc(pool, sizeof(*whb));
-  whb->stream = svn_txdelta_target_push(diff_wh, diff_whb, source, pool);
+  whb = apr_pcalloc(scratch_pool, sizeof(*whb));
+  whb->stream = svn_txdelta_target_push(diff_wh, diff_whb, source,
+                                        scratch_pool);
   whb->size = 0;
-  whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, pool);
-  whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, pool);
+  whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
+  whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);
 
   /* serialize the hash */
-  stream = svn_stream_create(whb, pool);
+  stream = svn_stream_create(whb, scratch_pool);
   svn_stream_set_write(stream, write_container_handler);
 
-  SVN_ERR(writer(stream, collection, pool));
+  SVN_ERR(writer(stream, collection, scratch_pool));
   SVN_ERR(svn_stream_close(whb->stream));
 
   /* Store the results. */
-  SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, pool));
+  SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));
 
   /* Check and see if we already have a representation somewhere that's
      identical to the one we just wrote out. */
-  SVN_ERR(get_shared_rep(&old_rep, fs, rep, reps_hash, pool));
+  SVN_ERR(get_shared_rep(&old_rep, fs, rep, reps_hash, scratch_pool,
+                         scratch_pool));
 
   if (old_rep)
     {
       SVN_ERR(svn_stream_close(file_stream));
 
       /* We need to erase from the protorev the data we just wrote. */
-      SVN_ERR(svn_io_file_trunc(file, offset, pool));
+      SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));
 
       /* Use the old rep for this content. */
       memcpy(rep, old_rep, sizeof (*rep));
@@ -2657,24 +2686,26 @@ write_container_delta_rep(representation
       svn_fs_x__id_part_t noderev_id;
 
       /* Write out our cosmetic end marker. */
-      SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, pool));
+      SVN_ERR(svn_fs_x__get_file_offset(&rep_end, file, scratch_pool));
       SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
       SVN_ERR(svn_stream_close(file_stream));
 
-      SVN_ERR(allocate_item_index(&rep->id.number, fs, txn_id, pool));
-      SVN_ERR(store_l2p_index_entry(fs, txn_id, offset, rep->id.number, pool));
+      SVN_ERR(allocate_item_index(&rep->id.number, fs, txn_id,
+                                  scratch_pool));
+      SVN_ERR(store_l2p_index_entry(fs, txn_id, offset, rep->id.number,
+                                    scratch_pool));
 
       noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
       noderev_id.number = rep->id.number;
 
       entry.offset = offset;
-      SVN_ERR(svn_fs_x__get_file_offset(&offset, file, pool));
+      SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
       entry.size = offset - entry.offset;
       entry.type = item_type;
       entry.item_count = 1;
       entry.items = &noderev_id;
 
-      SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, pool));
+      SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, scratch_pool));
 
       /* update the representation */
       rep->expanded_size = whb->size;
@@ -2711,7 +2742,7 @@ validate_root_noderev(svn_fs_t *fs,
     SVN_ERR(svn_fs_x__revision_root(&head_revision, fs, head_revnum, pool));
     SVN_ERR(svn_fs_x__node_id(&head_root_id, head_revision, "/", pool));
     SVN_ERR(svn_fs_x__get_node_revision(&head_root_noderev, fs, head_root_id,
-                                        pool));
+                                        pool, pool));
 
     head_predecessor_count = head_root_noderev->predecessor_count;
   }
@@ -2804,6 +2835,7 @@ write_final_rev(const svn_fs_id_t **new_
   svn_fs_x__p2l_entry_t entry;
   svn_fs_x__change_set_t change_set = svn_fs_x__change_set_by_rev(rev);
   svn_stream_t *file_stream;
+  apr_pool_t *subpool;
 
   *new_id_p = NULL;
 
@@ -2811,16 +2843,15 @@ write_final_rev(const svn_fs_id_t **new_
   if (! svn_fs_x__id_is_txn(id))
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool));
+  subpool = svn_pool_create(pool);
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool, subpool));
 
   if (noderev->kind == svn_node_dir)
     {
-      apr_pool_t *subpool;
       apr_array_header_t *entries;
       int i;
 
       /* This is a directory.  Write out all the children first. */
-      subpool = svn_pool_create(pool);
 
       SVN_ERR(svn_fs_x__rep_contents_dir(&entries, fs, noderev, pool,
                                          subpool));
@@ -2836,7 +2867,6 @@ write_final_rev(const svn_fs_id_t **new_
           if (new_id && (svn_fs_x__id_rev(new_id) == rev))
             dirent->id = svn_fs_x__id_copy(new_id, pool);
         }
-      svn_pool_destroy(subpool);
 
       if (noderev->data_rep
           && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
@@ -2864,6 +2894,8 @@ write_final_rev(const svn_fs_id_t **new_
         }
     }
 
+  svn_pool_destroy(subpool);
+
   /* Fix up the property reps. */
   if (noderev->prop_rep
       && svn_fs_x__is_txn(noderev->prop_rep->id.change_set))
@@ -2947,7 +2979,7 @@ write_final_rev(const svn_fs_id_t **new_
                                   &entry.fnv1_checksum,
                                   svn_stream_from_aprfile2(file, TRUE, pool),
                                   pool);
-  SVN_ERR(svn_fs_x__write_noderev(file_stream, noderev, ffd->format, pool));
+  SVN_ERR(svn_fs_x__write_noderev(file_stream, noderev, pool));
   SVN_ERR(svn_stream_close(file_stream));
 
   /* reference the root noderev from the log-to-phys index */
@@ -3567,7 +3599,7 @@ svn_fs_x__delete_node_revision(svn_fs_t 
 {
   node_revision_t *noderev;
 
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool));
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, pool, pool));
 
   /* Delete any mutable property representation. */
   if (noderev->prop_rep