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 2015/01/21 17:22:22 UTC

svn commit: r1653578 [11/18] - in /subversion/branches/pin-externals: ./ notes/ subversion/bindings/swig/ subversion/bindings/swig/include/ subversion/bindings/swig/perl/native/ subversion/bindings/swig/perl/native/t/ subversion/bindings/swig/python/te...

Modified: subversion/branches/pin-externals/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/libsvn_fs_x/transaction.c?rev=1653578&r1=1653577&r2=1653578&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/branches/pin-externals/subversion/libsvn_fs_x/transaction.c Wed Jan 21 16:22:19 2015
@@ -85,14 +85,14 @@ svn_fs_x__txn_get_id(svn_fs_txn_t *txn)
    txn_list_lock mutex).  If the transaction does not exist in the list,
    then create a new transaction object and return it (if CREATE_NEW is
    true) or return NULL (otherwise). */
-static fs_x_shared_txn_data_t *
+static svn_fs_x__shared_txn_data_t *
 get_shared_txn(svn_fs_t *fs,
                svn_fs_x__txn_id_t txn_id,
                svn_boolean_t create_new)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
-  fs_x_shared_data_t *ffsd = ffd->shared;
-  fs_x_shared_txn_data_t *txn;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  svn_fs_x__shared_data_t *ffsd = ffd->shared;
+  svn_fs_x__shared_txn_data_t *txn;
 
   for (txn = ffsd->txns; txn; txn = txn->next)
     if (txn->txn_id == txn_id)
@@ -135,9 +135,9 @@ get_shared_txn(svn_fs_t *fs,
 static void
 free_shared_txn(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
-  fs_x_shared_data_t *ffsd = ffd->shared;
-  fs_x_shared_txn_data_t *txn, *prev = NULL;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  svn_fs_x__shared_data_t *ffsd = ffd->shared;
+  svn_fs_x__shared_txn_data_t *txn, *prev = NULL;
 
   for (txn = ffsd->txns; txn; prev = txn, txn = txn->next)
     if (txn->txn_id == txn_id)
@@ -172,8 +172,8 @@ with_txnlist_lock(svn_fs_t *fs,
                   const void *baton,
                   apr_pool_t *pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
-  fs_x_shared_data_t *ffsd = ffd->shared;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  svn_fs_x__shared_data_t *ffsd = ffd->shared;
 
   SVN_MUTEX__WITH_LOCK(ffsd->txn_list_lock,
                        body(fs, baton, pool));
@@ -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.
@@ -196,7 +197,7 @@ get_lock_on_filesystem(const char *lock_
 static apr_status_t
 reset_lock_flag(void *baton_void)
 {
-  fs_x_data_t *ffd = baton_void;
+  svn_fs_x__data_t *ffd = baton_void;
   ffd->has_write_lock = FALSE;
   return APR_SUCCESS;
 }
@@ -233,7 +234,7 @@ typedef struct with_lock_baton_t
   /* Function body to execute after we acquired the lock.
      This may be user-provided or a nested call to with_lock(). */
   svn_error_t *(*body)(void *baton,
-                       apr_pool_t *pool);
+                       apr_pool_t *scratch_pool);
 
   /* Baton to pass to BODY; possibly NULL.
      This may be user-provided or a nested lock baton instance. */
@@ -266,7 +267,7 @@ with_some_lock_file(with_lock_baton_t *b
   if (!err)
     {
       svn_fs_t *fs = baton->fs;
-      fs_x_data_t *ffd = fs->fsap_data;
+      svn_fs_x__data_t *ffd = fs->fsap_data;
 
       if (baton->is_global_lock)
         {
@@ -299,11 +300,11 @@ with_some_lock_file(with_lock_baton_t *b
 
 /* Wraps with_some_lock_file, protecting it with BATON->MUTEX.
 
-   POOL is unused here and only provided for signature compatibility with
-   WITH_LOCK_BATON_T.BODY. */
+   SCRATCH_POOL is unused here and only provided for signature compatibility
+   with WITH_LOCK_BATON_T.BODY. */
 static svn_error_t *
 with_lock(void *baton,
-          apr_pool_t *pool)
+          apr_pool_t *scratch_pool)
 {
   with_lock_baton_t *lock_baton = baton;
   SVN_MUTEX__WITH_LOCK(lock_baton->mutex, with_some_lock_file(lock_baton));
@@ -326,8 +327,8 @@ static void
 init_lock_baton(with_lock_baton_t *baton,
                 lock_id_t lock_id)
 {
-  fs_x_data_t *ffd = baton->fs->fsap_data;
-  fs_x_shared_data_t *ffsd = ffd->shared;
+  svn_fs_x__data_t *ffd = baton->fs->fsap_data;
+  svn_fs_x__shared_data_t *ffsd = ffd->shared;
 
   switch (lock_id)
     {
@@ -355,19 +356,20 @@ 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,
                   lock_id_t lock_id,
                   svn_error_t *(*body)(void *baton,
-                                       apr_pool_t *pool),
+                                       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. */
@@ -428,97 +430,102 @@ chain_lock_baton(lock_id_t lock_id,
 svn_error_t *
 svn_fs_x__with_write_lock(svn_fs_t *fs,
                           svn_error_t *(*body)(void *baton,
-                                               apr_pool_t *pool),
+                                               apr_pool_t *scratch_pool),
                           void *baton,
-                          apr_pool_t *pool)
+                          apr_pool_t *scratch_pool)
 {
   return svn_error_trace(
-           with_lock(create_lock_baton(fs, write_lock, body, baton, pool),
-                     pool));
+           with_lock(create_lock_baton(fs, write_lock, body, baton,
+                                       scratch_pool),
+                     scratch_pool));
 }
 
 svn_error_t *
 svn_fs_x__with_pack_lock(svn_fs_t *fs,
                          svn_error_t *(*body)(void *baton,
-                                              apr_pool_t *pool),
+                                              apr_pool_t *scratch_pool),
                          void *baton,
-                         apr_pool_t *pool)
+                         apr_pool_t *scratch_pool)
 {
   return svn_error_trace(
-           with_lock(create_lock_baton(fs, pack_lock, body, baton, pool),
-                     pool));
+           with_lock(create_lock_baton(fs, pack_lock, body, baton,
+                                       scratch_pool),
+                     scratch_pool));
 }
 
 svn_error_t *
 svn_fs_x__with_txn_current_lock(svn_fs_t *fs,
                                 svn_error_t *(*body)(void *baton,
-                                                     apr_pool_t *pool),
+                                                     apr_pool_t *scratch_pool),
                                 void *baton,
-                                apr_pool_t *pool)
+                                apr_pool_t *scratch_pool)
 {
   return svn_error_trace(
-           with_lock(create_lock_baton(fs, txn_lock, body, baton, pool),
-                     pool));
+           with_lock(create_lock_baton(fs, txn_lock, body, baton,
+                                       scratch_pool),
+                     scratch_pool));
 }
 
 svn_error_t *
 svn_fs_x__with_all_locks(svn_fs_t *fs,
                          svn_error_t *(*body)(void *baton,
-                                              apr_pool_t *pool),
+                                              apr_pool_t *scratch_pool),
                          void *baton,
-                         apr_pool_t *pool)
+                         apr_pool_t *scratch_pool)
 {
   /* Be sure to use the correct lock ordering as documented in
      fs_fs_shared_data_t.  The lock chain is being created in 
      innermost (last to acquire) -> outermost (first to acquire) order. */
   with_lock_baton_t *lock_baton
-    = create_lock_baton(fs, write_lock, body, baton, pool);
+    = create_lock_baton(fs, write_lock, body, baton, scratch_pool);
 
   lock_baton = chain_lock_baton(pack_lock, lock_baton);
   lock_baton = chain_lock_baton(txn_lock, lock_baton);
 
-  return svn_error_trace(with_lock(lock_baton, pool));
+  return svn_error_trace(with_lock(lock_baton, scratch_pool));
 }
 
 
 /* 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 *
-unlock_proto_rev_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
+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;
-  fs_x_shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, FALSE);
+  svn_fs_x__shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, FALSE);
   apr_status_t apr_err;
 
   if (!txn)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Can't unlock unknown transaction '%s'"),
-                             svn_fs_x__txn_name(b->txn_id, pool));
+                             svn_fs_x__txn_name(b->txn_id, scratch_pool));
   if (!txn->being_written)
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Can't unlock nonlocked transaction '%s'"),
-                             svn_fs_x__txn_name(b->txn_id, pool));
+                             svn_fs_x__txn_name(b->txn_id, scratch_pool));
 
   apr_err = apr_file_unlock(lockfile);
   if (apr_err)
     return svn_error_wrap_apr
       (apr_err,
        _("Can't unlock prototype revision lockfile for transaction '%s'"),
-       svn_fs_x__txn_name(b->txn_id, pool));
+       svn_fs_x__txn_name(b->txn_id, scratch_pool));
   apr_err = apr_file_close(lockfile);
   if (apr_err)
     return svn_error_wrap_apr
       (apr_err,
        _("Can't close prototype revision lockfile for transaction '%s'"),
-       svn_fs_x__txn_name(b->txn_id, pool));
+       svn_fs_x__txn_name(b->txn_id, scratch_pool));
 
   txn->being_written = FALSE;
 
@@ -529,35 +536,37 @@ unlock_proto_rev_body(svn_fs_t *fs, cons
    FS using cookie LOCKCOOKIE.  The original prototype revision file must
    have been closed _before_ calling this function.
 
-   Perform temporary allocations in POOL. */
+   Perform temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 unlock_proto_rev(svn_fs_t *fs,
                  svn_fs_x__txn_id_t txn_id,
                  void *lockcookie,
-                 apr_pool_t *pool)
+                 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;
-  return with_txnlist_lock(fs, unlock_proto_rev_body, &b, pool);
+  return with_txnlist_lock(fs, unlock_proto_rev_body, &b, scratch_pool);
 }
 
 /* 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 *
-get_writable_proto_rev_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
+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;
-  fs_x_shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, TRUE);
+  svn_fs_x__shared_txn_data_t *txn = get_shared_txn(fs, b->txn_id, TRUE);
 
   /* First, ensure that no thread in this process (including this one)
      is currently writing to this transaction's proto-rev file. */
