aboutsummaryrefslogtreecommitdiff
path: root/subversion/libsvn_fs_x/verify.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_fs_x/verify.c')
-rw-r--r--subversion/libsvn_fs_x/verify.c116
1 files changed, 58 insertions, 58 deletions
diff --git a/subversion/libsvn_fs_x/verify.c b/subversion/libsvn_fs_x/verify.c
index 4ea0728f7d5f..6f03201b2b8e 100644
--- a/subversion/libsvn_fs_x/verify.c
+++ b/subversion/libsvn_fs_x/verify.c
@@ -27,6 +27,7 @@
#include "cached_data.h"
#include "rep-cache.h"
+#include "revprops.h"
#include "util.h"
#include "index.h"
@@ -141,30 +142,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 +173,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 +200,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 +239,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 +330,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 +419,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 +434,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 +448,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 +466,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 +484,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 +493,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 +510,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 +530,7 @@ expected_buffered_checksum(apr_file_t *file,
* 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 +545,7 @@ expected_streamed_checksum(apr_file_t *file,
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 +579,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 +617,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 +650,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));
}
@@ -703,6 +692,10 @@ verify_revprops(svn_fs_t *fs,
svn_revnum_t revision;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+ /* Invalidate the revprop generation once.
+ * Use the cache inside the loop to speed up packed revprop access. */
+ svn_fs_x__invalidate_revprop_generation(fs);
+
for (revision = start; revision < end; ++revision)
{
svn_string_t *date;
@@ -713,7 +706,7 @@ verify_revprops(svn_fs_t *fs,
/* Access the svn:date revprop.
* This implies parsing all revprops for that revision. */
SVN_ERR(svn_fs_x__revision_prop(&date, fs, revision,
- SVN_PROP_REVISION_DATE,
+ SVN_PROP_REVISION_DATE, FALSE,
iterpool, iterpool));
/* The time stamp is the only revprop that, if given, needs to
@@ -790,8 +783,15 @@ verify_metadata_consistency(svn_fs_t *fs,
/* 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, scratch_pool));
+ {
+ svn_error_t *err2
+ = svn_fs_x__read_min_unpacked_rev(&ffd->min_unpacked_rev,
+ fs, scratch_pool);
+
+ /* Be careful to not leak ERR. */
+ if (err2)
+ return svn_error_trace(svn_error_compose_create(err, err2));
+ }
/* retry the whole shard if it got packed in the meantime */
if (err && count != svn_fs_x__pack_size(fs, revision))
@@ -824,14 +824,14 @@ svn_fs_x__verify(svn_fs_t *fs,
void *cancel_baton,
apr_pool_t *scratch_pool)
{
- svn_fs_x__data_t *ffd = fs->fsap_data;
- svn_revnum_t youngest = ffd->youngest_rev_cache; /* cache is current */
-
/* Input validation. */
if (! SVN_IS_VALID_REVNUM(start))
start = 0;
if (! SVN_IS_VALID_REVNUM(end))
- end = youngest;
+ {
+ SVN_ERR(svn_fs_x__youngest_rev(&end, fs, scratch_pool));
+ }
+
SVN_ERR(svn_fs_x__ensure_revision_exists(start, fs, scratch_pool));
SVN_ERR(svn_fs_x__ensure_revision_exists(end, fs, scratch_pool));