You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2015/01/28 00:27:46 UTC

svn commit: r1655189 [3/9] - in /subversion/branches/svn-auth-x509: ./ build/ build/generator/ subversion/bindings/javahl/native/ subversion/include/ subversion/include/private/ subversion/libsvn_client/ subversion/libsvn_fs_base/ subversion/libsvn_fs_...

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.c Tue Jan 27 23:27:44 2015
@@ -182,12 +182,13 @@ with_txnlist_lock(svn_fs_t *fs,
 }
 
 
-/* Get a lock on empty file LOCK_FILENAME, creating it in POOL. */
+/* Get a lock on empty file LOCK_FILENAME, creating it in RESULT_POOL. */
 static svn_error_t *
 get_lock_on_filesystem(const char *lock_filename,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool)
 {
-  return svn_error_trace(svn_io__file_lock_autocreate(lock_filename, pool));
+  return svn_error_trace(svn_io__file_lock_autocreate(lock_filename,
+                                                      result_pool));
 }
 
 /* Reset the HAS_WRITE_LOCK member in the FFD given as BATON_VOID.
@@ -355,7 +356,8 @@ init_lock_baton(with_lock_baton_t *baton
 
 /* Return the  baton for the innermost lock of a (potential) lock chain.
    The baton shall take out LOCK_ID from FS and execute BODY with BATON
-   while the lock is being held.  Allocate the result in a sub-pool of POOL.
+   while the lock is being held.  Allocate the result in a sub-pool of
+   RESULT_POOL.
  */
 static with_lock_baton_t *
 create_lock_baton(svn_fs_t *fs,
@@ -363,11 +365,11 @@ create_lock_baton(svn_fs_t *fs,
                   svn_error_t *(*body)(void *baton,
                                        apr_pool_t *scratch_pool),
                   void *baton,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool)
 {
   /* Allocate everything along the lock chain into a single sub-pool.
      This minimizes memory usage and cleanup overhead. */
-  apr_pool_t *lock_pool = svn_pool_create(pool);
+  apr_pool_t *lock_pool = svn_pool_create(result_pool);
   with_lock_baton_t *result = apr_pcalloc(lock_pool, sizeof(*result));
 
   /* Store parameters. */
@@ -486,11 +488,11 @@ svn_fs_x__with_all_locks(svn_fs_t *fs,
 
 /* A structure used by unlock_proto_rev() and unlock_proto_rev_body(),
    which see. */
-struct unlock_proto_rev_baton
+typedef struct unlock_proto_rev_baton_t
 {
   svn_fs_x__txn_id_t txn_id;
   void *lockcookie;
-};
+} unlock_proto_rev_baton_t;
 
 /* Callback used in the implementation of unlock_proto_rev(). */
 static svn_error_t *
@@ -498,7 +500,7 @@ unlock_proto_rev_body(svn_fs_t *fs,
                       const void *baton,
                       apr_pool_t *scratch_pool)
 {
-  const struct unlock_proto_rev_baton *b = baton;
+  const unlock_proto_rev_baton_t *b = baton;
   apr_file_t *lockfile = b->lockcookie;
   svn_fs_x__shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, FALSE);
   apr_status_t apr_err;
@@ -541,7 +543,7 @@ unlock_proto_rev(svn_fs_t *fs,
                  void *lockcookie,
                  apr_pool_t *scratch_pool)
 {
-  struct unlock_proto_rev_baton b;
+  unlock_proto_rev_baton_t b;
 
   b.txn_id = txn_id;
   b.lockcookie = lockcookie;
@@ -550,11 +552,11 @@ unlock_proto_rev(svn_fs_t *fs,
 
 /* A structure used by get_writable_proto_rev() and
    get_writable_proto_rev_body(), which see. */
-struct get_writable_proto_rev_baton
+typedef struct get_writable_proto_rev_baton_t
 {
   void **lockcookie;
   svn_fs_x__txn_id_t txn_id;
-};
+} get_writable_proto_rev_baton_t;
 
 /* Callback used in the implementation of get_writable_proto_rev(). */
 static svn_error_t *
@@ -562,7 +564,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
                             const void *baton,
                             apr_pool_t *scratch_pool)
 {
-  const struct get_writable_proto_rev_baton *b = baton;
+  const get_writable_proto_rev_baton_t *b = baton;
   void **lockcookie = b->lockcookie;
   svn_fs_x__shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, TRUE);
 
@@ -688,7 +690,7 @@ get_writable_proto_rev(apr_file_t **file
                        svn_fs_x__txn_id_t txn_id,
                        apr_pool_t *pool)
 {
-  struct get_writable_proto_rev_baton b;
+  get_writable_proto_rev_baton_t b;
   svn_error_t *err;
   apr_off_t end_offset = 0;
 
@@ -773,7 +775,8 @@ svn_fs_x__put_node_revision(svn_fs_t *fs
                              svn_fs_x__id_unparse(id, scratch_pool)->data);
 
   SVN_ERR(svn_io_file_open(&noderev_file,
-                           svn_fs_x__path_txn_node_rev(fs, id, scratch_pool),
+                           svn_fs_x__path_txn_node_rev(fs, id, scratch_pool,
+                                                       scratch_pool),
                            APR_WRITE | APR_CREATE | APR_TRUNCATE
                            | APR_BUFFERED, APR_OS_DEFAULT, scratch_pool));
 
@@ -1168,11 +1171,11 @@ create_new_txn_noderev_from_rev(svn_fs_t
 }
 
 /* A structure used by get_and_increment_txn_key_body(). */
-struct get_and_increment_txn_key_baton {
+typedef struct get_and_increment_txn_key_baton_t
+{
   svn_fs_t *fs;
   apr_uint64_t txn_number;
-  apr_pool_t *pool;
-};
+} get_and_increment_txn_key_baton_t;
 
 /* Callback used in the implementation of create_txn_dir().  This gets
    the current base 36 value in PATH_TXN_CURRENT and increments it.
@@ -1181,14 +1184,14 @@ static svn_error_t *
 get_and_increment_txn_key_body(void *baton,
                                apr_pool_t *scratch_pool)
 {
-  struct get_and_increment_txn_key_baton *cb = baton;
+  get_and_increment_txn_key_baton_t *cb = baton;
   const char *txn_current_filename = svn_fs_x__path_txn_current(cb->fs,
                                                                 scratch_pool);
   const char *tmp_filename;
   char new_id_str[SVN_INT64_BUFFER_SIZE];
 
   svn_stringbuf_t *buf;
-  SVN_ERR(svn_fs_x__read_content(&buf, txn_current_filename, cb->pool));
+  SVN_ERR(svn_fs_x__read_content(&buf, txn_current_filename, scratch_pool));
 
   /* remove trailing newlines */
   cb->txn_number = svn__base36toui64(NULL, buf->data);
@@ -1214,44 +1217,52 @@ static svn_error_t *
 create_txn_dir(const char **id_p,
                svn_fs_x__txn_id_t *txn_id,
                svn_fs_t *fs,
-               apr_pool_t *pool)
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
-  struct get_and_increment_txn_key_baton cb;
+  get_and_increment_txn_key_baton_t cb;
   const char *txn_dir;
 
   /* Get the current transaction sequence value, which is a base-36
      number, from the txn-current file, and write an
      incremented value back out to the file.  Place the revision
      number the transaction is based off into the transaction id. */
-  cb.pool = pool;
   cb.fs = fs;
   SVN_ERR(svn_fs_x__with_txn_current_lock(fs,
                                           get_and_increment_txn_key_body,
                                           &cb,
-                                          pool));
+                                          scratch_pool));
   *txn_id = cb.txn_number;
 
-  *id_p = svn_fs_x__txn_name(*txn_id, pool);
-  txn_dir = svn_fs_x__path_txn_dir(fs, *txn_id, pool);
+  *id_p = svn_fs_x__txn_name(*txn_id, result_pool);
+  txn_dir = svn_fs_x__path_txn_dir(fs, *txn_id, scratch_pool);
 
-  return svn_io_dir_make(txn_dir, APR_OS_DEFAULT, pool);
+  return svn_io_dir_make(txn_dir, APR_OS_DEFAULT, scratch_pool);
 }
 
-svn_error_t *
-svn_fs_x__create_txn(svn_fs_txn_t **txn_p,
-                     svn_fs_t *fs,
-                     svn_revnum_t rev,
-                     apr_pool_t *pool)
+/* Create a new transaction in filesystem FS, based on revision REV,
+   and store it in *TXN_P, allocated in RESULT_POOL.  Allocate necessary
+   temporaries from SCRATCH_POOL. */
+static svn_error_t *
+create_txn(svn_fs_txn_t **txn_p,
+           svn_fs_t *fs,
+           svn_revnum_t rev,
+           apr_pool_t *result_pool,
+           apr_pool_t *scratch_pool)
 {
   svn_fs_txn_t *txn;
   fs_txn_data_t *ftd;
   svn_fs_x__id_t root_id;
 
-  txn = apr_pcalloc(pool, sizeof(*txn));
-  ftd = apr_pcalloc(pool, sizeof(*ftd));
+  txn = apr_pcalloc(result_pool, sizeof(*txn));
+  ftd = apr_pcalloc(result_pool, sizeof(*ftd));
+
+  /* Valid revision number? */
+  SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, scratch_pool));
 
   /* Get the txn_id. */
-  SVN_ERR(create_txn_dir(&txn->id, &ftd->txn_id, fs, pool));
+  SVN_ERR(create_txn_dir(&txn->id, &ftd->txn_id, fs, result_pool,
+                         scratch_pool));
 
   txn->fs = fs;
   txn->base_rev = rev;