@@ -567,7 +576,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
                                "of transaction '%s' because a previous "
                                "representation is currently being written by "
                                "this process"),
-                             svn_fs_x__txn_name(b->txn_id, pool));
+                             svn_fs_x__txn_name(b->txn_id, scratch_pool));
 
 
   /* We know that no thread in this process is writing to the proto-rev
@@ -580,7 +589,7 @@ get_writable_proto_rev_body(svn_fs_t *fs
     apr_file_t *lockfile;
     apr_status_t apr_err;
     const char *lockfile_path
-      = svn_fs_x__path_txn_proto_rev_lock(fs, b->txn_id, pool);
+      = svn_fs_x__path_txn_proto_rev_lock(fs, b->txn_id, scratch_pool);
 
     /* Open the proto-rev lockfile, creating it if necessary, as it may
        not exist if the transaction dates from before the lockfiles were
@@ -590,13 +599,14 @@ get_writable_proto_rev_body(svn_fs_t *fs
            that forces us to create a subpool just to be able to unlock
            the file, which seems a waste. */
     SVN_ERR(svn_io_file_open(&lockfile, lockfile_path,
-                             APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));
+                             APR_WRITE | APR_CREATE, APR_OS_DEFAULT,
+                             scratch_pool));
 
     apr_err = apr_file_lock(lockfile,
                             APR_FLOCK_EXCLUSIVE | APR_FLOCK_NONBLOCK);
     if (apr_err)
       {
-        svn_error_clear(svn_io_file_close(lockfile, pool));
+        svn_error_clear(svn_io_file_close(lockfile, scratch_pool));
 
         if (APR_STATUS_IS_EAGAIN(apr_err))
           return svn_error_createf(SVN_ERR_FS_REP_BEING_WRITTEN, NULL,
@@ -604,11 +614,13 @@ get_writable_proto_rev_body(svn_fs_t *fs
                                      "file of transaction '%s' because a "
                                      "previous representation is currently "
                                      "being written by another process"),
-                                   svn_fs_x__txn_name(b->txn_id, pool));
+                                   svn_fs_x__txn_name(b->txn_id,
+                                                      scratch_pool));
 
         return svn_error_wrap_apr(apr_err,
                                   _("Can't get exclusive lock on file '%s'"),
-                                  svn_dirent_local_style(lockfile_path, pool));
+                                  svn_dirent_local_style(lockfile_path,
+                                                         scratch_pool));
       }
 
     *lockcookie = lockfile;
@@ -626,37 +638,37 @@ get_writable_proto_rev_body(svn_fs_t *fs
 
    If the prototype revision file is too short, we can't do much but bail out.
 
-   Perform all allocations in POOL. */
+   Perform all allocations in SCRATCH_POOL. */
 static svn_error_t *
 auto_truncate_proto_rev(svn_fs_t *fs,
                         apr_file_t *proto_rev,
                         apr_off_t actual_length,
                         svn_fs_x__txn_id_t txn_id,
-                        apr_pool_t *pool)
+                        apr_pool_t *scratch_pool)
 {
   /* Determine file range covered by the proto-index so far.  Note that
      we always append to both file, i.e. the last index entry also
      corresponds to the last addition in the rev file. */
-  const char *path = svn_fs_x__path_p2l_proto_index(fs, txn_id, pool);
+  const char *path = svn_fs_x__path_p2l_proto_index(fs, txn_id, scratch_pool);
   apr_file_t *file;
   apr_off_t indexed_length;
 
-  SVN_ERR(svn_fs_x__p2l_proto_index_open(&file, path, pool));
+  SVN_ERR(svn_fs_x__p2l_proto_index_open(&file, path, scratch_pool));
   SVN_ERR(svn_fs_x__p2l_proto_index_next_offset(&indexed_length, file,
-                                                pool));
-  SVN_ERR(svn_io_file_close(file, pool));
+                                                scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   /* Handle mismatches. */
   if (indexed_length < actual_length)
-    SVN_ERR(svn_io_file_trunc(proto_rev, indexed_length, pool));
+    SVN_ERR(svn_io_file_trunc(proto_rev, indexed_length, scratch_pool));
   else if (indexed_length > actual_length)
     return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT,
                              NULL,
                              _("p2l proto index offset %s beyond proto"
                                "rev file size %s for TXN %s"),
-                             apr_off_t_toa(pool, indexed_length),
-                             apr_off_t_toa(pool, actual_length),
-                             svn_fs_x__txn_name(txn_id, pool));
+                             apr_off_t_toa(scratch_pool, indexed_length),
+                             apr_off_t_toa(scratch_pool, actual_length),
+                             svn_fs_x__txn_name(txn_id, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -678,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;
 
@@ -724,7 +736,9 @@ get_writable_proto_rev(apr_file_t **file
 
 /* Callback used in the implementation of purge_shared_txn(). */
 static svn_error_t *
-purge_shared_txn_body(svn_fs_t *fs, const void *baton, apr_pool_t *pool)
+purge_shared_txn_body(svn_fs_t *fs,
+                      const void *baton,
+                      apr_pool_t *scratch_pool)
 {
   svn_fs_x__txn_id_t txn_id = *(const svn_fs_x__txn_id_t *)baton;
 
@@ -734,42 +748,43 @@ purge_shared_txn_body(svn_fs_t *fs, cons
 }
 
 /* Purge the shared data for transaction TXN_ID in filesystem FS.
-   Perform all allocations in POOL. */
+   Perform all temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 purge_shared_txn(svn_fs_t *fs,
                  svn_fs_x__txn_id_t txn_id,
-                 apr_pool_t *pool)
+                 apr_pool_t *scratch_pool)
 {
-  return with_txnlist_lock(fs, purge_shared_txn_body, &txn_id, pool);
+  return with_txnlist_lock(fs, purge_shared_txn_body, &txn_id, scratch_pool);
 }
 
 
 svn_error_t *
 svn_fs_x__put_node_revision(svn_fs_t *fs,
-                            const svn_fs_id_t *id,
-                            node_revision_t *noderev,
+                            svn_fs_x__noderev_t *noderev,
                             svn_boolean_t fresh_txn_root,
-                            apr_pool_t *pool)
+                            apr_pool_t *scratch_pool)
 {
   apr_file_t *noderev_file;
+  const svn_fs_x__id_t *id = &noderev->noderev_id;
 
   noderev->is_fresh_txn_root = fresh_txn_root;
 
-  if (! svn_fs_x__id_is_txn(id))
+  if (! svn_fs_x__is_txn(id->change_set))
     return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              _("Attempted to write to non-transaction '%s'"),
-                             svn_fs_x__id_unparse(id, pool)->data);
+                             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, 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, pool));
+                           | APR_BUFFERED, APR_OS_DEFAULT, scratch_pool));
 
   SVN_ERR(svn_fs_x__write_noderev(svn_stream_from_aprfile2(noderev_file, TRUE,
-                                                           pool),
-                                  noderev, pool));
+                                                           scratch_pool),
+                                  noderev, scratch_pool));
 
