subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1697403 - in /subversion/trunk/subversion: libsvn_fs_fs/load-index.c tests/libsvn_fs_fs/fs-fs-private-test.c
Date Mon, 24 Aug 2015 14:13:15 GMT
Author: stefan2
Date: Mon Aug 24 14:13:14 2015
New Revision: 1697403

URL: http://svn.apache.org/r1697403
Log:
Make 'svnfsfs load-index' more convenient to use in case the revision
footer is corrupted or missing.  Also, as long as the footer is valid,
make sure the new index actually covers all revision contents.

* subversion/libsvn_fs_fs/load-index.c
  (get_max_covered): New utility function.
  (svn_fs_fs__load_index): In case of a footer parser error, truncate
                           the rev file where the coverage of new index
                           data ends.  Otherwise, require the coverage
                           to be the same as the old index coverage.

* subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
  (load_index): Update test to pass the stricter internal checks.

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/load-index.c
    subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c

Modified: subversion/trunk/subversion/libsvn_fs_fs/load-index.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/load-index.c?rev=1697403&r1=1697402&r2=1697403&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/load-index.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/load-index.c Mon Aug 24 14:13:14 2015
@@ -29,6 +29,20 @@
 #include "util.h"
 #include "transaction.h"
 
+/* From the ENTRIES array of svn_fs_fs__p2l_entry_t*, sorted by offset,
+ * return the first offset behind the last item. */
+static apr_off_t
+get_max_covered(apr_array_header_t *entries)
+{
+  const svn_fs_fs__p2l_entry_t *entry;
+  if (entries->nelts == 0)
+    return -1;
+
+  entry = APR_ARRAY_IDX(entries, entries->nelts - 1,
+                        const svn_fs_fs__p2l_entry_t *);
+  return entry->offset + entry->size;
+}
+
 /* Make sure that the svn_fs_fs__p2l_entry_t* in ENTRIES are consecutive
  * and non-overlapping.  Use SCRATCH_POOL for temporaries. */
 static svn_error_t *
@@ -101,6 +115,8 @@ svn_fs_fs__load_index(svn_fs_t *fs,
       const char *l2p_proto_index;
       const char *p2l_proto_index;
       svn_fs_fs__revision_file_t *rev_file;
+      svn_error_t *err;
+      apr_off_t max_covered = get_max_covered(entries);
 
       /* Ensure that the index data is complete. */
       SVN_ERR(check_all_covered(entries, scratch_pool));
@@ -109,9 +125,33 @@ svn_fs_fs__load_index(svn_fs_t *fs,
       SVN_ERR(svn_fs_fs__open_pack_or_rev_file_writable(&rev_file, fs,
                                                         revision, iterpool,
                                                         iterpool));
-      SVN_ERR(svn_fs_fs__auto_read_footer(rev_file));
-      SVN_ERR(svn_io_file_trunc(rev_file->file, rev_file->l2p_offset,
-                                iterpool));
+
+      /* Remove the existing index info. */
+      err = svn_fs_fs__auto_read_footer(rev_file);
+      if (err)
+        {
+          /* Even the index footer cannot be read, even less be trusted.
+           * Take the range of valid data from the new index data. */
+          svn_error_clear(err);
+          SVN_ERR(svn_io_file_trunc(rev_file->file, max_covered,
+                                    iterpool));
+        }
+      else
+        {
+          /* We assume that the new index data covers all contents.
+           * Error out if it doesn't.  The user can always truncate
+           * the file themselves. */
+          if (max_covered != rev_file->l2p_offset)
+            return svn_error_createf(SVN_ERR_INVALID_INPUT, NULL,
+                       "New index data ends at %s, old index ended at %s",
+                       apr_psprintf(scratch_pool, "%" APR_UINT64_T_HEX_FMT,
+                                    (apr_uint64_t)max_covered),
+                       apr_psprintf(scratch_pool, "%" APR_UINT64_T_HEX_FMT,
+                                    (apr_uint64_t) rev_file->l2p_offset));
+
+          SVN_ERR(svn_io_file_trunc(rev_file->file, rev_file->l2p_offset,
+                                    iterpool));
+        }
 
       /* Create proto index files for the new index data
        * (will be cleaned up automatically with iterpool). */

Modified: subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c?rev=1697403&r1=1697402&r2=1697403&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs_fs/fs-fs-private-test.c Mon Aug 24 14:13:14
2015
@@ -388,10 +388,11 @@ load_index(const svn_test_opts_t *opts,
   SVN_ERR(svn_fs_fs__dump_index(svn_repos_fs(repos), rev, receive_index,
                                 entries, NULL, NULL, pool));
 
-  /* Replace it with an empty index.
-   * Note that the API requires at least one entry. Give it a dummy. */
+  /* Replace it with an index that declares the whole revision contents as
+   * "unused". */
+  entry = *APR_ARRAY_IDX(entries, entries->nelts-1, svn_fs_fs__p2l_entry_t *);
+  entry.size += entry.offset;
   entry.offset = 0;
-  entry.size = 0;
   entry.type = SVN_FS_FS__ITEM_TYPE_UNUSED;
   entry.item.number = SVN_FS_FS__ITEM_INDEX_UNUSED;
   entry.item.revision = SVN_INVALID_REVNUM;



Mime
View raw message