@@ -1261,28 +1272,31 @@ 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(create_new_txn_noderev_from_rev(fs, ftd->txn_id, &root_id, pool));
+  svn_fs_x__init_rev_root(&root_id, rev);
+  SVN_ERR(create_new_txn_noderev_from_rev(fs, ftd->txn_id, &root_id,
+                                          scratch_pool));
 
   /* Create an empty rev file. */
   SVN_ERR(svn_io_file_create_empty(
-              svn_fs_x__path_txn_proto_rev(fs, ftd->txn_id, pool),
-              pool));
+              svn_fs_x__path_txn_proto_rev(fs, ftd->txn_id, scratch_pool),
+              scratch_pool));
 
   /* Create an empty rev-lock file. */
   SVN_ERR(svn_io_file_create_empty(
-              svn_fs_x__path_txn_proto_rev_lock(fs, ftd->txn_id, pool),
-              pool));
+              svn_fs_x__path_txn_proto_rev_lock(fs, ftd->txn_id, scratch_pool),
+              scratch_pool));
 
   /* Create an empty changes file. */
   SVN_ERR(svn_io_file_create_empty(
-              svn_fs_x__path_txn_changes(fs, ftd->txn_id, pool),
-              pool));
+              svn_fs_x__path_txn_changes(fs, ftd->txn_id, scratch_pool),
+              scratch_pool));
 
   /* Create the next-ids file. */
-  return svn_io_file_create(
-              svn_fs_x__path_txn_next_ids(fs, ftd->txn_id, pool),
-              "0 0\n", pool);
+  SVN_ERR(svn_io_file_create(
+              svn_fs_x__path_txn_next_ids(fs, ftd->txn_id, scratch_pool),
+              "0 0\n", scratch_pool));
+
+  return SVN_NO_ERROR;
 }
 
 /* Store the property list for transaction TXN_ID in PROPLIST.
@@ -1691,12 +1705,13 @@ svn_fs_x__set_entry(svn_fs_t *fs,
                     const char *name,
                     const svn_fs_x__id_t *id,
                     svn_node_kind_t kind,
+                    apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
 {
   svn_fs_x__representation_t *rep = parent_noderev->data_rep;
   const char *filename
     = svn_fs_x__path_txn_node_children(fs, &parent_noderev->noderev_id,
-                                       scratch_pool);
+                                       scratch_pool, scratch_pool);
   apr_file_t *file;
   svn_stream_t *out;
   svn_fs_x__data_t *ffd = fs->fsap_data;
@@ -1718,13 +1733,21 @@ svn_fs_x__set_entry(svn_fs_t *fs,
 
       svn_pool_clear(subpool);
 
+      /* Provide the parent with a data rep if it had none before
+         (directories so far empty). */
+      if (!rep)
+        {
+          rep = apr_pcalloc(result_pool, sizeof(*rep));
+          parent_noderev->data_rep = rep;
+        }
+
       /* Mark the node-rev's data rep as mutable. */
-      rep = apr_pcalloc(scratch_pool, sizeof(*rep));
       rep->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
       rep->id.number = SVN_FS_X__ITEM_INDEX_UNUSED;
-      parent_noderev->data_rep = rep;
+
+      /* Save noderev to disk. */
       SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev, FALSE,
-                                          scratch_pool));
+                                          subpool));
     }
   else
     {
@@ -1829,7 +1852,7 @@ svn_fs_x__add_change(svn_fs_t *fs,
 /* This baton is used by the representation writing streams.  It keeps
    track of the checksum information as well as the total size of the
    representation so far. */
-struct rep_write_baton
+typedef struct rep_write_baton_t
 {
   /* The FS we are writing to. */
   svn_fs_t *fs;
@@ -1865,22 +1888,23 @@ struct rep_write_baton
   /* Receives the low-level checksum when closing REP_STREAM. */
   apr_uint32_t fnv1a_checksum;
 
-  /* Local / scratch pool, available for temporary allocations. */
-  apr_pool_t *scratch_pool;
+  /* Local pool, available for allocations that must remain valid as long
+     as this baton is used but may be cleaned up immediately afterwards. */
+  apr_pool_t *local_pool;
 
   /* Outer / result pool. */
   apr_pool_t *result_pool;
-};
+} rep_write_baton_t;
 
 /* Handler for the write method of the representation writable stream.
-   BATON is a rep_write_baton, DATA is the data to write, and *LEN is
+   BATON is a rep_write_baton_t, DATA is the data to write, and *LEN is
    the length of this data. */
 static svn_error_t *
 rep_write_contents(void *baton,
                    const char *data,
                    apr_size_t *len)
 {
-  struct rep_write_baton *b = baton;
+  rep_write_baton_t *b = baton;
 
   SVN_ERR(svn_checksum_update(b->md5_checksum_ctx, data, *len));
   SVN_ERR(svn_checksum_update(b->sha1_checksum_ctx, data, *len));
@@ -2057,14 +2081,14 @@ static apr_status_t
 rep_write_cleanup(void *data)
 {
   svn_error_t *err;
-  struct rep_write_baton *b = data;
+  rep_write_baton_t *b = data;
   svn_fs_x__txn_id_t txn_id
     = svn_fs_x__get_txn_id(b->noderev->noderev_id.change_set);
 
   /* Truncate and close the protorevfile. */
-  err = svn_io_file_trunc(b->file, b->rep_offset, b->scratch_pool);
+  err = svn_io_file_trunc(b->file, b->rep_offset, b->local_pool);
   err = svn_error_compose_create(err, svn_io_file_close(b->file,
-                                                        b->scratch_pool));
+                                                        b->local_pool));
 
   /* Remove our lock regardless of any preceding errors so that the
      being_written flag is always removed and stays consistent with the
@@ -2073,7 +2097,7 @@ rep_write_cleanup(void *data)
   err = svn_error_compose_create(err,
                                  unlock_proto_rev(b->fs, txn_id,
                                                   b->lockcookie,
-                                                  b->scratch_pool));
+                                                  b->local_pool));
   if (err)
     {
       apr_status_t rc = err->apr_err;
@@ -2084,18 +2108,18 @@ rep_write_cleanup(void *data)
   return APR_SUCCESS;
 }
 
-/* Get a rep_write_baton and store it in *WB_P for the representation
-   indicated by NODEREV in filesystem FS.  Perform allocations in
-   POOL.  Only appropriate for file contents, not for props or
-   directory contents. */
+/* Get a rep_write_baton_t, allocated from RESULT_POOL, and store it in
+   WB_P for the representation indicated by NODEREV in filesystem FS.
+   Only appropriate for file contents, not for props or directory contents.
+ */
 static svn_error_t *
-rep_write_get_baton(struct rep_write_baton **wb_p,
+rep_write_get_baton(rep_write_baton_t **wb_p,
                     svn_fs_t *fs,
                     svn_fs_x__noderev_t *noderev,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool)
 {
   svn_fs_x__data_t *ffd = fs->fsap_data;
-  struct rep_write_baton *b;
+  rep_write_baton_t *b;
   apr_file_t *file;
   svn_fs_x__representation_t *base_rep;
   svn_stream_t *source;
@@ -2106,34 +2130,36 @@ rep_write_get_baton(struct rep_write_bat
   svn_fs_x__txn_id_t txn_id
     = svn_fs_x__get_txn_id(noderev->noderev_id.change_set);
 
-  b = apr_pcalloc(pool, sizeof(*b));
+  b = apr_pcalloc(result_pool, sizeof(*b));
 
-  b->sha1_checksum_ctx = svn_checksum_ctx_create(svn_checksum_sha1, pool);
-  b->md5_checksum_ctx = svn_checksum_ctx_create(svn_checksum_md5, pool);
+  b->sha1_checksum_ctx = svn_checksum_ctx_create(svn_checksum_sha1,
+                                                 result_pool);
+  b->md5_checksum_ctx = svn_checksum_ctx_create(svn_checksum_md5,
+                                                result_pool);
 
   b->fs = fs;
-  b->result_pool = pool;
-  b->scratch_pool = svn_pool_create(pool);
+  b->result_pool = result_pool;
+  b->local_pool = svn_pool_create(result_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, txn_id,
-                                 b->scratch_pool));
+                                 b->local_pool));
 
   b->file = file;
   b->rep_stream = svn_checksum__wrap_write_stream_fnv1a_32x4(
                               &b->fnv1a_checksum,
                               svn_stream_from_aprfile2(file, TRUE,
-                                                       b->scratch_pool),
-                              b->scratch_pool);
+                                                       b->local_pool),
+                              b->local_pool);
 
-  SVN_ERR(svn_fs_x__get_file_offset(&b->rep_offset, file, b->scratch_pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&b->rep_offset, file, b->local_pool));
 
   /* Get the base for this delta. */
-  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, FALSE, b->scratch_pool));
+  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, FALSE, b->local_pool));
   SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, TRUE,
-                                 b->scratch_pool));
+                                 b->local_pool));
 
   /* Write out the rep header. */
   if (base_rep)
@@ -2148,14 +2174,14 @@ 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->scratch_pool));
+                                      b->local_pool));
 
   /* Now determine the offset of the actual svndiff data. */
   SVN_ERR(svn_fs_x__get_file_offset(&b->delta_start, file,
-                                    b->scratch_pool));
+                                    b->local_pool));
 
   /* Cleanup in case something goes wrong. */