-  SVN_ERR(svn_io_file_close(noderev_file, pool));
+  SVN_ERR(svn_io_file_close(noderev_file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -780,10 +795,10 @@ svn_fs_x__put_node_revision(svn_fs_t *fs
  */
 static svn_error_t *
 store_sha1_rep_mapping(svn_fs_t *fs,
-                       node_revision_t *noderev,
+                       svn_fs_x__noderev_t *noderev,
                        apr_pool_t *scratch_pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
 
   /* if rep sharing has been enabled and the noderev has a data rep and
    * its SHA-1 is known, store the rep struct under its SHA1. */
@@ -817,42 +832,43 @@ store_sha1_rep_mapping(svn_fs_t *fs,
 }
 
 static svn_error_t *
-unparse_dir_entry(svn_fs_dirent_t *dirent,
+unparse_dir_entry(svn_fs_x__dirent_t *dirent,
                   svn_stream_t *stream,
-                  apr_pool_t *pool)
+                  apr_pool_t *scratch_pool)
 {
   const char *val
-    = apr_psprintf(pool, "%s %s",
+    = apr_psprintf(scratch_pool, "%s %s",
                    (dirent->kind == svn_node_file) ? SVN_FS_X__KIND_FILE
                                                    : SVN_FS_X__KIND_DIR,
-                   svn_fs_x__id_unparse(dirent->id, pool)->data);
+                   svn_fs_x__id_unparse(&dirent->id, scratch_pool)->data);
 
-  SVN_ERR(svn_stream_printf(stream, pool, "K %" APR_SIZE_T_FMT "\n%s\n"
-                            "V %" APR_SIZE_T_FMT "\n%s\n",
+  SVN_ERR(svn_stream_printf(stream, scratch_pool, "K %" APR_SIZE_T_FMT
+                            "\n%s\nV %" APR_SIZE_T_FMT "\n%s\n",
                             strlen(dirent->name), dirent->name,
                             strlen(val), val));
   return SVN_NO_ERROR;
 }
 
 /* Write the directory given as array of dirent structs in ENTRIES to STREAM.
-   Perform temporary allocations in POOL. */
+   Perform temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 unparse_dir_entries(apr_array_header_t *entries,
                     svn_stream_t *stream,
-                    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);
   int i;
   for (i = 0; i < entries->nelts; ++i)
     {
-      svn_fs_dirent_t *dirent;
+      svn_fs_x__dirent_t *dirent;
 
       svn_pool_clear(iterpool);
-      dirent = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+      dirent = APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *);
       SVN_ERR(unparse_dir_entry(dirent, stream, iterpool));
     }
 
-  SVN_ERR(svn_stream_printf(stream, pool, "%s\n", SVN_HASH_TERMINATOR));
+  SVN_ERR(svn_stream_printf(stream, scratch_pool, "%s\n",
+                            SVN_HASH_TERMINATOR));
 
   svn_pool_destroy(iterpool);
   return SVN_NO_ERROR;
@@ -860,13 +876,15 @@ unparse_dir_entries(apr_array_header_t *
 
 /* Return a deep copy of SOURCE and allocate it in RESULT_POOL.
  */
-static svn_fs_path_change2_t *
-path_change_dup(const svn_fs_path_change2_t *source,
+static svn_fs_x__change_t *
+path_change_dup(const svn_fs_x__change_t *source,
                 apr_pool_t *result_pool)
 {
-  svn_fs_path_change2_t *result = apr_pmemdup(result_pool, source,
-                                              sizeof(*source));
-  result->node_rev_id = svn_fs_x__id_copy(source->node_rev_id, result_pool);
+  svn_fs_x__change_t *result
+    = apr_pmemdup(result_pool, source, sizeof(*source));
+  result->path.data
+    = apr_pstrmemdup(result_pool, source->path.data, source->path.len);
+
   if (source->copyfrom_path)
     result->copyfrom_path = apr_pstrdup(result_pool, source->copyfrom_path);
 
@@ -874,29 +892,28 @@ path_change_dup(const svn_fs_path_change
 }
 
 /* Merge the internal-use-only CHANGE into a hash of public-FS
-   svn_fs_path_change2_t CHANGED_PATHS, collapsing multiple changes into a
+   svn_fs_x__change_t CHANGED_PATHS, collapsing multiple changes into a
    single summarical (is that real word?) change per path.  DELETIONS is
-   also a path->svn_fs_path_change2_t hash and contains all the deletions
+   also a path->svn_fs_x__change_t hash and contains all the deletions
    that got turned into a replacement. */
 static svn_error_t *
 fold_change(apr_hash_t *changed_paths,
             apr_hash_t *deletions,
-            const change_t *change)
+            const svn_fs_x__change_t *change)
 {
   apr_pool_t *pool = apr_hash_pool_get(changed_paths);
-  svn_fs_path_change2_t *old_change, *new_change;
+  svn_fs_x__change_t *old_change, *new_change;
   const svn_string_t *path = &change->path;
-  const svn_fs_path_change2_t *info = &change->info;
 
   if ((old_change = apr_hash_get(changed_paths, path->data, path->len)))
     {
       /* This path already exists in the hash, so we have to merge
          this change into the already existing one. */
 
-      /* Sanity check:  only allow NULL node revision ID in the
+      /* Sanity check:  only allow unused node revision IDs in the
          `reset' case. */
-      if ((! info->node_rev_id)
-           && (info->change_kind != svn_fs_path_change_reset))
+      if ((! svn_fs_x__id_used(&change->noderev_id))
+           && (change->change_kind != svn_fs_path_change_reset))
         return svn_error_create
           (SVN_ERR_FS_CORRUPT, NULL,
            _("Missing required node revision ID"));
@@ -904,8 +921,8 @@ fold_change(apr_hash_t *changed_paths,
       /* Sanity check: we should be talking about the same node
          revision ID as our last change except where the last change
          was a deletion. */
-      if (info->node_rev_id
-          && (! svn_fs_x__id_eq(old_change->node_rev_id, info->node_rev_id))
+      if (svn_fs_x__id_used(&change->noderev_id)
+          && (!svn_fs_x__id_eq(&old_change->noderev_id, &change->noderev_id))
           && (old_change->change_kind != svn_fs_path_change_delete))
         return svn_error_create
           (SVN_ERR_FS_CORRUPT, NULL,
@@ -915,16 +932,16 @@ fold_change(apr_hash_t *changed_paths,
       /* Sanity check: an add, replacement, or reset must be the first
          thing to follow a deletion. */
       if ((old_change->change_kind == svn_fs_path_change_delete)
-          && (! ((info->change_kind == svn_fs_path_change_replace)
-                 || (info->change_kind == svn_fs_path_change_reset)
-                 || (info->change_kind == svn_fs_path_change_add))))
+          && (! ((change->change_kind == svn_fs_path_change_replace)
+                 || (change->change_kind == svn_fs_path_change_reset)
+                 || (change->change_kind == svn_fs_path_change_add))))
         return svn_error_create
           (SVN_ERR_FS_CORRUPT, NULL,
            _("Invalid change ordering: non-add change on deleted path"));
 
       /* Sanity check: an add can't follow anything except
          a delete or reset.  */
-      if ((info->change_kind == svn_fs_path_change_add)
+      if ((change->change_kind == svn_fs_path_change_add)
           && (old_change->change_kind != svn_fs_path_change_delete)
           && (old_change->change_kind != svn_fs_path_change_reset))
         return svn_error_create
@@ -932,7 +949,7 @@ fold_change(apr_hash_t *changed_paths,
            _("Invalid change ordering: add change on preexisting path"));
 
       /* Now, merge that change in. */
-      switch (info->change_kind)
+      switch (change->change_kind)
         {
         case svn_fs_path_change_reset:
           /* A reset here will simply remove the path change from the
@@ -958,7 +975,7 @@ fold_change(apr_hash_t *changed_paths,
           else
             {
               /* A deletion overrules a previous change (modify). */
-              new_change = path_change_dup(info, pool);
+              new_change = path_change_dup(change, pool);
               apr_hash_set(changed_paths, path->data, path->len, new_change);
             }
           break;
@@ -969,7 +986,7 @@ fold_change(apr_hash_t *changed_paths,
              so treat it just like a replace.  Remember the original
              deletion such that we are able to delete this path again
              (the replacement may have changed node kind and id). */
-          new_change = path_change_dup(info, pool);
+          new_change = path_change_dup(change, pool);
           new_change->change_kind = svn_fs_path_change_replace;
 
           apr_hash_set(changed_paths, path->data, path->len, new_change);
@@ -987,11 +1004,11 @@ fold_change(apr_hash_t *changed_paths,
           /* If the new change modifies some attribute of the node, set
              the corresponding flag, whether it already was set or not.
              Note: We do not reset a flag to FALSE if a change is undone. */
-          if (info->text_mod)
+          if (change->text_mod)
             old_change->text_mod = TRUE;
-          if (info->prop_mod)
+          if (change->prop_mod)
             old_change->prop_mod = TRUE;
-          if (info->mergeinfo_mod == svn_tristate_true)
+          if (change->mergeinfo_mod == svn_tristate_true)
             old_change->mergeinfo_mod = svn_tristate_true;
           break;
         }
@@ -1001,9 +1018,9 @@ fold_change(apr_hash_t *changed_paths,
       /* Add this path.  The API makes no guarantees that this (new) key
          will not be retained.  Thus, we copy the key into the target pool
          to ensure a proper lifetime.  */
-      apr_hash_set(changed_paths,
-                   apr_pstrmemdup(pool, path->data, path->len), path->len,
-                   path_change_dup(info, pool));
+      new_change = path_change_dup(change, pool);
+      apr_hash_set(changed_paths, new_change->path.data,
+                   new_change->path.len, new_change);
     }
 
   return SVN_NO_ERROR;
@@ -1027,7 +1044,7 @@ typedef struct process_changes_baton_t
    data. Use SCRATCH_POOL for temporary allocations. */
 static svn_error_t *
 process_changes(void *baton_p,
-                change_t *change,
+                svn_fs_x__change_t *change,
                 apr_pool_t *scratch_pool)
 {
   process_changes_baton_t *baton = baton_p;
@@ -1042,8 +1059,8 @@ process_changes(void *baton_p,
      is already a temporary subpool.
   */
 
-  if ((change->info.change_kind == svn_fs_path_change_delete)
-       || (change->info.change_kind == svn_fs_path_change_replace))
+  if ((change->change_kind == svn_fs_path_change_delete)
+       || (change->change_kind == svn_fs_path_change_replace))
     {
       apr_hash_index_t *hi;
 
@@ -1121,85 +1138,60 @@ svn_fs_x__txn_changes_fetch(apr_hash_t *
   return SVN_NO_ERROR;
 }
 
-
-svn_error_t *
-svn_fs_x__paths_changed(apr_hash_t **changed_paths_p,
-                        svn_fs_t *fs,
-                        svn_revnum_t rev,
-                        apr_pool_t *pool)
-{
-  apr_hash_t *changed_paths;
-  apr_array_header_t *changes;
-  int i;
-
-  SVN_ERR(svn_fs_x__get_changes(&changes, fs, rev, pool));
-
-  changed_paths = svn_hash__make(pool);
-  for (i = 0; i < changes->nelts; ++i)
-    {
-      change_t *change = APR_ARRAY_IDX(changes, i, change_t *);
-      apr_hash_set(changed_paths, change->path.data, change->path.len,
-                   &change->info);
-    }
-
-  *changed_paths_p = changed_paths;
-
-  return SVN_NO_ERROR;
-}
-
 /* Copy a revision node-rev SRC into the current transaction TXN_ID in
    the filesystem FS.  This is only used to create the root of a transaction.
-   Allocations are from POOL.  */
+   Temporary allocations are from SCRATCH_POOL.  */
 static svn_error_t *
 create_new_txn_noderev_from_rev(svn_fs_t *fs,
                                 svn_fs_x__txn_id_t txn_id,
-                                svn_fs_id_t *src,
-                                apr_pool_t *pool)
+                                svn_fs_x__id_t *src,
+                                apr_pool_t *scratch_pool)
 {
-  node_revision_t *noderev;
-
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, src, pool, pool));
+  svn_fs_x__noderev_t *noderev;
+  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, src, scratch_pool,
+                                      scratch_pool));
 
   /* This must be a root node. */
-  SVN_ERR_ASSERT(   svn_fs_x__id_node_id(noderev->id)->number == 0
-                 && svn_fs_x__id_copy_id(noderev->id)->number == 0);
+  SVN_ERR_ASSERT(   noderev->node_id.number == 0
+                 && noderev->copy_id.number == 0);
 
-  if (svn_fs_x__id_is_txn(noderev->id))
+  if (svn_fs_x__is_txn(noderev->noderev_id.change_set))
     return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                             _("Copying from transactions not allowed"));
 
-  noderev->predecessor_id = noderev->id;
+  noderev->predecessor_id = noderev->noderev_id;
   noderev->predecessor_count++;
   noderev->copyfrom_path = NULL;
   noderev->copyfrom_rev = SVN_INVALID_REVNUM;
 
   /* For the transaction root, the copyroot never changes. */
+  svn_fs_x__init_txn_root(&noderev->noderev_id, txn_id);
 
-  noderev->id = svn_fs_x__id_txn_create_root(txn_id, pool);
-
-  return svn_fs_x__put_node_revision(fs, noderev->id, noderev, TRUE, pool);
+  return svn_fs_x__put_node_revision(fs, noderev, TRUE, scratch_pool);
 }
 
 /* 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.
    It returns the original value by the baton. */
 static svn_error_t *
-get_and_increment_txn_key_body(void *baton, apr_pool_t *pool)
+get_and_increment_txn_key_body(void *baton,
+                               apr_pool_t *scratch_pool)
 {
-  struct get_and_increment_txn_key_baton *cb = baton;
-  const char *txn_current_filename = svn_fs_x__path_txn_current(cb->fs, pool);
+  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);
@@ -1207,12 +1199,13 @@ get_and_increment_txn_key_body(void *bat
   /* Increment the key and add a trailing \n to the string so the
      txn-current file has a newline in it. */
   SVN_ERR(svn_io_write_unique(&tmp_filename,
-                              svn_dirent_dirname(txn_current_filename, pool),
+                              svn_dirent_dirname(txn_current_filename,
+                                                 scratch_pool),
                               new_id_str,
                               svn__ui64tobase36(new_id_str, cb->txn_number+1),
-                              svn_io_file_del_none, pool));
+                              svn_io_file_del_none, scratch_pool));
   SVN_ERR(svn_fs_x__move_into_place(tmp_filename, txn_current_filename,
-                                    txn_current_filename, pool));
+                                    txn_current_filename, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1224,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_id_t *root_id;
+  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;
@@ -1271,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, 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.
@@ -1324,29 +1328,31 @@ get_txn_proplist(apr_hash_t *proplist,
 }
 
 /* Save the property list PROPS as the revprops for transaction TXN_ID
-   in FS.  Perform temporary allocations in POOL. */
+   in FS.  Perform temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 set_txn_proplist(svn_fs_t *fs,
                  svn_fs_x__txn_id_t txn_id,
                  apr_hash_t *props,
                  svn_boolean_t final,
-                 apr_pool_t *pool)
+                 apr_pool_t *scratch_pool)
 {
   svn_stringbuf_t *buf;
   svn_stream_t *stream;
 
   /* Write out the new file contents to BUF. */
-  buf = svn_stringbuf_create_ensure(1024, pool);
-  stream = svn_stream_from_stringbuf(buf, pool);
-  SVN_ERR(svn_hash_write2(props, stream, SVN_HASH_TERMINATOR, pool));
+  buf = svn_stringbuf_create_ensure(1024, scratch_pool);
+  stream = svn_stream_from_stringbuf(buf, scratch_pool);
+  SVN_ERR(svn_hash_write2(props, stream, SVN_HASH_TERMINATOR, scratch_pool));
   SVN_ERR(svn_stream_close(stream));
 
   /* Open the transaction properties file and write new contents to it. */
   SVN_ERR(svn_io_write_atomic((final 
-                               ? svn_fs_x__path_txn_props_final(fs, txn_id, pool)
-                               : svn_fs_x__path_txn_props(fs, txn_id, pool)),
+                               ? svn_fs_x__path_txn_props_final(fs, txn_id,
+                                                                scratch_pool)
+                               : svn_fs_x__path_txn_props(fs, txn_id,
+                                                          scratch_pool)),
                               buf->data, buf->len,
-                              NULL /* copy_perms_path */, pool));
+                              NULL /* copy_perms_path */, scratch_pool));
   return SVN_NO_ERROR;
 }
 
@@ -1355,29 +1361,30 @@ svn_error_t *
 svn_fs_x__change_txn_prop(svn_fs_txn_t *txn,
                           const char *name,
                           const svn_string_t *value,
-                          apr_pool_t *pool)
+                          apr_pool_t *scratch_pool)
 {
-  apr_array_header_t *props = apr_array_make(pool, 1, sizeof(svn_prop_t));
+  apr_array_header_t *props = apr_array_make(scratch_pool, 1,
+                                             sizeof(svn_prop_t));
   svn_prop_t prop;
 
   prop.name = name;
   prop.value = value;
   APR_ARRAY_PUSH(props, svn_prop_t) = prop;
 
-  return svn_fs_x__change_txn_props(txn, props, pool);
+  return svn_fs_x__change_txn_props(txn, props, scratch_pool);
 }
 
 svn_error_t *
 svn_fs_x__change_txn_props(svn_fs_txn_t *txn,
                            const apr_array_header_t *props,
-                           apr_pool_t *pool)
+                           apr_pool_t *scratch_pool)
 {
   fs_txn_data_t *ftd = txn->fsap_data;
-  apr_hash_t *txn_prop = apr_hash_make(pool);
+  apr_hash_t *txn_prop = apr_hash_make(scratch_pool);
   int i;
   svn_error_t *err;
 
-  err = get_txn_proplist(txn_prop, txn->fs, ftd->txn_id, pool);
+  err = get_txn_proplist(txn_prop, txn->fs, ftd->txn_id, scratch_pool);
   /* Here - and here only - we need to deal with the possibility that the
      transaction property file doesn't yet exist.  The rest of the
      implementation assumes that the file exists, but we're called to set the
@@ -1394,38 +1401,38 @@ svn_fs_x__change_txn_props(svn_fs_txn_t
       if (svn_hash_gets(txn_prop, SVN_FS__PROP_TXN_CLIENT_DATE)
           && !strcmp(prop->name, SVN_PROP_REVISION_DATE))
         svn_hash_sets(txn_prop, SVN_FS__PROP_TXN_CLIENT_DATE,
-                      svn_string_create("1", pool));
+                      svn_string_create("1", scratch_pool));
 
       svn_hash_sets(txn_prop, prop->name, prop->value);
     }
 
   /* Create a new version of the file and write out the new props. */
   /* Open the transaction properties file. */
-  SVN_ERR(set_txn_proplist(txn->fs, ftd->txn_id, txn_prop, FALSE, pool));
+  SVN_ERR(set_txn_proplist(txn->fs, ftd->txn_id, txn_prop, FALSE,
+                           scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_fs_x__get_txn(transaction_t **txn_p,
+svn_fs_x__get_txn(svn_fs_x__transaction_t **txn_p,
                   svn_fs_t *fs,
                   svn_fs_x__txn_id_t txn_id,
                   apr_pool_t *pool)
 {
-  transaction_t *txn;
-  node_revision_t *noderev;
-  svn_fs_id_t *root_id;
+  svn_fs_x__transaction_t *txn;
+  svn_fs_x__noderev_t *noderev;
+  svn_fs_x__id_t root_id;
 
   txn = apr_pcalloc(pool, sizeof(*txn));
   txn->proplist = apr_hash_make(pool);
 
   SVN_ERR(get_txn_proplist(txn->proplist, fs, txn_id, pool));
-  root_id = svn_fs_x__id_txn_create_root(txn_id, pool);
+  svn_fs_x__init_txn_root(&root_id, txn_id);
 
-  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, root_id, pool, 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);
+  txn->base_rev = svn_fs_x__get_revnum(noderev->predecessor_id.change_set);
   txn->copies = NULL;
 
   *txn_p = txn;
@@ -1435,52 +1442,52 @@ svn_fs_x__get_txn(transaction_t **txn_p,
 
 /* If it is supported by the format of file system FS, store the (ITEM_INDEX,
  * OFFSET) pair in the log-to-phys proto index file of transaction TXN_ID.
- * Use POOL for allocations.
+ * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 store_l2p_index_entry(svn_fs_t *fs,
                       svn_fs_x__txn_id_t txn_id,
                       apr_off_t offset,
                       apr_uint64_t item_index,
-                      apr_pool_t *pool)
+                      apr_pool_t *scratch_pool)
 {
-  const char *path = svn_fs_x__path_l2p_proto_index(fs, txn_id, pool);
+  const char *path = svn_fs_x__path_l2p_proto_index(fs, txn_id, scratch_pool);
   apr_file_t *file;
-  SVN_ERR(svn_fs_x__l2p_proto_index_open(&file, path, pool));
+  SVN_ERR(svn_fs_x__l2p_proto_index_open(&file, path, scratch_pool));
   SVN_ERR(svn_fs_x__l2p_proto_index_add_entry(file, offset, 0,
-                                              item_index, pool));
-  SVN_ERR(svn_io_file_close(file, pool));
+                                              item_index, scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 /* If it is supported by the format of file system FS, store ENTRY in the
  * phys-to-log proto index file of transaction TXN_ID.
- * Use POOL for allocations.
+ * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 store_p2l_index_entry(svn_fs_t *fs,
                       svn_fs_x__txn_id_t txn_id,
                       svn_fs_x__p2l_entry_t *entry,
-                      apr_pool_t *pool)
+                      apr_pool_t *scratch_pool)
 {
-  const char *path = svn_fs_x__path_p2l_proto_index(fs, txn_id, pool);
+  const char *path = svn_fs_x__path_p2l_proto_index(fs, txn_id, scratch_pool);
   apr_file_t *file;
-  SVN_ERR(svn_fs_x__p2l_proto_index_open(&file, path, pool));
-  SVN_ERR(svn_fs_x__p2l_proto_index_add_entry(file, entry, pool));
-  SVN_ERR(svn_io_file_close(file, pool));
+  SVN_ERR(svn_fs_x__p2l_proto_index_open(&file, path, scratch_pool));
+  SVN_ERR(svn_fs_x__p2l_proto_index_add_entry(file, entry, scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 /* Allocate an item index in the transaction TXN_ID of file system FS and
- * return it in *ITEM_INDEX.  Use POOL for allocations.
+ * return it in *ITEM_INDEX.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 allocate_item_index(apr_uint64_t *item_index,
                     svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   apr_file_t *file;
   char buffer[SVN_INT64_BUFFER_SIZE] = { 0 };
@@ -1491,12 +1498,13 @@ allocate_item_index(apr_uint64_t *item_i
 
   /* read number */
   SVN_ERR(svn_io_file_open(&file,
-                            svn_fs_x__path_txn_item_index(fs, txn_id, pool),
+                            svn_fs_x__path_txn_item_index(fs, txn_id,
+                                                          scratch_pool),
                             APR_READ | APR_WRITE
                             | APR_CREATE | APR_BUFFERED,
-                            APR_OS_DEFAULT, pool));
+                            APR_OS_DEFAULT, scratch_pool));
   SVN_ERR(svn_io_file_read_full2(file, buffer, sizeof(buffer)-1,
-                                  &read, &eof, pool));
+                                  &read, &eof, scratch_pool));
   if (read)
     SVN_ERR(svn_cstring_atoui64(item_index, buffer));
   else
@@ -1506,9 +1514,9 @@ allocate_item_index(apr_uint64_t *item_i
   to_write = svn__ui64toa(buffer, *item_index + 1);
 
   /* write it back to disk */
-  SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, pool));
-  SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, pool));
-  SVN_ERR(svn_io_file_close(file, pool));
+  SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, scratch_pool));
+  SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1517,13 +1525,13 @@ allocate_item_index(apr_uint64_t *item_i
    COPY_ID for transaction TXN_ID in filesystem FS.  The next node-id is
    used both for creating new unique nodes for the given transaction, as
    well as uniquifying representations.  Perform temporary allocations in
-   POOL. */
+   SCRATCH_POOL. */
 static svn_error_t *
 write_next_ids(svn_fs_t *fs,
                svn_fs_x__txn_id_t txn_id,
                apr_uint64_t node_id,
                apr_uint64_t copy_id,
-               apr_pool_t *pool)
+               apr_pool_t *scratch_pool)
 {
   apr_file_t *file;
   char buffer[2 * SVN_INT64_BUFFER_SIZE + 2];
@@ -1536,30 +1544,33 @@ write_next_ids(svn_fs_t *fs,
   *(p++) = '\0';
 
   SVN_ERR(svn_io_file_open(&file,
-                           svn_fs_x__path_txn_next_ids(fs, txn_id, pool),
+                           svn_fs_x__path_txn_next_ids(fs, txn_id,
+                                                       scratch_pool),
                            APR_WRITE | APR_TRUNCATE,
-                           APR_OS_DEFAULT, pool));
-  SVN_ERR(svn_io_file_write_full(file, buffer, p - buffer, NULL, pool));
-  return svn_io_file_close(file, pool);
+                           APR_OS_DEFAULT, scratch_pool));
+  SVN_ERR(svn_io_file_write_full(file, buffer, p - buffer, NULL,
+                                 scratch_pool));
+  return svn_io_file_close(file, scratch_pool);
 }
 
 /* Find out what the next unique node-id and copy-id are for
    transaction TXN_ID in filesystem FS.  Store the results in *NODE_ID
    and *COPY_ID.  The next node-id is used both for creating new unique
    nodes for the given transaction, as well as uniquifying representations.
-   Perform all allocations in POOL. */
+   Perform temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
 read_next_ids(apr_uint64_t *node_id,
               apr_uint64_t *copy_id,
               svn_fs_t *fs,
               svn_fs_x__txn_id_t txn_id,
-              apr_pool_t *pool)
+              apr_pool_t *scratch_pool)
 {
   svn_stringbuf_t *buf;
   const char *str;
   SVN_ERR(svn_fs_x__read_content(&buf,
-                            svn_fs_x__path_txn_next_ids(fs, txn_id, pool),
-                            pool));
+                                 svn_fs_x__path_txn_next_ids(fs, txn_id,
+                                                             scratch_pool),
+                                 scratch_pool));
 
   /* Parse this into two separate strings. */
 
