/* transaction.c --- transaction-related functions of FSX
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include "transaction.h"

#include <assert.h>
#include <apr_sha1.h>

#include "svn_error_codes.h"
#include "svn_hash.h"
#include "svn_props.h"
#include "svn_sorts.h"
#include "svn_time.h"
#include "svn_dirent_uri.h"

#include "fs_x.h"
#include "tree.h"
#include "util.h"
#include "id.h"
#include "low_level.h"
#include "temp_serializer.h"
#include "cached_data.h"
#include "lock.h"
#include "rep-cache.h"
#include "index.h"
#include "batch_fsync.h"
#include "revprops.h"

#include "private/svn_fs_util.h"
#include "private/svn_fspath.h"
#include "private/svn_sorts_private.h"
#include "private/svn_string_private.h"
#include "private/svn_subr_private.h"
#include "private/svn_io_private.h"
#include "../libsvn_fs/fs-loader.h"

#include "svn_private_config.h"

/* The vtable associated with an open transaction object. */
static txn_vtable_t txn_vtable = {
  svn_fs_x__commit_txn,
  svn_fs_x__abort_txn,
  svn_fs_x__txn_prop,
  svn_fs_x__txn_proplist,
  svn_fs_x__change_txn_prop,
  svn_fs_x__txn_root,
  svn_fs_x__change_txn_props
};

/* FSX-specific data being attached to svn_fs_txn_t.
 */
typedef struct fs_txn_data_t
{
  /* Strongly typed representation of the TXN's ID member. */
  svn_fs_x__txn_id_t txn_id;
} fs_txn_data_t;

svn_fs_x__txn_id_t
svn_fs_x__txn_get_id(svn_fs_txn_t *txn)
{
  fs_txn_data_t *ftd = txn->fsap_data;
  return ftd->txn_id;
}

/* Functions for working with shared transaction data. */

/* Return the transaction object for transaction TXN_ID from the
   transaction list of filesystem FS (which must already be locked via the
   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 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)
{
  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)
      break;

  if (txn || !create_new)
    return txn;

  /* Use the transaction object from the (single-object) freelist,
     if one is available, or otherwise create a new object. */
  if (ffsd->free_txn)
    {
      txn = ffsd->free_txn;
      ffsd->free_txn = NULL;
    }
  else
    {
      apr_pool_t *subpool = svn_pool_create(ffsd->common_pool);
      txn = apr_palloc(subpool, sizeof(*txn));
      txn->pool = subpool;
    }

  txn->txn_id = txn_id;
  txn->being_written = FALSE;

  /* Link this transaction into the head of the list.  We will typically
     be dealing with only one active transaction at a time, so it makes
     sense for searches through the transaction list to look at the
     newest transactions first.  */
  txn->next = ffsd->txns;
  ffsd->txns = txn;

  return txn;
}

/* Free the transaction object for transaction TXN_ID, and remove it
   from the transaction list of filesystem FS (which must already be
   locked via the txn_list_lock mutex).  Do nothing if the transaction
   does not exist. */
static void
free_shared_txn(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id)
{
  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)
      break;

  if (!txn)
    return;

  if (prev)
    prev->next = txn->next;
  else
    ffsd->txns = txn->next;

  /* As we typically will be dealing with one transaction after another,
     we will maintain a single-object free list so that we can hopefully
     keep reusing the same transaction object. */
  if (!ffsd->free_txn)
    ffsd->free_txn = txn;
  else
    svn_pool_destroy(txn->pool);
}


/* Obtain a lock on the transaction list of filesystem FS, call BODY
   with FS, BATON, and POOL, and then unlock the transaction list.
   Return what BODY returned. */
static svn_error_t *
with_txnlist_lock(svn_fs_t *fs,
                  svn_error_t *(*body)(svn_fs_t *fs,
                                       const void *baton,
                                       apr_pool_t *pool),
                  const void *baton,
                  apr_pool_t *pool)
{
  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));

  return SVN_NO_ERROR;
}


/* 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 *result_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.
   When registered with the pool holding the lock on the lock file,
   this makes sure the flag gets reset just before we release the lock. */
static apr_status_t
reset_lock_flag(void *baton_void)
{
  svn_fs_x__data_t *ffd = baton_void;
  ffd->has_write_lock = FALSE;
  return APR_SUCCESS;
}

/* Structure defining a file system lock to be acquired and the function
   to be executed while the lock is held.

   Instances of this structure may be nested to allow for multiple locks to
   be taken out before executing the user-provided body.  In that case, BODY
   and BATON of the outer instances will be with_lock and a with_lock_baton_t
   instance (transparently, no special treatment is required.).  It is
   illegal to attempt to acquire the same lock twice within the same lock
   chain or via nesting calls using separate lock chains.

   All instances along the chain share the same LOCK_POOL such that only one
   pool needs to be created and cleared for all locks.  We also allocate as
   much data from that lock pool as possible to minimize memory usage in
   caller pools. */
typedef struct with_lock_baton_t
{
  /* The filesystem we operate on.  Same for all instances along the chain. */
  svn_fs_t *fs;

  /* Mutex to complement the lock file in an APR threaded process.
     No-op object for non-threaded processes but never NULL. */
  svn_mutex__t *mutex;

  /* Path to the file to lock. */
  const char *lock_path;

  /* If true, set FS->HAS_WRITE_LOCK after we acquired the lock. */
  svn_boolean_t is_global_lock;

  /* 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 *scratch_pool);

  /* Baton to pass to BODY; possibly NULL.
     This may be user-provided or a nested lock baton instance. */
  void *baton;

  /* Pool for all allocations along the lock chain and BODY.  Will hold the
     file locks and gets destroyed after the outermost BODY returned,
     releasing all file locks.
     Same for all instances along the chain. */
  apr_pool_t *lock_pool;

  /* TRUE, iff BODY is the user-provided body. */
  svn_boolean_t is_inner_most_lock;

  /* TRUE, iff this is not a nested lock.
     Then responsible for destroying LOCK_POOL. */
  svn_boolean_t is_outer_most_lock;
} with_lock_baton_t;

/* Obtain a write lock on the file BATON->LOCK_PATH and call BATON->BODY
   with BATON->BATON.  If this is the outermost lock call, release all file
   locks after the body returned.  If BATON->IS_GLOBAL_LOCK is set, set the
   HAS_WRITE_LOCK flag while we keep the write lock. */
static svn_error_t *
with_some_lock_file(with_lock_baton_t *baton)
{
  apr_pool_t *pool = baton->lock_pool;
  svn_error_t *err = get_lock_on_filesystem(baton->lock_path, pool);

  if (!err)
    {
      svn_fs_t *fs = baton->fs;
      svn_fs_x__data_t *ffd = fs->fsap_data;

      if (baton->is_global_lock)
        {
          /* set the "got the lock" flag and register reset function */
          apr_pool_cleanup_register(pool,
                                    ffd,
                                    reset_lock_flag,
                                    apr_pool_cleanup_null);
          ffd->has_write_lock = TRUE;
        }

      if (baton->is_inner_most_lock)
        {
          /* Use a separate sub-pool for the actual function body and a few
           * file accesses. So, the lock-pool only contains the file locks.
           */
          apr_pool_t *subpool = svn_pool_create(pool);

          /* nobody else will modify the repo state
             => read HEAD & pack info once */
          err = svn_fs_x__update_min_unpacked_rev(fs, subpool);
          if (!err)
            err = svn_fs_x__youngest_rev(&ffd->youngest_rev_cache, fs,
                                         subpool);

          /* We performed a few file operations. Clean the pool. */
          svn_pool_clear(subpool);

          if (!err)
            err = baton->body(baton->baton, subpool);

          svn_pool_destroy(subpool);
        }
      else
        {
          /* Nested lock level */
          err = baton->body(baton->baton, pool);
        }
    }

  if (baton->is_outer_most_lock)
    svn_pool_destroy(pool);

  return svn_error_trace(err);
}

/* Wraps with_some_lock_file, protecting it with BATON->MUTEX.

   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 *scratch_pool)
{
  with_lock_baton_t *lock_baton = baton;
  SVN_MUTEX__WITH_LOCK(lock_baton->mutex, with_some_lock_file(lock_baton));

  return SVN_NO_ERROR;
}

/* Enum identifying a filesystem lock. */
typedef enum lock_id_t
{
  txn_lock,
  write_lock,
  pack_lock
} lock_id_t;

/* Initialize BATON->MUTEX, BATON->LOCK_PATH and BATON->IS_GLOBAL_LOCK
   according to the LOCK_ID.  All other members of BATON must already be
   valid. */
static void
init_lock_baton(with_lock_baton_t *baton,
                lock_id_t lock_id)
{
  svn_fs_x__data_t *ffd = baton->fs->fsap_data;
  svn_fs_x__shared_data_t *ffsd = ffd->shared;

  switch (lock_id)
    {
    case txn_lock:
      baton->mutex = ffsd->txn_current_lock;
      baton->lock_path = svn_fs_x__path_txn_current_lock(baton->fs,
                                                         baton->lock_pool);
      baton->is_global_lock = FALSE;
      break;

    case write_lock:
      baton->mutex = ffsd->fs_write_lock;
      baton->lock_path = svn_fs_x__path_lock(baton->fs, baton->lock_pool);
      baton->is_global_lock = TRUE;
      break;

    case pack_lock:
      baton->mutex = ffsd->fs_pack_lock;
      baton->lock_path = svn_fs_x__path_pack_lock(baton->fs,
                                                  baton->lock_pool);
      baton->is_global_lock = FALSE;
      break;
    }
}

/* 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
   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 *scratch_pool),
                  void *baton,
                  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(result_pool);
  with_lock_baton_t *result = apr_pcalloc(lock_pool, sizeof(*result));

  /* Store parameters. */
  result->fs = fs;
  result->body = body;
  result->baton = baton;

  /* File locks etc. will use this pool as well for easy cleanup. */
  result->lock_pool = lock_pool;

  /* Right now, we are the first, (only, ) and last struct in the chain. */
  result->is_inner_most_lock = TRUE;
  result->is_outer_most_lock = TRUE;

  /* Select mutex and lock file path depending on LOCK_ID.
     Also, initialize dependent members (IS_GLOBAL_LOCK only, ATM). */
  init_lock_baton(result, lock_id);

  return result;
}

/* Return a baton that wraps NESTED and requests LOCK_ID as additional lock.
 *
 * That means, when you create a lock chain, start with the last / innermost
 * lock to take out and add the first / outermost lock last.
 */
static with_lock_baton_t *
chain_lock_baton(lock_id_t lock_id,
                 with_lock_baton_t *nested)
{
  /* Use the same pool for batons along the lock chain. */
  apr_pool_t *lock_pool = nested->lock_pool;
  with_lock_baton_t *result = apr_pcalloc(lock_pool, sizeof(*result));

  /* All locks along the chain operate on the same FS. */
  result->fs = nested->fs;

  /* Execution of this baton means acquiring the nested lock and its
     execution. */
  result->body = with_lock;
  result->baton = nested;

  /* Shared among all locks along the chain. */
  result->lock_pool = lock_pool;

  /* We are the new outermost lock but surely not the innermost lock. */
  result->is_inner_most_lock = FALSE;
  result->is_outer_most_lock = TRUE;
  nested->is_outer_most_lock = FALSE;

  /* Select mutex and lock file path depending on LOCK_ID.
     Also, initialize dependent members (IS_GLOBAL_LOCK only, ATM). */
  init_lock_baton(result, lock_id);

  return result;
}

svn_error_t *
svn_fs_x__with_write_lock(svn_fs_t *fs,
                          svn_error_t *(*body)(void *baton,
                                               apr_pool_t *scratch_pool),
                          void *baton,
                          apr_pool_t *scratch_pool)
{
  return svn_error_trace(
           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 *scratch_pool),
                         void *baton,
                         apr_pool_t *scratch_pool)
{
  return svn_error_trace(
           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 *scratch_pool),
                                void *baton,
                                apr_pool_t *scratch_pool)
{
  return svn_error_trace(
           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 *scratch_pool),
                         void *baton,
                         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, txn_lock, body, baton, scratch_pool);

  lock_baton = chain_lock_baton(write_lock, lock_baton);
  lock_baton = chain_lock_baton(pack_lock, lock_baton);

  return svn_error_trace(with_lock(lock_baton, scratch_pool));
}


/* A structure used by unlock_proto_rev() and unlock_proto_rev_body(),
   which see. */
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 *scratch_pool)
{
  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;

  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, 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, 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, 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, scratch_pool));

  txn->being_written = FALSE;

  return SVN_NO_ERROR;
}

/* Unlock the prototype revision file for transaction TXN_ID in filesystem
   FS using cookie LOCKCOOKIE.  The original prototype revision file must
   have been closed _before_ calling this function.

   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 *scratch_pool)
{
  unlock_proto_rev_baton_t b;

  b.txn_id = txn_id;
  b.lockcookie = lockcookie;
  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. */
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 *scratch_pool)
{
  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);

  /* First, ensure that no thread in this process (including this one)
     is currently writing to this transaction's proto-rev file. */
  if (txn->being_written)
    return svn_error_createf(SVN_ERR_FS_REP_BEING_WRITTEN, NULL,
                             _("Cannot write to the prototype revision file "
                               "of transaction '%s' because a previous "
                               "representation is currently being written by "
                               "this process"),
                             svn_fs_x__txn_name(b->txn_id, scratch_pool));


  /* We know that no thread in this process is writing to the proto-rev
     file, and by extension, that no thread in this process is holding a
     lock on the prototype revision lock file.  It is therefore safe
     for us to attempt to lock this file, to see if any other process
     is holding a lock. */

  {
    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, 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
       introduced.

       ### We'd also like to use something like svn_io_file_lock2(), but
           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,
                             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, scratch_pool));

        if (APR_STATUS_IS_EAGAIN(apr_err))
          return svn_error_createf(SVN_ERR_FS_REP_BEING_WRITTEN, NULL,
                                   _("Cannot write to the prototype revision "
                                     "file of transaction '%s' because a "
                                     "previous representation is currently "
                                     "being written by another process"),
                                   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,
                                                         scratch_pool));
      }

    *lockcookie = lockfile;
  }

  /* We've successfully locked the transaction; mark it as such. */
  txn->being_written = TRUE;

  return SVN_NO_ERROR;
}