-  apr_pool_cleanup_register(b->scratch_pool, b, rep_write_cleanup,
+  apr_pool_cleanup_register(b->local_pool, b, rep_write_cleanup,
                             apr_pool_cleanup_null);
 
   /* Prepare to write the svndiff data. */
@@ -2164,7 +2190,7 @@ rep_write_get_baton(struct rep_write_bat
                           svn_stream_disown(b->rep_stream, b->result_pool),
                           diff_version,
                           ffd->delta_compression_level,
-                          pool);
+                          result_pool);
 
   b->delta_stream = svn_txdelta_target_push(wh, whb, source,
                                             b->result_pool);
@@ -2213,7 +2239,9 @@ get_shared_rep(svn_fs_x__representation_
       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, result_pool);
+      err = svn_fs_x__get_rep_reference(old_rep, fs, &checksum, result_pool,
+                                        scratch_pool);
+
       /* ### Other error codes that we shouldn't mask out? */
       if (err == SVN_NO_ERROR)
         {
@@ -2301,12 +2329,12 @@ digests_final(svn_fs_x__representation_t
 }
 
 /* Close handler for the representation write stream.  BATON is a
-   rep_write_baton.  Writes out a new node-rev that correctly
+   rep_write_baton_t.  Writes out a new node-rev that correctly
    references the representation we just finished writing. */
 static svn_error_t *
 rep_write_contents_close(void *baton)
 {
-  struct rep_write_baton *b = baton;
+  rep_write_baton_t *b = baton;
   svn_fs_x__representation_t *rep;
   svn_fs_x__representation_t *old_rep;
   apr_off_t offset;
@@ -2319,7 +2347,7 @@ rep_write_contents_close(void *baton)
   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->scratch_pool));
+  SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->local_pool));
   rep->size = offset - b->delta_start;
 
   /* Fill in the rest of the representation field. */
@@ -2334,12 +2362,12 @@ rep_write_contents_close(void *baton)
   /* 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->result_pool,
-                         b->scratch_pool));
+                         b->local_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->scratch_pool));
+      SVN_ERR(svn_io_file_trunc(b->file, b->rep_offset, b->local_pool));
 
       /* Use the old rep for this content. */
       b->noderev->data_rep = old_rep;
@@ -2349,9 +2377,9 @@ 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->scratch_pool));
+                                  b->local_pool));
       SVN_ERR(store_l2p_index_entry(b->fs, txn_id, b->rep_offset,
-                                    rep->id.number, b->scratch_pool));
+                                    rep->id.number, b->local_pool));
 
       b->noderev->data_rep = rep;
     }
@@ -2359,11 +2387,11 @@ rep_write_contents_close(void *baton)
   SVN_ERR(svn_stream_close(b->rep_stream));
 
   /* Remove cleanup callback. */
-  apr_pool_cleanup_kill(b->scratch_pool, b, rep_write_cleanup);
+  apr_pool_cleanup_kill(b->local_pool, b, rep_write_cleanup);
 
   /* Write out the new node-rev information. */
   SVN_ERR(svn_fs_x__put_node_revision(b->fs, b->noderev, FALSE,
-                                      b->scratch_pool));
+                                      b->local_pool));
   if (!old_rep)
     {
       svn_fs_x__p2l_entry_t entry;
@@ -2372,46 +2400,45 @@ 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->scratch_pool));
+      SVN_ERR(svn_fs_x__get_file_offset(&offset, b->file, b->local_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->scratch_pool));
-      SVN_ERR(store_p2l_index_entry(b->fs, txn_id, &entry, b->scratch_pool));
+      SVN_ERR(store_sha1_rep_mapping(b->fs, b->noderev, b->local_pool));
+      SVN_ERR(store_p2l_index_entry(b->fs, txn_id, &entry, b->local_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);
+  SVN_ERR(svn_io_file_close(b->file, b->local_pool));
+  SVN_ERR(unlock_proto_rev(b->fs, txn_id, b->lockcookie, b->local_pool));
+  svn_pool_destroy(b->local_pool);
 
   return SVN_NO_ERROR;
 }
 
-/* Store a writable stream in *CONTENTS_P that will receive all data
-   written and store it as the file data representation referenced by
-   NODEREV in filesystem FS.  Perform temporary allocations in
-   POOL.  Only appropriate for file data, not props or directory
-   contents. */
+/* Store a writable stream in *CONTENTS_P, allocated in RESULT_POOL, that
+   will receive all data written and store it as the file data representation
+   referenced by NODEREV in filesystem FS.  Only appropriate for file data,
+   not props or directory contents. */
 static svn_error_t *
 set_representation(svn_stream_t **contents_p,
                    svn_fs_t *fs,
                    svn_fs_x__noderev_t *noderev,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool)
 {
-  struct rep_write_baton *wb;
+  rep_write_baton_t *wb;
 
   if (! svn_fs_x__is_txn(noderev->noderev_id.change_set))
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Attempted to write to non-transaction '%s'"),
                              svn_fs_x__id_unparse(&noderev->noderev_id,
-                                                  pool)->data);
+                                                  result_pool)->data);
 
-  SVN_ERR(rep_write_get_baton(&wb, fs, noderev, pool));
+  SVN_ERR(rep_write_get_baton(&wb, fs, noderev, result_pool));
 
-  *contents_p = svn_stream_create(wb, pool);
+  *contents_p = svn_stream_create(wb, result_pool);
   svn_stream_set_write(*contents_p, rep_write_contents);
   svn_stream_set_close(*contents_p, rep_write_contents_close);
 
@@ -2422,13 +2449,13 @@ svn_error_t *
 svn_fs_x__set_contents(svn_stream_t **stream,
                        svn_fs_t *fs,
                        svn_fs_x__noderev_t *noderev,
-                       apr_pool_t *pool)
+                       apr_pool_t *result_pool)
 {
   if (noderev->kind != svn_node_file)
     return svn_error_create(SVN_ERR_FS_NOT_FILE, NULL,
                             _("Can't set text contents of a directory"));
 
-  return set_representation(stream, fs, noderev, pool);
+  return set_representation(stream, fs, noderev, result_pool);
 }
 
 svn_error_t *