@@ -1581,70 +1592,65 @@ read_next_ids(apr_uint64_t *node_id,
 /* Get a new and unique to this transaction node-id for transaction
    TXN_ID in filesystem FS.  Store the new node-id in *NODE_ID_P.
    Node-ids are guaranteed to be unique to this transction, but may
-   not necessarily be sequential.  Perform all allocations in POOL. */
+   not necessarily be sequential.
+   Perform temporary allocations in SCRATCH_POOL. */
 static svn_error_t *
-get_new_txn_node_id(svn_fs_x__id_part_t *node_id_p,
+get_new_txn_node_id(svn_fs_x__id_t *node_id_p,
                     svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   apr_uint64_t node_id, copy_id;
 
   /* First read in the current next-ids file. */
-  SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));
+  SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, scratch_pool));
 
   node_id_p->change_set = svn_fs_x__change_set_by_txn(txn_id);
   node_id_p->number = node_id;
 
-  SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, pool));
+  SVN_ERR(write_next_ids(fs, txn_id, ++node_id, copy_id, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_fs_x__reserve_copy_id(svn_fs_x__id_part_t *copy_id_p,
+svn_fs_x__reserve_copy_id(svn_fs_x__id_t *copy_id_p,
                           svn_fs_t *fs,
                           svn_fs_x__txn_id_t txn_id,
-                          apr_pool_t *pool)
+                          apr_pool_t *scratch_pool)
 {
   apr_uint64_t node_id, copy_id;
 
   /* First read in the current next-ids file. */
-  SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, pool));
+  SVN_ERR(read_next_ids(&node_id, &copy_id, fs, txn_id, scratch_pool));
 
   copy_id_p->change_set = svn_fs_x__change_set_by_txn(txn_id);
   copy_id_p->number = copy_id;
 
-  SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, pool));
+  SVN_ERR(write_next_ids(fs, txn_id, node_id, ++copy_id, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
-svn_fs_x__create_node(const svn_fs_id_t **id_p,
-                      svn_fs_t *fs,
-                      node_revision_t *noderev,
-                      const svn_fs_x__id_part_t *copy_id,
+svn_fs_x__create_node(svn_fs_t *fs,
+                      svn_fs_x__noderev_t *noderev,
+                      const svn_fs_x__id_t *copy_id,
                       svn_fs_x__txn_id_t txn_id,
-                      apr_pool_t *pool)
+                      apr_pool_t *scratch_pool)
 {
-  svn_fs_x__id_part_t node_id;
-  const svn_fs_id_t *id;
-  apr_uint64_t number;
-
   /* Get a new node-id for this node. */
-  SVN_ERR(get_new_txn_node_id(&node_id, fs, txn_id, pool));
-
-  /* Item number within this change set. */
-  SVN_ERR(allocate_item_index(&number, fs, txn_id, pool));
+  SVN_ERR(get_new_txn_node_id(&noderev->node_id, fs, txn_id, scratch_pool));
 
-  /* Construct the ID object from all the above parts. */
-  id = svn_fs_x__id_txn_create(&node_id, copy_id, txn_id, number, pool);
-  noderev->id = id;
+  /* Assign copy-id. */
+  noderev->copy_id = *copy_id;
 
-  SVN_ERR(svn_fs_x__put_node_revision(fs, noderev->id, noderev, FALSE, pool));
+  /* Noderev-id = Change set and item number within this change set. */
+  noderev->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+  SVN_ERR(allocate_item_index(&noderev->noderev_id.number, fs, txn_id,
+                              scratch_pool));
 
-  *id_p = id;
+  SVN_ERR(svn_fs_x__put_node_revision(fs, noderev, FALSE, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1652,27 +1658,27 @@ svn_fs_x__create_node(const svn_fs_id_t
 svn_error_t *
 svn_fs_x__purge_txn(svn_fs_t *fs,
                     const char *txn_id_str,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   svn_fs_x__txn_id_t txn_id;
   SVN_ERR(svn_fs_x__txn_by_name(&txn_id, txn_id_str));
 
   /* Remove the shared transaction object associated with this transaction. */
-  SVN_ERR(purge_shared_txn(fs, txn_id, pool));
+  SVN_ERR(purge_shared_txn(fs, txn_id, scratch_pool));
   /* Remove the directory associated with this transaction. */
-  SVN_ERR(svn_io_remove_dir2(svn_fs_x__path_txn_dir(fs, txn_id, pool),
-                             FALSE, NULL, NULL, pool));
+  SVN_ERR(svn_io_remove_dir2(svn_fs_x__path_txn_dir(fs, txn_id, scratch_pool),
+                             FALSE, NULL, NULL, scratch_pool));
 
   /* Delete protorev and its lock, which aren't in the txn
       directory.  It's OK if they don't exist (for example, if this
       is post-commit and the proto-rev has been moved into
       place). */
   SVN_ERR(svn_io_remove_file2(
-                  svn_fs_x__path_txn_proto_rev(fs, txn_id, pool),
-                  TRUE, pool));
+                  svn_fs_x__path_txn_proto_rev(fs, txn_id, scratch_pool),
+                  TRUE, scratch_pool));
   SVN_ERR(svn_io_remove_file2(
-                  svn_fs_x__path_txn_proto_rev_lock(fs, txn_id, pool),
-                  TRUE, pool));
+                  svn_fs_x__path_txn_proto_rev_lock(fs, txn_id, scratch_pool),
+                  TRUE, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1680,13 +1686,13 @@ svn_fs_x__purge_txn(svn_fs_t *fs,
 
 svn_error_t *
 svn_fs_x__abort_txn(svn_fs_txn_t *txn,
-                    apr_pool_t *pool)
+                    apr_pool_t *scratch_pool)
 {
   SVN_ERR(svn_fs__check_fs(txn->fs, TRUE));
 
   /* Now, purge the transaction. */
-  SVN_ERR_W(svn_fs_x__purge_txn(txn->fs, txn->id, pool),
-            apr_psprintf(pool, _("Transaction '%s' cleanup failed"),
+  SVN_ERR_W(svn_fs_x__purge_txn(txn->fs, txn->id, scratch_pool),
+            apr_psprintf(scratch_pool, _("Transaction '%s' cleanup failed"),
                          txn->id));
 
   return SVN_NO_ERROR;
@@ -1695,19 +1701,21 @@ svn_fs_x__abort_txn(svn_fs_txn_t *txn,
 svn_error_t *
 svn_fs_x__set_entry(svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
-                    node_revision_t *parent_noderev,
+                    svn_fs_x__noderev_t *parent_noderev,
                     const char *name,
-                    const svn_fs_id_t *id,
+                    const svn_fs_x__id_t *id,
                     svn_node_kind_t kind,
-                    apr_pool_t *pool)
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
 {
-  representation_t *rep = parent_noderev->data_rep;
+  svn_fs_x__representation_t *rep = parent_noderev->data_rep;
   const char *filename
-    = svn_fs_x__path_txn_node_children(fs, parent_noderev->id, pool);
+    = svn_fs_x__path_txn_node_children(fs, &parent_noderev->noderev_id,
+                                       scratch_pool, scratch_pool);
   apr_file_t *file;
   svn_stream_t *out;
-  fs_x_data_t *ffd = fs->fsap_data;
-  apr_pool_t *subpool = svn_pool_create(pool);
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  apr_pool_t *subpool = svn_pool_create(scratch_pool);
 
   if (!rep || !svn_fs_x__is_txn(rep->id.change_set))
     {
@@ -1719,33 +1727,40 @@ svn_fs_x__set_entry(svn_fs_t *fs,
                                          subpool, subpool));
       SVN_ERR(svn_io_file_open(&file, filename,
                                APR_WRITE | APR_CREATE | APR_BUFFERED,
-                               APR_OS_DEFAULT, pool));
-      out = svn_stream_from_aprfile2(file, TRUE, pool);
+                               APR_OS_DEFAULT, scratch_pool));
+      out = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
       SVN_ERR(unparse_dir_entries(entries, out, subpool));
 
       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(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;
-      SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev->id,
-                                          parent_noderev, FALSE, pool));
+
+      /* Save noderev to disk. */
+      SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev, FALSE,
+                                          subpool));
     }
   else
     {
       /* The directory rep is already mutable, so just open it for append. */
       SVN_ERR(svn_io_file_open(&file, filename, APR_WRITE | APR_APPEND,
-                               APR_OS_DEFAULT, pool));
-      out = svn_stream_from_aprfile2(file, TRUE, pool);
+                               APR_OS_DEFAULT, scratch_pool));
+      out = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
     }
 
   /* update directory cache */
     {
       /* build parameters: (name, new entry) pair */
-      const svn_fs_x__id_part_t *key
-        = svn_fs_x__id_noderev_id(parent_noderev->id);
+      const svn_fs_x__id_t *key = &(parent_noderev->noderev_id);
       replace_baton_t baton;
 
       baton.name = name;
@@ -1756,7 +1771,7 @@ svn_fs_x__set_entry(svn_fs_t *fs,
           baton.new_entry = apr_pcalloc(subpool, sizeof(*baton.new_entry));
           baton.new_entry->name = name;
           baton.new_entry->kind = kind;
-          baton.new_entry->id = id;
+          baton.new_entry->id = *id;
         }
 
       /* actually update the cached directory (if cached) */
@@ -1769,9 +1784,9 @@ svn_fs_x__set_entry(svn_fs_t *fs,
   /* Append an incremental hash entry for the entry change. */
   if (id)
     {
-      svn_fs_dirent_t entry;
+      svn_fs_x__dirent_t entry;
       entry.name = name;
-      entry.id = id;
+      entry.id = *id;
       entry.kind = kind;
 
       SVN_ERR(unparse_dir_entry(&entry, out, subpool));
@@ -1791,7 +1806,7 @@ svn_error_t *
 svn_fs_x__add_change(svn_fs_t *fs,
                      svn_fs_x__txn_id_t txn_id,
                      const char *path,
-                     const svn_fs_id_t *id,
+                     const svn_fs_x__id_t *id,
                      svn_fs_path_change_kind_t change_kind,
                      svn_boolean_t text_mod,
                      svn_boolean_t prop_mod,
@@ -1799,41 +1814,45 @@ svn_fs_x__add_change(svn_fs_t *fs,
                      svn_node_kind_t node_kind,
                      svn_revnum_t copyfrom_rev,
                      const char *copyfrom_path,
-                     apr_pool_t *pool)
+                     apr_pool_t *scratch_pool)
 {
   apr_file_t *file;
-  svn_fs_path_change2_t *change;
-  apr_hash_t *changes = apr_hash_make(pool);
+  svn_fs_x__change_t change;
+  apr_hash_t *changes = apr_hash_make(scratch_pool);
 
   /* Not using APR_BUFFERED to append change in one atomic write operation. */
   SVN_ERR(svn_io_file_open(&file,
-                           svn_fs_x__path_txn_changes(fs, txn_id, pool),
+                           svn_fs_x__path_txn_changes(fs, txn_id,
+                                                      scratch_pool),
                            APR_APPEND | APR_WRITE | APR_CREATE,
-                           APR_OS_DEFAULT, pool));
+                           APR_OS_DEFAULT, scratch_pool));
 
-  change = svn_fs__path_change_create_internal(id, change_kind, pool);
-  change->text_mod = text_mod;
-  change->prop_mod = prop_mod;
-  change->mergeinfo_mod = mergeinfo_mod
-                        ? svn_tristate_true
-                        : svn_tristate_false;
-  change->node_kind = node_kind;
-  change->copyfrom_known = TRUE;
-  change->copyfrom_rev = copyfrom_rev;
+  change.path.data = path;
+  change.path.len = strlen(path);
+  change.noderev_id = *id;
+  change.change_kind = change_kind;
+  change.text_mod = text_mod;
+  change.prop_mod = prop_mod;
+  change.mergeinfo_mod = mergeinfo_mod ? svn_tristate_true
+                                       : svn_tristate_false;
+  change.node_kind = node_kind;
+  change.copyfrom_known = TRUE;
+  change.copyfrom_rev = copyfrom_rev;
   if (copyfrom_path)
-    change->copyfrom_path = apr_pstrdup(pool, copyfrom_path);
+    change.copyfrom_path = apr_pstrdup(scratch_pool, copyfrom_path);
 
-  svn_hash_sets(changes, path, change);
-  SVN_ERR(svn_fs_x__write_changes(svn_stream_from_aprfile2(file, TRUE, pool),
-                                  fs, changes, FALSE, pool));
+  svn_hash_sets(changes, path, &change);
+  SVN_ERR(svn_fs_x__write_changes(svn_stream_from_aprfile2(file, TRUE,
+                                                           scratch_pool),
+                                  fs, changes, FALSE, scratch_pool));
 
-  return svn_io_file_close(file, pool);
+  return svn_io_file_close(file, scratch_pool);
 }
 
 /* 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;
@@ -1855,7 +1874,7 @@ struct rep_write_baton
   svn_filesize_t rep_size;
 
   /* The node revision for which we're writing out info. */
-  node_revision_t *noderev;
+  svn_fs_x__noderev_t *noderev;
 
   /* Actual output file. */
   apr_file_t *file;
@@ -1869,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));
@@ -1894,29 +1914,31 @@ rep_write_contents(void *baton,
 }
 
 /* Set *SPANNED to the number of shards touched when walking WALK steps on
- * NODEREV's predecessor chain in FS.  Use POOL for temporary allocations.
+ * NODEREV's predecessor chain in FS.
+ * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
 shards_spanned(int *spanned,
                svn_fs_t *fs,
-               node_revision_t *noderev,
+               svn_fs_x__noderev_t *noderev,
                int walk,
-               apr_pool_t *pool)
+               apr_pool_t *scratch_pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
   int shard_size = ffd->max_files_per_dir;
   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);
+  iterpool = svn_pool_create(scratch_pool);
   while (walk-- && noderev->predecessor_count)
     {
+      svn_fs_x__id_t id = noderev->predecessor_id;
+
       svn_pool_clear(iterpool);
-      SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs,
-                                          noderev->predecessor_id, pool,
+      SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, &id, scratch_pool,
                                           iterpool));
-      shard = svn_fs_x__id_rev(noderev->id) / shard_size;
+      shard = svn_fs_x__get_revnum(id.change_set) / shard_size;
       if (shard != last_shard)
         {
           ++count;
@@ -1935,9 +1957,9 @@ shards_spanned(int *spanned,
    base representation will be returned.  Perform temporary allocations
    in *POOL. */
 static svn_error_t *
-choose_delta_base(representation_t **rep,
+choose_delta_base(svn_fs_x__representation_t **rep,
                   svn_fs_t *fs,
-                  node_revision_t *noderev,
+                  svn_fs_x__noderev_t *noderev,
                   svn_boolean_t props,
                   apr_pool_t *pool)
 {
@@ -1948,8 +1970,8 @@ choose_delta_base(representation_t **rep
    * skip-delta bits for the high-order bits and are linear in the low-order
    * bits.) */
   int walk;
-  node_revision_t *base;
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__noderev_t *base;
+  svn_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
@@ -2000,10 +2022,9 @@ choose_delta_base(representation_t **rep
   iterpool = svn_pool_create(pool);
   while ((count++) < noderev->predecessor_count)
     {
+      svn_fs_x__id_t id = noderev->predecessor_id;
       svn_pool_clear(iterpool);
-      SVN_ERR(svn_fs_x__get_node_revision(&base, fs,
-                                          base->predecessor_id, pool,
-                                          iterpool));
+      SVN_ERR(svn_fs_x__get_node_revision(&base, fs, &id, pool, iterpool));
     }
   svn_pool_destroy(iterpool);
 
@@ -2060,21 +2081,23 @@ 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
      file lock which will be removed no matter what since the pool is
      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->scratch_pool));
+                                 unlock_proto_rev(b->fs, txn_id,
+                                                  b->lockcookie,
+                                                  b->local_pool));
   if (err)
     {
       apr_status_t rc = err->apr_err;
@@ -2085,55 +2108,58 @@ 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,
-                    node_revision_t *noderev,
-                    apr_pool_t *pool)
+                    svn_fs_x__noderev_t *noderev,
+                    apr_pool_t *result_pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
-  struct rep_write_baton *b;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
+  rep_write_baton_t *b;
   apr_file_t *file;
-  representation_t *base_rep;
+  svn_fs_x__representation_t *base_rep;
   svn_stream_t *source;
   svn_txdelta_window_handler_t wh;
   void *whb;
   int diff_version = 1;
   svn_fs_x__rep_header_t header = { 0 };
+  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, svn_fs_x__id_txn_id(noderev->id),
-                                 b->scratch_pool));
+  SVN_ERR(get_writable_proto_rev(&file, &b->lockcookie, fs, txn_id,
+                                 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);
@@ -2179,20 +2205,20 @@ rep_write_get_baton(struct rep_write_bat
    if rep sharing has been disabled for FS, NULL will be returned.  Since
    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.
+   svn_fs_x__representation_t*), otherwise pass in NULL for REPS_HASH.
    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,
+get_shared_rep(svn_fs_x__representation_t **old_rep,
                svn_fs_t *fs,
-               representation_t *rep,
+               svn_fs_x__representation_t *rep,
                apr_hash_t *reps_hash,
                apr_pool_t *result_pool,
                apr_pool_t *scratch_pool)
 {
   svn_error_t *err;
-  fs_x_data_t *ffd = fs->fsap_data;
+  svn_fs_x__data_t *ffd = fs->fsap_data;
 
   /* Return NULL, if rep sharing has been disabled. */
   *old_rep = NULL;
@@ -2213,7 +2239,9 @@ 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, 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)
         {
@@ -2280,19 +2308,19 @@ get_shared_rep(representation_t **old_re
 }
 
 /* Copy the hash sum calculation results from MD5_CTX, SHA1_CTX into REP.
- * Use POOL for allocations.
+ * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-digests_final(representation_t *rep,
+digests_final(svn_fs_x__representation_t *rep,
               const svn_checksum_ctx_t *md5_ctx,
               const svn_checksum_ctx_t *sha1_ctx,
-              apr_pool_t *pool)
+              apr_pool_t *scratch_pool)
 {
   svn_checksum_t *checksum;
 
-  SVN_ERR(svn_checksum_final(&checksum, md5_ctx, pool));
+  SVN_ERR(svn_checksum_final(&checksum, md5_ctx, scratch_pool));
   memcpy(rep->md5_digest, checksum->digest, svn_checksum_size(checksum));
-  SVN_ERR(svn_checksum_final(&checksum, sha1_ctx, pool));
+  SVN_ERR(svn_checksum_final(&checksum, sha1_ctx, scratch_pool));
   rep->has_sha1 = checksum != NULL;
   if (rep->has_sha1)
     memcpy(rep->sha1_digest, checksum->digest, svn_checksum_size(checksum));
@@ -2301,14 +2329,14 @@ digests_final(representation_t *rep,
 }
 
 /* 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;
-  representation_t *rep;
-  representation_t *old_rep;
+  rep_write_baton_t *b = baton;
+  svn_fs_x__representation_t *rep;
+  svn_fs_x__representation_t *old_rep;
   apr_off_t offset;
   apr_int64_t txn_id;
 
@@ -2319,12 +2347,12 @@ 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. */
   rep->expanded_size = b->rep_size;
-  txn_id = svn_fs_x__id_txn_id(b->noderev->id);
+  txn_id = svn_fs_x__get_txn_id(b->noderev->noderev_id.change_set);
   rep->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
 
   /* Finalize the checksum. */
@@ -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,58 +2387,58 @@ 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->id, b->noderev,
-                                      FALSE, b->scratch_pool));
+  SVN_ERR(svn_fs_x__put_node_revision(b->fs, b->noderev, FALSE,
+                                      b->local_pool));
   if (!old_rep)
     {
       svn_fs_x__p2l_entry_t entry;
-      svn_fs_x__id_part_t noderev_id;
+      svn_fs_x__id_t noderev_id;
       noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
       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,
-                   node_revision_t *noderev,
-                   apr_pool_t *pool)
+                   svn_fs_x__noderev_t *noderev,
+                   apr_pool_t *result_pool)
 {
-  struct rep_write_baton *wb;
+  rep_write_baton_t *wb;
 
-  if (! svn_fs_x__id_is_txn(noderev->id))
+  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->id, pool)->data);
+                             svn_fs_x__id_unparse(&noderev->noderev_id,
+                                                  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);
 