/* Make sure the length ACTUAL_LENGTH of the proto-revision file PROTO_REV
   of transaction TXN_ID in filesystem FS matches the proto-index file.
   Trim any crash / failure related extra data from the proto-rev file.

   If the prototype revision file is too short, we can't do much but bail out.

   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 *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, scratch_pool);
  apr_file_t *file;
  apr_off_t indexed_length;

  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,
                                                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, 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(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;
}

/* Get a handle to the prototype revision file for transaction TXN_ID in
   filesystem FS, and lock it for writing.  Return FILE, a file handle
   positioned at the end of the file, and LOCKCOOKIE, a cookie that
   should be passed to unlock_proto_rev() to unlock the file once FILE
   has been closed.

   If the prototype revision file is already locked, return error
   SVN_ERR_FS_REP_BEING_WRITTEN.

   Perform all allocations in POOL. */
static svn_error_t *
get_writable_proto_rev(apr_file_t **file,
                       void **lockcookie,
                       svn_fs_t *fs,
                       svn_fs_x__txn_id_t txn_id,
                       apr_pool_t *pool)
{
  get_writable_proto_rev_baton_t b;
  svn_error_t *err;
  apr_off_t end_offset = 0;

  b.lockcookie = lockcookie;
  b.txn_id = txn_id;

  SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &b, pool));

  /* Now open the prototype revision file and seek to the end. */
  err = svn_io_file_open(file,
                         svn_fs_x__path_txn_proto_rev(fs, txn_id, pool),
                         APR_WRITE | APR_BUFFERED, APR_OS_DEFAULT, pool);

  /* You might expect that we could dispense with the following seek
     and achieve the same thing by opening the file using APR_APPEND.
     Unfortunately, APR's buffered file implementation unconditionally
     places its initial file pointer at the start of the file (even for
     files opened with APR_APPEND), so we need this seek to reconcile
     the APR file pointer to the OS file pointer (since we need to be
     able to read the current file position later). */
  if (!err)
    err = svn_io_file_seek(*file, APR_END, &end_offset, pool);

  /* We don't want unused sections (such as leftovers from failed delta
     stream) in our file.  If we use log addressing, we would need an
     index entry for the unused section and that section would need to
     be all NUL by convention.  So, detect and fix those cases by truncating
     the protorev file. */
  if (!err)
    err = auto_truncate_proto_rev(fs, *file, end_offset, txn_id, pool);

  if (err)
    {
      err = svn_error_compose_create(
              err,
              unlock_proto_rev(fs, txn_id, *lockcookie, pool));

      *lockcookie = NULL;
    }

  return svn_error_trace(err);
}

/* 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 *scratch_pool)
{
  svn_fs_x__txn_id_t txn_id = *(const svn_fs_x__txn_id_t *)baton;

  free_shared_txn(fs, txn_id);

  return SVN_NO_ERROR;
}

/* Purge the shared data for transaction TXN_ID in filesystem FS.
   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 *scratch_pool)
{
  return with_txnlist_lock(fs, purge_shared_txn_body, &txn_id, scratch_pool);
}


svn_boolean_t
svn_fs_x__is_fresh_txn_root(svn_fs_x__noderev_t *noderev)
{
  /* Is it a root node? */
  if (noderev->noderev_id.number != SVN_FS_X__ITEM_INDEX_ROOT_NODE)
    return FALSE;

  /* ... in a transaction? */
  if (!svn_fs_x__is_txn(noderev->noderev_id.change_set))
    return FALSE;

  /* ... with no prop change in that txn?
     (Once we set a property, the prop rep will never become NULL again.) */
  if (noderev->prop_rep && svn_fs_x__is_txn(noderev->prop_rep->id.change_set))
    return FALSE;

  /* ... and no sub-tree change?
     (Once we set a text, the data rep will never become NULL again.) */
  if (noderev->data_rep && svn_fs_x__is_txn(noderev->data_rep->id.change_set))
    return FALSE;

  /* Root node of a txn with no changes. */
  return TRUE;
}

svn_error_t *
svn_fs_x__put_node_revision(svn_fs_t *fs,
                            svn_fs_x__noderev_t *noderev,
                            apr_pool_t *scratch_pool)
{
  apr_file_t *noderev_file;
  const svn_fs_x__id_t *id = &noderev->noderev_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, scratch_pool)->data);

  SVN_ERR(svn_io_file_open(&noderev_file,
                           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));

  SVN_ERR(svn_fs_x__write_noderev(svn_stream_from_aprfile2(noderev_file, TRUE,
                                                           scratch_pool),
                                  noderev, scratch_pool));

  SVN_ERR(svn_io_file_close(noderev_file, scratch_pool));

  return SVN_NO_ERROR;
}

/* For the in-transaction NODEREV within FS, write the sha1->rep mapping
 * file in the respective transaction, if rep sharing has been enabled etc.
 * Use SCATCH_POOL for temporary allocations.
 */
static svn_error_t *
store_sha1_rep_mapping(svn_fs_t *fs,
                       svn_fs_x__noderev_t *noderev,
                       apr_pool_t *scratch_pool)
{
  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. */
  if (   ffd->rep_sharing_allowed
      && noderev->data_rep
      && noderev->data_rep->has_sha1)
    {
      apr_file_t *rep_file;
      apr_int64_t txn_id
        = svn_fs_x__get_txn_id(noderev->data_rep->id.change_set);
      const char *file_name
        = svn_fs_x__path_txn_sha1(fs, txn_id,
                                  noderev->data_rep->sha1_digest,
                                  scratch_pool);
      svn_stringbuf_t *rep_string
        = svn_fs_x__unparse_representation(noderev->data_rep,
                                           (noderev->kind == svn_node_dir),
                                           scratch_pool, scratch_pool);

      SVN_ERR(svn_io_file_open(&rep_file, file_name,
                               APR_WRITE | APR_CREATE | APR_TRUNCATE
                               | APR_BUFFERED, APR_OS_DEFAULT, scratch_pool));

      SVN_ERR(svn_io_file_write_full(rep_file, rep_string->data,
                                     rep_string->len, NULL, scratch_pool));

      SVN_ERR(svn_io_file_close(rep_file, scratch_pool));
    }

  return SVN_NO_ERROR;
}

static svn_error_t *
unparse_dir_entry(svn_fs_x__dirent_t *dirent,
                  svn_stream_t *stream,
                  apr_pool_t *scratch_pool)
{
  apr_size_t to_write;
  apr_size_t name_len = strlen(dirent->name);

  /* A buffer with sufficient space for 
   * - entry name + 1 terminating NUL
   * - 1 byte for the node kind
   * - 2 numbers in 7b/8b encoding for the noderev-id
   */
  apr_byte_t *buffer = apr_palloc(scratch_pool,
                                  name_len + 2 + 2 * SVN__MAX_ENCODED_UINT_LEN);

  /* Now construct the value. */
  apr_byte_t *p = buffer;

  /* The entry name, terminated by NUL. */
  memcpy(p, dirent->name, name_len + 1);
  p += name_len + 1;

  /* The entry type. */
  p = svn__encode_uint(p, dirent->kind);

  /* The ID. */
  p = svn__encode_int(p, dirent->id.change_set);
  p = svn__encode_uint(p, dirent->id.number);

  /* Add the entry to the output stream. */
  to_write = p - buffer;
  SVN_ERR(svn_stream_write(stream, (const char *)buffer, &to_write));

  return SVN_NO_ERROR;
}

/* Write the directory given as array of dirent structs in ENTRIES to STREAM.
   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 *scratch_pool)
{
  apr_byte_t buffer[SVN__MAX_ENCODED_UINT_LEN];
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  int i;

  /* Write the number of entries. */
  apr_size_t to_write = svn__encode_uint(buffer, entries->nelts) - buffer;
  SVN_ERR(svn_stream_write(stream, (const char *)buffer, &to_write));

  /* Write all entries */
  for (i = 0; i < entries->nelts; ++i)
    {
      svn_fs_x__dirent_t *dirent;

      svn_pool_clear(iterpool);
      dirent = APR_ARRAY_IDX(entries, i, svn_fs_x__dirent_t *);
      SVN_ERR(unparse_dir_entry(dirent, stream, iterpool));
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Return a deep copy of SOURCE and allocate it in RESULT_POOL.
 */
static svn_fs_x__change_t *
path_change_dup(const svn_fs_x__change_t *source,
                apr_pool_t *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);

  return result;
}