@@ -2463,7 +2490,8 @@ svn_fs_x__set_proplist(svn_fs_t *fs,
                        apr_pool_t *scratch_pool)
 {
   const svn_fs_x__id_t *id = &noderev->noderev_id;
-  const char *filename = svn_fs_x__path_txn_node_props(fs, id, scratch_pool);
+  const char *filename = svn_fs_x__path_txn_node_props(fs, id, scratch_pool,
+                                                       scratch_pool);
   apr_file_t *file;
   svn_stream_t *out;
 
@@ -2492,7 +2520,7 @@ svn_fs_x__set_proplist(svn_fs_t *fs,
 }
 
 /* This baton is used by the stream created for write_container_rep. */
-struct write_container_baton
+typedef struct write_container_baton_t
 {
   svn_stream_t *stream;
 
@@ -2500,17 +2528,17 @@ struct write_container_baton
 
   svn_checksum_ctx_t *md5_ctx;
   svn_checksum_ctx_t *sha1_ctx;
-};
+} write_container_baton_t;
 
 /* The handler for the write_container_rep stream.  BATON is a
-   write_container_baton, DATA has the data to write and *LEN is the number
+   write_container_baton_t, DATA has the data to write and *LEN is the number
    of bytes to write. */
 static svn_error_t *
 write_container_handler(void *baton,
                         const char *data,
                         apr_size_t *len)
 {
-  struct write_container_baton *whb = baton;
+  write_container_baton_t *whb = baton;
 
   SVN_ERR(svn_checksum_update(whb->md5_ctx, data, *len));
   SVN_ERR(svn_checksum_update(whb->sha1_ctx, data, *len));
@@ -2598,7 +2626,7 @@ write_container_delta_rep(svn_fs_x__repr
   apr_off_t delta_start = 0;
   apr_off_t offset = 0;
 
-  struct write_container_baton *whb;
+  write_container_baton_t *whb;
   int diff_version = 1;
   svn_boolean_t is_props = (item_type == SVN_FS_X__ITEM_TYPE_FILE_PROPS)
                         || (item_type == SVN_FS_X__ITEM_TYPE_DIR_PROPS);
@@ -2894,7 +2922,8 @@ write_final_rev(svn_fs_x__id_t *new_id_p
       apr_uint32_t item_type = noderev->kind == svn_node_dir
                              ? SVN_FS_X__ITEM_TYPE_DIR_PROPS
                              : SVN_FS_X__ITEM_TYPE_FILE_PROPS;
-      SVN_ERR(svn_fs_x__get_proplist(&proplist, fs, noderev, scratch_pool));
+      SVN_ERR(svn_fs_x__get_proplist(&proplist, fs, noderev, scratch_pool,
+                                     scratch_pool));
 
       noderev->prop_rep->id.change_set = change_set;
 
@@ -3257,23 +3286,23 @@ svn_fs_x__add_index_data(svn_fs_t *fs,
 }
 
 /* Baton used for commit_body below. */
-struct commit_baton {
+typedef struct commit_baton_t {
   svn_revnum_t *new_rev_p;
   svn_fs_t *fs;
   svn_fs_txn_t *txn;
   apr_array_header_t *reps_to_cache;
   apr_hash_t *reps_hash;
   apr_pool_t *reps_pool;
-};
+} commit_baton_t;
 
 /* The work-horse for svn_fs_x__commit, called with the FS write lock.
    This implements the svn_fs_x__with_write_lock() 'body' callback
-   type.  BATON is a 'struct commit_baton *'. */
+   type.  BATON is a 'commit_baton_t *'. */
 static svn_error_t *
 commit_body(void *baton,
             apr_pool_t *scratch_pool)
 {
-  struct commit_baton *cb = baton;
+  commit_baton_t *cb = baton;
   svn_fs_x__data_t *ffd = cb->fs->fsap_data;
   const char *old_rev_filename, *rev_filename, *proto_filename;
   const char *revprop_filename, *final_revprop;
@@ -3468,7 +3497,7 @@ svn_fs_x__commit(svn_revnum_t *new_rev_p
                  svn_fs_txn_t *txn,
                  apr_pool_t *scratch_pool)
 {
-  struct commit_baton cb;
+  commit_baton_t cb;
   svn_fs_x__data_t *ffd = fs->fsap_data;
 
   cb.new_rev_p = new_rev_p;
@@ -3625,6 +3654,7 @@ svn_fs_x__delete_node_revision(svn_fs_t
   if (noderev->prop_rep
       && svn_fs_x__is_txn(noderev->prop_rep->id.change_set))
     SVN_ERR(svn_io_remove_file2(svn_fs_x__path_txn_node_props(fs, id,
+                                                              scratch_pool,
                                                               scratch_pool),
                                 FALSE, scratch_pool));
 
@@ -3637,15 +3667,17 @@ svn_fs_x__delete_node_revision(svn_fs_t
       const svn_fs_x__id_t *key = id;
 
       SVN_ERR(svn_io_remove_file2(
-                  svn_fs_x__path_txn_node_children(fs, id, scratch_pool),
+                  svn_fs_x__path_txn_node_children(fs, id, scratch_pool,
+                                                   scratch_pool),
                   FALSE, scratch_pool));
 
       /* remove the corresponding entry from the cache, if such exists */
       SVN_ERR(svn_cache__set(ffd->dir_cache, key, NULL, scratch_pool));
     }
 
-  return svn_io_remove_file2(svn_fs_x__path_txn_node_rev(fs,
-                                                         id, scratch_pool),
+  return svn_io_remove_file2(svn_fs_x__path_txn_node_rev(fs, id,
+                                                         scratch_pool,
+                                                         scratch_pool),
                              FALSE, scratch_pool);
 }
 
@@ -3691,22 +3723,23 @@ svn_fs_x__begin_txn(svn_fs_txn_t **txn_p
                     svn_fs_t *fs,
                     svn_revnum_t rev,
                     apr_uint32_t flags,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
   svn_string_t date;
   fs_txn_data_t *ftd;
-  apr_hash_t *props = apr_hash_make(pool);
+  apr_hash_t *props = apr_hash_make(scratch_pool);
 
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
 
-  SVN_ERR(svn_fs_x__create_txn(txn_p, fs, rev, pool));
+  SVN_ERR(create_txn(txn_p, fs, rev, result_pool, scratch_pool));
 
   /* Put a datestamp on the newly created txn, so we always know
      exactly how old it is.  (This will help sysadmins identify
      long-abandoned txns that may need to be manually removed.)  When
      a txn is promoted to a revision, this property will be
      automatically overwritten with a revision datestamp. */
-  date.data = svn_time_to_cstring(apr_time_now(), pool);
+  date.data = svn_time_to_cstring(apr_time_now(), scratch_pool);
   date.len = strlen(date.data);
 
   svn_hash_sets(props, SVN_PROP_REVISION_DATE, &date);
@@ -3715,17 +3748,18 @@ svn_fs_x__begin_txn(svn_fs_txn_t **txn_p
      behaviors. */
   if (flags & SVN_FS_TXN_CHECK_OOD)
     svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_OOD,
-                  svn_string_create("true", pool));
+                  svn_string_create("true", scratch_pool));
 
   if (flags & SVN_FS_TXN_CHECK_LOCKS)
     svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_LOCKS,
-                  svn_string_create("true", pool));
+                  svn_string_create("true", scratch_pool));
 
   if (flags & SVN_FS_TXN_CLIENT_DATE)
     svn_hash_sets(props, SVN_FS__PROP_TXN_CLIENT_DATE,
-                  svn_string_create("0", pool));
+                  svn_string_create("0", scratch_pool));
 
   ftd = (*txn_p)->fsap_data;
-  return svn_error_trace(set_txn_proplist(fs, ftd->txn_id, props, FALSE,
-                                          pool));
+  SVN_ERR(set_txn_proplist(fs, ftd->txn_id, props, FALSE, scratch_pool));
+
+  return SVN_NO_ERROR;
 }

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.h?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/transaction.h Tue Jan 27 23:27:44 2015
@@ -91,15 +91,6 @@ svn_fs_x__txn_changes_fetch(apr_hash_t *
                             svn_fs_x__txn_id_t txn_id,
                             apr_pool_t *scratch_pool);
 
-/* Create a new transaction in filesystem FS, based on revision REV,
-   and store it in *TXN_P.  Allocate all necessary variables from
-   POOL. */
-svn_error_t *
-svn_fs_x__create_txn(svn_fs_txn_t **txn_p,
-                     svn_fs_t *fs,
-                     svn_revnum_t rev,
-                     apr_pool_t *pool);
-
 /* Set the transaction property NAME to the value VALUE in transaction
    TXN.  Perform temporary allocations from SCRATCH_POOL. */
 svn_error_t *
@@ -157,7 +148,11 @@ svn_fs_x__abort_txn(svn_fs_txn_t *txn,
 
 /* Add or set in filesystem FS, transaction TXN_ID, in directory
    PARENT_NODEREV a directory entry for NAME pointing to ID of type
-   KIND.  Temporary allocations are done in SCRATCH_POOL. */
+   KIND.  The PARENT_NODEREV's DATA_REP will be redirected to the in-txn
+   representation, if it had not been mutable before.
+
+   If PARENT_NODEREV does not have a DATA_REP, allocate one in RESULT_POOL.
+   Temporary allocations are done in SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__set_entry(svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
@@ -165,6 +160,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
                     const char *name,
                     const svn_fs_x__id_t *id,
                     svn_node_kind_t kind,
+                    apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool);
 
 /* Add a change to the changes record for filesystem FS in transaction
@@ -189,14 +185,14 @@ svn_fs_x__add_change(svn_fs_t *fs,
                      const char *copyfrom_path,
                      apr_pool_t *scratch_pool);
 
-/* Return a writable stream in *STREAM that allows storing the text
-   representation of node-revision NODEREV in filesystem FS.
-   Allocations are from POOL. */
+/* Return a writable stream in *STREAM, allocated in RESULT_POOL, that
+   allows storing the text representation of node-revision NODEREV in
+   filesystem FS. */
 svn_error_t *
 svn_fs_x__set_contents(svn_stream_t **stream,
                        svn_fs_t *fs,
                        svn_fs_x__noderev_t *noderev,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool);
 
 /* Create a node revision in FS which is an immediate successor of
    NEW_NODEREV's predecessor.  Use SCRATCH_POOL for any temporary allocation.
@@ -304,13 +300,14 @@ svn_fs_x__txn_prop(svn_string_t **value_
                    apr_pool_t *pool);
 
 /* Begin a new transaction in filesystem FS, based on existing
-   revision REV.  The new transaction is returned in *TXN_P.  Allocate
-   the new transaction structure from POOL. */
+   revision REV.  The new transaction is returned in *TXN_P, allocated
+   in RESULT_POOL.  Allocate temporaries from SCRATCH_POOL. */
 svn_error_t *
 svn_fs_x__begin_txn(svn_fs_txn_t **txn_p,
                     svn_fs_t *fs,
                     svn_revnum_t rev,
                     apr_uint32_t flags,
-                    apr_pool_t *pool);
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool);
 
 #endif

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.c?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.c Tue Jan 27 23:27:44 2015
@@ -106,8 +106,7 @@ get_dag(dag_node_t **dag_node_p,
 static svn_fs_root_t *
 make_revision_root(svn_fs_t *fs,
                    svn_revnum_t rev,
-                   dag_node_t *root_dir,
-                   apr_pool_t *pool);
+                   apr_pool_t *result_pool);
 
 static svn_error_t *
 make_txn_root(svn_fs_root_t **root_p,
@@ -115,7 +114,7 @@ make_txn_root(svn_fs_root_t **root_p,
               svn_fs_x__txn_id_t txn_id,
               svn_revnum_t base_rev,
               apr_uint32_t flags,
-              apr_pool_t *pool);
+              apr_pool_t *result_pool);
 
 static svn_error_t *
 x_closest_copy(svn_fs_root_t **root_p,
@@ -192,10 +191,10 @@ struct svn_fs_x__dag_cache_t
 };
 
 svn_fs_x__dag_cache_t*
-svn_fs_x__create_dag_cache(apr_pool_t *pool)
+svn_fs_x__create_dag_cache(apr_pool_t *result_pool)
 {
-  svn_fs_x__dag_cache_t *result = apr_pcalloc(pool, sizeof(*result));
-  result->pool = svn_pool_create(pool);
+  svn_fs_x__dag_cache_t *result = apr_pcalloc(result_pool, sizeof(*result));
+  result->pool = svn_pool_create(result_pool);
 
   return result;
 }
@@ -329,13 +328,13 @@ cache_lookup_last_path(svn_fs_x__dag_cac
 /* Find and return the DAG node cache for ROOT and the key that
    should be used for PATH.
 
-   Pool will only be used for allocating a new keys if necessary */
+   RESULT_POOL will only be used for allocating a new keys if necessary. */
 static void
 locate_cache(svn_cache__t **cache,
              const char **key,
              svn_fs_root_t *root,
              const char *path,
-             apr_pool_t *pool)
+             apr_pool_t *result_pool)
 {
   if (root->is_txn_root)
     {
@@ -353,7 +352,8 @@ locate_cache(svn_cache__t **cache,
       if (cache)
         *cache = ffd->rev_node_cache;
       if (key && path)
-        *key = svn_fs_x__combine_number_and_string(root->rev, path, pool);
+        *key = svn_fs_x__combine_number_and_string(root->rev, path,
+                                                   result_pool);
     }
 }
 
@@ -444,11 +444,12 @@ dag_node_cache_set(svn_fs_root_t *root,
 
 
 /* Baton for find_descendants_in_cache. */
-struct fdic_baton {
+typedef struct fdic_baton_t
+{
   const char *path;
   apr_array_header_t *list;
   apr_pool_t *pool;
-};
+} fdic_baton_t;
 
 /* If the given item is a descendant of BATON->PATH, push
  * it onto BATON->LIST (copying into BATON->POOL).  Implements
@@ -460,7 +461,7 @@ find_descendants_in_cache(void *baton,
                           void *val,
                           apr_pool_t *pool)
 {
-  struct fdic_baton *b = baton;
+  fdic_baton_t *b = baton;
   const char *item_path = key;
 
   if (svn_fspath__skip_ancestor(b->path, item_path))
@@ -476,7 +477,7 @@ dag_node_cache_invalidate(svn_fs_root_t
                           const char *path,
                           apr_pool_t *scratch_pool)
 {
-  struct fdic_baton b;
+  fdic_baton_t b;
   svn_cache__t *cache;
   apr_pool_t *iterpool;
   int i;
@@ -540,13 +541,10 @@ svn_fs_x__revision_root(svn_fs_root_t **
                         svn_revnum_t rev,
                         apr_pool_t *pool)
 {
-  dag_node_t *root_dir;
-
   SVN_ERR(svn_fs__check_fs(fs, TRUE));
+  SVN_ERR(svn_fs_x__ensure_revision_exists(rev, fs, pool));
 
-  SVN_ERR(svn_fs_x__dag_revision_root(&root_dir, fs, rev, pool));
-
-  *root_p = make_revision_root(fs, rev, root_dir, pool);
+  *root_p = make_revision_root(fs, rev, pool);
 
   return SVN_NO_ERROR;
 }
@@ -566,43 +564,42 @@ root_txn_id(svn_fs_root_t *root)
 }
 
 /* Set *NODE_P to a freshly opened dag node referring to the root
-   directory of ROOT, allocating from POOL.  */
+   directory of ROOT, allocating from RESULT_POOL.  */
 static svn_error_t *
 root_node(dag_node_t **node_p,
           svn_fs_root_t *root,
-          apr_pool_t *pool)
+          apr_pool_t *result_pool)
 {
   if (root->is_txn_root)
     {
       /* It's a transaction root.  Open a fresh copy.  */
       return svn_fs_x__dag_txn_root(node_p, root->fs, root_txn_id(root),
-                                     pool);
+                                    result_pool);
     }
   else
     {
       /* It's a revision root, so we already have its root directory
          opened.  */
-      dag_node_t *root_dir = root->fsap_data;
-      *node_p = svn_fs_x__dag_dup(root_dir, pool);
-      return SVN_NO_ERROR;
+      return svn_fs_x__dag_revision_root(node_p, root->fs, root->rev,
+                                         result_pool);
     }
 }
 
 
 /* Set *NODE_P to a mutable root directory for ROOT, cloning if
-   necessary, allocating in POOL.  ROOT must be a transaction root.
+   necessary, allocating in RESULT_POOL.  ROOT must be a transaction root.
    Use ERROR_PATH in error messages.  */
 static svn_error_t *
 mutable_root_node(dag_node_t **node_p,
                   svn_fs_root_t *root,
                   const char *error_path,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool)
 {
   if (root->is_txn_root)
     {
       /* It's a transaction root.  Open a fresh copy.  */
       return svn_fs_x__dag_clone_root(node_p, root->fs, root_txn_id(root),
-                                       pool);
+                                      result_pool);
     }
   else
     /* If it's not a transaction root, we can't change its contents.  */
@@ -771,17 +768,17 @@ get_copy_inheritance(copy_id_inherit_t *
   return SVN_NO_ERROR;
 }
 
-/* Allocate a new parent_path_t node from POOL, referring to NODE,
+/* Allocate a new parent_path_t node from RESULT_POOL, referring to NODE,
    ENTRY, PARENT, and COPY_ID.  */
 static parent_path_t *
 make_parent_path(dag_node_t *node,
                  char *entry,
                  parent_path_t *parent,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool)
 {
-  parent_path_t *parent_path = apr_pcalloc(pool, sizeof(*parent_path));
+  parent_path_t *parent_path = apr_pcalloc(result_pool, sizeof(*parent_path));
   if (node)
-    parent_path->node = svn_fs_x__dag_copy_into_pool(node, pool);
+    parent_path->node = svn_fs_x__dag_copy_into_pool(node, result_pool);
   parent_path->entry = entry;
   parent_path->parent = parent;
   parent_path->copy_inherit = copy_id_inherit_unknown;
@@ -1098,16 +1095,17 @@ open_path(parent_path_t **parent_path_p,
 }
 
 
-/* Make the node referred to by PARENT_PATH mutable, if it isn't
-   already, allocating from POOL.  ROOT must be the root from which
+/* Make the node referred to by PARENT_PATH mutable, if it isn't already,
+   allocating from RESULT_POOL.  ROOT must be the root from which
    PARENT_PATH descends.  Clone any parent directories as needed.
    Adjust the dag nodes in PARENT_PATH to refer to the clones.  Use
-   ERROR_PATH in error messages.  */
+   ERROR_PATH in error messages.  Use SCRATCH_POOL for temporaries. */
 static svn_error_t *
 make_path_mutable(svn_fs_root_t *root,
                   parent_path_t *parent_path,
                   const char *error_path,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   dag_node_t *clone;
   svn_fs_x__txn_id_t txn_id = root_txn_id(root);
@@ -1132,7 +1130,7 @@ make_path_mutable(svn_fs_root_t *root,
       /* We're trying to clone somebody's child.  Make sure our parent
          is mutable.  */
       SVN_ERR(make_path_mutable(root, parent_path->parent,
-                                error_path, pool));
+                                error_path, result_pool, scratch_pool));
 
       switch (inherit)
         {
@@ -1143,7 +1141,7 @@ make_path_mutable(svn_fs_root_t *root,
 
         case copy_id_inherit_new:
           SVN_ERR(svn_fs_x__reserve_copy_id(&copy_id, root->fs, txn_id,
-                                             pool));
+                                            scratch_pool));
           break;
 
         case copy_id_inherit_self:
@@ -1160,8 +1158,9 @@ make_path_mutable(svn_fs_root_t *root,
       SVN_ERR(svn_fs_x__dag_get_copyroot(&copyroot_rev, &copyroot_path,
                                           parent_path->node));
       SVN_ERR(svn_fs_x__revision_root(&copyroot_root, root->fs,
-                                      copyroot_rev, pool));
-      SVN_ERR(get_dag(&copyroot_node, copyroot_root, copyroot_path, pool));
+                                      copyroot_rev, scratch_pool));
+      SVN_ERR(get_dag(&copyroot_node, copyroot_root, copyroot_path,
+                      result_pool));
 
       SVN_ERR(svn_fs_x__dag_related_node(&related, copyroot_node,
                                          parent_path->node));
@@ -1169,23 +1168,25 @@ make_path_mutable(svn_fs_root_t *root,
         is_parent_copyroot = TRUE;
 
       /* Now make this node mutable.  */
-      clone_path = parent_path_path(parent_path->parent, pool);
+      clone_path = parent_path_path(parent_path->parent, scratch_pool);
       SVN_ERR(svn_fs_x__dag_clone_child(&clone,
                                         parent_path->parent->node,
                                         clone_path,
                                         parent_path->entry,
                                         copy_id_ptr, txn_id,
                                         is_parent_copyroot,
-                                        pool));
+                                        result_pool,
+                                        scratch_pool));
 
       /* Update the path cache. */
-      SVN_ERR(dag_node_cache_set(root, parent_path_path(parent_path, pool),
-                                 clone, pool));
+      SVN_ERR(dag_node_cache_set(root,
+                                 parent_path_path(parent_path, scratch_pool),
+                                 clone, scratch_pool));
     }
   else
     {
       /* We're trying to clone the root directory.  */
-      SVN_ERR(mutable_root_node(&clone, root, error_path, pool));
+      SVN_ERR(mutable_root_node(&clone, root, error_path, result_pool));
     }
 
   /* Update the PARENT_PATH link to refer to the clone.  */
