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 2013/10/14 21:08:22 UTC

svn commit: r1532029 - in /subversion/branches/log-addressing/subversion/libsvn_fs_fs: cached_data.c index.c index.h pack.c recovery.c verify.c

Author: stefan2
Date: Mon Oct 14 19:08:21 2013
New Revision: 1532029

URL: http://svn.apache.org/r1532029
Log:
On the log-addressing branch: switch the indexing API to accepting the
new revision file structure as parameter.  Update all callers but don't
actually use the extra data in the index code, yet.

* subversion/libsvn_fs_fs/index.h
  (svn_fs_fs__p2l_index_lookup,
   svn_fs_fs__p2l_entry_lookup,
   svn_fs_fs__item_offset,
   svn_fs_fs__p2l_get_max_offset): add REV_FILE parameter

* subversion/libsvn_fs_fs/index.c
  (svn_fs_fs__item_offset,
   svn_fs_fs__p2l_index_lookup,
   svn_fs_fs__p2l_entry_lookup,
   svn_fs_fs__p2l_get_max_offset): same on the implementation side

* subversion/libsvn_fs_fs/cached_data.c
  (open_and_seek_revision,
   open_and_seek_transaction,
   auto_set_start_offset,
   create_rep_state_body): pass rev_file to index API
  (svn_fs_fs__check_rep,
   block_read): ditto; retry once if the P2L lookup failed

* subversion/libsvn_fs_fs/pack.c
  (pack_range): provide additional parameter

* subversion/libsvn_fs_fs/recovery.c
  (recover_find_max_ids,
   svn_fs_fs__find_max_ids): ditto

* subversion/libsvn_fs_fs/verify.c
  (compare_l2p_to_p2l_index,
   compare_p2l_to_l2p_index): create a rev file struct and pass it to the
                              indexing code
  (compare_p2l_to_rev): provide additional parameter

Modified:
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/pack.c
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c
    subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c?rev=1532029&r1=1532028&r2=1532029&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/cached_data.c Mon Oct 14 19:08:21 2013
@@ -209,7 +209,9 @@ open_and_seek_revision(svn_fs_fs__revisi
   SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, pool));
 
   SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, rev, pool));
-  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev, NULL, item, pool));
+  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev_file, rev, NULL, item,
+                                 pool));
+
   SVN_ERR(aligned_seek(fs, rev_file->file, NULL, offset, pool));
 
   *file = rev_file;
@@ -230,7 +232,7 @@ open_and_seek_transaction(svn_fs_fs__rev
 
   SVN_ERR(svn_fs_fs__open_proto_rev_file(file, fs, &rep->txn_id, pool));
 
-  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, SVN_INVALID_REVNUM,
+  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, NULL, SVN_INVALID_REVNUM,
                                  &rep->txn_id, rep->item_index, pool));
   SVN_ERR(aligned_seek(fs, (*file)->file, NULL, offset, pool));
 