/* Merge the internal-use-only CHANGE into a hash of public-FS
   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_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 svn_fs_x__change_t *change)
{
  apr_pool_t *pool = apr_hash_pool_get(changed_paths);
  svn_fs_x__change_t *old_change, *new_change;
  const svn_string_t *path = &change->path;

  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: an add, replacement, or reset must be the first
         thing to follow a deletion. */
      if ((old_change->change_kind == svn_fs_path_change_delete)
          && (! ((change->change_kind == svn_fs_path_change_replace)
                 || (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 ((change->change_kind == svn_fs_path_change_add)
          && (old_change->change_kind != svn_fs_path_change_delete))
        return svn_error_create
          (SVN_ERR_FS_CORRUPT, NULL,
           _("Invalid change ordering: add change on preexisting path"));

      /* Now, merge that change in. */
      switch (change->change_kind)
        {
        case svn_fs_path_change_delete:
          if (old_change->change_kind == svn_fs_path_change_add)
            {
              /* If the path was introduced in this transaction via an
                 add, and we are deleting it, just remove the path
                 altogether.  (The caller will delete any child paths.) */
              apr_hash_set(changed_paths, path->data, path->len, NULL);
            }
          else if (old_change->change_kind == svn_fs_path_change_replace)
            {
              /* A deleting a 'replace' restore the original deletion. */
              new_change = apr_hash_get(deletions, path->data, path->len);
              SVN_ERR_ASSERT(new_change);
              apr_hash_set(changed_paths, path->data, path->len, new_change);
            }
          else
            {
              /* A deletion overrules a previous change (modify). */
              new_change = path_change_dup(change, pool);
              apr_hash_set(changed_paths, path->data, path->len, new_change);
            }
          break;

        case svn_fs_path_change_add:
        case svn_fs_path_change_replace:
          /* An add at this point must be following a previous delete,
             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(change, pool);
          new_change->change_kind = svn_fs_path_change_replace;

          apr_hash_set(changed_paths, path->data, path->len, new_change);

          /* Remember the original change.
           * Make sure to allocate the hash key in a durable pool. */
          apr_hash_set(deletions,
                       apr_pstrmemdup(apr_hash_pool_get(deletions),
                                      path->data, path->len),
                       path->len, old_change);
          break;

        case svn_fs_path_change_modify:
        default:
          /* 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 (change->text_mod)
            old_change->text_mod = TRUE;
          if (change->prop_mod)
            old_change->prop_mod = TRUE;
          if (change->mergeinfo_mod == svn_tristate_true)
            old_change->mergeinfo_mod = svn_tristate_true;
          break;
        }
    }
  else
    {
      /* 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.  */
      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;
}

/* Baton type to be used with process_changes(). */
typedef struct process_changes_baton_t
{
  /* Folded list of path changes. */
  apr_hash_t *changed_paths;

  /* Path changes that are deletions and have been turned into
     replacements.  If those replacements get deleted again, this
     container contains the record that we have to revert to. */
  apr_hash_t *deletions;
} process_changes_baton_t;

/* An implementation of svn_fs_x__change_receiver_t.
   Examine all the changed path entries in CHANGES and store them in
   *CHANGED_PATHS.  Folding is done to remove redundant or unnecessary
   data. Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
process_changes(void *baton_p,
                svn_fs_x__change_t *change,
                apr_pool_t *scratch_pool)
{
  process_changes_baton_t *baton = baton_p;

  SVN_ERR(fold_change(baton->changed_paths, baton->deletions, change));

  /* Now, if our change was a deletion or replacement, we have to
     blow away any changes thus far on paths that are (or, were)
     children of this path.
     ### i won't bother with another iteration pool here -- at
     most we talking about a few extra dups of paths into what
     is already a temporary subpool.
  */

  if ((change->change_kind == svn_fs_path_change_delete)
       || (change->change_kind == svn_fs_path_change_replace))
    {
      apr_hash_index_t *hi;

      /* a potential child path must contain at least 2 more chars
         (the path separator plus at least one char for the name).
         Also, we should not assume that all paths have been normalized
         i.e. some might have trailing path separators.
      */
      apr_ssize_t path_len = change->path.len;
      apr_ssize_t min_child_len = path_len == 0
                                ? 1
                                : change->path.data[path_len-1] == '/'
                                    ? path_len + 1
                                    : path_len + 2;

      /* CAUTION: This is the inner loop of an O(n^2) algorithm.
         The number of changes to process may be >> 1000.
         Therefore, keep the inner loop as tight as possible.
      */
      for (hi = apr_hash_first(scratch_pool, baton->changed_paths);
           hi;
           hi = apr_hash_next(hi))
        {
          /* KEY is the path. */
          const void *path;
          apr_ssize_t klen;
          apr_hash_this(hi, &path, &klen, NULL);

          /* If we come across a child of our path, remove it.
             Call svn_fspath__skip_ancestor only if there is a chance that
             this is actually a sub-path.
           */
          if (klen >= min_child_len)
            {
              const char *child;

              child = svn_fspath__skip_ancestor(change->path.data, path);
              if (child && child[0] != '\0')
                apr_hash_set(baton->changed_paths, path, klen, NULL);
            }
        }
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__txn_changes_fetch(apr_hash_t **changed_paths_p,
                            svn_fs_t *fs,
                            svn_fs_x__txn_id_t txn_id,
                            apr_pool_t *pool)
{
  apr_file_t *file;
  apr_hash_t *changed_paths = apr_hash_make(pool);
  apr_pool_t *scratch_pool = svn_pool_create(pool);
  process_changes_baton_t baton;

  baton.changed_paths = changed_paths;
  baton.deletions = apr_hash_make(scratch_pool);

  SVN_ERR(svn_io_file_open(&file,
                           svn_fs_x__path_txn_changes(fs, txn_id, scratch_pool),
                           APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
                           scratch_pool));

  SVN_ERR(svn_fs_x__read_changes_incrementally(
                                  svn_stream_from_aprfile2(file, TRUE,
                                                           scratch_pool),
                                  process_changes, &baton,
                                  scratch_pool));
  svn_pool_destroy(scratch_pool);

  *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.
   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_x__id_t *src,
                                apr_pool_t *scratch_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(   noderev->node_id.number == 0
                 && noderev->copy_id.number == 0);

  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->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);

  return svn_fs_x__put_node_revision(fs, noderev, scratch_pool);
}

/* A structure used by get_and_increment_txn_key_body(). */
typedef struct get_and_increment_txn_key_baton_t
{
  svn_fs_t *fs;
  apr_uint64_t txn_number;
} 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 *scratch_pool)
{
  get_and_increment_txn_key_baton_t *cb = baton;
  svn_fs_t *fs = cb->fs;
  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
  const char *txn_current_path = svn_fs_x__path_txn_current(fs, scratch_pool);
  char new_id_str[SVN_INT64_BUFFER_SIZE];

  svn_stringbuf_t *buf;
  SVN_ERR(svn_fs_x__read_content(&buf, txn_current_path, scratch_pool));

  /* Parse the txn number, stopping at the next non-digit.
   *
   * Note that an empty string is being interpreted as "0".
   * This gives us implicit recovery if the file contents should be lost
   * due to e.g. power failure.
   */
  cb->txn_number = svn__base36toui64(NULL, buf->data);
  if (cb->txn_number == 0)
    ++cb->txn_number;

  /* Check for conflicts.  Those might happen if the server crashed and we
   * had 'svnadmin recover' reset the txn counter.
   *
   * Once we found an unused txn id, claim it by creating the respective
   * txn directory.
   *
   * Note that this is not racy because we hold the txn-current-lock.
   */
  while (TRUE)
    {
      const char *txn_dir;
      svn_node_kind_t kind;
      svn_pool_clear(iterpool);

      txn_dir = svn_fs_x__path_txn_dir(fs, cb->txn_number, iterpool);
      SVN_ERR(svn_io_check_path(txn_dir, &kind, iterpool));
      if (kind == svn_node_none)
        {
          svn_io_dir_make(txn_dir, APR_OS_DEFAULT, iterpool);
          break;
        }

      ++cb->txn_number;
    }

  /* 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_atomic2(txn_current_path, new_id_str,
                               svn__ui64tobase36(new_id_str,
                                                 cb->txn_number + 1),
                               txn_current_path, FALSE, scratch_pool));

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Create a unique directory for a transaction in FS based on revision REV.
   Return the ID for this transaction in *ID_P, allocated from RESULT_POOL
   and *TXN_ID.  Use a sequence value in the transaction ID to prevent reuse
   of transaction IDs.  Allocate temporaries from SCRATCH_POOL. */
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 *result_pool,
               apr_pool_t *scratch_pool)
{
  get_and_increment_txn_key_baton_t cb;

  /* 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.fs = fs;
  SVN_ERR(svn_fs_x__with_txn_current_lock(fs,
                                          get_and_increment_txn_key_body,
                                          &cb,
                                          scratch_pool));
  *txn_id = cb.txn_number;
  *id_p = svn_fs_x__txn_name(*txn_id, result_pool);

  return SVN_NO_ERROR;
}

/* 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(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, result_pool,
                         scratch_pool));

  txn->fs = fs;
  txn->base_rev = rev;

  txn->vtable = &txn_vtable;
  txn->fsap_data = ftd;
  *txn_p = txn;

  /* Create a new root node for this transaction. */
  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, 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, 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, scratch_pool),
              scratch_pool));

  /* Create the next-ids file. */
  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, allocated
   from RESULT_POOL. Perform temporary allocations in SCRATCH_POOL. */
static svn_error_t *
get_txn_proplist(apr_hash_t **proplist,
                 svn_fs_t *fs,
                 svn_fs_x__txn_id_t txn_id,
                 apr_pool_t *result_pool,
                 apr_pool_t *scratch_pool)
{
  svn_stringbuf_t *content;

  /* Check for issue #3696. (When we find and fix the cause, we can change
   * this to an assertion.) */
  if (txn_id == SVN_FS_X__INVALID_TXN_ID)
    return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                            _("Internal error: a null transaction id was "
                              "passed to get_txn_proplist()"));

  /* Open the transaction properties file. */
  SVN_ERR(svn_stringbuf_from_file2(&content,
                                   svn_fs_x__path_txn_props(fs, txn_id,
                                                            scratch_pool),
                                   result_pool));

  /* Read in the property list. */
  SVN_ERR_W(svn_fs_x__parse_properties(proplist,
                                   svn_stringbuf__morph_into_string(content),
                                   result_pool),
            apr_psprintf(scratch_pool,
                         _("malformed property list in transaction '%s'"),
                         svn_fs_x__path_txn_props(fs, txn_id, scratch_pool)));

  return SVN_NO_ERROR;
}

/* Save the property list PROPS as the revprops for transaction TXN_ID
   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,
                 apr_pool_t *scratch_pool)
{
  svn_stream_t *stream;
  const char *temp_path;

  /* Write the new contents into a temporary file. */
  SVN_ERR(svn_stream_open_unique(&stream, &temp_path,
                                 svn_fs_x__path_txn_dir(fs, txn_id,
                                                        scratch_pool),
                                 svn_io_file_del_none,
                                 scratch_pool, scratch_pool));
  SVN_ERR(svn_fs_x__write_properties(stream, props, scratch_pool));
  SVN_ERR(svn_stream_close(stream));

  /* Replace the old file with the new one. */
  SVN_ERR(svn_io_file_rename2(temp_path,
                              svn_fs_x__path_txn_props(fs, txn_id,
                                                       scratch_pool),
                              FALSE,
                              scratch_pool));

  return SVN_NO_ERROR;
}


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 *scratch_pool)
{
  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, 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 *scratch_pool)
{
  fs_txn_data_t *ftd = txn->fsap_data;
  apr_pool_t *subpool = svn_pool_create(scratch_pool);
  apr_hash_t *txn_prop;
  int i;
  svn_error_t *err;

  err = get_txn_proplist(&txn_prop, txn->fs, ftd->txn_id, subpool, subpool);
  /* 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
     initial transaction properties as the transaction is being created. */
  if (err && (APR_STATUS_IS_ENOENT(err->apr_err)))
    svn_error_clear(err);
  else if (err)
    return svn_error_trace(err);

  for (i = 0; i < props->nelts; i++)
    {
      svn_prop_t *prop = &APR_ARRAY_IDX(props, i, svn_prop_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", subpool));

      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, subpool));

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}

svn_error_t *
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)
{
  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));
  svn_fs_x__init_txn_root(&root_id, txn_id);

  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, &root_id, pool, pool));

  txn->base_rev = svn_fs_x__get_revnum(noderev->predecessor_id.change_set);
  txn->copies = NULL;

  *txn_p = txn;

  return SVN_NO_ERROR;
}

/* Store the (ITEM_INDEX, OFFSET) pair in the log-to-phys proto index file
 * of transaction TXN_ID in filesystem FS.
 * 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 *scratch_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, scratch_pool));
  SVN_ERR(svn_fs_x__l2p_proto_index_add_entry(file, offset, 0,
                                              item_index, scratch_pool));
  SVN_ERR(svn_io_file_close(file, scratch_pool));

  return SVN_NO_ERROR;
}

/* Store ENTRY in the phys-to-log proto index file of transaction TXN_ID
 * in filesystem FS.  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 *scratch_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, 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 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 *scratch_pool)
{
  apr_file_t *file;
  char buffer[SVN_INT64_BUFFER_SIZE] = { 0 };
  svn_boolean_t eof = FALSE;
  apr_size_t to_write;
  apr_size_t bytes_read;
  apr_off_t offset = 0;

  /* read number */
  SVN_ERR(svn_io_file_open(&file,
                            svn_fs_x__path_txn_item_index(fs, txn_id,
                                                          scratch_pool),
                            APR_READ | APR_WRITE | APR_CREATE,
                            APR_OS_DEFAULT, scratch_pool));
  SVN_ERR(svn_io_file_read_full2(file, buffer, sizeof(buffer)-1,
                                  &bytes_read, &eof, scratch_pool));

  /* Item index file should be shorter than SVN_INT64_BUFFER_SIZE,
     otherwise we truncate data. */
  if (!eof)
    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                            _("Unexpected itemidx file length"));
  else if (bytes_read)
    SVN_ERR(svn_cstring_atoui64(item_index, buffer));
  else
    *item_index = SVN_FS_X__ITEM_INDEX_FIRST_USER;

  /* increment it */
  to_write = svn__ui64toa(buffer, *item_index + 1);

  /* write it back to disk */
  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;
}

/* Write out the currently available next node_id NODE_ID and copy_id
   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
   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 *scratch_pool)
{
  apr_file_t *file;
  char buffer[2 * SVN_INT64_BUFFER_SIZE + 2];
  char *p = buffer;

  p += svn__ui64tobase36(p, node_id);
  *(p++) = ' ';
  p += svn__ui64tobase36(p, copy_id);
  *(p++) = '\n';
  *(p++) = '\0';

  SVN_ERR(svn_io_file_open(&file,
                           svn_fs_x__path_txn_next_ids(fs, txn_id,
                                                       scratch_pool),
                           APR_WRITE | APR_TRUNCATE,
                           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 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 *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,
                                                             scratch_pool),
                                 scratch_pool));

  /* Parse this into two separate strings. */

  str = buf->data;
  *node_id = svn__base36toui64(&str, str);
  if (*str != ' ')
    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                            _("next-id file corrupt"));

  ++str;
  *copy_id = svn__base36toui64(&str, str);
  if (*str != '\n')
    return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
                            _("next-id file corrupt"));

  return SVN_NO_ERROR;
}

/* 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 temporary allocations in SCRATCH_POOL. */
static svn_error_t *
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 *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, 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, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
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 *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, 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, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
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 *scratch_pool)
{
  /* Get a new node-id for this node. */
  SVN_ERR(get_new_txn_node_id(&noderev->node_id, fs, txn_id, scratch_pool));

  /* Assign copy-id. */
  noderev->copy_id = *copy_id;

  /* 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));

  SVN_ERR(svn_fs_x__put_node_revision(fs, noderev, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__purge_txn(svn_fs_t *fs,
                    const char *txn_id_str,
                    apr_pool_t *scratch_pool)
{
  svn_fs_x__txn_id_t txn_id;

  /* The functions we are calling open files and operate on the OS FS.
     Since these may allocate a non-trivial amount of memory, do that
     in a SUBPOOL and clear that one up before returning. */
  apr_pool_t *subpool = svn_pool_create(scratch_pool);
  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, subpool));
  /* Remove the directory associated with this transaction. */
  SVN_ERR(svn_io_remove_dir2(svn_fs_x__path_txn_dir(fs, txn_id, subpool),
                             FALSE, NULL, NULL, subpool));

  /* 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, subpool),
                TRUE, subpool));
  SVN_ERR(svn_io_remove_file2(
                svn_fs_x__path_txn_proto_rev_lock(fs, txn_id, subpool),
                TRUE, subpool));

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_x__abort_txn(svn_fs_txn_t *txn,
                    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, scratch_pool),
            apr_psprintf(scratch_pool, _("Transaction '%s' cleanup failed"),
                         txn->id));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__set_entry(svn_fs_t *fs,
                    svn_fs_x__txn_id_t txn_id,
                    svn_fs_x__noderev_t *parent_noderev,
                    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);
  apr_file_t *file;
  svn_stream_t *out;
  svn_filesize_t filesize;
  svn_fs_x__data_t *ffd = fs->fsap_data;
  apr_pool_t *subpool = svn_pool_create(scratch_pool);
  const svn_fs_x__id_t *key = &(parent_noderev->noderev_id);
  svn_fs_x__dirent_t entry;

  if (!rep || !svn_fs_x__is_txn(rep->id.change_set))
    {
      apr_array_header_t *entries;
      svn_fs_x__dir_data_t dir_data;

      /* Before we can modify the directory, we need to dump its old
         contents into a mutable representation file. */
      SVN_ERR(svn_fs_x__rep_contents_dir(&entries, fs, parent_noderev,
                                         subpool, subpool));
      SVN_ERR(svn_io_file_open(&file, filename,
                               APR_WRITE | APR_CREATE | APR_BUFFERED,
                               APR_OS_DEFAULT, scratch_pool));
      out = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
      SVN_ERR(unparse_dir_entries(entries, out, 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->id.change_set = svn_fs_x__change_set_by_txn(txn_id);
      rep->id.number = SVN_FS_X__ITEM_INDEX_UNUSED;

      /* Save noderev to disk. */
      SVN_ERR(svn_fs_x__put_node_revision(fs, parent_noderev, subpool));

      /* Immediately populate the txn dir cache to avoid re-reading
       * the file we just wrote. */

      /* Flush APR buffers. */
      SVN_ERR(svn_io_file_flush(file, subpool));

      /* Obtain final file size to update txn_dir_cache. */
      SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));

      /* Store in the cache. */
      dir_data.entries = entries;
      dir_data.txn_filesize = filesize;
      SVN_ERR(svn_cache__set(ffd->dir_cache, key, &dir_data, subpool));

      svn_pool_clear(subpool);
    }
  else
    {
      svn_boolean_t found;
      svn_filesize_t cached_filesize;

      /* 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, subpool));
      out = svn_stream_from_aprfile2(file, TRUE, subpool);

      /* If the cache contents is stale, drop it.
       *
       * Note that the directory file is append-only, i.e. if the size
       * did not change, the contents didn't either. */

      /* Get the file size that corresponds to the cached contents
       * (if any). */
      SVN_ERR(svn_cache__get_partial((void **)&cached_filesize, &found,
                                     ffd->dir_cache, key,
                                     svn_fs_x__extract_dir_filesize,
                                     NULL, subpool));

      /* File size info still matches?
       * If not, we need to drop the cache entry. */
      if (found)
        {
          SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));

          if (cached_filesize != filesize)
            SVN_ERR(svn_cache__set(ffd->dir_cache, key, NULL, subpool));
        }
    }

  /* Append an incremental hash entry for the entry change.
     A deletion is represented by an "unused" noderev-id. */
  if (id)
    entry.id = *id;
  else
    svn_fs_x__id_reset(&entry.id);

  entry.name = name;
  entry.kind = kind;

  SVN_ERR(unparse_dir_entry(&entry, out, subpool));

  /* Flush APR buffers. */
  SVN_ERR(svn_io_file_flush(file, subpool));

  /* Obtain final file size to update txn_dir_cache. */
  SVN_ERR(svn_io_file_size_get(&filesize, file, subpool));

  /* Close file. */
  SVN_ERR(svn_io_file_close(file, subpool));
  svn_pool_clear(subpool);

  /* update directory cache */
    {
      /* build parameters: name, new entry, new file size  */
      replace_baton_t baton;

      baton.name = name;
      baton.new_entry = NULL;
      baton.txn_filesize = filesize;

      if (id)
        {
          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;
        }

      /* actually update the cached directory (if cached) */
      SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key,
                                     svn_fs_x__replace_dir_entry, &baton,
                                     subpool));
    }

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__add_change(svn_fs_t *fs,
                     svn_fs_x__txn_id_t txn_id,
                     const char *path,
                     svn_fs_path_change_kind_t change_kind,
                     svn_boolean_t text_mod,
                     svn_boolean_t prop_mod,
                     svn_boolean_t mergeinfo_mod,
                     svn_node_kind_t node_kind,
                     svn_revnum_t copyfrom_rev,
                     const char *copyfrom_path,
                     apr_pool_t *scratch_pool)
{
  apr_file_t *file;
  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,
                                                      scratch_pool),
                           APR_APPEND | APR_WRITE | APR_CREATE,
                           APR_OS_DEFAULT, scratch_pool));

  change.path.data = path;
  change.path.len = strlen(path);
  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(scratch_pool, copyfrom_path);

  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, 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. */