@@ -1288,7 +1289,7 @@ x_node_id(const svn_fs_id_t **id_p,
           const char *path,
           apr_pool_t *pool)
 {
-  const svn_fs_x__id_t *noderev_id;
+  svn_fs_x__id_t noderev_id;
 
   if ((! root->is_txn_root)
       && (path[0] == '\0' || ((path[0] == '/') && (path[1] == '\0'))))
@@ -1297,19 +1298,18 @@ x_node_id(const svn_fs_id_t **id_p,
          The root directory ("" or "/") node is stored in the
          svn_fs_root_t object, and never changes when it's a revision
          root, so we can just reach in and grab it directly. */
-      dag_node_t *root_dir = root->fsap_data;
-      noderev_id = svn_fs_x__dag_get_id(root_dir);
+      svn_fs_x__init_rev_root(&noderev_id, root->rev);
     }
   else
     {
       dag_node_t *node;
 
       SVN_ERR(get_dag(&node, root, path, pool));
-      noderev_id = svn_fs_x__dag_get_id(node);
+      noderev_id = *svn_fs_x__dag_get_id(node);
     }
 
   *id_p = svn_fs_x__id_create(svn_fs_x__id_create_context(root->fs, pool),
-                              noderev_id, pool);
+                              &noderev_id, pool);
 
   return SVN_NO_ERROR;
 }
