subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1636627 - in /subversion/trunk/subversion/libsvn_fs_x: ./ caching.c fs.c fs.h fs_x.c hotcopy.c index.c lock.c low_level.c recovery.c rev_file.c temp_serializer.c transaction.c util.h verify.c
Date Tue, 04 Nov 2014 16:07:34 GMT
Author: stefan2
Date: Tue Nov  4 16:07:33 2014
New Revision: 1636627

URL: http://svn.apache.org/r1636627
Log:
Sync FSX with FSFS:  Merge assorted fixes and improvements from libsvn_fs_fs
and resolve the usual conflicts with FSX.  The merged revisions are:

r1605633 - remove obsolete race handling between 'hotcopy' and 'pack'
r1616613 - improve config file documentation
r1620930 - reintroduce SVN_FS_FS__USE_LOCK_MUTEX conditional flag
r1622946 - fix rev/pack file open retry after pack
r1623368 - factor out some common code into svn_fs_fs__packed_base_rev()
r1623381 - bump instance ID upon recover
r1623402 - don't use instance IDs as part of the cache keys
r1626246 - fix some compiler warnings
r1627949 - make sure to detect format upgrades before committing
r1628161 - add missing error tracing
r1628393, r1628415 - fix compiler warnings in index.c
r1632908 - fix error leak

Modified:
    subversion/trunk/subversion/libsvn_fs_x/   (props changed)
    subversion/trunk/subversion/libsvn_fs_x/caching.c
    subversion/trunk/subversion/libsvn_fs_x/fs.c
    subversion/trunk/subversion/libsvn_fs_x/fs.h
    subversion/trunk/subversion/libsvn_fs_x/fs_x.c
    subversion/trunk/subversion/libsvn_fs_x/hotcopy.c
    subversion/trunk/subversion/libsvn_fs_x/index.c
    subversion/trunk/subversion/libsvn_fs_x/lock.c
    subversion/trunk/subversion/libsvn_fs_x/low_level.c
    subversion/trunk/subversion/libsvn_fs_x/recovery.c
    subversion/trunk/subversion/libsvn_fs_x/rev_file.c
    subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c
    subversion/trunk/subversion/libsvn_fs_x/transaction.c
    subversion/trunk/subversion/libsvn_fs_x/util.h
    subversion/trunk/subversion/libsvn_fs_x/verify.c

Propchange: subversion/trunk/subversion/libsvn_fs_x/
------------------------------------------------------------------------------
  Merged /subversion/trunk/subversion/libsvn_fs_fs:r1605633,1616613,1620930,1622946,1623368,1623381,1623402,1626246,1627949,1628161,1628393,1628415,1632908

Modified: subversion/trunk/subversion/libsvn_fs_x/caching.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/caching.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/caching.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/caching.c Tue Nov  4 16:07:33 2014
@@ -362,7 +362,6 @@ svn_fs_x__initialize_caches(svn_fs_t *fs
   fs_x_data_t *ffd = fs->fsap_data;
   const char *prefix = apr_pstrcat(pool,
                                    "fsx:", fs->uuid,
-                                   ":", ffd->instance_id,
                                    "/", normalize_key_part(fs->path, pool),
                                    ":",
                                    SVN_VA_NULL);

Modified: subversion/trunk/subversion/libsvn_fs_x/fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs.c Tue Nov  4 16:07:33 2014
@@ -108,13 +108,16 @@ x_serialized_init(svn_fs_t *fs, apr_pool
       /* POSIX fcntl locks are per-process, so we need a mutex for
          intra-process synchronization when grabbing the repository write
          lock. */
-      SVN_ERR(svn_mutex__init(&ffsd->fs_write_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->fs_write_lock,
+                              SVN_FS_X__USE_LOCK_MUTEX, common_pool));
 
       /* ... the pack lock ... */
-      SVN_ERR(svn_mutex__init(&ffsd->fs_pack_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->fs_pack_lock,
+                              SVN_FS_X__USE_LOCK_MUTEX, common_pool));
 
       /* ... not to mention locking the txn-current file. */
-      SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock, TRUE, common_pool));
+      SVN_ERR(svn_mutex__init(&ffsd->txn_current_lock,
+                              SVN_FS_X__USE_LOCK_MUTEX, common_pool));
 
       /* We also need a mutex for synchronizing access to the active
          transaction list and free transaction pointer. */