typedef struct rep_write_baton_t
{
  /* The FS we are writing to. */
  svn_fs_t *fs;

  /* Actual file to which we are writing. */
  svn_stream_t *rep_stream;

  /* A stream from the delta combiner.  Data written here gets
     deltified, then eventually written to rep_stream. */
  svn_stream_t *delta_stream;

  /* Where is this representation header stored. */
  apr_off_t rep_offset;

  /* Start of the actual data. */
  apr_off_t delta_start;

  /* How many bytes have been written to this rep already. */
  svn_filesize_t rep_size;

  /* The node revision for which we're writing out info. */
  svn_fs_x__noderev_t *noderev;

  /* Actual output file. */
  apr_file_t *file;
  /* Lock 'cookie' used to unlock the output file once we've finished
     writing to it. */
  void *lockcookie;

  svn_checksum_ctx_t *md5_checksum_ctx;
  svn_checksum_ctx_t *sha1_checksum_ctx;

  /* Receives the low-level checksum when closing REP_STREAM. */
  apr_uint32_t fnv1a_checksum;

  /* 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_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)
{
  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));
  b->rep_size += *len;

  return svn_stream_write(b->delta_stream, data, len);
}

/* Set *SPANNED to the number of shards touched when walking WALK steps on
 * NODEREV's predecessor chain in FS.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
shards_spanned(int *spanned,
               svn_fs_t *fs,
               svn_fs_x__noderev_t *noderev,
               int walk,
               apr_pool_t *scratch_pool)
{
  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(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, &id, scratch_pool,
                                          iterpool));
      shard = svn_fs_x__get_revnum(id.change_set) / shard_size;
      if (shard != last_shard)
        {
          ++count;
          last_shard = shard;
        }
    }
  svn_pool_destroy(iterpool);

  *spanned = count;
  return SVN_NO_ERROR;
}

/* Given a node-revision NODEREV in filesystem FS, return the
   representation in *REP to use as the base for a text representation
   delta if PROPS is FALSE.  If PROPS has been set, a suitable props
   base representation will be returned.  Perform allocations in POOL. */
static svn_error_t *
choose_delta_base(svn_fs_x__representation_t **rep,
                  svn_fs_t *fs,
                  svn_fs_x__noderev_t *noderev,
                  svn_boolean_t props,
                  apr_pool_t *pool)
{
  /* The zero-based index (counting from the "oldest" end), along NODEREVs
   * line predecessors, of the node-rev we will use as delta base. */
  int count;

  /* The length of the linear part of a delta chain.  (Delta chains use
   * skip-delta bits for the high-order bits and are linear in the low-order
   * bits.) */
  int walk;
  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
   * stream as a base. */
  if (! noderev->predecessor_count)
    {
      *rep = NULL;
      return SVN_NO_ERROR;
    }

  /* Flip the rightmost '1' bit of the predecessor count to determine
     which file rev (counting from 0) we want to use.  (To see why
     count & (count - 1) unsets the rightmost set bit, think about how
     you decrement a binary number.) */
  count = noderev->predecessor_count;
  count = count & (count - 1);

  /* Finding the delta base over a very long distance can become extremely
     expensive for very deep histories, possibly causing client timeouts etc.
     OTOH, this is a rare operation and its gains are minimal. Lets simply
     start deltification anew close every other 1000 changes or so.  */
  walk = noderev->predecessor_count - count;
  if (walk > (int)ffd->max_deltification_walk)
    {
      *rep = NULL;
      return SVN_NO_ERROR;
    }

  /* We use skip delta for limiting the number of delta operations
     along very long node histories.  Close to HEAD however, we create
     a linear history to minimize delta size.  */
  if (walk < (int)ffd->max_linear_deltification)
    {
      int shards;
      SVN_ERR(shards_spanned(&shards, fs, noderev, walk, pool));

      /* We also don't want the linear deltification to span more shards
         than if deltas we used in a simple skip-delta scheme. */
      if ((1 << (--shards)) <= walk)
        count = noderev->predecessor_count - 1;
    }

  /* Walk back a number of predecessors equal to the difference
     between count and the original predecessor count.  (For example,
     if noderev has ten predecessors and we want the eighth file rev,
     walk back two predecessors.) */
  base = noderev;
  iterpool = svn_pool_create(pool);
  while ((count++) < noderev->predecessor_count)
    {
      svn_fs_x__id_t id = noderev->predecessor_id;
      svn_pool_clear(iterpool);
      SVN_ERR(svn_fs_x__get_node_revision(&base, fs, &id, pool, iterpool));
    }
  svn_pool_destroy(iterpool);

  /* return a suitable base representation */
  *rep = props ? base->prop_rep : base->data_rep;

  /* if we encountered a shared rep, its parent chain may be different
   * from the node-rev parent chain. */
  if (*rep)
    {
      int chain_length = 0;
      int shard_count = 0;

      /* Very short rep bases are simply not worth it as we are unlikely
       * to re-coup the deltification space overhead of 20+ bytes. */
      svn_filesize_t rep_size = (*rep)->expanded_size
                              ? (*rep)->expanded_size
                              : (*rep)->size;
      if (rep_size < 64)
        {
          *rep = NULL;
          return SVN_NO_ERROR;
        }

      /* Check whether the length of the deltification chain is acceptable.
       * Otherwise, shared reps may form a non-skipping delta chain in
       * extreme cases. */
      SVN_ERR(svn_fs_x__rep_chain_length(&chain_length, &shard_count,
                                          *rep, fs, pool));

      /* Some reasonable limit, depending on how acceptable longer linear
       * chains are in this repo.  Also, allow for some minimal chain. */
      if (chain_length >= 2 * (int)ffd->max_linear_deltification + 2)
        *rep = NULL;
      else
        /* To make it worth opening additional shards / pack files, we
         * require that the reps have a certain minimal size.  To deltify
         * against a rep in different shard, the lower limit is 512 bytes
         * and doubles with every extra shard to visit along the delta
         * chain. */
        if (   shard_count > 1
            && ((svn_filesize_t)128 << shard_count) >= rep_size)
          *rep = NULL;
    }

  return SVN_NO_ERROR;
}

/* Something went wrong and the pool for the rep write is being
   cleared before we've finished writing the rep.  So we need
   to remove the rep from the protorevfile and we need to unlock
   the protorevfile. */
static apr_status_t
rep_write_cleanup(void *data)
{
  svn_error_t *err;
  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->local_pool);
  err = svn_error_compose_create(err, svn_io_file_close(b->file,
                                                        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, txn_id,
                                                  b->lockcookie,
                                                  b->local_pool));
  if (err)
    {
      apr_status_t rc = err->apr_err;
      svn_error_clear(err);
      return rc;
    }

  return APR_SUCCESS;
}

/* 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(rep_write_baton_t **wb_p,
                    svn_fs_t *fs,
                    svn_fs_x__noderev_t *noderev,
                    apr_pool_t *result_pool)
{
  svn_fs_x__data_t *ffd = fs->fsap_data;
  rep_write_baton_t *b;
  apr_file_t *file;
  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(result_pool, sizeof(*b));

  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 = 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->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->local_pool),
                              b->local_pool);

  SVN_ERR(svn_io_file_get_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->local_pool));
  SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, TRUE,
                                 b->local_pool));

  /* Write out the rep header. */
  if (base_rep)
    {
      header.base_revision = svn_fs_x__get_revnum(base_rep->id.change_set);
      header.base_item_index = base_rep->id.number;
      header.base_length = base_rep->size;
      header.type = svn_fs_x__rep_delta;
    }
  else
    {
      header.type = svn_fs_x__rep_self_delta;
    }
  SVN_ERR(svn_fs_x__write_rep_header(&header, b->rep_stream,
                                     b->local_pool));

  /* Now determine the offset of the actual svndiff data. */
  SVN_ERR(svn_io_file_get_offset(&b->delta_start, file, b->local_pool));

  /* Cleanup in case something goes wrong. */
  apr_pool_cleanup_register(b->local_pool, b, rep_write_cleanup,
                            apr_pool_cleanup_null);

  /* Prepare to write the svndiff data. */
  svn_txdelta_to_svndiff3(&wh,
                          &whb,
                          svn_stream_disown(b->rep_stream, b->result_pool),
                          diff_version,
                          ffd->delta_compression_level,
                          result_pool);

  b->delta_stream = svn_txdelta_target_push(wh, whb, source,
                                            b->result_pool);

  *wb_p = b;

  return SVN_NO_ERROR;
}

/* For REP->SHA1_CHECKSUM, try to find an already existing representation
   in FS and return it in *OLD_REP.  If no such representation exists or
   if rep sharing has been disabled for FS, NULL will be returned.  Since
   there may be new duplicate representations within the same uncommitted
   revision, those can be passed in REPS_HASH (maps a sha1 digest onto
   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(svn_fs_x__representation_t **old_rep,
               svn_fs_t *fs,
               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;
  svn_fs_x__data_t *ffd = fs->fsap_data;

  /* Return NULL, if rep sharing has been disabled. */
  *old_rep = NULL;
  if (!ffd->rep_sharing_allowed)
    return SVN_NO_ERROR;

  /* Can't look up if we don't know the key (happens for directories). */
  if (!rep->has_sha1)
    return SVN_NO_ERROR;

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out.  Start with the hash lookup
     because it is cheapest. */
  if (reps_hash)
    *old_rep = apr_hash_get(reps_hash,
                            rep->sha1_digest,
                            APR_SHA1_DIGESTSIZE);

  /* If we haven't found anything yet, try harder and consult our DB. */
  if (*old_rep == NULL)
    {
      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,
                                        scratch_pool);

      /* ### Other error codes that we shouldn't mask out? */
      if (err == SVN_NO_ERROR)
        {
          if (*old_rep)
            SVN_ERR(svn_fs_x__check_rep(*old_rep, fs, scratch_pool));
        }
      else if (err->apr_err == SVN_ERR_FS_CORRUPT
               || SVN_ERROR_IN_CATEGORY(err->apr_err,
                                        SVN_ERR_MALFUNC_CATEGORY_START))
        {
          /* Fatal error; don't mask it.

             In particular, this block is triggered when the rep-cache refers
             to revisions in the future.  We signal that as a corruption situation
             since, once those revisions are less than youngest (because of more
             commits), the rep-cache would be invalid.
           */
          SVN_ERR(err);
        }
      else
        {
          /* Something's wrong with the rep-sharing index.  We can continue
             without rep-sharing, but warn.
           */
          (fs->warning)(fs->warning_baton, err);
          svn_error_clear(err);
          *old_rep = NULL;
        }
    }

  /* look for intra-revision matches (usually data reps but not limited
     to them in case props happen to look like some data rep)
   */
  if (*old_rep == NULL && svn_fs_x__is_txn(rep->id.change_set))
    {
      svn_node_kind_t kind;
      const char *file_name
        = svn_fs_x__path_txn_sha1(fs,
                                  svn_fs_x__get_txn_id(rep->id.change_set),
                                  rep->sha1_digest, scratch_pool);

      /* in our txn, is there a rep file named with the wanted SHA1?
         If so, read it and use that rep.
       */
      SVN_ERR(svn_io_check_path(file_name, &kind, scratch_pool));
      if (kind == svn_node_file)
        {
          svn_stringbuf_t *rep_string;
          SVN_ERR(svn_stringbuf_from_file2(&rep_string, file_name,
                                           scratch_pool));
          SVN_ERR(svn_fs_x__parse_representation(old_rep, rep_string,
                                                 result_pool, scratch_pool));
        }
    }

  if (!*old_rep)
    return SVN_NO_ERROR;

  /* A simple guard against general rep-cache induced corruption. */
  if ((*old_rep)->expanded_size != rep->expanded_size)
    {
      /* Make the problem show up in the server log.

         Because not sharing reps is always a safe option,
         terminating the request would be inappropriate.
       */
      svn_checksum_t checksum;
      checksum.digest = rep->sha1_digest;
      checksum.kind = svn_checksum_sha1;

      err = svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                              "Rep size %s mismatches rep-cache.db value %s "
                              "for SHA1 %s.\n"
                              "You should delete the rep-cache.db and "
                              "verify the repository. The cached rep will "
                              "not be shared.",
                              apr_psprintf(scratch_pool,
                                           "%" SVN_FILESIZE_T_FMT,
                                           rep->expanded_size),
                              apr_psprintf(scratch_pool,
                                           "%" SVN_FILESIZE_T_FMT,
                                           (*old_rep)->expanded_size),
                              svn_checksum_to_cstring_display(&checksum,
                                                              scratch_pool));

      (fs->warning)(fs->warning_baton, err);
      svn_error_clear(err);

      /* Ignore the shared rep. */
      *old_rep = NULL;
    }
  else
    {
      /* Add information that is missing in the cached data.
         Use the old rep for this content. */
      memcpy((*old_rep)->md5_digest, rep->md5_digest, sizeof(rep->md5_digest));
    }

  return SVN_NO_ERROR;
}