@@ -1462,13 +1462,15 @@ x_node_prop(svn_string_t **value_p,
 {
   dag_node_t *node;
   apr_hash_t *proplist;
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   SVN_ERR(get_dag(&node, root, path,  pool));
-  SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, node, pool));
+  SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, node, pool, scratch_pool));
   *value_p = NULL;
   if (proplist)
     *value_p = svn_hash_gets(proplist, propname);
 
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
@@ -1483,13 +1485,13 @@ x_node_proplist(apr_hash_t **table_p,
                 const char *path,
                 apr_pool_t *pool)
 {
-  apr_hash_t *table;
   dag_node_t *node;
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   SVN_ERR(get_dag(&node, root, path, pool));
-  SVN_ERR(svn_fs_x__dag_get_proplist(&table, node, pool));
-  *table_p = table ? table : apr_hash_make(pool);
+  SVN_ERR(svn_fs_x__dag_get_proplist(table_p, node, pool, scratch_pool));
 
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
@@ -1499,11 +1501,17 @@ increment_mergeinfo_up_tree(parent_path_
                             apr_int64_t increment,
                             apr_pool_t *scratch_pool)
 {
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
   for (; pp; pp = pp->parent)
-    SVN_ERR(svn_fs_x__dag_increment_mergeinfo_count(pp->node,
-                                                    increment,
-                                                    scratch_pool));
+    {
+      svn_pool_clear(iterpool);
+      SVN_ERR(svn_fs_x__dag_increment_mergeinfo_count(pp->node,
+                                                      increment,
+                                                      iterpool));
+    }
 
+  svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
 }
 
@@ -1538,8 +1546,9 @@ x_change_node_prop(svn_fs_root_t *root,
     SVN_ERR(svn_fs_x__allow_locked_operation(path, root->fs, FALSE, FALSE,
                                              subpool));
 
-  SVN_ERR(make_path_mutable(root, parent_path, path, subpool));
-  SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, parent_path->node, subpool));
+  SVN_ERR(make_path_mutable(root, parent_path, path, subpool, subpool));
+  SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, parent_path->node, subpool,
+                                     subpool));
 
   /* If there's no proplist, but we're just deleting a property, exit now. */
   if ((! proplist) && (! value))