@@ -532,7 +535,7 @@ x_delete_fs(const char *path,
             apr_pool_t *pool)
 {
   /* Remove everything. */
-  return svn_io_remove_dir2(path, FALSE, NULL, NULL, pool);
+  return svn_error_trace(svn_io_remove_dir2(path, FALSE, NULL, NULL, pool));
 }
 
 static const svn_version_t *

Modified: subversion/trunk/subversion/libsvn_fs_x/fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs.h?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs.h Tue Nov  4 16:07:33 2014
@@ -126,6 +126,16 @@ extern "C" {
  */
 #define SVN_FS_X__FORMAT_NUMBER   1
 
+/* On most operating systems apr implements file locks per process, not
+   per file.  On Windows apr implements the locking as per file handle
+   locks, so we don't have to add our own mutex for just in-process
+   synchronization. */
+#if APR_HAS_THREADS && !defined(WIN32)
+#define SVN_FS_X__USE_LOCK_MUTEX 1
+#else
+#define SVN_FS_X__USE_LOCK_MUTEX 0
+#endif
+
 /* Private FSX-specific data shared between all svn_txn_t objects that
    relate to a particular transaction in a filesystem (as identified
    by transaction id and filesystem UUID).  Objects of this type are
@@ -245,9 +255,11 @@ typedef struct fs_x_data_t
   /* The maximum number of files to store per directory. */
   int max_files_per_dir;
 
-  /* Rev / pack file read granularity. */
+  /* Rev / pack file read granularity in bytes. */
   apr_int64_t block_size;
 
+  /* Rev / pack file granularity (in bytes) covered by a single phys-to-log
+   * index page. */
   /* Capacity in entries of log-to-phys index pages */
   apr_int64_t l2p_page_size;
 

Modified: subversion/trunk/subversion/libsvn_fs_x/fs_x.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs_x.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs_x.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs_x.c Tue Nov  4 16:07:33 2014
@@ -306,6 +306,7 @@ read_config(fs_x_data_t *ffd,
   /* convert kBytes to bytes */
   ffd->block_size *= 0x400;
   ffd->p2l_page_size *= 0x400;
+  /* L2P pages are in entries - not in (k)Bytes */
 
   /* Debug options. */
   SVN_ERR(svn_config_get_bool(config, &ffd->pack_after_commit,
@@ -471,7 +472,7 @@ write_config(svn_fs_t *fs,
 "### For SSD-based storage systems, slightly lower values around 16 kB"      NL
 "### may improve latency while still maximizing throughput."                 NL
 "### Can be changed at any time but must be a power of 2."                   NL
-"### block-size is 64 kBytes by default."                                    NL
+"### block-size is given in kBytes and with a default of 64 kBytes."         NL
 "# " CONFIG_OPTION_BLOCK_SIZE " = 64"                                        NL
 "###"                                                                        NL
 "### The log-to-phys index maps data item numbers to offsets within the"     NL
@@ -499,7 +500,7 @@ write_config(svn_fs_t *fs,
 "### smaller changes."                                                       NL
 "### For source code repositories, this should be about 16x the block-size." NL
 "### Must be a power of 2."                                                  NL
-"### p2l-page-size is 1024 kBytes by default."                               NL
+"### p2l-page-size is given in kBytes and with a default of 1024 kBytes."    NL
 "# " CONFIG_OPTION_P2L_PAGE_SIZE " = 1024"                                   NL
 ;
 #undef NL
@@ -1019,6 +1020,7 @@ svn_fs_x__create(svn_fs_t *fs,
         }
     }
 
+  /* Actual FS creation. */
   SVN_ERR(svn_fs_x__create_file_tree(fs, path, format,
                                      SVN_FS_X_DEFAULT_MAX_FILES_PER_DIR,
                                      pool));

Modified: subversion/trunk/subversion/libsvn_fs_x/hotcopy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/hotcopy.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/hotcopy.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/hotcopy.c Tue Nov  4 16:07:33 2014
@@ -655,7 +655,6 @@ hotcopy_revisions(svn_fs_t *src_fs,
    * If necessary, update 'current' after copying all files from a shard. */
   for (; rev <= src_youngest; rev++)
     {
-      svn_error_t *err;
       svn_boolean_t skipped = TRUE;
 
       svn_pool_clear(iterpool);
@@ -663,55 +662,22 @@ hotcopy_revisions(svn_fs_t *src_fs,
       if (cancel_func)
         SVN_ERR(cancel_func(cancel_baton));
 
-      /* Copy the rev file. */
-      err = hotcopy_copy_shard_file(&skipped, src_revs_dir, dst_revs_dir,
-                                    rev, max_files_per_dir,
-                                    iterpool);
-      if (err)
-        {
-          if (APR_STATUS_IS_ENOENT(err->apr_err))
-            {
-              svn_error_clear(err);
+      /* Copying non-packed revisions is racy in case the source repository is
+       * being packed concurrently with this hotcopy operation.  With the pack
+       * lock, however, the race is impossible, because hotcopy and pack
+       * operations block each other.
+       *
+       * We assume that all revisions coming after 'min-unpacked-rev' really
+       * are unpacked and that's not necessarily true with concurrent packing.
+       * Don't try to be smart in this edge case, because handling it properly
+       * might require copying *everything* from the start. Just abort the
+       * hotcopy with an ENOENT (revision file moved to a pack, so it is no
+       * longer where we expect it to be). */
 
-              /* The source rev file does not exist. This can happen if the
-               * source repository is being packed concurrently with this
-               * hotcopy operation.
-               *
-               * If the new revision is now packed, and the youngest revision
-               * we're interested in is not inside this pack, try to copy the
-               * pack instead.
-               *
-               * If the youngest revision ended up being packed, don't try
-               * to be smart and work around this. Just abort the hotcopy. */
-              SVN_ERR(svn_fs_x__update_min_unpacked_rev(src_fs, pool));
-              if (svn_fs_x__is_packed_rev(src_fs, rev))
-                {
-                  if (svn_fs_x__is_packed_rev(src_fs, src_youngest))
-                    return svn_error_createf(
-                             SVN_ERR_FS_NO_SUCH_REVISION, NULL,
-                             _("The assumed HEAD revision (%lu) of the "
-                               "hotcopy source has been packed while the "
-                               "hotcopy was in progress; please restart "
-                               "the hotcopy operation"),
-                             src_youngest);
-
-                  SVN_ERR(hotcopy_copy_packed_shard(&skipped,
-                                                    &dst_min_unpacked_rev,
-                                                    src_fs, dst_fs,
-                                                    rev, max_files_per_dir,
-                                                    iterpool));
-                  rev = dst_min_unpacked_rev;
-                  continue;
-                }
-              else
-                return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
-                                         _("Revision %lu disappeared from the "
-                                           "hotcopy source while hotcopy was "
-                                           "in progress"), rev);
-            }
-          else
-            return svn_error_trace(err);
-        }
+      /* Copy the rev file. */
+      SVN_ERR(hotcopy_copy_shard_file(&skipped, src_revs_dir, dst_revs_dir,
+                                      rev, max_files_per_dir,
+                                      iterpool));
 
       /* Copy the revprop file. */
       SVN_ERR(hotcopy_copy_shard_file(&skipped, src_revprops_dir,

Modified: subversion/trunk/subversion/libsvn_fs_x/index.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/index.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/index.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/index.c Tue Nov  4 16:07:33 2014
@@ -280,11 +280,11 @@ packed_stream_read(svn_fs_x__packed_numb
   read = sizeof(buffer);
   block_left = stream->block_size - (stream->next_offset - block_start);
   if (block_left >= 10 && block_left < read)
-    read = block_left;
+    read = (apr_size_t)block_left;
 
   /* Don't read beyond the end of the file section that belongs to this
    * index / stream. */
-  read = MIN(read, stream->stream_end - stream->next_offset);
+  read = (apr_size_t)MIN(read, stream->stream_end - stream->next_offset);
 
   err = apr_file_read(stream->file, buffer, &read);
   if (err && !APR_STATUS_IS_EOF(err))
@@ -958,8 +958,11 @@ svn_fs_x__l2p_index_append(svn_checksum_
           int entry_count = 0;
           for (i = 0; i < entries->nelts; i += entry_count)
             {
-              /* 1 page with up to 8k entries */
-              apr_size_t last_buffer_size = svn_spillbuf__get_size(buffer);
+              /* 1 page with up to L2P_PAGE_SIZE entries.
+               * fsfs.conf settings validation guarantees this to fit into
+               * our address space. */
+              apr_size_t last_buffer_size
+                = (apr_size_t)svn_spillbuf__get_size(buffer);
 
               svn_pool_clear(iterpool);
 
@@ -1260,11 +1263,12 @@ get_l2p_header_body(l2p_header_t **heade
 {
   fs_x_data_t *ffd = fs->fsap_data;
   apr_uint64_t value;
-  int i;
+  apr_size_t i;
   apr_size_t page, page_count;
   apr_off_t offset;
   l2p_header_t *result = apr_pcalloc(result_pool, sizeof(*result));
   apr_size_t page_table_index;
+  svn_revnum_t next_rev;
   apr_array_header_t *expanded_values
     = apr_array_make(scratch_pool, 16, sizeof(apr_uint64_t));
 
@@ -1305,12 +1309,11 @@ get_l2p_header_body(l2p_header_t **heade
     return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                             _("L2P index page count implausibly large"));
 
-  if (   result->first_revision > revision
-      || result->first_revision + result->revision_count <= revision)
+  next_rev = result->first_revision + (svn_revnum_t)result->revision_count;
+  if (result->first_revision > revision || next_rev <= revision)
     return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                       _("Corrupt L2P index for r%ld only covers r%ld:%ld"),
-                      revision, result->first_revision,
-                      result->first_revision + result->revision_count);
+                      revision, result->first_revision, next_rev);
 
   /* allocate the page tables */
   result->page_table
@@ -1701,6 +1704,17 @@ prefetch_l2p_pages(svn_boolean_t *end,
   apr_pool_t *iterpool;
   svn_fs_x__page_cache_key_t key = { 0 };
 
+  /* Parameter check. */
+  if (min_offset < 0)
+    min_offset = 0;
+
+  if (max_offset <= 0)
+    {
+      /* Nothing to do */
+      *end = TRUE;
+      return SVN_NO_ERROR;
+    }
+
   /* get the page table for REVISION from cache */
   *end = FALSE;
   SVN_ERR(get_l2p_page_table(pages, fs, revision, scratch_pool));
@@ -1730,8 +1744,8 @@ prefetch_l2p_pages(svn_boolean_t *end,
         continue;
 
       /* skip pages outside the specified index file range */
-      if (   entry->offset < min_offset
-          || entry->offset + entry->size > max_offset)
+      if (   entry->offset < (apr_uint64_t)min_offset
+          || entry->offset + entry->size > (apr_uint64_t)max_offset)
         {
           *end = TRUE;
           continue;
@@ -1809,7 +1823,7 @@ l2p_index_lookup(apr_off_t *offset,
       svn_revnum_t prefetch_revision;
       svn_revnum_t last_revision
         = info_baton.first_revision
-          + (key.is_packed ? ffd->max_files_per_dir : 1);
+          + svn_fs_x__pack_size(fs, info_baton.first_revision);
       apr_pool_t *iterpool = svn_pool_create(scratch_pool);
       svn_boolean_t end;
       apr_off_t max_offset
@@ -2431,13 +2445,15 @@ p2l_page_info_copy(p2l_page_info_baton_t
    */
   if (baton->offset / header->page_size < header->page_count)
     {
-      baton->page_no = baton->offset / header->page_size;
+      /* This cast is safe because the value is < header->page_count. */
+      baton->page_no = (apr_size_t)(baton->offset / header->page_size);
       baton->start_offset = offsets[baton->page_no];
       baton->next_offset = offsets[baton->page_no + 1];
       baton->page_size = header->page_size;
     }
   else
     {
+      /* Beyond the last page. */
       baton->page_no = header->page_count;
       baton->start_offset = offsets[baton->page_no];
       baton->next_offset = offsets[baton->page_no];
@@ -2516,7 +2532,7 @@ get_p2l_header(p2l_header_t **header,
 
   SVN_ERR(packed_stream_get(&value, rev_file->p2l_stream));
   result->file_size = value;
-  if (result->file_size != rev_file->l2p_offset)
+  if (result->file_size != (apr_uint64_t)rev_file->l2p_offset)
     return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                    _("Index offset and rev / pack file size do not match"));
 
@@ -2532,8 +2548,8 @@ get_p2l_header(p2l_header_t **header,
     return svn_error_create(SVN_ERR_FS_INDEX_CORRUPTION, NULL,
                    _("P2L page count does not match rev / pack file size"));
 
-  result->offsets = apr_pcalloc(result_pool, (result->page_count + 1)
-                                           * sizeof(*result->offsets));
+  result->offsets
+    = apr_pcalloc(result_pool, (result->page_count + 1) * sizeof(*result->offsets));
 
   /* read page sizes and derive page description offsets from them */
   result->offsets[0] = 0;

Modified: subversion/trunk/subversion/libsvn_fs_x/lock.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/lock.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/lock.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/lock.c Tue Nov  4 16:07:33 2014
@@ -386,7 +386,8 @@ add_to_digest(const char *fs_path,
   const char *index_digest_path;
   apr_hash_t *children;
   svn_lock_t *lock;
-  int i, original_count;
+  int i;
+  unsigned int original_count;
 
   SVN_ERR(digest_path_from_path(&index_digest_path, fs_path, index_path, pool));
 

Modified: subversion/trunk/subversion/libsvn_fs_x/low_level.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/low_level.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/low_level.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/low_level.c Tue Nov  4 16:07:33 2014
@@ -186,8 +186,8 @@ read_header_block(apr_hash_t **headers,
     {
       svn_stringbuf_t *header_str;
       const char *name, *value;
-      apr_ssize_t i = 0;
-      apr_ssize_t name_len;
+      apr_size_t i = 0;
+      apr_size_t name_len;
       svn_boolean_t eof;
 
       SVN_ERR(svn_stream_readline(stream, &header_str, "\n", &eof,
@@ -211,13 +211,10 @@ read_header_block(apr_hash_t **headers,
       name = header_str->data;
       name_len = i;
 
-      /* Skip over the NULL byte and the space following it. */
-      i += 2;
-
-      if (i > header_str->len)
+      /* Check if we have enough data to parse. */
+      if (i + 2 > header_str->len)
         {
           /* Restore the original line for the error. */
-          i -= 2;
           header_str->data[i] = ':';
           return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                    _("Found malformed header '%s' in "
@@ -225,6 +222,9 @@ read_header_block(apr_hash_t **headers,
                                    header_str->data);
         }
 
+      /* Skip over the NULL byte and the space following it. */
+      i += 2;
+
       value = header_str->data + i;
 
       /* header_str is safely in our pool, so we can use bits of it as

Modified: subversion/trunk/subversion/libsvn_fs_x/recovery.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/recovery.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/recovery.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/recovery.c Tue Nov  4 16:07:33 2014
@@ -126,6 +126,11 @@ recover_body(void *baton, apr_pool_t *po
   /* Lose potentially corrupted data in temp files */
   SVN_ERR(svn_fs_x__reset_revprop_generation_file(fs, pool));
 
+  /* The admin may have created a plain copy of this repo before attempting
+     to recover it (hotcopy may or may not work with corrupted repos).
+     Bump the instance ID. */
+  SVN_ERR(svn_fs_x__set_uuid(fs, fs->uuid, NULL, pool));
+
   /* We need to know the largest revision in the filesystem. */
   SVN_ERR(recover_get_largest_revision(fs, &max_rev, pool));
 

Modified: subversion/trunk/subversion/libsvn_fs_x/rev_file.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/rev_file.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/rev_file.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/rev_file.c Tue Nov  4 16:07:33 2014
@@ -66,13 +66,10 @@ init_revision_file(svn_fs_t *fs,
                    svn_revnum_t revision,
                    apr_pool_t *result_pool)
 {
-  fs_x_data_t *ffd = fs->fsap_data;
   svn_fs_x__revision_file_t *file = create_revision_file(fs, result_pool);
 
   file->is_packed = svn_fs_x__is_packed_rev(fs, revision);
-  file->start_revision = revision < ffd->min_unpacked_rev
-                       ? revision - (revision % ffd->max_files_per_dir)
-                       : revision;
+  file->start_revision = svn_fs_x__packed_base_rev(fs, revision);
 
   return file;
 }
@@ -194,6 +191,7 @@ open_pack_or_rev_file(svn_fs_x__revision
 
           /* We failed for the first time. Refresh cache & retry. */
           SVN_ERR(svn_fs_x__update_min_unpacked_rev(fs, scratch_pool));
+              file->start_revision = svn_fs_x__packed_base_rev(fs, rev);
 
           retry = TRUE;
         }

Modified: subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/temp_serializer.c Tue Nov  4 16:07:33 2014
@@ -242,7 +242,7 @@ static svn_temp_serializer__context_t *
 serialize_dir(apr_array_header_t *entries, apr_pool_t *pool)
 {
   dir_data_t dir_data;
-  apr_size_t i = 0;
+  int i = 0;
   svn_temp_serializer__context_t *context;
 
   /* calculate sizes */

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Tue Nov  4 16:07:33 2014
@@ -3293,6 +3293,22 @@ commit_body(void *baton, apr_pool_t *poo
   svn_fs_x__txn_id_t txn_id = svn_fs_x__txn_get_id(cb->txn);
   apr_hash_t *changed_paths;
 
+  /* 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.
+
+     Committing pre-format 3 txns will fail after upgrade to format 3+
+     because the proto-rev cannot be found; no further action needed.
+     Upgrades from pre-f7 to f7+ means a potential change in addressing
+     mode for the final rev.  We must be sure to detect that cause because
+     the failure would only manifest once the new revision got committed.
+   */
+  SVN_ERR(svn_fs_x__read_format_file(cb->fs, pool));
+
   /* Get the current youngest revision. */
   SVN_ERR(svn_fs_x__youngest_rev(&old_rev, cb->fs, 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=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.h Tue Nov  4 16:07:33 2014
@@ -78,9 +78,11 @@ svn_boolean_t
 svn_fs_x__is_packed_revprop(svn_fs_t *fs,
                             svn_revnum_t rev);
 
-/* Return the revision number of the pack / rev file in FS containing REV. */
+/* Return the first revision in the pack / rev file containing REVISION in
+ * filesystem FS.  For non-packed revs, this will simply be REVISION. */
 svn_revnum_t
-svn_fs_x__packed_base_rev(svn_fs_t *fs, svn_revnum_t rev);
+svn_fs_x__packed_base_rev(svn_fs_t *fs,
+                          svn_revnum_t rev);
 
 /* Return the number of revisions in the pack / rev file in FS that contains
  * revision REV. */

Modified: subversion/trunk/subversion/libsvn_fs_x/verify.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/verify.c?rev=1636627&r1=1636626&r2=1636627&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/verify.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/verify.c Tue Nov  4 16:07:33 2014
@@ -687,13 +687,16 @@ verify_index_consistency(svn_fs_t *fs,
 {
   svn_error_t *err;
   fs_x_data_t *ffd = fs->fsap_data;
-  svn_revnum_t revision, pack_start, pack_end;
+  svn_revnum_t revision, next_revision;
   apr_pool_t *iterpool = svn_pool_create(pool);
 
-  for (revision = start; revision <= end; revision = pack_end)
+  for (revision = start; revision <= end; revision = next_revision)
     {
-      pack_start = svn_fs_x__packed_base_rev(fs, revision);
-      pack_end = pack_start + svn_fs_x__pack_size(fs, revision);
+      svn_revnum_t count = svn_fs_x__packed_base_rev(fs, revision);
+      svn_revnum_t pack_start = count;
+      svn_revnum_t pack_end = pack_start + svn_fs_x__pack_size(fs, revision);
+
+      svn_pool_clear(iterpool);
 
       if (notify_func && (pack_start % ffd->max_files_per_dir == 0))
         notify_func(pack_start, notify_baton, iterpool);
@@ -711,10 +714,30 @@ verify_index_consistency(svn_fs_t *fs,
                                        cancel_func, cancel_baton, iterpool);
 
       /* verify in-index checksums and types vs. actual rev / pack files */
-      SVN_ERR(compare_p2l_to_rev(fs, pack_start, pack_end - pack_start,
-                                 cancel_func, cancel_baton, iterpool));
+      if (!err)
+        err = compare_p2l_to_rev(fs, pack_start, pack_end - pack_start,
+                                 cancel_func, cancel_baton, iterpool);
 
-      svn_pool_clear(iterpool);
+      /* concurrent packing is one of the reasons why verification may fail.
+         Make sure, we operate on up-to-date information. */
+      if (err)
+        SVN_ERR(svn_fs_x__read_min_unpacked_rev(&ffd->min_unpacked_rev,
+                                                fs, pool));
+
+      /* retry the whole shard if it got packed in the meantime */
+      if (err && count != svn_fs_x__pack_size(fs, revision))
+        {
+          svn_error_clear(err);
+
+          /* We could simply assign revision here but the code below is
+             more intuitive to maintainers. */
+          next_revision = svn_fs_x__packed_base_rev(fs, revision);
+        }
+      else
+        {
+          SVN_ERR(err);
+          next_revision = pack_end;
+        }
     }
 
   svn_pool_destroy(iterpool);



Mime
View raw message