/* Copy the hash sum calculation results from MD5_CTX, SHA1_CTX into REP.
 * SHA1 results are only be set if SHA1_CTX is not NULL.
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
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 *scratch_pool)
{
  svn_checksum_t *checksum;

  SVN_ERR(svn_checksum_final(&checksum, md5_ctx, scratch_pool));
  memcpy(rep->md5_digest, checksum->digest, svn_checksum_size(checksum));
  rep->has_sha1 = sha1_ctx != NULL;
  if (rep->has_sha1)
    {
      SVN_ERR(svn_checksum_final(&checksum, sha1_ctx, scratch_pool));
      memcpy(rep->sha1_digest, checksum->digest, svn_checksum_size(checksum));
    }

  return SVN_NO_ERROR;
}

/* Close handler for the representation write stream.  BATON is a
   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)
{
  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;

  rep = apr_pcalloc(b->result_pool, sizeof(*rep));

  /* Close our delta stream so the last bits of svndiff are written
     out. */
  SVN_ERR(svn_stream_close(b->delta_stream));

  /* Determine the length of the svndiff data. */
  SVN_ERR(svn_io_file_get_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__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. */
  SVN_ERR(digests_final(rep, b->md5_checksum_ctx, b->sha1_checksum_ctx,
                        b->result_pool));

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out. */
  SVN_ERR(get_shared_rep(&old_rep, b->fs, rep, NULL, b->result_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->local_pool));

      /* Use the old rep for this content. */
      b->noderev->data_rep = old_rep;
    }
  else
    {
      /* 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->local_pool));
      SVN_ERR(store_l2p_index_entry(b->fs, txn_id, b->rep_offset,
                                    rep->id.number, b->local_pool));

      b->noderev->data_rep = rep;
    }

  SVN_ERR(svn_stream_close(b->rep_stream));

  /* Remove cleanup callback. */
  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, b->local_pool));
  if (!old_rep)
    {
      svn_fs_x__p2l_entry_t entry;
      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_io_file_get_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->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->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, 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 *result_pool)
{
  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,
                                                  result_pool)->data);

  SVN_ERR(rep_write_get_baton(&wb, fs, noderev, result_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);

  return SVN_NO_ERROR;
}

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 *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, result_pool);
}

svn_error_t *
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 *scratch_pool)
{
  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(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, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__set_proplist(svn_fs_t *fs,
                       svn_fs_x__noderev_t *noderev,
                       apr_hash_t *proplist,
                       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,
                                                       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, scratch_pool));
  out = svn_stream_from_aprfile2(file, TRUE, scratch_pool);
  SVN_ERR(svn_fs_x__write_properties(out, proplist, 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))
    {
      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,
                                  txn_id, scratch_pool));
      SVN_ERR(svn_fs_x__put_node_revision(fs, noderev, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* This baton is used by the stream created for write_container_rep. */
typedef struct write_container_baton_t
{
  svn_stream_t *stream;

  apr_size_t size;

  svn_checksum_ctx_t *md5_ctx;

  /* SHA1 calculation is optional. If not needed, this will be NULL. */
  svn_checksum_ctx_t *sha1_ctx;
} write_container_baton_t;

/* The handler for the write_container_rep stream.  BATON is a
   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)
{
  write_container_baton_t *whb = baton;

  SVN_ERR(svn_checksum_update(whb->md5_ctx, data, *len));
  if (whb->sha1_ctx)
    SVN_ERR(svn_checksum_update(whb->sha1_ctx, data, *len));

  SVN_ERR(svn_stream_write(whb->stream, data, len));
  whb->size += *len;

  return SVN_NO_ERROR;
}

/* Callback function type.  Write the data provided by BATON into STREAM. */
typedef svn_error_t *
(* collection_writer_t)(svn_stream_t *stream,
                        void *baton,
                        apr_pool_t *scratch_pool);

/* Implement collection_writer_t writing the C string->svn_string_t hash
   given as BATON. */
static svn_error_t *
write_hash_to_stream(svn_stream_t *stream,
                     void *baton,
                     apr_pool_t *scratch_pool)
{
  apr_hash_t *hash = baton;
  SVN_ERR(svn_fs_x__write_properties(stream, hash, scratch_pool));

  return SVN_NO_ERROR;
}

/* Implement collection_writer_t writing the svn_fs_x__dirent_t* array given
   as BATON. */
static svn_error_t *
write_directory_to_stream(svn_stream_t *stream,
                          void *baton,
                          apr_pool_t *scratch_pool)
{
  apr_array_header_t *dir = baton;
  SVN_ERR(unparse_dir_entries(dir, stream, scratch_pool));

  return SVN_NO_ERROR;
}


/* Write out the COLLECTION pertaining to the NODEREV in FS as a deltified
   text representation to file FILE using WRITER.  In the process, record the
   total size and the md5 digest in REP and add the representation of type
   ITEM_TYPE to the indexes if necessary.  If rep sharing has been enabled and
   REPS_HASH is not NULL, it will be used in addition to the on-disk cache to
   find earlier reps with the same content.  When such existing reps can be
   found, we will truncate the one just written from the file and return the
   existing rep.

   If ITEM_TYPE is IS_PROPS equals SVN_FS_FS__ITEM_TYPE_*_PROPS, assume
   that we want to a props representation as the base for our delta.
   If FINAL_REVISION is not SVN_INVALID_REVNUM, use it to determine whether
   to write to the proto-index files.
   Perform temporary allocations in SCRATCH_POOL.
 */
static svn_error_t *
write_container_delta_rep(svn_fs_x__representation_t *rep,
                          apr_file_t *file,
                          void *collection,
                          collection_writer_t writer,
                          svn_fs_t *fs,
                          svn_fs_x__txn_id_t txn_id,
                          svn_fs_x__noderev_t *noderev,
                          apr_hash_t *reps_hash,
                          apr_uint32_t item_type,
                          svn_revnum_t final_revision,
                          apr_pool_t *scratch_pool)
{
  svn_fs_x__data_t *ffd = fs->fsap_data;
  svn_txdelta_window_handler_t diff_wh;
  void *diff_whb;

  svn_stream_t *file_stream;
  svn_stream_t *stream;
  svn_fs_x__representation_t *base_rep;
  svn_fs_x__representation_t *old_rep;
  svn_fs_x__p2l_entry_t entry;
  svn_stream_t *source;
  svn_fs_x__rep_header_t header = { 0 };

  apr_off_t rep_end = 0;
  apr_off_t delta_start = 0;
  apr_off_t offset = 0;

  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);

  /* Get the base for this delta. */
  SVN_ERR(choose_delta_base(&base_rep, fs, noderev, is_props, scratch_pool));
  SVN_ERR(svn_fs_x__get_contents(&source, fs, base_rep, FALSE, scratch_pool));

  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));

  /* Write out the rep header. */
  if (base_rep)
    {
      header.base_revision = svn_fs_x__get_revnum(base_rep->id.change_set);
      header.base_item_index = base_rep->id.number;
      header.base_length = base_rep->size;
      header.type = svn_fs_x__rep_delta;
    }
  else
    {
      header.type = svn_fs_x__rep_self_delta;
    }

  file_stream = svn_checksum__wrap_write_stream_fnv1a_32x4(
                                  &entry.fnv1_checksum,
                                  svn_stream_from_aprfile2(file, TRUE,
                                                           scratch_pool),
                                  scratch_pool);
  SVN_ERR(svn_fs_x__write_rep_header(&header, file_stream, scratch_pool));
  SVN_ERR(svn_io_file_get_offset(&delta_start, file, scratch_pool));

  /* Prepare to write the svndiff data. */
  svn_txdelta_to_svndiff3(&diff_wh,
                          &diff_whb,
                          svn_stream_disown(file_stream, scratch_pool),
                          diff_version,
                          ffd->delta_compression_level,
                          scratch_pool);

  whb = apr_pcalloc(scratch_pool, sizeof(*whb));
  whb->stream = svn_txdelta_target_push(diff_wh, diff_whb, source,
                                        scratch_pool);
  whb->size = 0;
  whb->md5_ctx = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
  if (item_type != SVN_FS_X__ITEM_TYPE_DIR_REP)
    whb->sha1_ctx = svn_checksum_ctx_create(svn_checksum_sha1, scratch_pool);

  /* serialize the hash */
  stream = svn_stream_create(whb, scratch_pool);
  svn_stream_set_write(stream, write_container_handler);

  SVN_ERR(writer(stream, collection, scratch_pool));
  SVN_ERR(svn_stream_close(whb->stream));

  /* Store the results. */
  SVN_ERR(digests_final(rep, whb->md5_ctx, whb->sha1_ctx, scratch_pool));
  rep->expanded_size = whb->size;

  /* Check and see if we already have a representation somewhere that's
     identical to the one we just wrote out. */
  SVN_ERR(get_shared_rep(&old_rep, fs, rep, reps_hash, scratch_pool,
                         scratch_pool));

  if (old_rep)
    {
      SVN_ERR(svn_stream_close(file_stream));

      /* We need to erase from the protorev the data we just wrote. */
      SVN_ERR(svn_io_file_trunc(file, offset, scratch_pool));

      /* Use the old rep for this content. */
      memcpy(rep, old_rep, sizeof (*rep));
    }
  else
    {
      svn_fs_x__id_t noderev_id;

      /* Write out our cosmetic end marker. */
      SVN_ERR(svn_io_file_get_offset(&rep_end, file, scratch_pool));
      SVN_ERR(svn_stream_puts(file_stream, "ENDREP\n"));
      SVN_ERR(svn_stream_close(file_stream));

      SVN_ERR(allocate_item_index(&rep->id.number, fs, txn_id,
                                  scratch_pool));
      SVN_ERR(store_l2p_index_entry(fs, txn_id, offset, rep->id.number,
                                    scratch_pool));

      noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;
      noderev_id.number = rep->id.number;

      entry.offset = offset;
      SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
      entry.size = offset - entry.offset;
      entry.type = item_type;
      entry.item_count = 1;
      entry.items = &noderev_id;

      SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, scratch_pool));

      /* update the representation */
      rep->size = rep_end - delta_start;
    }

  return SVN_NO_ERROR;
}

/* Sanity check ROOT_NODEREV, a candidate for being the root node-revision
   of (not yet committed) revision REV in FS.  Use SCRATCH_POOL for temporary
   allocations.

   If you change this function, consider updating svn_fs_x__verify() too.
 */
static svn_error_t *
validate_root_noderev(svn_fs_t *fs,
                      svn_fs_x__noderev_t *root_noderev,
                      svn_revnum_t rev,
                      apr_pool_t *scratch_pool)
{
  svn_revnum_t head_revnum = rev-1;
  int head_predecessor_count;

  SVN_ERR_ASSERT(rev > 0);

  /* Compute HEAD_PREDECESSOR_COUNT. */
  {
    svn_fs_x__id_t head_root_id;
    svn_fs_x__noderev_t *head_root_noderev;

    /* Get /@HEAD's noderev. */
    svn_fs_x__init_rev_root(&head_root_id, head_revnum);
    SVN_ERR(svn_fs_x__get_node_revision(&head_root_noderev, fs,
                                        &head_root_id, scratch_pool,
                                        scratch_pool));

    head_predecessor_count = head_root_noderev->predecessor_count;
  }

  /* Check that the root noderev's predecessor count equals REV.

     This kind of corruption was seen on svn.apache.org (both on
     the root noderev and on other fspaths' noderevs); see
     issue #4129.

     Normally (rev == root_noderev->predecessor_count), but here we
     use a more roundabout check that should only trigger on new instances
     of the corruption, rather than trigger on each and every new commit
     to a repository that has triggered the bug somewhere in its root
     noderev's history.
   */
  if ((root_noderev->predecessor_count - head_predecessor_count)
      != (rev - head_revnum))
    {
      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                               _("predecessor count for "
                                 "the root node-revision is wrong: "
                                 "found (%d+%ld != %d), committing r%ld"),
                                 head_predecessor_count,
                                 rev - head_revnum, /* This is equal to 1. */
                                 root_noderev->predecessor_count,
                                 rev);
    }

  return SVN_NO_ERROR;
}