@@ -643,7 +645,7 @@ auto_set_start_offset(rep_state_t *rs, a
   if (rs->start == -1)
     {
       SVN_ERR(svn_fs_fs__item_offset(&rs->start, rs->sfile->fs,
-                                     rs->revision, NULL,
+                                     rs->sfile->rfile, rs->revision, NULL,
                                      rs->item_index, pool));
       rs->start += rs->header_size;
     }
@@ -758,7 +760,7 @@ create_rep_state_body(rep_state_t **rep_
            */
           rs->sfile = *shared_file;
           SVN_ERR(auto_open_shared_file(rs->sfile));
-          SVN_ERR(svn_fs_fs__item_offset(&offset, fs,
+          SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rs->sfile->rfile,
                                          rep->revision, NULL, rep->item_index,
                                          pool));
           SVN_ERR(rs_aligned_seek(rs, NULL, offset, pool));
@@ -856,13 +858,30 @@ svn_fs_fs__check_rep(representation_t *r
 {
   if (svn_fs_fs__use_log_addressing(fs, rep->revision))
     {
+      svn_error_t *err;
       apr_off_t offset;
       svn_fs_fs__p2l_entry_t *entry;
+      svn_boolean_t is_packed;
 
-      SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rep->revision, NULL,
-                                     rep->item_index, pool));
-      SVN_ERR(svn_fs_fs__p2l_entry_lookup(&entry, fs, rep->revision,
-                                          offset, pool));
+      svn_fs_fs__revision_file_t rev_file;
+      svn_fs_fs__init_revision_file(&rev_file, fs, rep->revision, pool);
+      SVN_ERR(svn_fs_fs__item_offset(&offset, fs, &rev_file, rep->revision,
+                                     NULL, rep->item_index, pool));
+
+      is_packed = rev_file.is_packed;
+      err = svn_fs_fs__p2l_entry_lookup(&entry, fs, &rev_file, rep->revision,
+                                        offset, pool);
+
+      /* retry if the packing state has changed */
+      if (is_packed != rev_file.is_packed)
+        {
+          svn_error_clear(err);
+          return svn_error_trace(svn_fs_fs__check_rep(rep, fs, hint, pool));
+        }
+      else
+        {
+          SVN_ERR(err);
+        }
 
       if (   entry == NULL
           || entry->type < SVN_FS_FS__ITEM_TYPE_FILE_REP
@@ -2565,8 +2584,8 @@ block_read(void **result,
   
   /* index lookup: find the OFFSET of the item we *must* read plus (in the
    * "do-while" block) the list of items in the same block. */
-  SVN_ERR(svn_fs_fs__item_offset(&wanted_offset, fs, revision, NULL,
-                                 item_index, iterpool));
+  SVN_ERR(svn_fs_fs__item_offset(&wanted_offset, fs, revision_file,
+                                 revision, NULL, item_index, iterpool));
 
   offset = wanted_offset;
 
@@ -2580,8 +2599,24 @@ block_read(void **result,
    */
   do
     {
-      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, revision, offset,
-                                          scratch_pool));
+      /* fetch list of items in the block surrounding OFFSET */
+      svn_error_t *err
+        = svn_fs_fs__p2l_index_lookup(&entries, fs, revision_file,
+                                      revision, offset, scratch_pool);
+
+      /* if the revision got packed in the meantime and we still need need
+       * to actually read some item, we retry the whole process */
+      if (err &&
+          revision_file->is_packed != svn_fs_fs__is_packed_rev(fs, revision))
+        {
+          if (result && !*result)
+            SVN_ERR(block_read(result, fs, revision, item_index,
+                                revision_file, result_pool, scratch_pool));
+
+          return SVN_NO_ERROR;
+        }
+
+      SVN_ERR(err);
       SVN_ERR(aligned_seek(fs, revision_file->file, &block_start, offset,
                            iterpool));
 

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c?rev=1532029&r1=1532028&r2=1532029&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.c Mon Oct 14 19:08:21 2013
@@ -1441,6 +1441,7 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
 svn_error_t *
 svn_fs_fs__item_offset(apr_off_t *absolute_position,
                        svn_fs_t *fs,
+                       svn_fs_fs__revision_file_t *rev_file,
                        svn_revnum_t revision,
                        const svn_fs_fs__id_part_t *txn_id,
                        apr_uint64_t item_index,
@@ -2215,6 +2216,7 @@ p2l_index_lookup(apr_array_header_t **en
 svn_error_t *
 svn_fs_fs__p2l_index_lookup(apr_array_header_t **entries,
                             svn_fs_t *fs,
+                            svn_fs_fs__revision_file_t *rev_file,
                             svn_revnum_t revision,
                             apr_off_t offset,
                             apr_pool_t *pool)
@@ -2345,6 +2347,7 @@ p2l_entry_lookup(svn_fs_fs__p2l_entry_t 
 svn_error_t *
 svn_fs_fs__p2l_entry_lookup(svn_fs_fs__p2l_entry_t **entry_p,
                             svn_fs_t *fs,
+                            svn_fs_fs__revision_file_t *rev_file,
                             svn_revnum_t revision,
                             apr_off_t offset,
                             apr_pool_t *pool)
@@ -2380,6 +2383,7 @@ p2l_get_max_offset_func(void **out,
 svn_error_t *
 svn_fs_fs__p2l_get_max_offset(apr_off_t *offset,
                               svn_fs_t *fs,
+                              svn_fs_fs__revision_file_t *rev_file,
                               svn_revnum_t revision,
                               apr_pool_t *pool)
 {

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h?rev=1532029&r1=1532028&r2=1532029&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/index.h Mon Oct 14 19:08:21 2013
@@ -151,7 +151,9 @@ svn_fs_fs__p2l_index_create(svn_fs_t *fs
 /* Use the phys-to-log mapping files in FS to build a list of entries
  * that (partly) share in the same cluster as the item at global OFFSET
  * in the rep file containing REVISION.  Return the array in *ENTRIES,
- * elements being of type svn_fs_fs__p2l_entry_t.
+ * elements being of type svn_fs_fs__p2l_entry_t.  REV_FILE determines
+ * whether to access single rev or pack file data.  If that is not
+ * available anymore (neither in cache nor on disk), return an error.
  * Use POOL for allocations.
  *
  * Note that (only) the first and the last mapping may cross a cluster
@@ -160,6 +162,7 @@ svn_fs_fs__p2l_index_create(svn_fs_t *fs
 svn_error_t *
 svn_fs_fs__p2l_index_lookup(apr_array_header_t **entries,
                             svn_fs_t *fs,
+                            svn_fs_fs__revision_file_t *rev_file,
                             svn_revnum_t revision,
                             apr_off_t offset,
                             apr_pool_t *pool);
@@ -167,23 +170,33 @@ svn_fs_fs__p2l_index_lookup(apr_array_he
 /* Use the phys-to-log mapping files in FS to return the entry for the
  * item starting at global OFFSET in the rep file containing REVISION in
  * *ENTRY.  Sets *ENTRY to NULL if no item starts at exactly that offset.
- * Use POOL for allocations.
+ * REV_FILE determines whether to access single rev or pack file data.
+ * If that is not available anymore (neither in cache nor on disk),
+ * return an error.  Use POOL for allocations.
  */
 svn_error_t *
 svn_fs_fs__p2l_entry_lookup(svn_fs_fs__p2l_entry_t **entry,
                             svn_fs_t *fs,
+                            svn_fs_fs__revision_file_t *rev_file,
                             svn_revnum_t revision,
                             apr_off_t offset,
                             apr_pool_t *pool);
 
 /* For ITEM_INDEX within REV in FS, return the position in the respective
-   rev or pack file in *ABSOLUTE_POSITION.  If TXN_ID is not NULL, return
-   the file offset within that transaction and REV should be given as
-   SVN_INVALID_REVNUM in that case.  Use POOL for allocations.
+ * rev or pack file in *ABSOLUTE_POSITION.  If TXN_ID is not NULL, return
+ * the file offset within that transaction and REV should be given as
+ * SVN_INVALID_REVNUM in that case.
+ *
+ * REV_FILE determines whether to access single rev or pack file data.
+ * If that is not available anymore (neither in cache nor on disk), re-open
+ * the rev / pack file and retry to open the index file.  For anything but
+ * committed log addressed revisions, REV_FILE may be NULL.
+ * Use POOL for allocations.
  */
 svn_error_t *
 svn_fs_fs__item_offset(apr_off_t *absolute_position,
                        svn_fs_t *fs,
+                       svn_fs_fs__revision_file_t *rev_file,
                        svn_revnum_t revision,
                        const svn_fs_fs__id_part_t *txn_id,
                        apr_uint64_t item_index,
@@ -201,12 +214,16 @@ svn_fs_fs__l2p_get_max_ids(apr_array_hea
                            apr_size_t count,
                            apr_pool_t *pool);
 
-/* In *OFFSET, return the first OFFSET in the pack / rev file containing.
+/* In *OFFSET, return the last OFFSET in the pack / rev file containing.
+ * REV_FILE determines whether to access single rev or pack file data.
+ * If that is not available anymore (neither in cache nor on disk), re-open
+ * the rev / pack file and retry to open the index file.
  * Use POOL for allocations.
  */
 svn_error_t *
 svn_fs_fs__p2l_get_max_offset(apr_off_t *offset,
                               svn_fs_t *fs,
+                              svn_fs_fs__revision_file_t *rev_file,
                               svn_revnum_t revision,
                               apr_pool_t *pool);
 

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/pack.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/pack.c?rev=1532029&r1=1532028&r2=1532029&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/pack.c Mon Oct 14 19:08:21 2013
@@ -1163,7 +1163,7 @@ pack_range(pack_context_t *context,
           int i;
           apr_array_header_t *entries;
           SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, context->fs,
-                                              revision, offset,
+                                              rev_file, revision, offset,
                                               iterpool));
 
           for (i = 0; i < entries->nelts; ++i)

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c?rev=1532029&r1=1532028&r2=1532029&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/recovery.c Mon Oct 14 19:08:21 2013
@@ -183,7 +183,7 @@ recover_find_max_ids(svn_fs_t *fs,
 
   /* We could use get_dir_contents(), but this is much cheaper.  It does
      rely on directory entries being stored as PLAIN reps, though. */
-  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev, NULL,
+  SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev_file, rev, NULL,
                                  noderev->data_rep->item_index, pool));
   SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &offset, pool));
   SVN_ERR(svn_fs_fs__read_rep_header(&header, baton.stream, pool));
@@ -263,11 +263,8 @@ recover_find_max_ids(svn_fs_t *fs,
       if (kind == svn_node_file)
         continue;
 
-      SVN_ERR(svn_fs_fs__item_offset(&child_dir_offset,
-                                     fs,
-                                     rev_item->revision,
-                                     NULL,
-                                     rev_item->number,
+      SVN_ERR(svn_fs_fs__item_offset(&child_dir_offset, fs,
+                                     rev_file, rev, NULL, rev_item->number,
                                      iterpool));
       SVN_ERR(recover_find_max_ids(fs, rev, rev_file, child_dir_offset,
                                    max_node_id, max_copy_id, iterpool));
@@ -293,11 +290,8 @@ svn_fs_fs__find_max_ids(svn_fs_t *fs,
   SVN_ERR_ASSERT(ffd->format < SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT);
 
   SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, youngest, pool));
-  SVN_ERR(svn_fs_fs__item_offset(&root_offset, fs,
-                                 svn_fs_fs__id_rev(root_id),
-                                 NULL,
-                                 svn_fs_fs__id_item(root_id),
-                                 pool));
+  SVN_ERR(svn_fs_fs__item_offset(&root_offset, fs, rev_file, youngest, NULL,
+                                 svn_fs_fs__id_item(root_id), pool));
 
   SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, youngest, pool));
   SVN_ERR(recover_find_max_ids(fs, youngest, rev_file, root_offset,

Modified: subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c
URL: http://svn.apache.org/viewvc/subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c?rev=1532029&r1=1532028&r2=1532029&view=diff
==============================================================================
--- subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c (original)
+++ subversion/branches/log-addressing/subversion/libsvn_fs_fs/verify.c Mon Oct 14 19:08:21 2013
@@ -176,6 +176,10 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
   apr_pool_t *iterpool = svn_pool_create(pool);
   apr_array_header_t *max_ids;
 
+  /* common file access structure */
+  svn_fs_fs__revision_file_t rev_file;
+  svn_fs_fs__init_revision_file(&rev_file, fs, start, pool);
+
   /* determine the range of items to check for each revision */
   SVN_ERR(svn_fs_fs__l2p_get_max_ids(&max_ids, fs, start, count, pool));
 
@@ -192,14 +196,14 @@ compare_l2p_to_p2l_index(svn_fs_t *fs,
           svn_fs_fs__p2l_entry_t *p2l_entry;
 
           /* get L2P entry.  Ignore unused entries. */
-          SVN_ERR(svn_fs_fs__item_offset(&offset, fs,
-                                         revision, NULL, k, iterpool));
+          SVN_ERR(svn_fs_fs__item_offset(&offset, fs, &rev_file, revision,
+                                         NULL, k, iterpool));
           if (offset == -1)
             continue;
 
           /* find the corresponding P2L entry */
-          SVN_ERR(svn_fs_fs__p2l_entry_lookup(&p2l_entry, fs, start,
-                                              offset, iterpool));
+          SVN_ERR(svn_fs_fs__p2l_entry_lookup(&p2l_entry, fs, &rev_file,
+                                              revision, offset, iterpool));
 
           if (p2l_entry == NULL)
             return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT,
@@ -253,8 +257,13 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
   apr_off_t max_offset;
   apr_off_t offset = 0;
 
+  /* common file access structure */
+  svn_fs_fs__revision_file_t rev_file;
+  svn_fs_fs__init_revision_file(&rev_file, fs, start, pool);
+
   /* get the size of the rev / pack file as covered by the P2L index */
-  SVN_ERR(svn_fs_fs__p2l_get_max_offset(&max_offset, fs, start, pool));
+  SVN_ERR(svn_fs_fs__p2l_get_max_offset(&max_offset, fs, &rev_file, start,
+                                        pool));
 
   /* for all offsets in the file, get the P2L index entries and check
      them against the L2P index */
@@ -265,8 +274,8 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
       int i;
 
       /* get all entries for the current block */
-      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, start, offset,
-                                          iterpool));
+      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, &rev_file, start,
+                                          offset, iterpool));
       if (entries->nelts == 0)
         return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_CORRUPTION,
                                  NULL,
@@ -288,7 +297,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs,
           if (entry->type != SVN_FS_FS__ITEM_TYPE_UNUSED)
             {
               apr_off_t l2p_offset;
-              SVN_ERR(svn_fs_fs__item_offset(&l2p_offset, fs,
+              SVN_ERR(svn_fs_fs__item_offset(&l2p_offset, fs, &rev_file,
                                              entry->item.revision, NULL,
                                              entry->item.number, iterpool));
 
@@ -490,7 +499,8 @@ compare_p2l_to_rev(svn_fs_t *fs,
 
   /* check file size vs. range covered by index */
   SVN_ERR(svn_io_file_seek(rev_file->file, APR_END, &offset, pool));
-  SVN_ERR(svn_fs_fs__p2l_get_max_offset(&max_offset, fs, start, pool));
+  SVN_ERR(svn_fs_fs__p2l_get_max_offset(&max_offset, fs, rev_file, start,
+                                        pool));
 
   if (offset != max_offset)
     return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, NULL,
@@ -510,8 +520,8 @@ compare_p2l_to_rev(svn_fs_t *fs,
       int i;
 
       /* get all entries for the current block */
-      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, start, offset,
-                                          iterpool));
+      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, rev_file, start,
+                                          offset, iterpool));
 
       /* process all entries (and later continue with the next block) */
       for (i = 0; i < entries->nelts; ++i)