@@ -2420,89 +2448,79 @@ set_representation(svn_stream_t **conten
 svn_error_t *
 svn_fs_x__set_contents(svn_stream_t **stream,
                        svn_fs_t *fs,
-                       node_revision_t *noderev,
-                       apr_pool_t *pool)
+                       svn_fs_x__noderev_t *noderev,
+                       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 *
-svn_fs_x__create_successor(const svn_fs_id_t **new_id_p,
-                           svn_fs_t *fs,
-                           const svn_fs_id_t *old_idp,
-                           node_revision_t *new_noderev,
-                           const svn_fs_x__id_part_t *copy_id,
+svn_fs_x__create_successor(svn_fs_t *fs,
+                           svn_fs_x__noderev_t *new_noderev,
+                           const svn_fs_x__id_t *copy_id,
                            svn_fs_x__txn_id_t txn_id,
-                           apr_pool_t *pool)
+                           apr_pool_t *scratch_pool)
 {
-  const svn_fs_id_t *id;
-  apr_uint64_t number;
-
-  if (! copy_id)
-    copy_id = svn_fs_x__id_copy_id(old_idp);
-
-  SVN_ERR(allocate_item_index(&number, fs, txn_id, pool));
-  id = svn_fs_x__id_txn_create(svn_fs_x__id_node_id(old_idp), copy_id,
-                               txn_id, number, pool);
-
-  new_noderev->id = id;
+  new_noderev->copy_id = *copy_id;
+  new_noderev->noderev_id.change_set = svn_fs_x__change_set_by_txn(txn_id);
+  SVN_ERR(allocate_item_index(&new_noderev->noderev_id.number, fs, txn_id,
+                              scratch_pool));
 
   if (! new_noderev->copyroot_path)
     {
-      new_noderev->copyroot_path = apr_pstrdup(pool,
-                                               new_noderev->created_path);
-      new_noderev->copyroot_rev = svn_fs_x__id_rev(new_noderev->id);
+      new_noderev->copyroot_path
+        = apr_pstrdup(scratch_pool, new_noderev->created_path);
+      new_noderev->copyroot_rev
+        = svn_fs_x__get_revnum(new_noderev->noderev_id.change_set);
     }
 
-  SVN_ERR(svn_fs_x__put_node_revision(fs, new_noderev->id, new_noderev, FALSE,
-                                      pool));
-
-  *new_id_p = id;
+  SVN_ERR(svn_fs_x__put_node_revision(fs, new_noderev, FALSE, scratch_pool));
 
   return SVN_NO_ERROR;
 }
 
 svn_error_t *
 svn_fs_x__set_proplist(svn_fs_t *fs,
-                       node_revision_t *noderev,
+                       svn_fs_x__noderev_t *noderev,
                        apr_hash_t *proplist,
-                       apr_pool_t *pool)
+                       apr_pool_t *scratch_pool)
 {
-  const char *filename
-    = svn_fs_x__path_txn_node_props(fs, noderev->id, 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,
+                                                       scratch_pool);
   apr_file_t *file;
   svn_stream_t *out;
 
   /* Dump the property list to the mutable property file. */
   SVN_ERR(svn_io_file_open(&file, filename,
                            APR_WRITE | APR_CREATE | APR_TRUNCATE
-                           | APR_BUFFERED, APR_OS_DEFAULT, pool));
-  out = svn_stream_from_aprfile2(file, TRUE, pool);
-  SVN_ERR(svn_hash_write2(proplist, out, SVN_HASH_TERMINATOR, pool));
-  SVN_ERR(svn_io_file_close(file, pool));
+                           | APR_BUFFERED, APR_OS_DEFAULT, scratch_pool));
+  out = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
+  SVN_ERR(svn_hash_write2(proplist, out, SVN_HASH_TERMINATOR, scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   /* Mark the node-rev's prop rep as mutable, if not already done. */
   if (!noderev->prop_rep
       || svn_fs_x__is_revision(noderev->prop_rep->id.change_set))
     {
-      noderev->prop_rep = apr_pcalloc(pool, sizeof(*noderev->prop_rep));
-      noderev->prop_rep->id.change_set
-        = svn_fs_x__id_noderev_id(noderev->id)->change_set;
+      svn_fs_x__txn_id_t txn_id
+        = svn_fs_x__get_txn_id(noderev->noderev_id.change_set);
+      noderev->prop_rep = apr_pcalloc(scratch_pool, sizeof(*noderev->prop_rep));
+      noderev->prop_rep->id.change_set = id->change_set;
       SVN_ERR(allocate_item_index(&noderev->prop_rep->id.number, fs,
-                                  svn_fs_x__id_txn_id(noderev->id), pool));
-      SVN_ERR(svn_fs_x__put_node_revision(fs, noderev->id, noderev, FALSE,
-                                          pool));
+                                  txn_id, scratch_pool));
+      SVN_ERR(svn_fs_x__put_node_revision(fs, noderev, FALSE, scratch_pool));
     }
 
   return SVN_NO_ERROR;
 }
 
 /* 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;
 
@@ -2510,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,

[... 1027 lines stripped ...]