/* Given the potentially txn-local id PART, update that to a permanent ID
 * based on the REVISION.
 */
static void
get_final_id(svn_fs_x__id_t *part,
             svn_revnum_t revision)
{
  if (!svn_fs_x__is_revision(part->change_set))
    part->change_set = svn_fs_x__change_set_by_rev(revision);
}

/* Copy a node-revision specified by id ID in fileystem FS from a
   transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
   pointer to the new noderev-id.  If this is a directory, copy all
   children as well.

   START_NODE_ID and START_COPY_ID are
   the first available node and copy ids for this filesystem, for older
   FS formats.

   REV is the revision number that this proto-rev-file will represent.

   INITIAL_OFFSET is the offset of the proto-rev-file on entry to
   commit_body.

   Collect the pair_cache_key_t of all directories written to the
   committed cache in DIRECTORY_IDS.

   If REPS_TO_CACHE is not NULL, append to it a copy (allocated in
   REPS_POOL) of each data rep that is new in this revision.

   If REPS_HASH is not NULL, append copies (allocated in REPS_POOL)
   of the representations of each property rep that is new in this
   revision.

   AT_ROOT is true if the node revision being written is the root
   node-revision.  It is only controls additional sanity checking
   logic.

   CHANGED_PATHS is the changed paths hash for the new revision.
   The noderev-ids in it will be updated as soon as the respective
   nodesrevs got their final IDs assigned.

   Temporary allocations are also from SCRATCH_POOL. */
static svn_error_t *
write_final_rev(svn_fs_x__id_t *new_id_p,
                apr_file_t *file,
                svn_revnum_t rev,
                svn_fs_t *fs,
                const svn_fs_x__id_t *id,
                apr_off_t initial_offset,
                apr_array_header_t *directory_ids,
                apr_array_header_t *reps_to_cache,
                apr_hash_t *reps_hash,
                apr_pool_t *reps_pool,
                svn_boolean_t at_root,
                apr_hash_t *changed_paths,
                apr_pool_t *scratch_pool)
{
  svn_fs_x__noderev_t *noderev;
  apr_off_t my_offset;
  svn_fs_x__id_t new_id;
  svn_fs_x__id_t noderev_id;
  svn_fs_x__data_t *ffd = fs->fsap_data;
  svn_fs_x__txn_id_t txn_id = svn_fs_x__get_txn_id(id->change_set);
  svn_fs_x__p2l_entry_t entry;
  svn_fs_x__change_set_t change_set = svn_fs_x__change_set_by_rev(rev);
  svn_stream_t *file_stream;
  apr_pool_t *subpool;

  /* Check to see if this is a transaction node. */
  if (txn_id == SVN_FS_X__INVALID_TXN_ID)
    {
      svn_fs_x__id_reset(new_id_p);
      return SVN_NO_ERROR;
    }

  subpool = svn_pool_create(scratch_pool);
  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, scratch_pool,
                                      subpool));

  if (noderev->kind == svn_node_dir)
    {
      apr_array_header_t *entries;
      int i;

      /* This is a directory.  Write out all the children first. */

      SVN_ERR(svn_fs_x__rep_contents_dir(&entries, fs, noderev, scratch_pool,
                                         subpool));
      for (i = 0; i < entries->nelts; ++i)
        {
          svn_fs_x__dirent_t *dirent = APR_ARRAY_IDX(entries, i,
                                                     svn_fs_x__dirent_t *);

          svn_pool_clear(subpool);
          SVN_ERR(write_final_rev(&new_id, file, rev, fs, &dirent->id,
                                  initial_offset, directory_ids,
                                  reps_to_cache, reps_hash,
                                  reps_pool, FALSE, changed_paths, subpool));
          if (new_id.change_set == change_set)
            dirent->id = new_id;
        }

      if (noderev->data_rep
          && ! svn_fs_x__is_revision(noderev->data_rep->id.change_set))
        {
          svn_fs_x__pair_cache_key_t *key;
          svn_fs_x__dir_data_t dir_data;

          /* Write out the contents of this directory as a text rep. */
          noderev->data_rep->id.change_set = change_set;
          SVN_ERR(write_container_delta_rep(noderev->data_rep, file,
                                            entries,
                                            write_directory_to_stream,
                                            fs, txn_id, noderev, NULL,
                                            SVN_FS_X__ITEM_TYPE_DIR_REP,
                                            rev, scratch_pool));

          /* Cache the new directory contents.  Otherwise, subsequent reads
           * or commits will likely have to reconstruct, verify and parse
           * it again. */
          key = apr_array_push(directory_ids);
          key->revision = noderev->data_rep->id.change_set;
          key->second = noderev->data_rep->id.number;

          /* Store directory contents under the new revision number but mark
           * it as "stale" by setting the file length to 0.  Committed dirs
           * will report -1, in-txn dirs will report > 0, so that this can
           * never match.  We reset that to -1 after the commit is complete.
           */
          dir_data.entries = entries;
          dir_data.txn_filesize = 0;

          SVN_ERR(svn_cache__set(ffd->dir_cache, key, &dir_data, subpool));
        }
    }
  else
    {
      /* This is a file.  We should make sure the data rep, if it
         exists in a "this" state, gets rewritten to our new revision
         num. */

      if (noderev->data_rep
          && svn_fs_x__is_txn(noderev->data_rep->id.change_set))
        {
          noderev->data_rep->id.change_set = change_set;
        }
    }

  svn_pool_destroy(subpool);

  /* Fix up the property reps. */
  if (noderev->prop_rep
      && svn_fs_x__is_txn(noderev->prop_rep->id.change_set))
    {
      apr_hash_t *proplist;
      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,
                                     scratch_pool));

      noderev->prop_rep->id.change_set = change_set;

      SVN_ERR(write_container_delta_rep(noderev->prop_rep, file, proplist,
                                        write_hash_to_stream, fs, txn_id,
                                        noderev, reps_hash, item_type, rev,
                                        scratch_pool));
    }

  /* Convert our temporary ID into a permanent revision one. */
  get_final_id(&noderev->node_id, rev);
  get_final_id(&noderev->copy_id, rev);
  get_final_id(&noderev->noderev_id, rev);

  if (noderev->copyroot_rev == SVN_INVALID_REVNUM)
    noderev->copyroot_rev = rev;

  SVN_ERR(svn_io_file_get_offset(&my_offset, file, scratch_pool));

  SVN_ERR(store_l2p_index_entry(fs, txn_id, my_offset,
                                noderev->noderev_id.number, scratch_pool));
  new_id = noderev->noderev_id;

  if (ffd->rep_sharing_allowed)
    {
      /* Save the data representation's hash in the rep cache. */
      if (   noderev->data_rep && noderev->kind == svn_node_file
          && svn_fs_x__get_revnum(noderev->data_rep->id.change_set) == rev)
        {
          SVN_ERR_ASSERT(reps_to_cache && reps_pool);
          APR_ARRAY_PUSH(reps_to_cache, svn_fs_x__representation_t *)
            = svn_fs_x__rep_copy(noderev->data_rep, reps_pool);
        }

      if (   noderev->prop_rep
          && svn_fs_x__get_revnum(noderev->prop_rep->id.change_set) == rev)
        {
          /* Add new property reps to hash and on-disk cache. */
          svn_fs_x__representation_t *copy
            = svn_fs_x__rep_copy(noderev->prop_rep, reps_pool);

          SVN_ERR_ASSERT(reps_to_cache && reps_pool);
          APR_ARRAY_PUSH(reps_to_cache, svn_fs_x__representation_t *) = copy;

          apr_hash_set(reps_hash,
                        copy->sha1_digest,
                        APR_SHA1_DIGESTSIZE,
                        copy);
        }
    }

  /* don't serialize SHA1 for dirs to disk (waste of space) */
  if (noderev->data_rep && noderev->kind == svn_node_dir)
    noderev->data_rep->has_sha1 = FALSE;

  /* don't serialize SHA1 for props to disk (waste of space) */
  if (noderev->prop_rep)
    noderev->prop_rep->has_sha1 = FALSE;

  /* Write out our new node-revision. */
  if (at_root)
    SVN_ERR(validate_root_noderev(fs, noderev, rev, scratch_pool));

  file_stream = svn_checksum__wrap_write_stream_fnv1a_32x4(
                                  &entry.fnv1_checksum,
                                  svn_stream_from_aprfile2(file, TRUE,
                                                           scratch_pool),
                                  scratch_pool);
  SVN_ERR(svn_fs_x__write_noderev(file_stream, noderev, scratch_pool));
  SVN_ERR(svn_stream_close(file_stream));

  /* reference the root noderev from the log-to-phys index */
  noderev_id = noderev->noderev_id;
  noderev_id.change_set = SVN_FS_X__INVALID_CHANGE_SET;

  entry.offset = my_offset;
  SVN_ERR(svn_io_file_get_offset(&my_offset, file, scratch_pool));
  entry.size = my_offset - entry.offset;
  entry.type = SVN_FS_X__ITEM_TYPE_NODEREV;
  entry.item_count = 1;
  entry.items = &noderev_id;

  SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, scratch_pool));

  /* Return our ID that references the revision file. */
  *new_id_p = new_id;

  return SVN_NO_ERROR;
}

/* Write the changed path info CHANGED_PATHS from transaction TXN_ID to the
   permanent rev-file FILE representing NEW_REV in filesystem FS.  *OFFSET_P
   is set the to offset in the file of the beginning of this information.
   NEW_REV is the revision currently being committed.
   Perform temporary allocations in SCRATCH_POOL. */
static svn_error_t *
write_final_changed_path_info(apr_off_t *offset_p,
                              apr_file_t *file,
                              svn_fs_t *fs,
                              svn_fs_x__txn_id_t txn_id,
                              apr_hash_t *changed_paths,
                              svn_revnum_t new_rev,
                              apr_pool_t *scratch_pool)
{
  apr_off_t offset;
  svn_stream_t *stream;
  svn_fs_x__p2l_entry_t entry;
  svn_fs_x__id_t rev_item
    = {SVN_INVALID_REVNUM, SVN_FS_X__ITEM_INDEX_CHANGES};

  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));

  /* write to target file & calculate checksum */
  stream = svn_checksum__wrap_write_stream_fnv1a_32x4(&entry.fnv1_checksum,
                         svn_stream_from_aprfile2(file, TRUE, scratch_pool),
                         scratch_pool);
  SVN_ERR(svn_fs_x__write_changes(stream, fs, changed_paths, TRUE,
                                  scratch_pool));
  SVN_ERR(svn_stream_close(stream));

  *offset_p = offset;

  /* reference changes from the indexes */
  entry.offset = offset;
  SVN_ERR(svn_io_file_get_offset(&offset, file, scratch_pool));
  entry.size = offset - entry.offset;
  entry.type = SVN_FS_X__ITEM_TYPE_CHANGES;
  entry.item_count = 1;
  entry.items = &rev_item;

  SVN_ERR(store_p2l_index_entry(fs, txn_id, &entry, scratch_pool));
  SVN_ERR(store_l2p_index_entry(fs, txn_id, entry.offset,
                                SVN_FS_X__ITEM_INDEX_CHANGES, scratch_pool));

  return SVN_NO_ERROR;
}

/* Open a new svn_fs_t handle to FS, set that handle's concept of "current
   youngest revision" to NEW_REV, and call svn_fs_x__verify_root() on
   NEW_REV's revision root.

   Intended to be called as the very last step in a commit before 'current'
   is bumped.  This implies that we are holding the write lock. */
static svn_error_t *
verify_as_revision_before_current_plus_plus(svn_fs_t *fs,
                                            svn_revnum_t new_rev,
                                            apr_pool_t *scratch_pool)
{
#ifdef SVN_DEBUG
  svn_fs_x__data_t *ffd = fs->fsap_data;
  svn_fs_t *ft; /* fs++ == ft */
  svn_fs_root_t *root;
  svn_fs_x__data_t *ft_ffd;
  apr_hash_t *fs_config;

  SVN_ERR_ASSERT(ffd->svn_fs_open_);

  /* make sure FT does not simply return data cached by other instances
   * but actually retrieves it from disk at least once.
   */
  fs_config = apr_hash_make(scratch_pool);
  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NS,
                           svn_uuid_generate(scratch_pool));
  SVN_ERR(ffd->svn_fs_open_(&ft, fs->path,
                            fs_config,
                            scratch_pool,
                            scratch_pool));
  ft_ffd = ft->fsap_data;
  /* Don't let FT consult rep-cache.db, either. */
  ft_ffd->rep_sharing_allowed = FALSE;

  /* Time travel! */
  ft_ffd->youngest_rev_cache = new_rev;

  SVN_ERR(svn_fs_x__revision_root(&root, ft, new_rev, scratch_pool));
  SVN_ERR_ASSERT(root->is_txn_root == FALSE && root->rev == new_rev);
  SVN_ERR_ASSERT(ft_ffd->youngest_rev_cache == new_rev);
  SVN_ERR(svn_fs_x__verify_root(root, scratch_pool));
#endif /* SVN_DEBUG */

  return SVN_NO_ERROR;
}

/* Verify that the user registered with FS has all the locks necessary to
   permit all the changes associated with TXN_NAME.
   The FS write lock is assumed to be held by the caller. */
