You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2015/08/06 16:04:56 UTC

svn commit: r1694502 [6/6] - in /subversion/trunk: ./ notes/ subversion/include/private/ subversion/libsvn_fs_x/ subversion/libsvn_subr/ subversion/tests/cmdline/ subversion/tests/libsvn_fs/ subversion/tests/libsvn_fs_x/

Modified: subversion/trunk/subversion/libsvn_fs_x/tree.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.h Thu Aug  6 14:04:55 2015
@@ -20,10 +20,11 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS_TREE_H
-#define SVN_LIBSVN_FS_TREE_H
+#ifndef SVN_LIBSVN_FS_X_TREE_H
+#define SVN_LIBSVN_FS_X_TREE_H
 
 #include "fs.h"
+#include "dag.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -31,9 +32,13 @@ extern "C" {
 
 
 
-/* In RESULT_POOL, create an instance of a DAG node 1st level cache. */
-svn_fs_x__dag_cache_t*
-svn_fs_x__create_dag_cache(apr_pool_t *result_pool);
+/* Return the transaction ID to a given transaction ROOT. */
+svn_fs_x__txn_id_t
+svn_fs_x__root_txn_id(svn_fs_root_t *root);
+
+/* Return the change set to a given ROOT. */
+svn_fs_x__change_set_t
+svn_fs_x__root_change_set(svn_fs_root_t *root);
 
 /* Set *ROOT_P to the root directory of revision REV in filesystem FS.
    Allocate the structure in POOL. */
@@ -109,4 +114,4 @@ svn_fs_x__info_config_files(apr_array_he
 }
 #endif /* __cplusplus */
 
-#endif /* SVN_LIBSVN_FS_TREE_H */
+#endif /* SVN_LIBSVN_FS_X_TREE_H */

Modified: subversion/trunk/subversion/libsvn_fs_x/util.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/util.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.c Thu Aug  6 14:04:55 2015
@@ -110,11 +110,24 @@ svn_fs_x__path_current(svn_fs_t *fs,
 }
 
 const char *
+svn_fs_x__path_next(svn_fs_t *fs,
+                       apr_pool_t *result_pool)
+{
+  return svn_dirent_join(fs->path, PATH_NEXT, result_pool);
+}
+
+const char *
 svn_fs_x__path_txn_current(svn_fs_t *fs,
                            apr_pool_t *result_pool)
 {
-  return svn_dirent_join(fs->path, PATH_TXN_CURRENT,
-                         result_pool);
+  return svn_dirent_join(fs->path, PATH_TXN_CURRENT, result_pool);
+}
+
+const char *
+svn_fs_x__path_txn_next(svn_fs_t *fs,
+                           apr_pool_t *result_pool)
+{
+  return svn_dirent_join(fs->path, PATH_TXN_NEXT, result_pool);
 }
 
 const char *
