FreeBSD/contrib/subversion/subversion/libsvn_fs_fs/verify.c
/* Verify that for all phys-to-log index entries for revisions START to
 * START + COUNT-1 in FS there is a consistent entry in the log-to-phys
 * index.  If given, invoke CANCEL_FUNC with CANCEL_BATON at regular
 * intervals. Use POOL for allocations.
 *
 * Please note that we can only check on pack / rev file granularity and
 * must only be called for a single rev / pack file.
 */


Please note that we can only check on pack / rev file granularity and
must only be called for a single rev / pack file.
Please note that we can only check on pack / rev file granularity and must only be called for a single rev / pack file .
static svn_error_t *
compare_p2l_to_l2p_index(svn_fs_t *fs,
                         svn_revnum_t start,
                         svn_revnum_t count,
                         svn_cancel_func_t cancel_func,
                         void *cancel_baton,
                         apr_pool_t *pool)
{
  fs_fs_data_t *ffd = fs->fsap_data;
  apr_pool_t *iterpool = svn_pool_create(pool);
  apr_off_t max_offset;
  apr_off_t offset = 0;
  svn_fs_fs__revision_file_t *rev_file;
  SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, start, pool,
                                           iterpool));
  SVN_ERR(svn_fs_fs__p2l_get_max_offset(&max_offset, fs, rev_file, start,
                                        pool));
  for (offset = 0; offset < max_offset; )
    {
      apr_array_header_t *entries;
      svn_fs_fs__p2l_entry_t *last_entry;
      int i;
      svn_pool_clear(iterpool);
      SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, rev_file, start,
                                          offset, ffd->p2l_page_size,
                                          iterpool, iterpool));
      if (entries->nelts == 0)
        return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION,
                                 NULL,
                                 _("p2l does not cover offset %s"
                                   " for revision %ld"),
                                  apr_off_t_toa(pool, offset), start);
      last_entry
        = &APR_ARRAY_IDX(entries, entries->nelts-1, svn_fs_fs__p2l_entry_t);
      offset = last_entry->offset + last_entry->size;
      for (i = 0; i < entries->nelts; ++i)
        {
          svn_fs_fs__p2l_entry_t *entry
            = &APR_ARRAY_IDX(entries, i, svn_fs_fs__p2l_entry_t);
          if (entry->type == SVN_FS_FS__ITEM_TYPE_UNUSED)
            {
              if (   entry->item.revision != SVN_INVALID_REVNUM
                  && (   entry->item.revision < start
                      || entry->item.revision >= start + count))
                return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT,
                                         NULL,
                                         _("Empty P2L entry for PHYS %s "
                                           "refers to revision %ld outside "
                                           "the rev / pack file (%ld-%ld)"),
                                         apr_off_t_toa(pool, entry->offset),
                                         entry->item.revision,
                                         start, start + count - 1);
            }
          else
            {
              apr_off_t l2p_offset;
              SVN_ERR(svn_fs_fs__item_offset(&l2p_offset, fs, rev_file,
                                             entry->item.revision, NULL,
                                             entry->item.number, iterpool));
              if (l2p_offset != entry->offset)
                return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT,
                                         NULL,
                                         _("l2p index entry PHYS %s"
                                           "does not match p2l index value "
                                           "LOG r%ld:i%ld for PHYS %s"),
                                         apr_off_t_toa(pool, l2p_offset),
                                         entry->item.revision,
                                         (long)entry->item.number,
                                         apr_off_t_toa(pool, entry->offset));
            }
        }
      if (cancel_func)
        SVN_ERR(cancel_func(cancel_baton));
    }
  svn_pool_destroy(iterpool);
  SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
  return SVN_NO_ERROR;
}
static svn_error_t * compare_p2l_to_l2p_index ( svn_fs_t * fs , svn_revnum_t start , svn_revnum_t count , svn_cancel_func_t cancel_func , void * cancel_baton , apr_pool_t * pool ) { fs_fs_data_t * ffd = fs -> fsap_data ; apr_pool_t * iterpool = svn_pool_create ( pool ) ; apr_off_t max_offset ; apr_off_t offset = 0 ; svn_fs_fs__revision_file_t * rev_file ; SVN_ERR ( svn_fs_fs__open_pack_or_rev_file ( & rev_file , fs , start , pool , iterpool ) ) ; SVN_ERR ( svn_fs_fs__p2l_get_max_offset ( & max_offset , fs , rev_file , start , pool ) ) ; for ( offset = 0 ; offset < max_offset ; ) { apr_array_header_t * entries ; svn_fs_fs__p2l_entry_t * last_entry ; int i ; svn_pool_clear ( iterpool ) ; SVN_ERR ( svn_fs_fs__p2l_index_lookup ( & entries , fs , rev_file , start , offset , ffd -> p2l_page_size , iterpool , iterpool ) ) ; if ( entries -> nelts == 0 ) return svn_error_createf ( SVN_ERR_FS_INDEX_CORRUPTION , NULL , _ ( " " " " ) , apr_off_t_toa ( pool , offset ) , start ) ; last_entry = & APR_ARRAY_IDX ( entries , entries -> nelts - 1 , svn_fs_fs__p2l_entry_t ) ; offset = last_entry -> offset + last_entry -> size ; for ( i = 0 ; i < entries -> nelts ; ++ i ) { svn_fs_fs__p2l_entry_t * entry = & APR_ARRAY_IDX ( entries , i , svn_fs_fs__p2l_entry_t ) ; if ( entry -> type == SVN_FS_FS__ITEM_TYPE_UNUSED ) { if ( entry -> item . revision != SVN_INVALID_REVNUM && ( entry -> item . revision < start || entry -> item . revision >= start + count ) ) return svn_error_createf ( SVN_ERR_FS_INDEX_INCONSISTENT , NULL , _ ( " " " " " " ) , apr_off_t_toa ( pool , entry -> offset ) , entry -> item . revision , start , start + count - 1 ) ; } else { apr_off_t l2p_offset ; SVN_ERR ( svn_fs_fs__item_offset ( & l2p_offset , fs , rev_file , entry -> item . revision , NULL , entry -> item . number , iterpool ) ) ; if ( l2p_offset != entry -> offset ) return svn_error_createf ( SVN_ERR_FS_INDEX_INCONSISTENT , NULL , _ ( " " " " " " ) , apr_off_t_toa ( pool , l2p_offset ) , entry -> item . revision , ( long ) entry -> item . number , apr_off_t_toa ( pool , entry -> offset ) ) ; } } if ( cancel_func ) SVN_ERR ( cancel_func ( cancel_baton ) ) ; } svn_pool_destroy ( iterpool ) ; SVN_ERR ( svn_fs_fs__close_revision_file ( rev_file ) ) ; return SVN_NO_ERROR ; }
Verify that for all phys-to-log index entries for revisions START to
 START + COUNT-1 in FS there is a consistent entry in the log-to-phys
 index.
Verify that for all phys - to - log index entries for revisions START to START + COUNT - 1 in FS there is a consistent entry in the log - to - phys index .
/* common file access structure */ /* get the size of the rev / pack file as covered by the P2L index */ /* for all offsets in the file, get the P2L index entries and check
     them against the L2P index */ /* get all entries for the current block */ /* process all entries (and later continue with the next block) */ /* check all sub-items for consist entries in the L2P index */ /* There is no L2P entry for unused rev file sections.
               * And its P2L index data is hardly ever used.  But we
               * should still check whether someone tempered with it. */