static svn_error_t *
verify_locks(svn_fs_t *fs,
             svn_fs_x__txn_id_t txn_id,
             apr_hash_t *changed_paths,
             apr_pool_t *scratch_pool)
{
  apr_pool_t *iterpool;
  apr_array_header_t *changed_paths_sorted;
  svn_stringbuf_t *last_recursed = NULL;
  int i;

  /* Make an array of the changed paths, and sort them depth-first-ily.  */
  changed_paths_sorted = svn_sort__hash(changed_paths,
                                        svn_sort_compare_items_as_paths,
                                        scratch_pool);

  /* Now, traverse the array of changed paths, verify locks.  Note
     that if we need to do a recursive verification a path, we'll skip
     over children of that path when we get to them. */
  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < changed_paths_sorted->nelts; i++)
    {
      const svn_sort__item_t *item;
      const char *path;
      svn_fs_x__change_t *change;
      svn_boolean_t recurse = TRUE;

      svn_pool_clear(iterpool);

      item = &APR_ARRAY_IDX(changed_paths_sorted, i, svn_sort__item_t);

      /* Fetch the change associated with our path.  */
      path = item->key;
      change = item->value;

      /* If this path has already been verified as part of a recursive
         check of one of its parents, no need to do it again.  */
      if (last_recursed
          && svn_fspath__skip_ancestor(last_recursed->data, path))
        continue;

      /* What does it mean to succeed at lock verification for a given
         path?  For an existing file or directory getting modified
         (text, props), it means we hold the lock on the file or
         directory.  For paths being added or removed, we need to hold
         the locks for that path and any children of that path.

         WHEW!  We have no reliable way to determine the node kind
         of deleted items, but fortunately we are going to do a
         recursive check on deleted paths regardless of their kind.  */
      if (change->change_kind == svn_fs_path_change_modify)
        recurse = FALSE;
      SVN_ERR(svn_fs_x__allow_locked_operation(path, fs, recurse, TRUE,
                                               iterpool));

      /* If we just did a recursive check, remember the path we
         checked (so children can be skipped).  */
      if (recurse)
        {
          if (! last_recursed)
            last_recursed = svn_stringbuf_create(path, scratch_pool);
          else
            svn_stringbuf_set(last_recursed, path);
        }
    }
  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}

/* Based on the transaction properties of TXN, write the final revision
   properties for REVISION into their final location. Return that location
   in *PATH and schedule the necessary fsync calls in BATCH.  This involves
   setting svn:date and removing any temporary properties associated with
   the commit flags. */
static svn_error_t *
write_final_revprop(const char **path,
                    svn_fs_txn_t *txn,
                    svn_revnum_t revision,
                    svn_fs_x__batch_fsync_t *batch,
                    apr_pool_t *result_pool,
                    apr_pool_t *scratch_pool)
{
  apr_hash_t *props;
  svn_string_t date;
  svn_string_t *client_date;
  apr_file_t *file;

  SVN_ERR(svn_fs_x__txn_proplist(&props, txn, scratch_pool));

  /* Remove any temporary txn props representing 'flags'. */
  if (svn_hash_gets(props, SVN_FS__PROP_TXN_CHECK_OOD))
    svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_OOD, NULL);

  if (svn_hash_gets(props, SVN_FS__PROP_TXN_CHECK_LOCKS))
    svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_LOCKS, NULL);

  client_date = svn_hash_gets(props, SVN_FS__PROP_TXN_CLIENT_DATE);
  if (client_date)
    svn_hash_sets(props, SVN_FS__PROP_TXN_CLIENT_DATE, NULL);

  /* Update commit time to ensure that svn:date revprops remain ordered if
     requested. */
  if (!client_date || strcmp(client_date->data, "1"))
    {
      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);
    }

  /* Create a file at the final revprops location. */
  *path = svn_fs_x__path_revprops(txn->fs, revision, result_pool);
  SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, *path, scratch_pool));

  /* Write the new contents to the final revprops file. */
  SVN_ERR(svn_fs_x__write_non_packed_revprops(file, props, scratch_pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__add_index_data(svn_fs_t *fs,
                         apr_file_t *file,
                         const char *l2p_proto_index,
                         const char *p2l_proto_index,
                         svn_revnum_t revision,
                         apr_pool_t *scratch_pool)
{
  apr_off_t l2p_offset;
  apr_off_t p2l_offset;
  svn_stringbuf_t *footer;
  unsigned char footer_length;
  svn_checksum_t *l2p_checksum;
  svn_checksum_t *p2l_checksum;

  /* Append the actual index data to the pack file. */
  l2p_offset = 0;
  SVN_ERR(svn_io_file_seek(file, APR_END, &l2p_offset, scratch_pool));
  SVN_ERR(svn_fs_x__l2p_index_append(&l2p_checksum, fs, file,
                                     l2p_proto_index, revision,
                                     scratch_pool, scratch_pool));

  p2l_offset = 0;
  SVN_ERR(svn_io_file_seek(file, APR_END, &p2l_offset, scratch_pool));
  SVN_ERR(svn_fs_x__p2l_index_append(&p2l_checksum, fs, file,
                                     p2l_proto_index, revision,
                                     scratch_pool, scratch_pool));

  /* Append footer. */
  footer = svn_fs_x__unparse_footer(l2p_offset, l2p_checksum,
                                    p2l_offset, p2l_checksum, scratch_pool,
                                    scratch_pool);
  SVN_ERR(svn_io_file_write_full(file, footer->data, footer->len, NULL,
                                 scratch_pool));

  footer_length = footer->len;
  SVN_ERR_ASSERT(footer_length == footer->len);
  SVN_ERR(svn_io_file_write_full(file, &footer_length, 1, NULL,
                                 scratch_pool));

  return SVN_NO_ERROR;
}

/* Make sure that the shard folder for REVSION exists in FS.  If we had to
   create them, schedule their fsync in BATCH.  Use SCRATCH_POOL for
   temporary allocations. */
static svn_error_t *
auto_create_shard(svn_fs_t *fs,
                  svn_revnum_t revision,
                  svn_fs_x__batch_fsync_t *batch,
                  apr_pool_t *scratch_pool)
{
  svn_fs_x__data_t *ffd = fs->fsap_data;
  if (revision % ffd->max_files_per_dir == 0)
    {
      const char *new_dir = svn_fs_x__path_shard(fs, revision, scratch_pool);
      svn_error_t *err = svn_io_dir_make(new_dir, APR_OS_DEFAULT,
                                         scratch_pool);

      if (err && !APR_STATUS_IS_EEXIST(err->apr_err))
        return svn_error_trace(err);
      svn_error_clear(err);

      SVN_ERR(svn_io_copy_perms(svn_dirent_join(fs->path, PATH_REVS_DIR,
                                                scratch_pool),
                                new_dir, scratch_pool));
      SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, new_dir, scratch_pool));
    }

  return SVN_NO_ERROR;
}

/* Move the protype revision file of transaction TXN_ID in FS to the final
   location for REVISION and return a handle to it in *FILE.  Schedule any
   fsyncs in BATCH and use SCRATCH_POOL for temporaries.

   Note that the lifetime of *FILE is determined by BATCH instead of
   SCRATCH_POOL.  It will be invalidated by either BATCH being cleaned up
   itself of by running svn_fs_x__batch_fsync_run on it.

   This function will "destroy" the transaction by removing its prototype
   revision file, so it can at most be called once per transaction.  Also,
   later attempts to modify this txn will fail due to get_writable_proto_rev
   not finding the protorev file.  Therefore, we will take out the lock for
   it only until we move the file to its final location.

   If the prototype revision file is already locked, return error
   SVN_ERR_FS_REP_BEING_WRITTEN. */
static svn_error_t *
get_writable_final_rev(apr_file_t **file,
                       svn_fs_t *fs,
                       svn_fs_x__txn_id_t txn_id,
                       svn_revnum_t revision,
                       svn_fs_x__batch_fsync_t *batch,
                       apr_pool_t *scratch_pool)
{
  get_writable_proto_rev_baton_t baton;
  apr_off_t end_offset = 0;
  void *lockcookie;

  const char *proto_rev_filename
    = svn_fs_x__path_txn_proto_rev(fs, txn_id, scratch_pool);
  const char *final_rev_filename
    = svn_fs_x__path_rev(fs, revision, scratch_pool);

  /* Acquire exclusive access to the proto-rev file. */
  baton.lockcookie = &lockcookie;
  baton.txn_id = txn_id;

  SVN_ERR(with_txnlist_lock(fs, get_writable_proto_rev_body, &baton,
                            scratch_pool));

  /* Move the proto-rev file to its final location as revision data file.
     After that, we don't need to protect it anymore and can unlock it. */
  SVN_ERR(svn_error_compose_create(svn_io_file_rename2(proto_rev_filename,
                                                       final_rev_filename,
                                                       FALSE,
                                                       scratch_pool),
                                   unlock_proto_rev(fs, txn_id, lockcookie,
                                                    scratch_pool)));
  SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, final_rev_filename,
                                         scratch_pool));

  /* Now open the prototype revision file and seek to the end.
     Note that BATCH always seeks to position 0 before returning the file. */
  SVN_ERR(svn_fs_x__batch_fsync_open_file(file, batch, final_rev_filename,
                                          scratch_pool));
  SVN_ERR(svn_io_file_seek(*file, APR_END, &end_offset, scratch_pool));

  /* We don't want unused sections (such as leftovers from failed delta
     stream) in our file.  If we use log addressing, we would need an
     index entry for the unused section and that section would need to
     be all NUL by convention.  So, detect and fix those cases by truncating
     the protorev file. */
  SVN_ERR(auto_truncate_proto_rev(fs, *file, end_offset, txn_id,
                                  scratch_pool));

  return SVN_NO_ERROR;
}

/* Write REVISION into FS' 'next' file and schedule necessary fsyncs in BATCH.
   Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
write_next_file(svn_fs_t *fs,
                svn_revnum_t revision,
                svn_fs_x__batch_fsync_t *batch,
                apr_pool_t *scratch_pool)
{
  apr_file_t *file;
  const char *path = svn_fs_x__path_next(fs, scratch_pool);
  const char *perms_path = svn_fs_x__path_current(fs, scratch_pool);
  char *buf;

  /* Create / open the 'next' file. */
  SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, scratch_pool));

  /* Write its contents. */
  buf = apr_psprintf(scratch_pool, "%ld\n", revision);
  SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL, scratch_pool));

  /* Adjust permissions. */
  SVN_ERR(svn_io_copy_perms(perms_path, path, scratch_pool));

  return SVN_NO_ERROR;
}

/* Bump the 'current' file in FS to NEW_REV.  Schedule fsyncs in BATCH.
 * Use SCRATCH_POOL for temporary allocations. */
static svn_error_t *
bump_current(svn_fs_t *fs,
             svn_revnum_t new_rev,
             svn_fs_x__batch_fsync_t *batch,
             apr_pool_t *scratch_pool)
{
  const char *current_filename;

  /* Write the 'next' file. */
  SVN_ERR(write_next_file(fs, new_rev, batch, scratch_pool));

  /* Commit all changes to disk. */
  SVN_ERR(svn_fs_x__batch_fsync_run(batch, scratch_pool));

  /* Make the revision visible to all processes and threads. */
  current_filename = svn_fs_x__path_current(fs, scratch_pool);
  SVN_ERR(svn_fs_x__move_into_place(svn_fs_x__path_next(fs, scratch_pool),
                                    current_filename, current_filename,
                                    batch, scratch_pool));

  /* Make the new revision permanently visible. */
  SVN_ERR(svn_fs_x__batch_fsync_run(batch, scratch_pool));

  return SVN_NO_ERROR;
}

/* Mark the directories cached in FS with the keys from DIRECTORY_IDS
 * as "valid" now.  Use SCRATCH_POOL for temporaries. */
static svn_error_t *
promote_cached_directories(svn_fs_t *fs,
                           apr_array_header_t *directory_ids,
                           apr_pool_t *scratch_pool)
{
  svn_fs_x__data_t *ffd = fs->fsap_data;
  apr_pool_t *iterpool;
  int i;

  if (!ffd->dir_cache)
    return SVN_NO_ERROR;

  iterpool = svn_pool_create(scratch_pool);
  for (i = 0; i < directory_ids->nelts; ++i)
    {
      const svn_fs_x__pair_cache_key_t *key
        = &APR_ARRAY_IDX(directory_ids, i, svn_fs_x__pair_cache_key_t);

      svn_pool_clear(iterpool);

      /* Currently, the entry for KEY - if it still exists - is marked
       * as "stale" and would not be used.  Mark it as current for in-
       * revison data. */
      SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key,
                                     svn_fs_x__reset_txn_filesize, NULL,
                                     iterpool));
    }

  svn_pool_destroy(iterpool);

  return SVN_NO_ERROR;
}