@@ -147,14 +160,12 @@ svn_fs_x__path_revprop_generation(svn_fs
 
 /* Return the full path of the file FILENAME within revision REV's shard in
  * FS.  If FILENAME is NULL, return the shard directory directory itself.
- * REVPROPS indicates the parent of the shard parent folder ("revprops" or
- * "revs").  PACKED says whether we want the packed shard's name.
+ * PACKED says whether we want the packed shard's name.
  *
  * Allocate the result in RESULT_POOL.
  */static const char*
 construct_shard_sub_path(svn_fs_t *fs,
                          svn_revnum_t rev,
-                         svn_boolean_t revprops,
                          svn_boolean_t packed,
                          const char *filename,
                          apr_pool_t *result_pool)
@@ -162,9 +173,6 @@ construct_shard_sub_path(svn_fs_t *fs,
   svn_fs_x__data_t *ffd = fs->fsap_data;
   char buffer[SVN_INT64_BUFFER_SIZE + sizeof(PATH_EXT_PACKED_SHARD)] = { 0 };
 
-  /* Select the appropriate parent path constant. */
-  const char *parent = revprops ? PATH_REVPROPS_DIR : PATH_REVS_DIR;
-
   /* String containing the shard number. */
   apr_size_t len = svn__i64toa(buffer, rev / ffd->max_files_per_dir);
 
@@ -173,7 +181,7 @@ construct_shard_sub_path(svn_fs_t *fs,
     strncpy(buffer + len, PATH_EXT_PACKED_SHARD, sizeof(buffer) - len - 1);
 
   /* This will also work for NULL FILENAME as well. */
-  return svn_dirent_join_many(result_pool, fs->path, parent, buffer,
+  return svn_dirent_join_many(result_pool, fs->path, PATH_REVS_DIR, buffer,
                               filename, SVN_VA_NULL);
 }
 
@@ -184,15 +192,15 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs,
                           apr_pool_t *result_pool)
 {
   assert(svn_fs_x__is_packed_rev(fs, rev));
-  return construct_shard_sub_path(fs, rev, FALSE, TRUE, kind, result_pool);
+  return construct_shard_sub_path(fs, rev, TRUE, kind, result_pool);
 }
 
 const char *
-svn_fs_x__path_rev_shard(svn_fs_t *fs,
-                         svn_revnum_t rev,
-                         apr_pool_t *result_pool)
+svn_fs_x__path_shard(svn_fs_t *fs,
+                     svn_revnum_t rev,
+                     apr_pool_t *result_pool)
 {
-  return construct_shard_sub_path(fs, rev, FALSE, FALSE, NULL, result_pool);
+  return construct_shard_sub_path(fs, rev, FALSE, NULL, result_pool);
 }
 
 const char *
@@ -200,11 +208,12 @@ svn_fs_x__path_rev(svn_fs_t *fs,
                    svn_revnum_t rev,
                    apr_pool_t *result_pool)
 {
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  svn__i64toa(buffer, rev);
+  char buffer[SVN_INT64_BUFFER_SIZE + 1];
+  buffer[0] = 'r';
+  svn__i64toa(buffer + 1, rev);
 
   assert(! svn_fs_x__is_packed_rev(fs, rev));
-  return construct_shard_sub_path(fs, rev, FALSE, FALSE, buffer, result_pool);
+  return construct_shard_sub_path(fs, rev, FALSE, buffer, result_pool);
 }
 
 const char *
@@ -218,19 +227,11 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs
 }
 
 const char *
-svn_fs_x__path_revprops_shard(svn_fs_t *fs,
-                              svn_revnum_t rev,
-                              apr_pool_t *result_pool)
-{
-  return construct_shard_sub_path(fs, rev, TRUE, FALSE, NULL, result_pool);
-}
-
-const char *
-svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
+svn_fs_x__path_pack_shard(svn_fs_t *fs,
                                    svn_revnum_t rev,
                                    apr_pool_t *result_pool)
 {
-  return construct_shard_sub_path(fs, rev, TRUE, TRUE, NULL, result_pool);
+  return construct_shard_sub_path(fs, rev, TRUE, NULL, result_pool);
 }
 
 const char *
@@ -238,11 +239,17 @@ svn_fs_x__path_revprops(svn_fs_t *fs,
                         svn_revnum_t rev,
                         apr_pool_t *result_pool)
 {
-  char buffer[SVN_INT64_BUFFER_SIZE];
-  svn__i64toa(buffer, rev);
+  char buffer[SVN_INT64_BUFFER_SIZE + 1];
+  buffer[0] = 'p';
+  svn__i64toa(buffer + 1, rev);
 
   assert(! svn_fs_x__is_packed_revprop(fs, rev));
-  return construct_shard_sub_path(fs, rev, TRUE, FALSE, buffer, result_pool);
+
+  /* Revprops for packed r0 are not packed, yet stored in the packed shard.
+     Hence, the second flag must check for packed _rev_ - not revprop. */
+  return construct_shard_sub_path(fs, rev,
+                                  svn_fs_x__is_packed_rev(fs, rev) /* sic! */,
+                                  buffer, result_pool);
 }
 
 const char *
@@ -340,14 +347,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
   return construct_txn_path(fs, txn_id, PATH_TXN_PROPS, result_pool);
 }
 
