aboutsummaryrefslogtreecommitdiffstats
path: root/subversion/libsvn_fs_fs
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-05-31 20:58:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-05-31 20:58:28 +0000
commitbbee6e0814d5875b85b81f26fd4ca7a28b6f9570 (patch)
tree726fcf32b39ca8976d7aa51b67c7236509f1bde4 /subversion/libsvn_fs_fs
parent38cef28c88864beaadac7a7cffdec6da952c3eb2 (diff)
downloadsrc-bbee6e0814d5875b85b81f26fd4ca7a28b6f9570.tar.gz
src-bbee6e0814d5875b85b81f26fd4ca7a28b6f9570.zip
Notes
Notes: svn path=/vendor/subversion/dist/; revision=361669 svn path=/vendor/subversion/subversion-1.14.0/; revision=361670; tag=vendor/subversion/subversion-1.14.0
Diffstat (limited to 'subversion/libsvn_fs_fs')
-rw-r--r--subversion/libsvn_fs_fs/cached_data.c2
-rw-r--r--subversion/libsvn_fs_fs/cached_data.h2
-rw-r--r--subversion/libsvn_fs_fs/dag.c2
-rw-r--r--subversion/libsvn_fs_fs/dump-index.c2
-rw-r--r--subversion/libsvn_fs_fs/fs.c84
-rw-r--r--subversion/libsvn_fs_fs/fs_fs.c170
-rw-r--r--subversion/libsvn_fs_fs/fs_fs.h71
-rw-r--r--subversion/libsvn_fs_fs/id.c3
-rw-r--r--subversion/libsvn_fs_fs/index.c4
-rw-r--r--subversion/libsvn_fs_fs/libsvn_fs_fs.pc.in8
-rw-r--r--subversion/libsvn_fs_fs/load-index.c6
-rw-r--r--subversion/libsvn_fs_fs/low_level.c8
-rw-r--r--subversion/libsvn_fs_fs/pack.c18
-rw-r--r--subversion/libsvn_fs_fs/recovery.c12
-rw-r--r--subversion/libsvn_fs_fs/rep-cache-db.h4
-rw-r--r--subversion/libsvn_fs_fs/rep-cache-db.sql2
-rw-r--r--subversion/libsvn_fs_fs/rep-cache.c24
-rw-r--r--subversion/libsvn_fs_fs/revprops.c60
-rw-r--r--subversion/libsvn_fs_fs/revprops.h9
-rw-r--r--subversion/libsvn_fs_fs/stats.c97
-rw-r--r--subversion/libsvn_fs_fs/temp_serializer.c4
-rw-r--r--subversion/libsvn_fs_fs/temp_serializer.h6
-rw-r--r--subversion/libsvn_fs_fs/transaction.c2
-rw-r--r--subversion/libsvn_fs_fs/tree.c49
-rw-r--r--subversion/libsvn_fs_fs/verify.c11
25 files changed, 576 insertions, 84 deletions
diff --git a/subversion/libsvn_fs_fs/cached_data.c b/subversion/libsvn_fs_fs/cached_data.c
index 1bd82481daa6..9778dba908f0 100644
--- a/subversion/libsvn_fs_fs/cached_data.c
+++ b/subversion/libsvn_fs_fs/cached_data.c
@@ -2337,7 +2337,7 @@ svn_fs_fs__get_contents_from_file(svn_stream_t **contents_p,
rb->filehandle_pool));
/* Insert the access to REP as the first element of the delta chain. */
- svn_sort__array_insert(rb->rs_list, &rs, 0);
+ SVN_ERR(svn_sort__array_insert2(rb->rs_list, &rs, 0));
}
/* Now, the baton is complete and we can assemble the stream around it. */
diff --git a/subversion/libsvn_fs_fs/cached_data.h b/subversion/libsvn_fs_fs/cached_data.h
index 7b25fcf43cda..cdf3bfbc166f 100644
--- a/subversion/libsvn_fs_fs/cached_data.h
+++ b/subversion/libsvn_fs_fs/cached_data.h
@@ -171,7 +171,7 @@ svn_fs_fs__get_proplist(apr_hash_t **proplist,
apr_pool_t *pool);
/* Create a changes retrieval context object in *RESULT_POOL and return it
- * in *CONTEXT. It will allow svn_fs_x__get_changes to fetch consecutive
+ * in *CONTEXT. It will allow svn_fs_fs__get_changes to fetch consecutive
* blocks (one per invocation) from REV's changed paths list in FS. */
svn_error_t *
svn_fs_fs__create_changes_context(svn_fs_fs__changes_context_t **context,
diff --git a/subversion/libsvn_fs_fs/dag.c b/subversion/libsvn_fs_fs/dag.c
index 714235dd0ee0..2630af5605cf 100644
--- a/subversion/libsvn_fs_fs/dag.c
+++ b/subversion/libsvn_fs_fs/dag.c
@@ -1166,7 +1166,7 @@ svn_fs_fs__dag_serialize(void **data,
(const void * const *)&node->node_pool);
/* serialize other sub-structures */
- svn_fs_fs__id_serialize(context, (const svn_fs_id_t **)&node->id);
+ svn_fs_fs__id_serialize(context, (const svn_fs_id_t *const *)&node->id);
svn_fs_fs__id_serialize(context, &node->fresh_root_predecessor_id);
svn_temp_serializer__add_string(context, &node->created_path);
diff --git a/subversion/libsvn_fs_fs/dump-index.c b/subversion/libsvn_fs_fs/dump-index.c
index c97be10a41fc..c62622b6491b 100644
--- a/subversion/libsvn_fs_fs/dump-index.c
+++ b/subversion/libsvn_fs_fs/dump-index.c
@@ -21,8 +21,8 @@
*/
#include "svn_pools.h"
-#include "private/svn_fs_fs_private.h"
+#include "fs_fs.h"
#include "index.h"
#include "rev_file.h"
#include "util.h"
diff --git a/subversion/libsvn_fs_fs/fs.c b/subversion/libsvn_fs_fs/fs.c
index 508ecdbaba33..5174da2e4941 100644
--- a/subversion/libsvn_fs_fs/fs.c
+++ b/subversion/libsvn_fs_fs/fs.c
@@ -47,6 +47,7 @@
#include "verify.h"
#include "svn_private_config.h"
#include "private/svn_fs_util.h"
+#include "private/svn_fs_fs_private.h"
#include "../libsvn_fs/fs-loader.h"
@@ -254,6 +255,83 @@ fs_set_uuid(svn_fs_t *fs,
}
+static svn_error_t *
+fs_ioctl(svn_fs_t *fs, svn_fs_ioctl_code_t ctlcode,
+ void *input_void, void **output_p,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ if (strcmp(ctlcode.fs_type, SVN_FS_TYPE_FSFS) == 0)
+ {
+ if (ctlcode.code == SVN_FS_FS__IOCTL_GET_STATS.code)
+ {
+ svn_fs_fs__ioctl_get_stats_input_t *input = input_void;
+ svn_fs_fs__ioctl_get_stats_output_t *output;
+
+ output = apr_pcalloc(result_pool, sizeof(*output));
+ SVN_ERR(svn_fs_fs__get_stats(&output->stats, fs,
+ input->progress_func,
+ input->progress_baton,
+ cancel_func, cancel_baton,
+ result_pool, scratch_pool));
+ *output_p = output;
+ return SVN_NO_ERROR;
+ }
+ else if (ctlcode.code == SVN_FS_FS__IOCTL_DUMP_INDEX.code)
+ {
+ svn_fs_fs__ioctl_dump_index_input_t *input = input_void;
+
+ SVN_ERR(svn_fs_fs__dump_index(fs, input->revision,
+ input->callback_func,
+ input->callback_baton,
+ cancel_func, cancel_baton,
+ scratch_pool));
+ *output_p = NULL;
+ return SVN_NO_ERROR;
+ }
+ else if (ctlcode.code == SVN_FS_FS__IOCTL_LOAD_INDEX.code)
+ {
+ svn_fs_fs__ioctl_load_index_input_t *input = input_void;
+
+ SVN_ERR(svn_fs_fs__load_index(fs, input->revision, input->entries,
+ scratch_pool));
+ *output_p = NULL;
+ return SVN_NO_ERROR;
+ }
+ else if (ctlcode.code == SVN_FS_FS__IOCTL_REVISION_SIZE.code)
+ {
+ svn_fs_fs__ioctl_revision_size_input_t *input = input_void;
+ svn_fs_fs__ioctl_revision_size_output_t *output
+ = apr_pcalloc(result_pool, sizeof(*output));
+
+ SVN_ERR(svn_fs_fs__revision_size(&output->rev_size,
+ fs, input->revision,
+ scratch_pool));
+ *output_p = output;
+ return SVN_NO_ERROR;
+ }
+ else if (ctlcode.code == SVN_FS_FS__IOCTL_BUILD_REP_CACHE.code)
+ {
+ svn_fs_fs__ioctl_build_rep_cache_input_t *input = input_void;
+
+ SVN_ERR(svn_fs_fs__build_rep_cache(fs,
+ input->start_rev,
+ input->end_rev,
+ input->progress_func,
+ input->progress_baton,
+ cancel_func,
+ cancel_baton,
+ scratch_pool));
+
+ *output_p = NULL;
+ return SVN_NO_ERROR;
+ }
+ }
+
+ return svn_error_create(SVN_ERR_FS_UNRECOGNIZED_IOCTL_CODE, NULL, NULL);
+}
/* The vtable associated with a specific open filesystem. */
static fs_vtable_t fs_vtable = {
@@ -279,7 +357,8 @@ static fs_vtable_t fs_vtable = {
fs_info,
svn_fs_fs__verify_root,
fs_freeze,
- fs_set_errcall
+ fs_set_errcall,
+ fs_ioctl
};
@@ -602,7 +681,8 @@ static fs_library_vtable_t library_vtable = {
fs_logfiles,
NULL /* parse_id */,
fs_set_svn_fs_open,
- fs_info_dup
+ fs_info_dup,
+ NULL /* ioctl */
};
svn_error_t *
diff --git a/subversion/libsvn_fs_fs/fs_fs.c b/subversion/libsvn_fs_fs/fs_fs.c
index 5cb1362d8451..76b053e23229 100644
--- a/subversion/libsvn_fs_fs/fs_fs.c
+++ b/subversion/libsvn_fs_fs/fs_fs.c
@@ -37,6 +37,7 @@
#include "cached_data.h"
#include "id.h"
#include "index.h"
+#include "low_level.h"
#include "rep-cache.h"
#include "revprops.h"
#include "transaction.h"
@@ -2343,3 +2344,172 @@ svn_fs_fs__info_config_files(apr_array_header_t **files,
result_pool);
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+ensure_representation_sha1(svn_fs_t *fs,
+ representation_t *rep,
+ apr_pool_t *pool)
+{
+ if (!rep->has_sha1)
+ {
+ svn_stream_t *contents;
+ svn_checksum_t *checksum;
+
+ SVN_ERR(svn_fs_fs__get_contents(&contents, fs, rep, FALSE, pool));
+ SVN_ERR(svn_stream_contents_checksum(&checksum, contents,
+ svn_checksum_sha1, pool, pool));
+
+ memcpy(rep->sha1_digest, checksum->digest, APR_SHA1_DIGESTSIZE);
+ rep->has_sha1 = TRUE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+reindex_node(svn_fs_t *fs,
+ const svn_fs_id_t *id,
+ svn_revnum_t rev,
+ svn_fs_fs__revision_file_t *rev_file,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool)
+{
+ node_revision_t *noderev;
+ apr_off_t offset;
+
+ if (svn_fs_fs__id_rev(id) != rev)
+ {
+ return SVN_NO_ERROR;
+ }
+
+ if (cancel_func)
+ SVN_ERR(cancel_func(cancel_baton));
+
+ SVN_ERR(svn_fs_fs__item_offset(&offset, fs, rev_file, rev, NULL,
+ svn_fs_fs__id_item(id), pool));
+
+ SVN_ERR(svn_io_file_seek(rev_file->file, APR_SET, &offset, pool));
+ SVN_ERR(svn_fs_fs__read_noderev(&noderev, rev_file->stream,
+ pool, pool));
+
+ /* Make sure EXPANDED_SIZE has the correct value for every rep. */
+ SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, noderev->data_rep, pool));
+ SVN_ERR(svn_fs_fs__fixup_expanded_size(fs, noderev->prop_rep, pool));
+
+ /* First reindex sub-directory to match write_final_rev() behavior. */
+ if (noderev->kind == svn_node_dir)
+ {
+ apr_array_header_t *entries;
+
+ SVN_ERR(svn_fs_fs__rep_contents_dir(&entries, fs, noderev, pool, pool));
+
+ if (entries->nelts > 0)
+ {
+ int i;
+ apr_pool_t *iterpool;
+
+ iterpool = svn_pool_create(pool);
+ for (i = 0; i < entries->nelts; i++)
+ {
+ const svn_fs_dirent_t *dirent;
+
+ svn_pool_clear(iterpool);
+
+ dirent = APR_ARRAY_IDX(entries, i, svn_fs_dirent_t *);
+
+ SVN_ERR(reindex_node(fs, dirent->id, rev, rev_file,
+ cancel_func, cancel_baton, iterpool));
+ }
+ svn_pool_destroy(iterpool);
+ }
+ }
+
+ if (noderev->data_rep && noderev->data_rep->revision == rev &&
+ noderev->kind == svn_node_file)
+ {
+ SVN_ERR(ensure_representation_sha1(fs, noderev->data_rep, pool));
+ SVN_ERR(svn_fs_fs__set_rep_reference(fs, noderev->data_rep, pool));
+ }
+
+ if (noderev->prop_rep && noderev->prop_rep->revision == rev)
+ {
+ SVN_ERR(ensure_representation_sha1(fs, noderev->prop_rep, pool));
+ SVN_ERR(svn_fs_fs__set_rep_reference(fs, noderev->prop_rep, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__build_rep_cache(svn_fs_t *fs,
+ svn_revnum_t start_rev,
+ svn_revnum_t end_rev,
+ svn_fs_progress_notify_func_t progress_func,
+ void *progress_baton,
+ 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_revnum_t rev;
+
+ if (ffd->format < SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+ {
+ return svn_error_createf(SVN_ERR_FS_REP_SHARING_NOT_SUPPORTED, NULL,
+ _("FSFS format (%d) too old for rep-sharing; "
+ "please upgrade the filesystem."),
+ ffd->format);
+ }
+
+ if (!ffd->rep_sharing_allowed)
+ {
+ return svn_error_create(SVN_ERR_FS_REP_SHARING_NOT_ALLOWED, NULL,
+ _("Filesystem does not allow rep-sharing."));
+ }
+
+ /* Do not build rep-cache for revision zero to match
+ * svn_fs_fs__create() behavior. */
+ if (start_rev == SVN_INVALID_REVNUM)
+ start_rev = 1;
+
+ if (end_rev == SVN_INVALID_REVNUM)
+ SVN_ERR(svn_fs_fs__youngest_rev(&end_rev, fs, pool));
+
+ /* Do nothing for empty FS. */
+ if (start_rev > end_rev)
+ {
+ return SVN_NO_ERROR;
+ }
+
+ if (!ffd->rep_cache_db)
+ SVN_ERR(svn_fs_fs__open_rep_cache(fs, pool));
+
+ iterpool = svn_pool_create(pool);
+ for (rev = start_rev; rev <= end_rev; rev++)
+ {
+ svn_fs_id_t *root_id;
+ svn_fs_fs__revision_file_t *file;
+ svn_error_t *err;
+
+ svn_pool_clear(iterpool);
+
+ if (progress_func)
+ progress_func(rev, progress_baton, iterpool);
+
+ SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&file, fs, rev,
+ iterpool, iterpool));
+ SVN_ERR(svn_fs_fs__rev_get_root(&root_id, fs, rev, iterpool, iterpool));
+
+ SVN_ERR(svn_sqlite__begin_transaction(ffd->rep_cache_db));
+ err = reindex_node(fs, root_id, rev, file, cancel_func, cancel_baton, iterpool);
+ SVN_ERR(svn_sqlite__finish_transaction(ffd->rep_cache_db, err));
+
+ SVN_ERR(svn_fs_fs__close_revision_file(file));
+ }
+
+ svn_pool_destroy(iterpool);
+
+ return SVN_NO_ERROR;
+}
diff --git a/subversion/libsvn_fs_fs/fs_fs.h b/subversion/libsvn_fs_fs/fs_fs.h
index cef95fe3209e..b233be1b2ea1 100644
--- a/subversion/libsvn_fs_fs/fs_fs.h
+++ b/subversion/libsvn_fs_fs/fs_fs.h
@@ -304,4 +304,75 @@ svn_fs_fs__initialize_txn_caches(svn_fs_t *fs,
void
svn_fs_fs__reset_txn_caches(svn_fs_t *fs);
+/* Scan all contents of the repository FS and return statistics in *STATS,
+ * allocated in RESULT_POOL. Report progress through PROGRESS_FUNC with
+ * PROGRESS_BATON, if PROGRESS_FUNC is not NULL.
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+svn_fs_fs__get_stats(svn_fs_fs__stats_t **stats,
+ svn_fs_t *fs,
+ svn_fs_progress_notify_func_t progress_func,
+ void *progress_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Read the P2L index for the rev / pack file containing REVISION in FS.
+ * For each index entry, invoke CALLBACK_FUNC with CALLBACK_BATON.
+ * If not NULL, call CANCEL_FUNC with CANCEL_BATON from time to time.
+ * Use SCRATCH_POOL for temporary allocations.
+ */
+svn_error_t *
+svn_fs_fs__dump_index(svn_fs_t *fs,
+ svn_revnum_t revision,
+ svn_fs_fs__dump_index_func_t callback_func,
+ void *callback_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *scratch_pool);
+
+
+/* Rewrite the respective index information of the rev / pack file in FS
+ * containing REVISION and use the svn_fs_fs__p2l_entry_t * array ENTRIES
+ * as the new index contents. Allocate temporaries from SCRATCH_POOL.
+ *
+ * Note that this becomes a no-op if ENTRIES is empty. You may use a zero-
+ * sized empty entry instead.
+ */
+svn_error_t *
+svn_fs_fs__load_index(svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_array_header_t *entries,
+ apr_pool_t *scratch_pool);
+
+/* Set *REV_SIZE to the total size of objects belonging to revision REVISION
+ * in FS. The size includes revision properties and excludes indexes.
+ */
+svn_error_t *
+svn_fs_fs__revision_size(apr_off_t *rev_size,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool);
+
+/* Add missing entries to the rep-cache on the filesystem FS. Process data
+ * in revisions START_REV through END_REV inclusive. If START_REV is
+ * SVN_INVALID_REVNUM, start at revision 1; if END_REV is SVN_INVALID_REVNUM,
+ * end at the head revision. If the rep-cache does not exist, then create it.
+ *
+ * Indicate progress via the optional PROGRESS_FUNC callback using
+ * PROGRESS_BATON. The optional CANCEL_FUNC will periodically be called with
+ * CANCEL_BATON to allow cancellation. Use POOL for temporary allocations.
+ */
+svn_error_t *
+svn_fs_fs__build_rep_cache(svn_fs_t *fs,
+ svn_revnum_t start_rev,
+ svn_revnum_t end_rev,
+ svn_fs_progress_notify_func_t progress_func,
+ void *progress_baton,
+ svn_cancel_func_t cancel_func,
+ void *cancel_baton,
+ apr_pool_t *pool);
+
#endif
diff --git a/subversion/libsvn_fs_fs/id.c b/subversion/libsvn_fs_fs/id.c
index d22b8f776359..5f2730305a06 100644
--- a/subversion/libsvn_fs_fs/id.c
+++ b/subversion/libsvn_fs_fs/id.c
@@ -591,7 +591,8 @@ svn_fs_fs__id_parse(const svn_fs_id_t **id_p,
svn_fs_id_t *id = id_parse(data, pool);
if (id == NULL)
return svn_error_createf(SVN_ERR_FS_MALFORMED_NODEREV_ID, NULL,
- "Malformed node revision ID string");
+ "Malformed node revision ID string '%s'",
+ data);
*id_p = id;
diff --git a/subversion/libsvn_fs_fs/index.c b/subversion/libsvn_fs_fs/index.c
index 1cb8fba80ad6..b7ba79f96313 100644
--- a/subversion/libsvn_fs_fs/index.c
+++ b/subversion/libsvn_fs_fs/index.c
@@ -3191,9 +3191,9 @@ compare_p2l_entry_revision(const void *lhs,
const void *rhs)
{
const svn_fs_fs__p2l_entry_t *lhs_entry
- =*(const svn_fs_fs__p2l_entry_t **)lhs;
+ =*(const svn_fs_fs__p2l_entry_t *const *)lhs;
const svn_fs_fs__p2l_entry_t *rhs_entry
- =*(const svn_fs_fs__p2l_entry_t **)rhs;
+ =*(const svn_fs_fs__p2l_entry_t *const *)rhs;
if (lhs_entry->item.revision < rhs_entry->item.revision)
return -1;
diff --git a/subversion/libsvn_fs_fs/libsvn_fs_fs.pc.in b/subversion/libsvn_fs_fs/libsvn_fs_fs.pc.in
index 324a709eedea..2a2d624d9b21 100644
--- a/subversion/libsvn_fs_fs/libsvn_fs_fs.pc.in
+++ b/subversion/libsvn_fs_fs/libsvn_fs_fs.pc.in
@@ -6,7 +6,7 @@ includedir=@includedir@
Name: libsvn_fs_fs
Description: Subversion FSFS Repository Filesystem Library
Version: @PACKAGE_VERSION@
-Requires: apr-util-@SVN_APR_MAJOR_VERSION@ apr-@SVN_APR_MAJOR_VERSION@
-Requires.private: libsvn_delta libsvn_subr libsvn_fs_util
-Libs: -L${libdir} -lsvn_fs_fs
-Cflags: -I${includedir}
+Requires: apr-util-@SVN_APR_MAJOR_VERSION@, apr-@SVN_APR_MAJOR_VERSION@
+Requires.private: libsvn_delta, libsvn_subr, libsvn_fs_util
+Libs: -L${libdir} -lsvn_fs_fs-1
+Cflags: -I${includedir}/subversion-1
diff --git a/subversion/libsvn_fs_fs/load-index.c b/subversion/libsvn_fs_fs/load-index.c
index 0ba66725d35c..8608cb204dd2 100644
--- a/subversion/libsvn_fs_fs/load-index.c
+++ b/subversion/libsvn_fs_fs/load-index.c
@@ -22,9 +22,9 @@
#include "svn_pools.h"
-#include "private/svn_fs_fs_private.h"
#include "private/svn_sorts_private.h"
+#include "fs_fs.h"
#include "index.h"
#include "util.h"
#include "transaction.h"
@@ -83,9 +83,9 @@ compare_p2l_entry_revision(const void *lhs,
const void *rhs)
{
const svn_fs_fs__p2l_entry_t *lhs_entry
- =*(const svn_fs_fs__p2l_entry_t **)lhs;
+ =*(const svn_fs_fs__p2l_entry_t *const *)lhs;
const svn_fs_fs__p2l_entry_t *rhs_entry
- =*(const svn_fs_fs__p2l_entry_t **)rhs;
+ =*(const svn_fs_fs__p2l_entry_t *const *)rhs;
if (lhs_entry->offset < rhs_entry->offset)
return -1;
diff --git a/subversion/libsvn_fs_fs/low_level.c b/subversion/libsvn_fs_fs/low_level.c
index 2854bc6e2d84..906f47fc22dc 100644
--- a/subversion/libsvn_fs_fs/low_level.c
+++ b/subversion/libsvn_fs_fs/low_level.c
@@ -254,10 +254,10 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_offset,
"P2L offset %s must be larger than L2P offset %s"
" in r%ld footer",
apr_psprintf(result_pool,
- "%" APR_UINT64_T_HEX_FMT,
+ "0x%" APR_UINT64_T_HEX_FMT,
(apr_uint64_t)*p2l_offset),
apr_psprintf(result_pool,
- "%" APR_UINT64_T_HEX_FMT,
+ "0x%" APR_UINT64_T_HEX_FMT,
(apr_uint64_t)*l2p_offset),
rev);
@@ -506,7 +506,7 @@ svn_fs_fs__read_changes(apr_array_header_t **changes,
SVN_ERR(read_change(&change, stream, result_pool, iterpool));
if (!change)
break;
-
+
APR_ARRAY_PUSH(*changes, change_t*) = change;
}
svn_pool_destroy(iterpool);
@@ -670,7 +670,7 @@ svn_fs_fs__write_changes(svn_stream_t *stream,
}
if (terminate_list)
- svn_stream_puts(stream, "\n");
+ SVN_ERR(svn_stream_puts(stream, "\n"));
svn_pool_destroy(iterpool);
diff --git a/subversion/libsvn_fs_fs/pack.c b/subversion/libsvn_fs_fs/pack.c
index 1119857998fc..c9e2b4dd4e55 100644
--- a/subversion/libsvn_fs_fs/pack.c
+++ b/subversion/libsvn_fs_fs/pack.c
@@ -315,12 +315,12 @@ initialize_pack_context(pack_context_t *context,
context->file_props = apr_array_make(pool, max_items,
sizeof(svn_fs_fs__p2l_entry_t *));
SVN_ERR(svn_io_open_unique_file3(&context->file_props_file, NULL, temp_dir,
- svn_io_file_del_on_close,
+ svn_io_file_del_on_close,
context->info_pool, pool));
context->dir_props = apr_array_make(pool, max_items,
sizeof(svn_fs_fs__p2l_entry_t *));
SVN_ERR(svn_io_open_unique_file3(&context->dir_props_file, NULL, temp_dir,
- svn_io_file_del_on_close,
+ svn_io_file_del_on_close,
context->info_pool, pool));
/* noderev and representation item bucket */
@@ -2067,9 +2067,9 @@ pack_body(void *baton,
if (fully_packed)
{
if (pb->notify_func)
- (*pb->notify_func)(pb->notify_baton,
- ffd->min_unpacked_rev / ffd->max_files_per_dir,
- svn_fs_pack_notify_noop, pool);
+ SVN_ERR(pb->notify_func(pb->notify_baton,
+ ffd->min_unpacked_rev / ffd->max_files_per_dir,
+ svn_fs_pack_notify_noop, pool));
return SVN_NO_ERROR;
}
@@ -2122,7 +2122,7 @@ svn_fs_fs__pack(svn_fs_t *fs,
if (!ffd->max_files_per_dir)
{
if (notify_func)
- (*notify_func)(notify_baton, -1, svn_fs_pack_notify_noop, pool);
+ SVN_ERR(notify_func(notify_baton, -1, svn_fs_pack_notify_noop, pool));
return SVN_NO_ERROR;
}
@@ -2132,9 +2132,9 @@ svn_fs_fs__pack(svn_fs_t *fs,
if (fully_packed)
{
if (notify_func)
- (*notify_func)(notify_baton,
- ffd->min_unpacked_rev / ffd->max_files_per_dir,
- svn_fs_pack_notify_noop, pool);
+ SVN_ERR(notify_func(notify_baton,
+ ffd->min_unpacked_rev / ffd->max_files_per_dir,
+ svn_fs_pack_notify_noop, pool));
return SVN_NO_ERROR;
}
diff --git a/subversion/libsvn_fs_fs/recovery.c b/subversion/libsvn_fs_fs/recovery.c
index eef06f65942a..09030f4e6f97 100644
--- a/subversion/libsvn_fs_fs/recovery.c
+++ b/subversion/libsvn_fs_fs/recovery.c
@@ -471,9 +471,15 @@ recover_body(void *baton, apr_pool_t *pool)
}
/* Prune younger-than-(newfound-youngest) revisions from the rep
- cache if sharing is enabled taking care not to create the cache
- if it does not exist. */
- if (ffd->rep_sharing_allowed)
+ cache, taking care not to create the cache if it does not exist.
+
+ We do this whenever rep-cache.db exists, whether it's currently enabled
+ or not, to prevent a data loss that could result from having revisions
+ created after this 'recover' operation referring to rep-cache.db rows
+ that were created before the recover and that point to revisions younger-
+ than-(newfound-youngest).
+ */
+ if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT)
{
svn_boolean_t rep_cache_exists;
diff --git a/subversion/libsvn_fs_fs/rep-cache-db.h b/subversion/libsvn_fs_fs/rep-cache-db.h
index e66253810c9d..4cad0667a8fe 100644
--- a/subversion/libsvn_fs_fs/rep-cache-db.h
+++ b/subversion/libsvn_fs_fs/rep-cache-db.h
@@ -1,4 +1,4 @@
-/* This file is automatically generated from rep-cache-db.sql and subversion/libsvn_fs_fs/token-map.h.
+/* This file is automatically generated from rep-cache-db.sql and token-map.h.
* Do not edit this file -- edit the source and rerun gen-make.py */
#define STMT_CREATE_SCHEMA_V1 0
@@ -38,7 +38,7 @@
#define STMT_SET_REP 3
#define STMT_3_INFO {"STMT_SET_REP", NULL}
#define STMT_3 \
- "INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size) " \
+ "INSERT OR IGNORE INTO rep_cache (hash, revision, offset, size, expanded_size) " \
"VALUES (?1, ?2, ?3, ?4, ?5) " \
""
diff --git a/subversion/libsvn_fs_fs/rep-cache-db.sql b/subversion/libsvn_fs_fs/rep-cache-db.sql
index cd89f35c63ee..a700a9dcd026 100644
--- a/subversion/libsvn_fs_fs/rep-cache-db.sql
+++ b/subversion/libsvn_fs_fs/rep-cache-db.sql
@@ -61,7 +61,7 @@ WHERE hash = ?1
-- STMT_SET_REP
/* Works for both V1 and V2 schemas. */
-INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size)
+INSERT OR IGNORE INTO rep_cache (hash, revision, offset, size, expanded_size)
VALUES (?1, ?2, ?3, ?4, ?5)
-- STMT_GET_REPS_FOR_RANGE
diff --git a/subversion/libsvn_fs_fs/rep-cache.c b/subversion/libsvn_fs_fs/rep-cache.c
index b0b81fad9ac3..c51cde3954b4 100644
--- a/subversion/libsvn_fs_fs/rep-cache.c
+++ b/subversion/libsvn_fs_fs/rep-cache.c
@@ -328,7 +328,6 @@ svn_fs_fs__set_rep_reference(svn_fs_t *fs,
{
fs_fs_data_t *ffd = fs->fsap_data;
svn_sqlite__stmt_t *stmt;
- svn_error_t *err;
svn_checksum_t checksum;
checksum.kind = svn_checksum_sha1;
checksum.digest = rep->sha1_digest;
@@ -351,28 +350,7 @@ svn_fs_fs__set_rep_reference(svn_fs_t *fs,
(apr_int64_t) rep->size,
(apr_int64_t) rep->expanded_size));
- err = svn_sqlite__insert(NULL, stmt);
- if (err)
- {
- representation_t *old_rep;
-
- if (err->apr_err != SVN_ERR_SQLITE_CONSTRAINT)
- return svn_error_trace(err);
-
- svn_error_clear(err);
-
- /* Constraint failed so the mapping for SHA1_CHECKSUM->REP
- should exist. If so that's cool -- just do nothing. If not,
- that's a red flag! */
- SVN_ERR(svn_fs_fs__get_rep_reference(&old_rep, fs, &checksum, pool));
-
- if (!old_rep)
- {
- /* Something really odd at this point, we failed to insert the
- checksum AND failed to read an existing checksum. Do we need
- to flag this? */
- }
- }
+ SVN_ERR(svn_sqlite__insert(NULL, stmt));
return SVN_NO_ERROR;
}
diff --git a/subversion/libsvn_fs_fs/revprops.c b/subversion/libsvn_fs_fs/revprops.c
index 6d41fd882d7e..bba40ce82027 100644
--- a/subversion/libsvn_fs_fs/revprops.c
+++ b/subversion/libsvn_fs_fs/revprops.c
@@ -261,7 +261,7 @@ cache_revprops(svn_boolean_t *is_cached,
}
/* Read the non-packed revprops for revision REV in FS, put them into the
- * revprop cache if PROPULATE_CACHE is set and return them in *PROPERTIES.
+ * revprop cache if PROPULATE_CACHE is set and return them in *PROPERTIES.
*
* If the data could not be read due to an otherwise recoverable error,
* leave *PROPERTIES unchanged. No error will be returned in that case.
@@ -672,6 +672,64 @@ read_pack_revprop(packed_revprops_t **revprops,
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_fs_fs__get_revision_props_size(apr_off_t *props_size_p,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *scratch_pool)
+{
+ fs_fs_data_t *ffd = fs->fsap_data;
+
+ /* should they be available at all? */
+ SVN_ERR(svn_fs_fs__ensure_revision_exists(rev, fs, scratch_pool));
+
+ /* if REV had not been packed when we began, try reading it from the
+ * non-packed shard. If that fails, we will fall through to packed
+ * shard reads. */
+ if (!svn_fs_fs__is_packed_revprop(fs, rev))
+ {
+ const char *path = svn_fs_fs__path_revprops(fs, rev, scratch_pool);
+ svn_error_t *err;
+ apr_file_t *file;
+ svn_filesize_t file_size;
+
+ err = svn_io_file_open(&file, path, APR_FOPEN_READ, APR_OS_DEFAULT,
+ scratch_pool);
+ if (!err)
+ err = svn_io_file_size_get(&file_size, file, scratch_pool);
+ if (!err)
+ {
+ *props_size_p = (apr_off_t)file_size;
+ return SVN_NO_ERROR;
+ }
+ else if (!APR_STATUS_IS_ENOENT(err->apr_err)
+ || ffd->format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT)
+ {
+ return svn_error_trace(err);
+ }
+
+ /* fall through: maybe the revision got packed while we were looking */
+ svn_error_clear(err);
+ }
+
+ /* Try reading packed revprops. If that fails, REV is most
+ * likely invalid (or its revprops highly contested). */
+ {
+ packed_revprops_t *revprops;
+
+ /* ### This is inefficient -- reading all the revprops in a pack. We
+ should just read the index. */
+ SVN_ERR(read_pack_revprop(&revprops, fs, rev,
+ TRUE /*read_all*/, FALSE /*populate_cache*/,
+ scratch_pool));
+ *props_size_p = (apr_off_t)APR_ARRAY_IDX(revprops->sizes,
+ rev - revprops->start_revision,
+ apr_size_t);
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
*
* Allocations will be done in POOL.
diff --git a/subversion/libsvn_fs_fs/revprops.h b/subversion/libsvn_fs_fs/revprops.h
index 37063f96e9ae..32df18387a68 100644
--- a/subversion/libsvn_fs_fs/revprops.h
+++ b/subversion/libsvn_fs_fs/revprops.h
@@ -62,6 +62,15 @@ svn_fs_fs__upgrade_cleanup_pack_revprops(svn_fs_t *fs,
void
svn_fs_fs__reset_revprop_cache(svn_fs_t *fs);
+/* Set *PROPS_SIZE_P to the size in bytes on disk of the revprops for
+ * revision REV in FS. The size excludes indexes.
+ */
+svn_error_t *
+svn_fs_fs__get_revision_props_size(apr_off_t *props_size_p,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *scratch_pool);
+
/* Read the revprops for revision REV in FS and return them in *PROPERTIES_P.
* If REFRESH is set, clear the revprop cache before accessing the data.
*
diff --git a/subversion/libsvn_fs_fs/stats.c b/subversion/libsvn_fs_fs/stats.c
index 36992dbaeb66..98a421f20a86 100644
--- a/subversion/libsvn_fs_fs/stats.c
+++ b/subversion/libsvn_fs_fs/stats.c
@@ -28,7 +28,6 @@
#include "private/svn_cache.h"
#include "private/svn_sorts_private.h"
#include "private/svn_string_private.h"
-#include "private/svn_fs_fs_private.h"
#include "index.h"
#include "pack.h"
@@ -37,6 +36,7 @@
#include "fs_fs.h"
#include "cached_data.h"
#include "low_level.h"
+#include "revprops.h"
#include "../libsvn_fs/fs-loader.h"
@@ -488,7 +488,7 @@ parse_representation(rep_stats_t **representation,
}
}
- svn_sort__array_insert(revision_info->representations, &result, idx);
+ SVN_ERR(svn_sort__array_insert2(revision_info->representations, &result, idx));
}
*representation = result;
@@ -1397,3 +1397,96 @@ svn_fs_fs__get_stats(svn_fs_fs__stats_t **stats,
return SVN_NO_ERROR;
}
+
+/* Baton for rev_size_index_entry_cb. */
+struct rev_size_baton_t {
+ svn_revnum_t revision;
+ apr_off_t rev_size;
+};
+
+/* Implements svn_fs_fs__dump_index_func_t, summing object sizes for
+ * revision BATON->revision into BATON->rev_size.
+ */
+static svn_error_t *
+rev_size_index_entry_cb(const svn_fs_fs__p2l_entry_t *entry,
+ void *baton,
+ apr_pool_t *scratch_pool)
+{
+ struct rev_size_baton_t *b = baton;
+
+ if (entry->item.revision == b->revision)
+ b->rev_size += entry->size;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_fs_fs__revision_size(apr_off_t *rev_size,
+ svn_fs_t *fs,
+ svn_revnum_t revision,
+ apr_pool_t *scratch_pool)
+{
+ /* Get the size of the revision (excluding rev-props) */
+ if (svn_fs_fs__use_log_addressing(fs))
+ {
+ /* This works for a packed or a non-packed revision.
+ We could provide an optimized case for a non-packed revision
+ using svn_fs_fs__p2l_get_max_offset(). */
+ struct rev_size_baton_t b = { 0, 0 };
+
+ b.revision = revision;
+ SVN_ERR(svn_fs_fs__dump_index(fs, revision,
+ rev_size_index_entry_cb, &b,
+ NULL, NULL, scratch_pool));
+ *rev_size = b.rev_size;
+ }
+ else
+ {
+ svn_fs_fs__revision_file_t *rev_file;
+ svn_revnum_t min_unpacked_rev;
+
+ SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, revision,
+ scratch_pool, scratch_pool));
+ SVN_ERR(svn_fs_fs__min_unpacked_rev(&min_unpacked_rev, fs,
+ scratch_pool));
+ if (revision < min_unpacked_rev)
+ {
+ int shard_size = svn_fs_fs__shard_size(fs);
+ apr_off_t start_offset, end_offset;
+
+ SVN_ERR(svn_fs_fs__get_packed_offset(&start_offset, fs, revision,
+ scratch_pool));
+ if (((revision + 1) % shard_size) == 0)
+ {
+ svn_filesize_t file_size;
+
+ SVN_ERR(svn_io_file_size_get(&file_size, rev_file->file, scratch_pool));
+ end_offset = (apr_off_t)file_size;
+ }
+ else
+ {
+ SVN_ERR(svn_fs_fs__get_packed_offset(&end_offset, fs,
+ revision + 1, scratch_pool));
+ }
+ *rev_size = (end_offset - start_offset);
+ }
+ else
+ {
+ svn_filesize_t file_size;
+
+ SVN_ERR(svn_io_file_size_get(&file_size, rev_file->file, scratch_pool));
+ *rev_size = (apr_off_t)file_size;
+ }
+
+ SVN_ERR(svn_fs_fs__close_revision_file(rev_file));
+ }
+
+ /* Add the size of the rev-props */
+ {
+ apr_off_t size;
+
+ SVN_ERR(svn_fs_fs__get_revision_props_size(&size, fs, revision, scratch_pool));
+ *rev_size += size;
+ }
+
+ return SVN_NO_ERROR;
+}
diff --git a/subversion/libsvn_fs_fs/temp_serializer.c b/subversion/libsvn_fs_fs/temp_serializer.c
index f6e9e3a0971c..b4f6b86d8ed1 100644
--- a/subversion/libsvn_fs_fs/temp_serializer.c
+++ b/subversion/libsvn_fs_fs/temp_serializer.c
@@ -1013,13 +1013,13 @@ slowly_replace_dir_entry(void **data,
APR_ARRAY_IDX(entries, idx, svn_fs_dirent_t *)
= replace_baton->new_entry;
else
- svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
+ SVN_ERR(svn_sort__array_insert2(entries, &replace_baton->new_entry, idx));
}
else
{
/* Remove the old ENTRY. */
if (entry)
- svn_sort__array_delete(entries, idx, 1);
+ SVN_ERR(svn_sort__array_delete2(entries, idx, 1));
}
return svn_fs_fs__serialize_dir_entries(data, data_len, dir, pool);
diff --git a/subversion/libsvn_fs_fs/temp_serializer.h b/subversion/libsvn_fs_fs/temp_serializer.h
index 187c8d000206..32bb554ba87c 100644
--- a/subversion/libsvn_fs_fs/temp_serializer.h
+++ b/subversion/libsvn_fs_fs/temp_serializer.h
@@ -53,7 +53,7 @@ svn_fs_fs__noderev_deserialize(void *buffer,
/**
* Adds position information to the raw window data in WINDOW.
*/
-typedef struct
+typedef struct svn_fs_fs__raw_cached_window_t
{
/* the (unprocessed) txdelta window byte sequence cached / to be cached */
svn_string_t window;
@@ -89,7 +89,7 @@ svn_fs_fs__deserialize_raw_window(void **item,
* #svn_txdelta_window_t is not sufficient for caching the data it
* represents because data read process needs auxiliary information.
*/
-typedef struct
+typedef struct svn_fs_fs__txdelta_cached_window_t
{
/* the txdelta window information cached / to be cached */
svn_txdelta_window_t *window;
@@ -377,7 +377,7 @@ typedef struct svn_fs_fs__changes_list_t
of elements in the list is a multiple of our block / range size. */
svn_boolean_t eol;
- /* Array of #svn_fs_x__change_t * representing a consecutive sub-range of
+ /* Array of #svn_fs_fs__change_t * representing a consecutive sub-range of
elements in a changed paths list. */
/* number of entries in the array */
diff --git a/subversion/libsvn_fs_fs/transaction.c b/subversion/libsvn_fs_fs/transaction.c
index eb6fefaeae22..9e1e40c86ce9 100644
--- a/subversion/libsvn_fs_fs/transaction.c
+++ b/subversion/libsvn_fs_fs/transaction.c
@@ -587,7 +587,7 @@ unparse_dir_entry(svn_fs_dirent_t *dirent,
: sizeof(SVN_FS_FS__KIND_DIR);
apr_size_t value_len = type_len + id_str->len;
- /* A buffer with sufficient space for
+ /* A buffer with sufficient space for
* - both string lines
* - 4 newlines
* - 2 lines K/V lines containing a number each
diff --git a/subversion/libsvn_fs_fs/tree.c b/subversion/libsvn_fs_fs/tree.c
index 76209f368bf9..764052b3fa89 100644
--- a/subversion/libsvn_fs_fs/tree.c
+++ b/subversion/libsvn_fs_fs/tree.c
@@ -920,6 +920,25 @@ try_match_last_node(dag_node_t **node_p,
return SVN_NO_ERROR;
}
+/* Helper for open_path() that constructs and returns an appropriate
+ SVN_ERR_FS_NOT_DIRECTORY error. */
+static svn_error_t *
+err_not_directory(svn_fs_root_t *root,
+ const char *path,
+ apr_pool_t *scratch_pool)
+{
+ const char *msg;
+
+ msg = root->is_txn_root
+ ? apr_psprintf(scratch_pool,
+ _("Failure opening '%s' in transaction '%s'"),
+ path, root->txn)
+ : apr_psprintf(scratch_pool,
+ _("Failure opening '%s' in revision %ld"),
+ path, root->rev);
+
+ return svn_error_quick_wrap(SVN_FS__ERR_NOT_DIRECTORY(root->fs, path), msg);
+}
/* Open the node identified by PATH in ROOT, allocating in POOL. Set
*PARENT_PATH_P to a path from the node up to ROOT. The resulting
@@ -1016,12 +1035,26 @@ open_path(parent_path_t **parent_path_p,
SVN_ERR(dag_node_cache_get(&here, root, directory, pool));
/* Did the shortcut work? */
- if (here)
+ if (here && svn_fs_fs__dag_node_kind(here) == svn_node_dir)
{
apr_size_t dirname_len = strlen(directory);
path_so_far->len = dirname_len;
rest = path + dirname_len + 1;
}
+ else if (here)
+ {
+ /* The parent node is not a directory. We are looking for some
+ sub-path, so that sub-path will not exist. That will be o.k.
+ if we are just here to check for the path's existence, but
+ should result in an error otherwise. */
+ if (flags & open_path_allow_null)
+ {
+ *parent_path_p = NULL;
+ return SVN_NO_ERROR;
+ }
+ else
+ return svn_error_trace(err_not_directory(root, directory, pool));
+ }
}
}
@@ -1144,8 +1177,6 @@ open_path(parent_path_t **parent_path_p,
/* The path isn't finished yet; we'd better be in a directory. */
if (svn_fs_fs__dag_node_kind(child) != svn_node_dir)
{
- const char *msg;
-
/* Since this is not a directory and we are looking for some
sub-path, that sub-path will not exist. That will be o.k.,
if we are just here to check for the path's existence. */
@@ -1156,14 +1187,8 @@ open_path(parent_path_t **parent_path_p,
}
/* It's really a problem ... */
- msg = root->is_txn_root
- ? apr_psprintf(iterpool,
- _("Failure opening '%s' in transaction '%s'"),
- path, root->txn)
- : apr_psprintf(iterpool,
- _("Failure opening '%s' in revision %ld"),
- path, root->rev);
- SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data), msg);
+ return svn_error_trace(
+ err_not_directory(root, path_so_far->data, iterpool));
}
rest = next;
@@ -4619,7 +4644,7 @@ make_txn_root(svn_fs_root_t **root_p,
svn_fs_fs__dag_deserialize,
APR_HASH_KEY_STRING,
32, 20, FALSE,
- apr_pstrcat(pool, txn, ":TXN",
+ apr_pstrcat(pool, root->txn, ":TXN",
SVN_VA_NULL),
root->pool));
diff --git a/subversion/libsvn_fs_fs/verify.c b/subversion/libsvn_fs_fs/verify.c
index 7fe5ecbbd494..9d70d6cfbc8d 100644
--- a/subversion/libsvn_fs_fs/verify.c
+++ b/subversion/libsvn_fs_fs/verify.c
@@ -681,10 +681,10 @@ compare_p2l_to_rev(svn_fs_t *fs,
NULL,
_("p2l index entry for revision r%ld"
" at offset %s contains invalid item"
- " type %d"),
+ " type %u"),
start,
apr_off_t_toa(pool, offset),
- entry->type);
+ (unsigned int)entry->type);
/* There can be only one changes entry and that has a fixed type
* and item number. Its presence and parse-ability will be checked
@@ -694,11 +694,12 @@ compare_p2l_to_rev(svn_fs_t *fs,
return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION,
NULL,
_("p2l index entry for changes in"
- " revision r%ld is item %ld of type"
- " %d at offset %s"),
+ " revision r%ld is item"
+ " %"APR_UINT64_T_FMT
+ " of type %u at offset %s"),
entry->item.revision,
entry->item.number,
- entry->type,
+ (unsigned int)entry->type,
apr_off_t_toa(pool, offset));
/* Check contents. */