/* Baton used for commit_body below. */
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 'commit_baton_t *'. */
static svn_error_t *
commit_body(void *baton,
            apr_pool_t *scratch_pool)
{
  commit_baton_t *cb = baton;
  svn_fs_x__data_t *ffd = cb->fs->fsap_data;
  const char *old_rev_filename, *rev_filename;
  const char *revprop_filename;
  svn_fs_x__id_t root_id, new_root_id;
  svn_revnum_t old_rev, new_rev;
  apr_file_t *proto_file;
  apr_off_t initial_offset, changed_path_offset;
  svn_fs_x__txn_id_t txn_id = svn_fs_x__txn_get_id(cb->txn);
  apr_hash_t *changed_paths;
  svn_fs_x__batch_fsync_t *batch;
  apr_array_header_t *directory_ids
    = apr_array_make(scratch_pool, 4, sizeof(svn_fs_x__pair_cache_key_t));

  /* We perform a sequence of (potentially) large allocations.
     Keep the peak memory usage low by using a SUBPOOL and cleaning it
     up frequently. */
  apr_pool_t *subpool = svn_pool_create(scratch_pool);

  /* Re-Read the current repository format.  All our repo upgrade and
     config evaluation strategies are such that existing information in
     FS and FFD remains valid.

     Although we don't recommend upgrading hot repositories, people may
     still do it and we must make sure to either handle them gracefully
     or to error out.
   */
  SVN_ERR(svn_fs_x__read_format_file(cb->fs, subpool));

  /* Get the current youngest revision. */
  SVN_ERR(svn_fs_x__youngest_rev(&old_rev, cb->fs, subpool));
  svn_pool_clear(subpool);

  /* Check to make sure this transaction is based off the most recent
     revision. */
  if (cb->txn->base_rev != old_rev)
    return svn_error_create(SVN_ERR_FS_TXN_OUT_OF_DATE, NULL,
                            _("Transaction out of date"));

  /* We need the changes list for verification as well as for writing it
     to the final rev file. */
  SVN_ERR(svn_fs_x__txn_changes_fetch(&changed_paths, cb->fs, txn_id,
                                      scratch_pool));

  /* Locks may have been added (or stolen) between the calling of
     previous svn_fs.h functions and svn_fs_commit_txn(), so we need
     to re-examine every changed-path in the txn and re-verify all
     discovered locks. */
  SVN_ERR(verify_locks(cb->fs, txn_id, changed_paths, subpool));
  svn_pool_clear(subpool);

  /* We are going to be one better than this puny old revision. */
  new_rev = old_rev + 1;

  /* Use this to force all data to be flushed to physical storage
     (to the degree our environment will allow). */
  SVN_ERR(svn_fs_x__batch_fsync_create(&batch, ffd->flush_to_disk,
                                       scratch_pool));

  /* Set up the target directory. */
  SVN_ERR(auto_create_shard(cb->fs, new_rev, batch, subpool));

  /* Get a write handle on the proto revision file.

     ### This "breaks" the transaction by removing the protorev file
     ### but the revision is not yet complete.  If this commit does
     ### not complete for any reason the transaction will be lost. */
  SVN_ERR(get_writable_final_rev(&proto_file, cb->fs, txn_id, new_rev,
                                 batch, subpool));
  SVN_ERR(svn_io_file_get_offset(&initial_offset, proto_file, subpool));
  svn_pool_clear(subpool);

  /* Write out all the node-revisions and directory contents. */
  svn_fs_x__init_txn_root(&root_id, txn_id);
  SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, &root_id,
                          initial_offset, directory_ids, cb->reps_to_cache,
                          cb->reps_hash, cb->reps_pool, TRUE, changed_paths,
                          subpool));
  svn_pool_clear(subpool);

  /* Write the changed-path information. */
  SVN_ERR(write_final_changed_path_info(&changed_path_offset, proto_file,
                                        cb->fs, txn_id, changed_paths,
                                        new_rev, subpool));
  svn_pool_clear(subpool);

  /* Append the index data to the rev file. */
  SVN_ERR(svn_fs_x__add_index_data(cb->fs, proto_file,
                      svn_fs_x__path_l2p_proto_index(cb->fs, txn_id, subpool),
                      svn_fs_x__path_p2l_proto_index(cb->fs, txn_id, subpool),
                      new_rev, subpool));
  svn_pool_clear(subpool);

  /* Set the correct permissions. */
  old_rev_filename = svn_fs_x__path_rev_absolute(cb->fs, old_rev, subpool);
  rev_filename = svn_fs_x__path_rev(cb->fs, new_rev, subpool);
  SVN_ERR(svn_io_copy_perms(rev_filename, old_rev_filename, subpool));

  /* Move the revprops file into place. */
  SVN_ERR_ASSERT(! svn_fs_x__is_packed_revprop(cb->fs, new_rev));
  SVN_ERR(write_final_revprop(&revprop_filename, cb->txn, new_rev, batch,
                              subpool, subpool));
  SVN_ERR(svn_io_copy_perms(revprop_filename, old_rev_filename, subpool));
  svn_pool_clear(subpool);

  /* Verify contents (no-op outside DEBUG mode). */
  SVN_ERR(svn_io_file_flush(proto_file, subpool));
  SVN_ERR(verify_as_revision_before_current_plus_plus(cb->fs, new_rev,
                                                      subpool));

  /* Bump 'current'. */
  SVN_ERR(bump_current(cb->fs, new_rev, batch, subpool));

  /* At this point the new revision is committed and globally visible
     so let the caller know it succeeded by giving it the new revision
     number, which fulfills svn_fs_commit_txn() contract.  Any errors
     after this point do not change the fact that a new revision was
     created. */
  *cb->new_rev_p = new_rev;

  ffd->youngest_rev_cache = new_rev;

  /* Make the directory contents already cached for the new revision
   * visible. */
  SVN_ERR(promote_cached_directories(cb->fs, directory_ids, subpool));

  /* Remove this transaction directory. */
  SVN_ERR(svn_fs_x__purge_txn(cb->fs, cb->txn->id, subpool));

  svn_pool_destroy(subpool);
  return SVN_NO_ERROR;
}

/* Add the representations in REPS_TO_CACHE (an array of
 * svn_fs_x__representation_t *) to the rep-cache database of FS. */
static svn_error_t *
write_reps_to_cache(svn_fs_t *fs,
                    const apr_array_header_t *reps_to_cache,
                    apr_pool_t *scratch_pool)
{
  int i;

  for (i = 0; i < reps_to_cache->nelts; i++)
    {
      svn_fs_x__representation_t *rep
        = APR_ARRAY_IDX(reps_to_cache, i, svn_fs_x__representation_t *);

      /* FALSE because we don't care if another parallel commit happened to
       * collide with us.  (Non-parallel collisions will not be detected.) */
      SVN_ERR(svn_fs_x__set_rep_reference(fs, rep, scratch_pool));
    }

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__commit(svn_revnum_t *new_rev_p,
                 svn_fs_t *fs,
                 svn_fs_txn_t *txn,
                 apr_pool_t *scratch_pool)
{
  commit_baton_t cb;
  svn_fs_x__data_t *ffd = fs->fsap_data;

  cb.new_rev_p = new_rev_p;
  cb.fs = fs;
  cb.txn = txn;

  if (ffd->rep_sharing_allowed)
    {
      cb.reps_to_cache = apr_array_make(scratch_pool, 5,
                                        sizeof(svn_fs_x__representation_t *));
      cb.reps_hash = apr_hash_make(scratch_pool);
      cb.reps_pool = scratch_pool;
    }
  else
    {
      cb.reps_to_cache = NULL;
      cb.reps_hash = NULL;
      cb.reps_pool = NULL;
    }

  SVN_ERR(svn_fs_x__with_write_lock(fs, commit_body, &cb, scratch_pool));

  /* At this point, *NEW_REV_P has been set, so errors below won't affect
     the success of the commit.  (See svn_fs_commit_txn().)  */

  if (ffd->rep_sharing_allowed)
    {
      svn_error_t *err;

      SVN_ERR(svn_fs_x__open_rep_cache(fs, scratch_pool));

      /* Write new entries to the rep-sharing database.
       *
       * We use an sqlite transaction to speed things up;
       * see <http://www.sqlite.org/faq.html#q19>.
       */
      /* ### A commit that touches thousands of files will starve other
             (reader/writer) commits for the duration of the below call.
             Maybe write in batches? */
      SVN_ERR(svn_sqlite__begin_transaction(ffd->rep_cache_db));
      err = write_reps_to_cache(fs, cb.reps_to_cache, scratch_pool);
      err = svn_sqlite__finish_transaction(ffd->rep_cache_db, err);

      if (svn_error_find_cause(err, SVN_ERR_SQLITE_ROLLBACK_FAILED))
        {
          /* Failed rollback means that our db connection is unusable, and
             the only thing we can do is close it.  The connection will be
             reopened during the next operation with rep-cache.db. */
          return svn_error_trace(
              svn_error_compose_create(err,
                                       svn_fs_x__close_rep_cache(fs)));
        }
      else if (err)
        return svn_error_trace(err);
    }

  return SVN_NO_ERROR;
}


svn_error_t *
svn_fs_x__list_transactions(apr_array_header_t **names_p,
                            svn_fs_t *fs,
                            apr_pool_t *pool)
{
  const char *txn_dir;
  apr_hash_t *dirents;
  apr_hash_index_t *hi;
  apr_array_header_t *names;
  apr_size_t ext_len = strlen(PATH_EXT_TXN);

  names = apr_array_make(pool, 1, sizeof(const char *));

  /* Get the transactions directory. */
  txn_dir = svn_fs_x__path_txns_dir(fs, pool);

  /* Now find a listing of this directory. */
  SVN_ERR(svn_io_get_dirents3(&dirents, txn_dir, TRUE, pool, pool));

  /* Loop through all the entries and return anything that ends with '.txn'. */
  for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))
    {
      const char *name = apr_hash_this_key(hi);
      apr_ssize_t klen = apr_hash_this_key_len(hi);
      const char *id;

      /* The name must end with ".txn" to be considered a transaction. */
      if ((apr_size_t) klen <= ext_len
          || (strcmp(name + klen - ext_len, PATH_EXT_TXN)) != 0)
        continue;

      /* Truncate the ".txn" extension and store the ID. */
      id = apr_pstrndup(pool, name, strlen(name) - ext_len);
      APR_ARRAY_PUSH(names, const char *) = id;
    }

  *names_p = names;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__open_txn(svn_fs_txn_t **txn_p,
                   svn_fs_t *fs,
                   const char *name,
                   apr_pool_t *pool)
{
  svn_fs_txn_t *txn;
  fs_txn_data_t *ftd;
  svn_node_kind_t kind;
  svn_fs_x__transaction_t *local_txn;
  svn_fs_x__txn_id_t txn_id;

  SVN_ERR(svn_fs_x__txn_by_name(&txn_id, name));

  /* First check to see if the directory exists. */
  SVN_ERR(svn_io_check_path(svn_fs_x__path_txn_dir(fs, txn_id, pool),
                            &kind, pool));

  /* Did we find it? */
  if (kind != svn_node_dir)
    return svn_error_createf(SVN_ERR_FS_NO_SUCH_TRANSACTION, NULL,
                             _("No such transaction '%s'"),
                             name);

  txn = apr_pcalloc(pool, sizeof(*txn));
  ftd = apr_pcalloc(pool, sizeof(*ftd));
  ftd->txn_id = txn_id;

  /* Read in the root node of this transaction. */
  txn->id = apr_pstrdup(pool, name);
  txn->fs = fs;

  SVN_ERR(svn_fs_x__get_txn(&local_txn, fs, txn_id, pool));

  txn->base_rev = local_txn->base_rev;

  txn->vtable = &txn_vtable;
  txn->fsap_data = ftd;
  *txn_p = txn;

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__txn_proplist(apr_hash_t **table_p,
                       svn_fs_txn_t *txn,
                       apr_pool_t *pool)
{
  SVN_ERR(get_txn_proplist(table_p, txn->fs, svn_fs_x__txn_get_id(txn),
                           pool, pool));

  return SVN_NO_ERROR;
}

svn_error_t *
svn_fs_x__delete_node_revision(svn_fs_t *fs,
                               const svn_fs_x__id_t *id,
                               apr_pool_t *scratch_pool)
{
  svn_fs_x__noderev_t *noderev;
  SVN_ERR(svn_fs_x__get_node_revision(&noderev, fs, id, scratch_pool,
                                      scratch_pool));

  /* Delete any mutable property representation. */
  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));

  /* Delete any mutable data representation. */
  if (noderev->data_rep
      && svn_fs_x__is_txn(noderev->data_rep->id.change_set)
      && noderev->kind == svn_node_dir)
    {
      svn_fs_x__data_t *ffd = fs->fsap_data;
      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,
                                                   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,
                                                         scratch_pool),
                             FALSE, scratch_pool);
}



/*** Transactions ***/

svn_error_t *
svn_fs_x__get_base_rev(svn_revnum_t *revnum,
                       svn_fs_t *fs,
                       svn_fs_x__txn_id_t txn_id,
                       apr_pool_t *scratch_pool)
{
  svn_fs_x__transaction_t *txn;
  SVN_ERR(svn_fs_x__get_txn(&txn, fs, txn_id, scratch_pool));
  *revnum = txn->base_rev;

  return SVN_NO_ERROR;
}


/* Generic transaction operations.  */

svn_error_t *
svn_fs_x__txn_prop(svn_string_t **value_p,
                   svn_fs_txn_t *txn,
                   const char *propname,
                   apr_pool_t *pool)
{
  apr_hash_t *table;
  svn_fs_t *fs = txn->fs;

  SVN_ERR(svn_fs__check_fs(fs, TRUE));
  SVN_ERR(svn_fs_x__txn_proplist(&table, txn, pool));

  *value_p = svn_hash_gets(table, propname);

  return SVN_NO_ERROR;
}

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 *result_pool,
                    apr_pool_t *scratch_pool)
{
  svn_string_t date;
  fs_txn_data_t *ftd;
  apr_hash_t *props = apr_hash_make(scratch_pool);

  SVN_ERR(svn_fs__check_fs(fs, TRUE));

  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(), scratch_pool);
  date.len = strlen(date.data);

  svn_hash_sets(props, SVN_PROP_REVISION_DATE, &date);

  /* Set temporary txn props that represent the requested 'flags'
     behaviors. */
  if (flags & SVN_FS_TXN_CHECK_OOD)
    svn_hash_sets(props, SVN_FS__PROP_TXN_CHECK_OOD,
                  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", scratch_pool));

  if (flags & SVN_FS_TXN_CLIENT_DATE)
    svn_hash_sets(props, SVN_FS__PROP_TXN_CLIENT_DATE,
                  svn_string_create("0", scratch_pool));

  ftd = (*txn_p)->fsap_data;
  SVN_ERR(set_txn_proplist(fs, ftd->txn_id, props, scratch_pool));

  return SVN_NO_ERROR;
}