@@ -1661,8 +1670,10 @@ compare_dir_structure(svn_boolean_t *cha
   int i;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-  SVN_ERR(svn_fs_x__dag_dir_entries(&lhs_entries, lhs, scratch_pool));
-  SVN_ERR(svn_fs_x__dag_dir_entries(&rhs_entries, rhs, scratch_pool));
+  SVN_ERR(svn_fs_x__dag_dir_entries(&lhs_entries, lhs, scratch_pool,
+                                    iterpool));
+  SVN_ERR(svn_fs_x__dag_dir_entries(&rhs_entries, rhs, scratch_pool,
+                                    iterpool));
 
   /* Since directories are sorted by name, we can simply compare their
      entries one-by-one without binary lookup etc. */
@@ -1909,12 +1920,12 @@ merge(svn_stringbuf_t *conflict_p,
   /* ### todo: it would be more efficient to simply check for a NULL
      entries hash where necessary below than to allocate an empty hash
      here, but another day, another day... */
-  SVN_ERR(svn_fs_x__dag_dir_entries(&s_entries, source, pool));
-  SVN_ERR(svn_fs_x__dag_dir_entries(&t_entries, target, pool));
-  SVN_ERR(svn_fs_x__dag_dir_entries(&a_entries, ancestor, pool));
+  iterpool = svn_pool_create(pool);
+  SVN_ERR(svn_fs_x__dag_dir_entries(&s_entries, source, pool, iterpool));
+  SVN_ERR(svn_fs_x__dag_dir_entries(&t_entries, target, pool, iterpool));
+  SVN_ERR(svn_fs_x__dag_dir_entries(&a_entries, ancestor, pool, iterpool));
 
   /* for each entry E in a_entries... */
-  iterpool = svn_pool_create(pool);
   for (i = 0; i < a_entries->nelts; ++i)
     {
       svn_fs_x__dirent_t *s_entry, *t_entry, *a_entry;
@@ -2100,8 +2111,8 @@ merge_changes(dag_node_t *ancestor_node,
 
   if (ancestor_node == NULL)
     {
-      SVN_ERR(svn_fs_x__dag_txn_base_root(&ancestor_node, fs,
-                                          txn_id, scratch_pool));
+      SVN_ERR(svn_fs_x__dag_txn_base_root(&ancestor_node, fs, txn_id,
+                                          scratch_pool, scratch_pool));
     }
 
   SVN_ERR(svn_fs_x__dag_related_node(&related, ancestor_node, txn_root_node));
@@ -2357,10 +2368,12 @@ x_dir_entries(apr_hash_t **table_p,
   apr_array_header_t *table;
   int i;
   svn_fs_x__id_context_t *context = NULL;
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   /* Get the entries for this path in the caller's pool. */
-  SVN_ERR(get_dag(&node, root, path, pool));
-  SVN_ERR(svn_fs_x__dag_dir_entries(&table, node, pool));
+  SVN_ERR(get_dag(&node, root, path, scratch_pool));
+  SVN_ERR(svn_fs_x__dag_dir_entries(&table, node, scratch_pool,
+                                    scratch_pool));
 
   if (table->nelts)
     context = svn_fs_x__id_create_context(root->fs, pool);
@@ -2370,16 +2383,19 @@ x_dir_entries(apr_hash_t **table_p,
     {
       svn_fs_x__dirent_t *entry
         = APR_ARRAY_IDX(table, i, svn_fs_x__dirent_t *);
+      apr_size_t len = strlen(entry->name);
 
       svn_fs_dirent_t *api_dirent = apr_pcalloc(pool, sizeof(*api_dirent));
-      api_dirent->name = entry->name;
+      api_dirent->name = apr_pstrmemdup(pool, entry->name, len);
       api_dirent->kind = entry->kind;
       api_dirent->id = svn_fs_x__id_create(context, &entry->id, pool);
 
-      svn_hash_sets(hash, api_dirent->name, api_dirent);
+      apr_hash_set(hash, api_dirent->name, len, api_dirent);
     }
 
   *table_p = hash;
+  svn_pool_destroy(scratch_pool);
+
   return SVN_NO_ERROR;
 }
 
@@ -2425,14 +2441,15 @@ x_make_dir(svn_fs_root_t *root,
     return SVN_FS__ALREADY_EXISTS(root, path);
 
   /* Create the subdirectory.  */
-  SVN_ERR(make_path_mutable(root, parent_path->parent, path, subpool));
+  SVN_ERR(make_path_mutable(root, parent_path->parent, path, subpool,
+                            subpool));
   SVN_ERR(svn_fs_x__dag_make_dir(&sub_dir,
                                  parent_path->parent->node,
                                  parent_path_path(parent_path->parent,
                                                   subpool),
                                  parent_path->entry,
                                  txn_id,
-                                 subpool));
+                                 subpool, subpool));
 
   /* Add this directory to the path cache. */
   SVN_ERR(dag_node_cache_set(root, parent_path_path(parent_path, subpool),
@@ -2481,7 +2498,8 @@ x_delete_node(svn_fs_root_t *root,
                                              subpool));
 
   /* Make the parent directory mutable, and do the deletion.  */
-  SVN_ERR(make_path_mutable(root, parent_path->parent, path, subpool));
+  SVN_ERR(make_path_mutable(root, parent_path->parent, path, subpool,
+                            subpool));
   SVN_ERR(svn_fs_x__dag_get_mergeinfo_count(&mergeinfo_count,
                                             parent_path->node));
   SVN_ERR(svn_fs_x__dag_delete(parent_path->parent->node,
@@ -2609,7 +2627,7 @@ copy_helper(svn_fs_root_t *from_root,
 
       /* Make sure the target node's parents are mutable.  */
       SVN_ERR(make_path_mutable(to_root, to_parent_path->parent,
-                                to_path, scratch_pool));
+                                to_path, scratch_pool, scratch_pool));
 
       /* Canonicalize the copyfrom path. */
       from_canonpath = svn_fs__canonicalize_abspath(from_path, scratch_pool);
@@ -2763,14 +2781,15 @@ x_make_file(svn_fs_root_t *root,
                                              subpool));
 
   /* Create the file.  */
-  SVN_ERR(make_path_mutable(root, parent_path->parent, path, subpool));
+  SVN_ERR(make_path_mutable(root, parent_path->parent, path, subpool,
+                            subpool));
   SVN_ERR(svn_fs_x__dag_make_file(&child,
                                   parent_path->parent->node,
                                   parent_path_path(parent_path->parent,
                                                    subpool),
                                   parent_path->entry,
                                   txn_id,
-                                  subpool));
+                                  subpool, subpool));
 
   /* Add this file to the path cache. */
   SVN_ERR(dag_node_cache_set(root, parent_path_path(parent_path, subpool),
@@ -2943,7 +2962,8 @@ apply_textdelta(void *baton,
                                              FALSE, FALSE, scratch_pool));
 
   /* Now, make sure this path is mutable. */
-  SVN_ERR(make_path_mutable(tb->root, parent_path, tb->path, scratch_pool));
+  SVN_ERR(make_path_mutable(tb->root, parent_path, tb->path, scratch_pool,
+                            scratch_pool));
   tb->node = svn_fs_x__dag_dup(parent_path->node, tb->pool);
 
   if (tb->base_checksum)
@@ -3001,7 +3021,7 @@ x_apply_textdelta(svn_txdelta_window_han
                   svn_checksum_t *result_checksum,
                   apr_pool_t *pool)
 {
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
   txdelta_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
 
   tb->root = root;
@@ -3010,12 +3030,12 @@ x_apply_textdelta(svn_txdelta_window_han
   tb->base_checksum = svn_checksum_dup(base_checksum, pool);
   tb->result_checksum = svn_checksum_dup(result_checksum, pool);
 
-  SVN_ERR(apply_textdelta(tb, subpool));
+  SVN_ERR(apply_textdelta(tb, scratch_pool));
 
   *contents_p = window_consumer;
   *contents_baton_p = tb;
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
@@ -3024,7 +3044,7 @@ x_apply_textdelta(svn_txdelta_window_han
 /* --- Machinery for svn_fs_apply_text() ---  */
 
 /* Baton for svn_fs_apply_text(). */
-struct text_baton_t
+typedef struct text_baton_t
 {
   /* The original file info */
   svn_fs_root_t *root;
@@ -3045,7 +3065,7 @@ struct text_baton_t
 
   /* Pool used by db txns */
   apr_pool_t *pool;
-};
+} text_baton_t;
 
 
 /* A wrapper around svn_fs_x__dag_finalize_edits, but for
@@ -3064,7 +3084,7 @@ text_stream_writer(void *baton,
                    const char *data,
                    apr_size_t *len)
 {
-  struct text_baton_t *tb = baton;
+  text_baton_t *tb = baton;
 
   /* Psst, here's some data.  Pass it on to the -real- file stream. */
   return svn_stream_write(tb->file_stream, data, len);
@@ -3074,7 +3094,7 @@ text_stream_writer(void *baton,
 static svn_error_t *
 text_stream_closer(void *baton)
 {
-  struct text_baton_t *tb = baton;
+  text_baton_t *tb = baton;
 
   /* Close the internal-use stream.  ### This used to be inside of
      txn_body_fulltext_finalize_edits(), but that invoked a nested
@@ -3093,7 +3113,7 @@ static svn_error_t *
 apply_text(void *baton,
            apr_pool_t *scratch_pool)
 {
-  struct text_baton_t *tb = baton;
+  text_baton_t *tb = baton;
   parent_path_t *parent_path;
   svn_fs_x__txn_id_t txn_id = root_txn_id(tb->root);
 
@@ -3108,7 +3128,8 @@ apply_text(void *baton,
                                              FALSE, FALSE, scratch_pool));
 
   /* Now, make sure this path is mutable. */
-  SVN_ERR(make_path_mutable(tb->root, parent_path, tb->path, scratch_pool));
+  SVN_ERR(make_path_mutable(tb->root, parent_path, tb->path, scratch_pool,
+                            scratch_pool));
   tb->node = svn_fs_x__dag_dup(parent_path->node, tb->pool);
 
   /* Make a writable stream for replacing the file's text. */
@@ -3138,19 +3159,19 @@ x_apply_text(svn_stream_t **contents_p,
              svn_checksum_t *result_checksum,
              apr_pool_t *pool)
 {
-  apr_pool_t *subpool = svn_pool_create(pool);
-  struct text_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
+  text_baton_t *tb = apr_pcalloc(pool, sizeof(*tb));
 
   tb->root = root;
   tb->path = svn_fs__canonicalize_abspath(path, pool);
   tb->pool = pool;
   tb->result_checksum = svn_checksum_dup(result_checksum, pool);
 
-  SVN_ERR(apply_text(tb, subpool));
+  SVN_ERR(apply_text(tb, scratch_pool));
 
   *contents_p = tb->stream;
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
@@ -3215,19 +3236,20 @@ x_get_file_delta_stream(svn_txdelta_stre
                         apr_pool_t *pool)
 {
   dag_node_t *source_node, *target_node;
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   if (source_root && source_path)
-    SVN_ERR(get_dag(&source_node, source_root, source_path, pool));
+    SVN_ERR(get_dag(&source_node, source_root, source_path, scratch_pool));
   else
     source_node = NULL;
-  SVN_ERR(get_dag(&target_node, target_root, target_path, pool));
+  SVN_ERR(get_dag(&target_node, target_root, target_path, scratch_pool));
 
   /* Create a delta stream that turns the source into the target.  */
   SVN_ERR(svn_fs_x__dag_get_file_delta_stream(stream_p, source_node,
-                                              target_node, pool));
+                                              target_node, pool,
+                                              scratch_pool));
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
@@ -3346,7 +3368,7 @@ assemble_history(svn_fs_t *fs,
                  svn_boolean_t is_interesting,
                  const char *path_hint,
                  svn_revnum_t rev_hint,
-                 apr_pool_t *pool);
+                 apr_pool_t *result_pool);
 
 
 /* Set *HISTORY_P to an opaque node history object which represents
@@ -3430,14 +3452,14 @@ x_closest_copy(svn_fs_root_t **root_p,
   svn_fs_root_t *copy_dst_root;
   dag_node_t *copy_dst_node;
   svn_boolean_t related;
-  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_pool_t *scratch_pool = svn_pool_create(pool);
 
   /* Initialize return values. */
   *root_p = NULL;
   *path_p = NULL;
 
-  path = svn_fs__canonicalize_abspath(path, subpool);
-  SVN_ERR(open_path(&parent_path, root, path, 0, FALSE, subpool));
+  path = svn_fs__canonicalize_abspath(path, scratch_pool);
+  SVN_ERR(open_path(&parent_path, root, path, 0, FALSE, scratch_pool));
 
   /* Find the youngest copyroot in the path of this node-rev, which
      will indicate the target of the innermost copy affecting the
@@ -3446,7 +3468,7 @@ x_closest_copy(svn_fs_root_t **root_p,
                                  fs, parent_path));
   if (copy_dst_rev == 0)  /* There are no copies affecting this node-rev. */
     {
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(scratch_pool);
       return SVN_NO_ERROR;
     }
 
@@ -3456,10 +3478,10 @@ x_closest_copy(svn_fs_root_t **root_p,
   SVN_ERR(svn_fs_x__revision_root(&copy_dst_root, fs, copy_dst_rev, pool));
   SVN_ERR(open_path(&copy_dst_parent_path, copy_dst_root, path,
                     open_path_node_only | open_path_allow_null, FALSE,
-                    subpool));
+                    scratch_pool));
   if (copy_dst_parent_path == NULL)
     {
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(scratch_pool);
       return SVN_NO_ERROR;
     }
 
@@ -3468,7 +3490,7 @@ x_closest_copy(svn_fs_root_t **root_p,
                                      parent_path->node));
   if (!related)
     {
-      svn_pool_destroy(subpool);
+      svn_pool_destroy(scratch_pool);
       return SVN_NO_ERROR;
     }
 
@@ -3493,7 +3515,7 @@ x_closest_copy(svn_fs_root_t **root_p,
       SVN_ERR(svn_fs_x__dag_get_predecessor_id(&pred, copy_dst_node));
       if (!svn_fs_x__id_used(&pred))
         {
-          svn_pool_destroy(subpool);
+          svn_pool_destroy(scratch_pool);
           return SVN_NO_ERROR;
         }
     }
@@ -3502,7 +3524,7 @@ x_closest_copy(svn_fs_root_t **root_p,
   *root_p = copy_dst_root;
   *path_p = apr_pstrdup(pool, copy_dst_path);
 
-  svn_pool_destroy(subpool);
+  svn_pool_destroy(scratch_pool);
   return SVN_NO_ERROR;
 }
 
@@ -3736,16 +3758,16 @@ fs_history_prev(svn_fs_history_t **prev_
 
 
 /* Set *PATH and *REVISION to the path and revision for the HISTORY
-   object.  Use POOL for all allocations. */
+   object.  Allocate *PATH in RESULT_POOL. */
 static svn_error_t *
 fs_history_location(const char **path,
                     svn_revnum_t *revision,
                     svn_fs_history_t *history,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool)
 {
   fs_history_data_t *fhd = history->fsap_data;
 
-  *path = apr_pstrdup(pool, fhd->path);
+  *path = apr_pstrdup(result_pool, fhd->path);
   *revision = fhd->revision;
   return SVN_NO_ERROR;
 }
@@ -3756,9 +3778,9 @@ static history_vtable_t history_vtable =
 };
 
 /* Return a new history object (marked as "interesting") for PATH and
-   REVISION, allocated in POOL, and with its members set to the values
-   of the parameters provided.  Note that PATH and PATH_HINT get
-   normalized and duplicated in POOL. */
+   REVISION, allocated in RESULT_POOL, and with its members set to the
+   values of the parameters provided.  Note that PATH and PATH_HINT get
+   normalized and duplicated in RESULT_POOL. */
 static svn_fs_history_t *
 assemble_history(svn_fs_t *fs,
                  const char *path,
@@ -3766,15 +3788,16 @@ assemble_history(svn_fs_t *fs,
                  svn_boolean_t is_interesting,
                  const char *path_hint,
                  svn_revnum_t rev_hint,
-                 apr_pool_t *pool)
+                 apr_pool_t *result_pool)
 {
-  svn_fs_history_t *history = apr_pcalloc(pool, sizeof(*history));
-  fs_history_data_t *fhd = apr_pcalloc(pool, sizeof(*fhd));
-  fhd->path = svn_fs__canonicalize_abspath(path, pool);
+  svn_fs_history_t *history = apr_pcalloc(result_pool, sizeof(*history));
+  fs_history_data_t *fhd = apr_pcalloc(result_pool, sizeof(*fhd));
+  fhd->path = svn_fs__canonicalize_abspath(path, result_pool);
   fhd->revision = revision;
   fhd->is_interesting = is_interesting;
-  fhd->path_hint = path_hint ? svn_fs__canonicalize_abspath(path_hint, pool)
-                             : NULL;
+  fhd->path_hint = path_hint
+                 ? svn_fs__canonicalize_abspath(path_hint, result_pool)
+                 : NULL;
   fhd->rev_hint = rev_hint;
   fhd->fs = fs;
 
@@ -3810,7 +3833,8 @@ crawl_directory_dag_for_mergeinfo(svn_fs
   int i;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-  SVN_ERR(svn_fs_x__dag_dir_entries(&entries, dir_dag, scratch_pool));
+  SVN_ERR(svn_fs_x__dag_dir_entries(&entries, dir_dag, scratch_pool,
+                                    iterpool));
   for (i = 0; i < entries->nelts; ++i)
     {
       svn_fs_x__dirent_t *dirent = APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *);
@@ -3834,7 +3858,8 @@ crawl_directory_dag_for_mergeinfo(svn_fs
           svn_string_t *mergeinfo_string;
           svn_error_t *err;
 
-          SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, kid_dag, iterpool));
+          SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, kid_dag, iterpool,
+                                             iterpool));
           mergeinfo_string = svn_hash_gets(proplist, SVN_PROP_MERGEINFO);
           if (!mergeinfo_string)
             {
@@ -3881,21 +3906,21 @@ crawl_directory_dag_for_mergeinfo(svn_fs
 
 /* Return the cache key as a combination of REV_ROOT->REV, the inheritance
    flags INHERIT and ADJUST_INHERITED_MERGEINFO, and the PATH.  The result
-   will be allocated in POOL..
+   will be allocated in RESULT_POOL.
  */
 static const char *
 mergeinfo_cache_key(const char *path,
                     svn_fs_root_t *rev_root,
                     svn_mergeinfo_inheritance_t inherit,
                     svn_boolean_t adjust_inherited_mergeinfo,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool)
 {
   apr_int64_t number = rev_root->rev;
   number = number * 4
          + (inherit == svn_mergeinfo_nearest_ancestor ? 2 : 0)
          + (adjust_inherited_mergeinfo ? 1 : 0);
 
-  return svn_fs_x__combine_number_and_string(number, path, pool);
+  return svn_fs_x__combine_number_and_string(number, path, result_pool);
 }
 
 /* Calculates the mergeinfo for PATH under REV_ROOT using inheritance
@@ -3953,7 +3978,7 @@ get_mergeinfo_for_path_internal(svn_merg
     }
 
   SVN_ERR(svn_fs_x__dag_get_proplist(&proplist, nearest_ancestor->node,
-                                     scratch_pool));
+                                     scratch_pool, scratch_pool));
   mergeinfo_string = svn_hash_gets(proplist, SVN_PROP_MERGEINFO);
   if (!mergeinfo_string)
     return svn_error_createf
@@ -4196,34 +4221,32 @@ static root_vtable_t root_vtable = {
   x_get_mergeinfo,
 };
 
-/* Construct a new root object in FS, allocated from POOL.  */
+/* Construct a new root object in FS, allocated from RESULT_POOL.  */
 static svn_fs_root_t *
 make_root(svn_fs_t *fs,
-          apr_pool_t *pool)
+          apr_pool_t *result_pool)
 {
-  svn_fs_root_t *root = apr_pcalloc(pool, sizeof(*root));
+  svn_fs_root_t *root = apr_pcalloc(result_pool, sizeof(*root));
 
   root->fs = fs;
-  root->pool = pool;
+  root->pool = result_pool;
   root->vtable = &root_vtable;
 
   return root;
 }
 
 
-/* Construct a root object referring to the root of REVISION in FS,
-   whose root directory is ROOT_DIR.  Create the new root in POOL.  */
+/* Construct a root object referring to the root of revision REV in FS.
+   Create the new root in RESULT_POOL.  */
 static svn_fs_root_t *
 make_revision_root(svn_fs_t *fs,
                    svn_revnum_t rev,
-                   dag_node_t *root_dir,
-                   apr_pool_t *pool)
+                   apr_pool_t *result_pool)
 {
-  svn_fs_root_t *root = make_root(fs, pool);
+  svn_fs_root_t *root = make_root(fs, result_pool);
 
   root->is_txn_root = FALSE;
   root->rev = rev;
-  root->fsap_data = root_dir;
 
   return root;
 }
@@ -4231,16 +4254,16 @@ make_revision_root(svn_fs_t *fs,
 
 /* Construct a root object referring to the root of the transaction
    named TXN and based on revision BASE_REV in FS, with FLAGS to
-   describe transaction's behavior.  Create the new root in POOL.  */
+   describe transaction's behavior.  Create the new root in RESULT_POOL.  */
 static svn_error_t *
 make_txn_root(svn_fs_root_t **root_p,
               svn_fs_t *fs,
               svn_fs_x__txn_id_t txn_id,
               svn_revnum_t base_rev,
               apr_uint32_t flags,
-              apr_pool_t *pool)
+              apr_pool_t *result_pool)
 {
-  svn_fs_root_t *root = make_root(fs, pool);
+  svn_fs_root_t *root = make_root(fs, result_pool);
   fs_txn_root_data_t *frd = apr_pcalloc(root->pool, sizeof(*frd));
   frd->txn_id = txn_id;
 
@@ -4259,8 +4282,7 @@ make_txn_root(svn_fs_root_t **root_p,
                                       svn_fs_x__dag_deserialize,
                                       APR_HASH_KEY_STRING,
                                       32, 20, FALSE,
-                                      apr_pstrcat(pool, root->txn, ":TXN",
-                                                  SVN_VA_NULL),
+                                      root->txn,
                                       root->pool));
 
   root->fsap_data = frd;
@@ -4274,10 +4296,10 @@ make_txn_root(svn_fs_root_t **root_p,
 /* Verify. */
 static const char *
 stringify_node(dag_node_t *node,
-               apr_pool_t *pool)
+               apr_pool_t *result_pool)
 {
   /* ### TODO: print some PATH@REV to it, too. */
-  return svn_fs_x__id_unparse(svn_fs_x__dag_get_id(node), pool)->data;
+  return svn_fs_x__id_unparse(svn_fs_x__dag_get_id(node), result_pool)->data;
 }
 
 /* Check metadata sanity on NODE, and on its children.  Manually verify
@@ -4363,12 +4385,14 @@ verify_node(dag_node_t *node,
       apr_int64_t children_mergeinfo = 0;
       APR_ARRAY_PUSH(parent_nodes, dag_node_t*) = node;
 
-      SVN_ERR(svn_fs_x__dag_dir_entries(&entries, node, scratch_pool));
+      SVN_ERR(svn_fs_x__dag_dir_entries(&entries, node, scratch_pool,
+                                        iterpool));
 
       /* Compute CHILDREN_MERGEINFO. */
       for (i = 0; i < entries->nelts; ++i)
         {
-          svn_fs_x__dirent_t *dirent = APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *);
+          svn_fs_x__dirent_t *dirent
+            = APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *);
           dag_node_t *child;
           apr_int64_t child_mergeinfo;
 
@@ -4415,7 +4439,6 @@ svn_error_t *
 svn_fs_x__verify_root(svn_fs_root_t *root,
                       apr_pool_t *scratch_pool)
 {
-  svn_fs_t *fs = root->fs;
   dag_node_t *root_dir;
   apr_array_header_t *parent_nodes;
 
@@ -4429,17 +4452,7 @@ svn_fs_x__verify_root(svn_fs_root_t *roo
      When this code is called in the library, we want to ensure we
      use the on-disk data --- rather than some data that was read
      in the possibly-distance past and cached since. */
-
-  if (root->is_txn_root)
-    {
-      fs_txn_root_data_t *frd = root->fsap_data;
-      SVN_ERR(svn_fs_x__dag_txn_root(&root_dir, fs, frd->txn_id,
-                                     scratch_pool));
-    }
-  else
-    {
-      root_dir = root->fsap_data;
-    }
+  SVN_ERR(root_node(&root_dir, root, scratch_pool));
 
   /* Recursively verify ROOT_DIR. */
   parent_nodes = apr_array_make(scratch_pool, 16, sizeof(dag_node_t *));

Modified: subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.h
URL: http://svn.apache.org/viewvc/subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.h?rev=1655189&r1=1655188&r2=1655189&view=diff
==============================================================================
--- subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.h (original)
+++ subversion/branches/svn-auth-x509/subversion/libsvn_fs_x/tree.h Tue Jan 27 23:27:44 2015
@@ -31,10 +31,9 @@ extern "C" {
 
 
 
-/* In POOL, create an instance of a DAG node 1st level cache.
-   The POOL will be cleared at regular intervals. */
+/* In RESULT_POOL, create an instance of a DAG node 1st level cache. */
 svn_fs_x__dag_cache_t*
-svn_fs_x__create_dag_cache(apr_pool_t *pool);
+svn_fs_x__create_dag_cache(apr_pool_t *result_pool);
 
 /* Set *ROOT_P to the root directory of revision REV in filesystem FS.
    Allocate the structure in POOL. */