-const char *
-svn_fs_x__path_txn_props_final(svn_fs_t *fs,
-                               svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *result_pool)
-{
-  return construct_txn_path(fs, txn_id, PATH_TXN_PROPS_FINAL, result_pool);
-}
-
 const char*
 svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
                                svn_fs_x__txn_id_t txn_id,
@@ -583,15 +582,20 @@ svn_fs_x__write_current(svn_fs_t *fs,
 {
   char *buf;
   const char *tmp_name, *name;
+  apr_file_t *file;
 
   /* Now we can just write out this line. */
   buf = apr_psprintf(scratch_pool, "%ld\n", rev);
 
   name = svn_fs_x__path_current(fs, scratch_pool);
-  SVN_ERR(svn_io_write_unique(&tmp_name,
-                              svn_dirent_dirname(name, scratch_pool),
-                              buf, strlen(buf),
-                              svn_io_file_del_none, scratch_pool));
+  tmp_name = svn_fs_x__path_next(fs, scratch_pool);
+
+  SVN_ERR(svn_io_file_open(&file, tmp_name,
+                           APR_WRITE | APR_CREATE | APR_BUFFERED,
+                           APR_OS_DEFAULT, scratch_pool));
+  SVN_ERR(svn_io_file_write_full(file, buf, strlen(buf), NULL,
+                                 scratch_pool));
+  SVN_ERR(svn_io_file_close(file, scratch_pool));
 
   return svn_fs_x__move_into_place(tmp_name, name, name, scratch_pool);
 }

Modified: subversion/trunk/subversion/libsvn_fs_x/util.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/util.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.h Thu Aug  6 14:04:55 2015
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__UTIL_H
-#define SVN_LIBSVN_FS__UTIL_H
+#ifndef SVN_LIBSVN_FS_X_UTIL_H
+#define SVN_LIBSVN_FS_X_UTIL_H
 
 #include "svn_fs.h"
 #include "id.h"
@@ -102,6 +102,12 @@ const char *
 svn_fs_x__path_current(svn_fs_t *fs,
                        apr_pool_t *result_pool);
 
+/* Return the path to the 'next' file in FS.
+   Perform allocation in RESULT_POOL. */
+const char *
+svn_fs_x__path_next(svn_fs_t *fs,
+                    apr_pool_t *result_pool);
+
 /* Return the full path of the "uuid" file in FS.
  * The result will be allocated in RESULT_POOL.
  */
@@ -116,6 +122,13 @@ const char *
 svn_fs_x__path_txn_current(svn_fs_t *fs,
                            apr_pool_t *result_pool);
 
+/* Return the full path of the "txn-next" file in FS.
+ * The result will be allocated in RESULT_POOL.
+ */
+const char *
+svn_fs_x__path_txn_next(svn_fs_t *fs,
+                        apr_pool_t *result_pool);
+
 /* Return the full path of the "txn-current-lock" file in FS.
  * The result will be allocated in RESULT_POOL.
  */
@@ -158,9 +171,9 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs,
  * revision REV in FS.  Allocate the result in RESULT_POOL.
  */
 const char *
-svn_fs_x__path_rev_shard(svn_fs_t *fs,
-                         svn_revnum_t rev,
-                         apr_pool_t *result_pool);
+svn_fs_x__path_shard(svn_fs_t *fs,
+                     svn_revnum_t rev,
+                     apr_pool_t *result_pool);
 
 /* Return the full path of the non-packed rev file containing revision REV
  * in FS.  Allocate the result in RESULT_POOL.
@@ -183,23 +196,13 @@ svn_fs_x__path_rev_absolute(svn_fs_t *fs
                             svn_revnum_t rev,
                             apr_pool_t *result_pool);
 
-/* Return the full path of the revision properties shard directory that
- * will contain the properties of revision REV in FS.
- * Allocate the result in RESULT_POOL.
- */
-const char *
-svn_fs_x__path_revprops_shard(svn_fs_t *fs,
-                              svn_revnum_t rev,
-                              apr_pool_t *result_pool);
-
-/* Return the full path of the revision properties pack shard directory
- * that will contain the packed properties of revision REV in FS.
- * Allocate the result in RESULT_POOL.
+/* Return the full path of the pack shard directory that will contain the
+ * packed revision REV in FS.  Allocate the result in RESULT_POOL.
  */
 const char *
-svn_fs_x__path_revprops_pack_shard(svn_fs_t *fs,
-                                   svn_revnum_t rev,
-                                   apr_pool_t *result_pool);
+svn_fs_x__path_pack_shard(svn_fs_t *fs,
+                          svn_revnum_t rev,
+                          apr_pool_t *result_pool);
 
 /* Return the full path of the non-packed revision properties file that
  * contains the props for revision REV in FS.
@@ -287,15 +290,6 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
                          svn_fs_x__txn_id_t txn_id,
                          apr_pool_t *result_pool);
 
-/* Return the path of the file containing the "final" transaction
- * properties for the transaction identified by TXN_ID in FS.
- * The result will be allocated in RESULT_POOL.
- */
-const char *
-svn_fs_x__path_txn_props_final(svn_fs_t *fs,
-                               svn_fs_x__txn_id_t txn_id,
-                               apr_pool_t *result_pool);
-
 /* Return the path of the file containing the node and copy ID counters for
  * the transaction identified by TXN_ID in FS.
  * The result will be allocated in RESULT_POOL.

Modified: subversion/trunk/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/verify.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/verify.c Thu Aug  6 14:04:55 2015
@@ -141,30 +141,27 @@ verify_rep_cache(svn_fs_t *fs,
  * indedx NAME in the error message.  Supports cancellation with CANCEL_FUNC
  * and CANCEL_BATON.  SCRATCH_POOL is for temporary allocations. */
 static svn_error_t *
-verify_index_checksum(apr_file_t *file,
+verify_index_checksum(svn_fs_x__revision_file_t *file,
                       const char *name,
-                      apr_off_t start,
-                      apr_off_t end,
-                      svn_checksum_t *expected,
+                      svn_fs_x__index_info_t *index_info,
                       svn_cancel_func_t cancel_func,
                       void *cancel_baton,
                       apr_pool_t *scratch_pool)
 {
   unsigned char buffer[SVN__STREAM_CHUNK_SIZE];
-  apr_off_t size = end - start;
+  apr_off_t size = index_info->end - index_info->start;
   svn_checksum_t *actual;
   svn_checksum_ctx_t *context
     = svn_checksum_ctx_create(svn_checksum_md5, scratch_pool);
 
   /* Calculate the index checksum. */
-  SVN_ERR(svn_io_file_seek(file, APR_SET, &start, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(file, NULL, index_info->start));
   while (size > 0)
     {
       apr_size_t to_read = size > sizeof(buffer)
                          ? sizeof(buffer)
                          : (apr_size_t)size;
-      SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL,
-                                     scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read));
       SVN_ERR(svn_checksum_update(context, buffer, to_read));
       size -= to_read;
 
@@ -175,12 +172,13 @@ verify_index_checksum(apr_file_t *file,
   SVN_ERR(svn_checksum_final(&actual, context, scratch_pool));
 
   /* Verify that it matches the expected checksum. */
-  if (!svn_checksum_match(expected, actual))
+  if (!svn_checksum_match(index_info->checksum, actual))
     {
       const char *file_name;
 
-      SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
-      SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool,
+      SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
+      SVN_ERR(svn_checksum_mismatch_err(index_info->checksum, actual,
+                                        scratch_pool, 
                                         _("%s checksum mismatch in file %s"),
                                         name, file_name));
     }
@@ -201,20 +199,18 @@ verify_index_checksums(svn_fs_t *fs,
                        apr_pool_t *scratch_pool)
 {
   svn_fs_x__revision_file_t *rev_file;
+  svn_fs_x__index_info_t l2p_index_info;
+  svn_fs_x__index_info_t p2l_index_info;
 
   /* Open the rev / pack file and read the footer */
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start,
-                                          scratch_pool, scratch_pool));
-  SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
+  SVN_ERR(svn_fs_x__rev_file_p2l_info(&p2l_index_info, rev_file));
 
   /* Verify the index contents against the checksum from the footer. */
-  SVN_ERR(verify_index_checksum(rev_file->file, "L2P index",
-                                rev_file->l2p_offset, rev_file->p2l_offset,
-                                rev_file->l2p_checksum,
+  SVN_ERR(verify_index_checksum(rev_file, "L2P index", &l2p_index_info,
                                 cancel_func, cancel_baton, scratch_pool));
-  SVN_ERR(verify_index_checksum(rev_file->file, "P2L index",
-                                rev_file->p2l_offset, rev_file->footer_offset,
-                                rev_file->p2l_checksum,
+  SVN_ERR(verify_index_checksum(rev_file, "P2L index", &p2l_index_info,
                                 cancel_func, cancel_baton, scratch_pool));
 
   /* Done. */
@@ -242,8 +238,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
 
   /* common file access structure */
   svn_fs_x__revision_file_t *rev_file;
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
-                                          iterpool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
 
   /* determine the range of items to check for each revision */
   SVN_ERR(svn_fs_x__l2p_get_max_ids(&max_ids, fs, start, count, scratch_pool,
@@ -334,8 +329,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
 
   /* common file access structure */
   svn_fs_x__revision_file_t *rev_file;
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
-                                          iterpool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
 
   /* get the size of the rev / pack file as covered by the P2L index */
   SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start,
@@ -424,7 +418,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
  * exceed STREAM_THRESHOLD.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-expect_buffer_nul(apr_file_t *file,
+expect_buffer_nul(svn_fs_x__revision_file_t *file,
                   apr_off_t size,
                   apr_pool_t *scratch_pool)
 {
@@ -439,8 +433,7 @@ expect_buffer_nul(apr_file_t *file,
 
   /* read the whole data block; error out on failure */
   data.chunks[(size - 1)/ sizeof(apr_uint64_t)] = 0;
-  SVN_ERR(svn_io_file_read_full2(file, data.buffer, size, NULL, NULL,
-                                 scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_read(file, data.buffer, size));
 
   /* chunky check */
   for (i = 0; i < size / sizeof(apr_uint64_t); ++i)
@@ -454,8 +447,8 @@ expect_buffer_nul(apr_file_t *file,
         const char *file_name;
         apr_off_t offset;
 
-        SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
-        SVN_ERR(svn_fs_x__get_file_offset(&offset, file, scratch_pool));
+        SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
+        SVN_ERR(svn_fs_x__rev_file_offset(&offset, file));
         offset -= size - i;
 
         return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
@@ -472,7 +465,7 @@ expect_buffer_nul(apr_file_t *file,
  * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-read_all_nul(apr_file_t *file,
+read_all_nul(svn_fs_x__revision_file_t *file,
              apr_off_t size,
              apr_pool_t *scratch_pool)
 {
@@ -490,7 +483,7 @@ read_all_nul(apr_file_t *file,
  * in error message.  Allocate temporary data in SCRATCH_POOL.
  */
 static svn_error_t *
-expected_checksum(apr_file_t *file,
+expected_checksum(svn_fs_x__revision_file_t *file,
                   svn_fs_x__p2l_entry_t *entry,
                   apr_uint32_t actual,
                   apr_pool_t *scratch_pool)
@@ -499,8 +492,7 @@ expected_checksum(apr_file_t *file,
     {
       const char *file_name;
 
-      SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
-      SVN_ERR(svn_io_file_name_get(&file_name, file, scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool));
       return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                _("Checksum mismatch in item at offset %s of "
                                  "length %s bytes in file %s"),
@@ -517,15 +509,14 @@ expected_checksum(apr_file_t *file,
  * exceed STREAM_THRESHOLD.  Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-expected_buffered_checksum(apr_file_t *file,
+expected_buffered_checksum(svn_fs_x__revision_file_t *file,
                            svn_fs_x__p2l_entry_t *entry,
                            apr_pool_t *scratch_pool)
 {
   unsigned char buffer[STREAM_THRESHOLD];
   SVN_ERR_ASSERT(entry->size <= STREAM_THRESHOLD);
 
-  SVN_ERR(svn_io_file_read_full2(file, buffer, (apr_size_t)entry->size,
-                                 NULL, NULL, scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_read(file, buffer, (apr_size_t)entry->size));
   SVN_ERR(expected_checksum(file, entry,
                             svn__fnv1a_32x4(buffer, (apr_size_t)entry->size),
                             scratch_pool));
@@ -538,7 +529,7 @@ expected_buffered_checksum(apr_file_t *f
  * Use SCRATCH_POOL for temporary allocations.
  */
 static svn_error_t *
-expected_streamed_checksum(apr_file_t *file,
+expected_streamed_checksum(svn_fs_x__revision_file_t *file,
                            svn_fs_x__p2l_entry_t *entry,
                            apr_pool_t *scratch_pool)
 {
@@ -553,8 +544,7 @@ expected_streamed_checksum(apr_file_t *f
       apr_size_t to_read = size > sizeof(buffer)
                          ? sizeof(buffer)
                          : (apr_size_t)size;
-      SVN_ERR(svn_io_file_read_full2(file, buffer, to_read, NULL, NULL,
-                                     scratch_pool));
+      SVN_ERR(svn_fs_x__rev_file_read(file, buffer, to_read));
       SVN_ERR(svn_checksum_update(context, buffer, to_read));
       size -= to_read;
     }
@@ -588,28 +578,27 @@ compare_p2l_to_rev(svn_fs_t *fs,
   apr_off_t max_offset;
   apr_off_t offset = 0;
   svn_fs_x__revision_file_t *rev_file;
+  svn_fs_x__index_info_t l2p_index_info;
 
   /* open the pack / rev file that is covered by the p2l index */
-  SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, scratch_pool,
-                                          iterpool));
+  SVN_ERR(svn_fs_x__rev_file_init(&rev_file, fs, start, scratch_pool));
 
   /* check file size vs. range covered by index */
-  SVN_ERR(svn_fs_x__auto_read_footer(rev_file));
+  SVN_ERR(svn_fs_x__rev_file_l2p_info(&l2p_index_info, rev_file));
   SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, rev_file, start,
                                        scratch_pool));
 
-  if (rev_file->l2p_offset != max_offset)
+  if (l2p_index_info.start != max_offset)
     return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL,
                              _("File size of %s for revision r%ld does "
                                "not match p2l index size of %s"),
                              apr_off_t_toa(scratch_pool,
-                                           rev_file->l2p_offset),
+                                           l2p_index_info.start),
                              start,
                              apr_off_t_toa(scratch_pool,
                                            max_offset));
 
-  SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, NULL, 0,
-                                   scratch_pool));
+  SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, 0));
 
   /* for all offsets in the file, get the P2L index entries and check
      them against the L2P index */
@@ -627,8 +616,7 @@ compare_p2l_to_rev(svn_fs_t *fs,
 
       /* The above might have moved the file pointer.
        * Ensure we actually start reading at OFFSET.  */
-      SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size,
-                                       NULL, offset, iterpool));
+      SVN_ERR(svn_fs_x__rev_file_seek(rev_file, NULL, offset));
 
       /* process all entries (and later continue with the next block) */
       for (i = 0; i < entries->nelts; ++i)
@@ -661,15 +649,15 @@ compare_p2l_to_rev(svn_fs_t *fs,
             {
               /* skip filler entry at the end of the p2l index */
               if (entry->offset != max_offset)
-                SVN_ERR(read_all_nul(rev_file->file, entry->size, iterpool));
+                SVN_ERR(read_all_nul(rev_file, entry->size, iterpool));
             }
           else
             {
               if (entry->size < STREAM_THRESHOLD)
-                SVN_ERR(expected_buffered_checksum(rev_file->file, entry,
+                SVN_ERR(expected_buffered_checksum(rev_file, entry,
                                                    iterpool));
               else
-                SVN_ERR(expected_streamed_checksum(rev_file->file, entry,
+                SVN_ERR(expected_streamed_checksum(rev_file, entry,
                                                    iterpool));
             }
 

Modified: subversion/trunk/subversion/libsvn_fs_x/verify.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/verify.h?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/verify.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/verify.h Thu Aug  6 14:04:55 2015
@@ -1,4 +1,4 @@
-/* verify.h : verification interface of the native filesystem layer
+/* verify.h : verification interface of the FSX filesystem
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -20,8 +20,8 @@
  * ====================================================================
  */
 
-#ifndef SVN_LIBSVN_FS__VERIFY_H
-#define SVN_LIBSVN_FS__VERIFY_H
+#ifndef SVN_LIBSVN_FS_X_VERIFY_H
+#define SVN_LIBSVN_FS_X_VERIFY_H
 
 #include "fs.h"
 

Modified: subversion/trunk/subversion/libsvn_subr/mutex.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/mutex.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/mutex.c (original)
+++ subversion/trunk/subversion/libsvn_subr/mutex.c Thu Aug  6 14:04:55 2015
@@ -105,3 +105,13 @@ svn_mutex__unlock(svn_mutex__t *mutex,
 
   return err;
 }
+
+#if APR_HAS_THREADS
+
+apr_thread_mutex_t *
+svn_mutex__get(svn_mutex__t *mutex)
+{
+  return mutex->mutex;
+}
+
+#endif

Modified: subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py Thu Aug  6 14:04:55 2015
@@ -2743,7 +2743,10 @@ def verify_quickly(sbox):
   "verify quickly using metadata"
 
   sbox.build(create_wc = False)
-  rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
+  if svntest.main.is_fs_type_fsfs():
+    rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
+  else:
+    rev_file = open(fsfs_file(sbox.repo_dir, 'revs', 'r1'), 'r+b')
 
   # set new contents
   rev_file.seek(8)

Modified: subversion/trunk/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs/fs-test.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs/fs-test.c Thu Aug  6 14:04:55 2015
@@ -5345,20 +5345,20 @@ test_fs_info_format(const svn_test_opts_
   int fs_format;
   svn_version_t *supports_version;
   svn_version_t v1_5_0 = {1, 5, 0, ""};
-  svn_version_t v1_9_0 = {1, 9, 0, ""};
+  svn_version_t v1_10_0 = {1, 10, 0, ""};
   svn_test_opts_t opts2;
   svn_boolean_t is_fsx = strcmp(opts->fs_type, "fsx") == 0;
 
   opts2 = *opts;
-  opts2.server_minor_version = is_fsx ? 9 : 5;
+  opts2.server_minor_version = is_fsx ? 10 : 5;
 
   SVN_ERR(svn_test__create_fs(&fs, "test-fs-format-info", &opts2, pool));
   SVN_ERR(svn_fs_info_format(&fs_format, &supports_version, fs, pool, pool));
 
   if (is_fsx)
     {
-      SVN_TEST_ASSERT(fs_format == 1);
-      SVN_TEST_ASSERT(svn_ver_equal(supports_version, &v1_9_0));
+      SVN_TEST_ASSERT(fs_format == 2);
+      SVN_TEST_ASSERT(svn_ver_equal(supports_version, &v1_10_0));
     }
   else
     {

Propchange: subversion/trunk/subversion/tests/libsvn_fs_x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Thu Aug  6 14:04:55 2015
@@ -20,6 +20,7 @@
 /subversion/branches/fsfs-lock-many/subversion/tests/libsvn_fs_x:1571740-1577217
 /subversion/branches/fsfs-pack/subversion/tests/libsvn_fs_x:873717-874575
 /subversion/branches/fsx/subversion/tests/libsvn_fs_x:1507845-1508076
+/subversion/branches/fsx-1.10/subversion/tests/libsvn_fs_x:1658219-1694500
 /subversion/branches/gnome-keyring/subversion/tests/libsvn_fs_x:870558-871410
 /subversion/branches/gpg-agent-password-store/subversion/tests/libsvn_fs_x:1005036-1150766
 /subversion/branches/gtest_addition/subversion/tests/libsvn_fs_x:1452117-1502138

Modified: subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c?rev=1694502&r1=1694501&r2=1694502&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs_x/fs-x-pack-test.c Thu Aug  6 14:04:55 2015
@@ -25,6 +25,7 @@
 #include <apr_pools.h>
 
 #include "../svn_test.h"
+#include "../../libsvn_fs_x/batch_fsync.h"
 #include "../../libsvn_fs_x/fs.h"
 #include "../../libsvn_fs_x/reps.h"
 
@@ -657,8 +658,8 @@ recover_fully_packed(const svn_test_opts
   /* Now, delete the youngest revprop file, and recover again.  This
      time we want to see an error! */
   SVN_ERR(svn_io_remove_file2(
-              svn_dirent_join_many(pool, REPO_NAME, PATH_REVPROPS_DIR,
-                                   apr_psprintf(pool, "%ld/%ld",
+              svn_dirent_join_many(pool, REPO_NAME, PATH_REVS_DIR,
+                                   apr_psprintf(pool, "%ld/p%ld",
                                                 after_rev / SHARD_SIZE,
                                                 after_rev),
                                    SVN_VA_NULL),
@@ -844,6 +845,87 @@ pack_shard_size_one(const svn_test_opts_
 #undef SHARD_SIZE
 #undef MAX_REV
 /* ------------------------------------------------------------------------ */
+#define REPO_NAME "test-repo-fsx-batch-fsync"
+static svn_error_t *
+test_batch_fsync(const svn_test_opts_t *opts,
+                 apr_pool_t *pool)
+{
+  const char *abspath;
+  svn_fs_x__batch_fsync_t *batch;
+  int i;
+
+  /* Create an empty working directory and let it be cleaned up by the test
+   * harness. */
+  SVN_ERR(svn_dirent_get_absolute(&abspath, REPO_NAME, pool));
+
+  SVN_ERR(svn_io_remove_dir2(abspath, TRUE, NULL, NULL, pool));
+  SVN_ERR(svn_io_make_dir_recursively(abspath, pool));
+  svn_test_add_dir_cleanup(abspath);
+
+  /* Initialize infrastructure with a pool that lives as long as this
+   * application. */
+  SVN_ERR(svn_fs_x__batch_fsync_init());
+
+  /* We use and re-use the same batch object throughout this test. */
+  SVN_ERR(svn_fs_x__batch_fsync_create(&batch, pool));
+
+  /* The working directory is new. */
+  SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, abspath, pool));
+
+  /* 1st run: Has to fire up worker threads etc. */
+  for (i = 0; i < 10; ++i)
+    {
+      apr_file_t *file;
+      const char *path = svn_dirent_join(abspath,
+                                         apr_psprintf(pool, "file%i", i),
+                                         pool);
+      apr_size_t len = strlen(path);
+
+      SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, pool));
+      SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, path, pool));
+
+      SVN_ERR(svn_io_file_write(file, path, &len, pool));
+    }
+
+  SVN_ERR(svn_fs_x__batch_fsync_run(batch, pool));
+
+  /* 2nd run: Running a batch must leave the container in an empty,
+   * re-usable state. Hence, try to re-use it. */
+  for (i = 0; i < 10; ++i)
+    {
+      apr_file_t *file;
+      const char *path = svn_dirent_join(abspath,
+                                         apr_psprintf(pool, "new%i", i),
+                                         pool);
+      apr_size_t len = strlen(path);
+
+      SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, pool));
+      SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, path, pool));
+
+      SVN_ERR(svn_io_file_write(file, path, &len, pool));
+    }
+
+  SVN_ERR(svn_fs_x__batch_fsync_run(batch, pool));
+
+  /* 3rd run: Schedule but don't execute. POOL cleanup shall not fail. */
+  for (i = 0; i < 10; ++i)
+    {
+      apr_file_t *file;
+      const char *path = svn_dirent_join(abspath,
+                                         apr_psprintf(pool, "another%i", i),
+                                         pool);
+      apr_size_t len = strlen(path);
+
+      SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, pool));
+      SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, path, pool));
+
+      SVN_ERR(svn_io_file_write(file, path, &len, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+#undef REPO_NAME
+/* ------------------------------------------------------------------------ */
 
 /* The test table.  */
 
@@ -876,6 +958,8 @@ static struct svn_test_descriptor_t test
                        "test representations container"),
     SVN_TEST_OPTS_PASS(pack_shard_size_one,
                        "test packing with shard size = 1"),
+    SVN_TEST_OPTS_PASS(test_batch_fsync,
+                       "test batch fsync"),
     SVN_TEST_NULL
   };