Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0346A10544 for ; Sat, 3 Jan 2015 14:00:57 +0000 (UTC) Received: (qmail 86711 invoked by uid 500); 3 Jan 2015 14:00:56 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 86647 invoked by uid 500); 3 Jan 2015 14:00:56 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 86402 invoked by uid 99); 3 Jan 2015 14:00:56 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 03 Jan 2015 14:00:56 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id 85BB9AC0A5C; Sat, 3 Jan 2015 14:00:52 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1649205 [20/30] - in /subversion/branches/authzperf: ./ build/ build/ac-macros/ notes/ subversion/bindings/ctypes-python/ subversion/bindings/cxxhl/ subversion/bindings/javahl/tests/org/apache/subversion/javahl/ subversion/bindings/swig/ s... Date: Sat, 03 Jan 2015 14:00:44 -0000 To: commits@subversion.apache.org From: brane@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150103140052.85BB9AC0A5C@hades.apache.org> Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/util.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/util.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_fs_x/util.c (original) +++ subversion/branches/authzperf/subversion/libsvn_fs_x/util.c Sat Jan 3 14:00:41 2015 @@ -55,7 +55,7 @@ are likely some errors because of that. svn_boolean_t svn_fs_x__is_packed_rev(svn_fs_t *fs, svn_revnum_t rev) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return (rev < ffd->min_unpacked_rev); } @@ -64,7 +64,7 @@ svn_fs_x__is_packed_rev(svn_fs_t *fs, sv svn_boolean_t svn_fs_x__is_packed_revprop(svn_fs_t *fs, svn_revnum_t rev) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; /* rev 0 will not be packed */ return (rev < ffd->min_unpacked_rev) && (rev != 0); @@ -73,7 +73,7 @@ svn_fs_x__is_packed_revprop(svn_fs_t *fs svn_revnum_t svn_fs_x__packed_base_rev(svn_fs_t *fs, svn_revnum_t rev) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return rev < ffd->min_unpacked_rev ? rev - (rev % ffd->max_files_per_dir) @@ -83,7 +83,7 @@ svn_fs_x__packed_base_rev(svn_fs_t *fs, svn_revnum_t svn_fs_x__pack_size(svn_fs_t *fs, svn_revnum_t rev) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return rev < ffd->min_unpacked_rev ? ffd->max_files_per_dir : 1; } @@ -141,7 +141,7 @@ const char * svn_fs_x__path_rev_packed(svn_fs_t *fs, svn_revnum_t rev, const char *kind, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; assert(svn_fs_x__is_packed_rev(fs, rev)); return svn_dirent_join_many(pool, fs->path, PATH_REVS_DIR, @@ -154,7 +154,7 @@ svn_fs_x__path_rev_packed(svn_fs_t *fs, const char * svn_fs_x__path_rev_shard(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return svn_dirent_join_many(pool, fs->path, PATH_REVS_DIR, apr_psprintf(pool, "%ld", rev / ffd->max_files_per_dir), @@ -172,24 +172,6 @@ svn_fs_x__path_rev(svn_fs_t *fs, svn_rev } const char * -svn_fs_x__path_l2p_index(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *pool) -{ - return apr_psprintf(pool, "%s" PATH_EXT_L2P_INDEX, - svn_fs_x__path_rev_absolute(fs, rev, pool)); -} - -const char * -svn_fs_x__path_p2l_index(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *pool) -{ - return apr_psprintf(pool, "%s" PATH_EXT_P2L_INDEX, - svn_fs_x__path_rev_absolute(fs, rev, pool)); -} - -const char * svn_fs_x__path_rev_absolute(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool) @@ -204,7 +186,7 @@ svn_fs_x__path_revprops_shard(svn_fs_t * svn_revnum_t rev, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return svn_dirent_join_many(pool, fs->path, PATH_REVPROPS_DIR, apr_psprintf(pool, "%ld", @@ -217,7 +199,7 @@ svn_fs_x__path_revprops_pack_shard(svn_f svn_revnum_t rev, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return svn_dirent_join_many(pool, fs->path, PATH_REVPROPS_DIR, apr_psprintf(pool, "%ld" PATH_EXT_PACKED_SHARD, @@ -270,11 +252,18 @@ combine_txn_id_string(svn_fs_x__txn_id_t } const char * +svn_fs_x__path_txns_dir(svn_fs_t *fs, + apr_pool_t *pool) +{ + return svn_dirent_join(fs->path, PATH_TXNS_DIR, pool); +} + +const char * svn_fs_x__path_txn_dir(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, apr_pool_t *pool) { - return svn_dirent_join_many(pool, fs->path, PATH_TXNS_DIR, + return svn_dirent_join_many(pool, svn_fs_x__path_txns_dir(fs, pool), combine_txn_id_string(txn_id, PATH_EXT_TXN, pool), SVN_VA_NULL); @@ -359,6 +348,13 @@ svn_fs_x__path_min_unpacked_rev(svn_fs_t } const char * +svn_fs_x__path_txn_proto_revs(svn_fs_t *fs, + apr_pool_t *pool) +{ + return svn_dirent_join(fs->path, PATH_TXN_PROTOS_DIR, pool); +} + +const char * svn_fs_x__path_txn_item_index(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, apr_pool_t *pool) @@ -372,7 +368,7 @@ svn_fs_x__path_txn_proto_rev(svn_fs_t *f svn_fs_x__txn_id_t txn_id, apr_pool_t *pool) { - return svn_dirent_join_many(pool, fs->path, PATH_TXN_PROTOS_DIR, + return svn_dirent_join_many(pool, svn_fs_x__path_txn_proto_revs(fs, pool), combine_txn_id_string(txn_id, PATH_EXT_REV, pool), SVN_VA_NULL); @@ -383,7 +379,7 @@ svn_fs_x__path_txn_proto_rev_lock(svn_fs svn_fs_x__txn_id_t txn_id, apr_pool_t *pool) { - return svn_dirent_join_many(pool, fs->path, PATH_TXN_PROTOS_DIR, + return svn_dirent_join_many(pool, svn_fs_x__path_txn_proto_revs(fs, pool), combine_txn_id_string(txn_id, PATH_EXT_REV_LOCK, pool), @@ -392,22 +388,20 @@ svn_fs_x__path_txn_proto_rev_lock(svn_fs const char * svn_fs_x__path_txn_node_rev(svn_fs_t *fs, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, apr_pool_t *pool) { - char *filename = (char *)svn_fs_x__id_unparse(id, pool)->data; - *strrchr(filename, '.') = '\0'; + const char *filename = svn_fs_x__id_unparse(id, pool)->data; + apr_int64_t txn_id = svn_fs_x__get_txn_id(id->change_set); - return svn_dirent_join(svn_fs_x__path_txn_dir(fs, svn_fs_x__id_txn_id(id), - pool), - apr_psprintf(pool, PATH_PREFIX_NODE "%s", - filename), + return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool), + apr_psprintf(pool, PATH_PREFIX_NODE "%s", filename), pool); } const char * svn_fs_x__path_txn_node_props(svn_fs_t *fs, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, apr_pool_t *pool) { return apr_pstrcat(pool, svn_fs_x__path_txn_node_rev(fs, id, pool), @@ -415,7 +409,9 @@ svn_fs_x__path_txn_node_props(svn_fs_t * } const char * -svn_fs_x__path_txn_node_children(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool) +svn_fs_x__path_txn_node_children(svn_fs_t *fs, + const svn_fs_x__id_t *id, + apr_pool_t *pool) { return apr_pstrcat(pool, svn_fs_x__path_txn_node_rev(fs, id, pool), PATH_EXT_CHILDREN, SVN_VA_NULL); @@ -462,14 +458,14 @@ svn_fs_x__read_min_unpacked_rev(svn_revn SVN_ERR(svn_io_read_length_line(file, buf, &len, pool)); SVN_ERR(svn_io_file_close(file, pool)); - *min_unpacked_rev = SVN_STR_TO_REV(buf); + SVN_ERR(svn_revnum_parse(min_unpacked_rev, buf, NULL)); return SVN_NO_ERROR; } svn_error_t * svn_fs_x__update_min_unpacked_rev(svn_fs_t *fs, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; return svn_fs_x__read_min_unpacked_rev(&ffd->min_unpacked_rev, fs, pool); } @@ -495,6 +491,24 @@ svn_fs_x__write_min_unpacked_rev(svn_fs_ return SVN_NO_ERROR; } + +svn_error_t * +svn_fs_x__read_current(svn_revnum_t *rev, + svn_fs_t *fs, + apr_pool_t *pool) +{ + const char *str; + svn_stringbuf_t *content; + SVN_ERR(svn_fs_x__read_content(&content, + svn_fs_x__path_current(fs, pool), + pool)); + SVN_ERR(svn_revnum_parse(rev, content->data, &str)); + if (*str != '\n') + return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, + _("Corrupt 'current' file")); + + return SVN_NO_ERROR; +} /* Atomically update the 'current' file to hold the specifed REV. Perform temporary allocations in POOL. */ Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/util.h URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/util.h?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_fs_x/util.h (original) +++ subversion/branches/authzperf/subversion/libsvn_fs_x/util.h Sat Jan 3 14:00:41 2015 @@ -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. */ @@ -135,16 +137,6 @@ svn_fs_x__path_rev(svn_fs_t *fs, apr_pool_t *pool); const char * -svn_fs_x__path_l2p_index(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *pool); - -const char * -svn_fs_x__path_p2l_index(svn_fs_t *fs, - svn_revnum_t rev, - apr_pool_t *pool); - -const char * svn_fs_x__path_revprops_shard(svn_fs_t *fs, svn_revnum_t rev, apr_pool_t *pool); @@ -167,11 +159,21 @@ svn_error_t * svn_fs_x__txn_by_name(svn_fs_x__txn_id_t *txn_id, const char *txn_name); +/* Return the path of the directory containing the transaction TXN_ID in FS. + * The result will be allocated in POOL. + */ const char * svn_fs_x__path_txn_dir(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, apr_pool_t *pool); +/* Return the path of the 'transactions' directory in FS. + * The result will be allocated in POOL. + */ +const char * +svn_fs_x__path_txns_dir(svn_fs_t *fs, + apr_pool_t *pool); + /* Return the name of the sha1->rep mapping file in transaction TXN_ID * within FS for the given SHA1 checksum. Use POOL for allocations. */ @@ -181,6 +183,16 @@ svn_fs_x__path_txn_sha1(svn_fs_t *fs, const unsigned char *sha1, apr_pool_t *pool); +/* Return the path of the 'txn-protorevs' directory in FS, even if that + * folder may not exist in FS. The result will be allocated in POOL. + */ +const char * +svn_fs_x__path_txn_proto_revs(svn_fs_t *fs, + apr_pool_t *pool); + +/* Return the path of the proto-revision file for transaction TXN_ID in FS. + * The result will be allocated in POOL. + */ const char * svn_fs_x__path_txn_changes(svn_fs_t *fs, svn_fs_x__txn_id_t txn_id, @@ -233,17 +245,17 @@ svn_fs_x__path_txn_proto_rev_lock(svn_fs const char * svn_fs_x__path_txn_node_rev(svn_fs_t *fs, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, apr_pool_t *pool); const char * svn_fs_x__path_txn_node_props(svn_fs_t *fs, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, apr_pool_t *pool); const char * svn_fs_x__path_txn_node_children(svn_fs_t *fs, - const svn_fs_id_t *id, + const svn_fs_x__id_t *id, apr_pool_t *pool); /* Check that BUF, a nul-terminated buffer of text from file PATH, @@ -276,6 +288,14 @@ svn_fs_x__write_min_unpacked_rev(svn_fs_ svn_revnum_t revnum, apr_pool_t *scratch_pool); +/* Set *REV to the value read from the 'current' file. Perform temporary + * allocations in POOL. + */ +svn_error_t * +svn_fs_x__read_current(svn_revnum_t *rev, + svn_fs_t *fs, + apr_pool_t *pool); + /* Atomically update the 'current' file to hold the specifed REV. Perform temporary allocations in POOL. */ svn_error_t * Modified: subversion/branches/authzperf/subversion/libsvn_fs_x/verify.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_fs_x/verify.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_fs_x/verify.c (original) +++ subversion/branches/authzperf/subversion/libsvn_fs_x/verify.c Sat Jan 3 14:00:41 2015 @@ -22,6 +22,7 @@ #include "verify.h" #include "fs_x.h" +#include "svn_time.h" #include "private/svn_subr_private.h" #include "cached_data.h" @@ -57,7 +58,7 @@ typedef struct verify_walker_baton_t /* Used by svn_fs_x__verify(). Implements svn_fs_x__walk_rep_reference().walker. */ static svn_error_t * -verify_walker(representation_t *rep, +verify_walker(svn_fs_x__representation_t *rep, void *baton, svn_fs_t *fs, apr_pool_t *scratch_pool) @@ -133,6 +134,93 @@ verify_rep_cache(svn_fs_t *fs, return SVN_NO_ERROR; } +/* Verify that the MD5 checksum of the data between offsets START and END + * in FILE matches the EXPECTED checksum. If there is a mismatch use the + * 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, + const char *name, + apr_off_t start, + apr_off_t end, + svn_checksum_t *expected, + 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; + 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)); + 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_checksum_update(context, buffer, to_read)); + size -= to_read; + + if (cancel_func) + SVN_ERR(cancel_func(cancel_baton)); + } + + SVN_ERR(svn_checksum_final(&actual, context, scratch_pool)); + + /* Verify that it matches the expected checksum. */ + if (!svn_checksum_match(expected, 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, + _("%s checksum mismatch in file %s"), + name, file_name)); + } + + return SVN_NO_ERROR; +} + +/* Verify the MD5 checksums of the index data in the rev / pack file + * containing revision START in FS. If given, invoke CANCEL_FUNC with + * CANCEL_BATON at regular intervals. Use SCRATCH_POOL for temporary + * allocations. + */ +static svn_error_t * +verify_index_checksums(svn_fs_t *fs, + svn_revnum_t start, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *scratch_pool) +{ + svn_fs_x__revision_file_t *rev_file; + + /* 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)); + + /* 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, + 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, + cancel_func, cancel_baton, scratch_pool)); + + /* Done. */ + SVN_ERR(svn_fs_x__close_revision_file(rev_file)); + + return SVN_NO_ERROR; +} + /* Verify that for all log-to-phys index entries for revisions START to * START + COUNT-1 in FS there is a consistent entry in the phys-to-log * index. If given, invoke CANCEL_FUNC with CANCEL_BATON at regular @@ -150,8 +238,14 @@ 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_x__revision_file_t *rev_file; + SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, pool, + iterpool)); + /* determine the range of items to check for each revision */ - SVN_ERR(svn_fs_x__l2p_get_max_ids(&max_ids, fs, start, count, pool)); + SVN_ERR(svn_fs_x__l2p_get_max_ids(&max_ids, fs, start, count, pool, + iterpool)); /* check all items in all revisions if the given range */ for (i = 0; i < max_ids->nelts; ++i) @@ -164,24 +258,25 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, { apr_off_t offset; apr_uint32_t sub_item; - svn_fs_x__id_part_t l2p_item; - svn_fs_x__id_part_t *p2l_item; + svn_fs_x__id_t l2p_item; + svn_fs_x__id_t *p2l_item; l2p_item.change_set = svn_fs_x__change_set_by_rev(revision); l2p_item.number = k; /* get L2P entry. Ignore unused entries. */ - SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, &l2p_item, - iterpool)); + SVN_ERR(svn_fs_x__item_offset(&offset, &sub_item, fs, rev_file, + &l2p_item, iterpool)); if (offset == -1) continue; /* find the corresponding P2L entry */ - SVN_ERR(svn_fs_x__p2l_item_lookup(&p2l_item, fs, start, - offset, sub_item, iterpool)); + SVN_ERR(svn_fs_x__p2l_item_lookup(&p2l_item, fs, rev_file, + revision, offset, sub_item, + iterpool, iterpool)); if (p2l_item == NULL) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("p2l index entry not found for " "PHYS o%s:s%ld returned by " @@ -189,8 +284,8 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, apr_off_t_toa(pool, offset), (long)sub_item, revision, (long)k); - if (!svn_fs_x__id_part_eq(&l2p_item, p2l_item)) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, + if (!svn_fs_x__id_eq(&l2p_item, p2l_item)) + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("p2l index info LOG r%ld:i%ld" " does not match " @@ -208,6 +303,8 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, svn_pool_destroy(iterpool); + SVN_ERR(svn_fs_x__close_revision_file(rev_file)); + return SVN_NO_ERROR; } @@ -227,13 +324,19 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, void *cancel_baton, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; apr_pool_t *iterpool = svn_pool_create(pool); apr_off_t max_offset; apr_off_t offset = 0; + /* 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, pool, + iterpool)); + /* 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, start, pool)); + SVN_ERR(svn_fs_x__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 */ @@ -244,10 +347,11 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, int i; /* get all entries for the current block */ - SVN_ERR(svn_fs_x__p2l_index_lookup(&entries, fs, start, offset, - ffd->p2l_page_size, iterpool)); + SVN_ERR(svn_fs_x__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_ITEM_INDEX_CORRUPTION, + return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL, _("p2l does not cover offset %s" " for revision %ld"), @@ -257,7 +361,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, last_entry = &APR_ARRAY_IDX(entries, entries->nelts-1, svn_fs_x__p2l_entry_t); offset = last_entry->offset + last_entry->size; - + for (i = 0; i < entries->nelts; ++i) { apr_uint32_t k; @@ -269,15 +373,15 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, { apr_off_t l2p_offset; apr_uint32_t sub_item; - svn_fs_x__id_part_t *p2l_item = &entry->items[k]; + svn_fs_x__id_t *p2l_item = &entry->items[k]; svn_revnum_t revision = svn_fs_x__get_revnum(p2l_item->change_set); SVN_ERR(svn_fs_x__item_offset(&l2p_offset, &sub_item, fs, - p2l_item, iterpool)); + rev_file, p2l_item, iterpool)); if (sub_item != k || l2p_offset != entry->offset) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("l2p index entry PHYS o%s:s%ld " "does not match p2l index value " @@ -297,6 +401,8 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, svn_pool_destroy(iterpool); + SVN_ERR(svn_fs_x__close_revision_file(rev_file)); + return SVN_NO_ERROR; } @@ -385,7 +491,7 @@ expected_checksum(apr_file_t *file, SVN_ERR(svn_io_file_name_get(&file_name, file, pool)); SVN_ERR(svn_io_file_name_get(&file_name, file, pool)); return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, - _("Checksum mismatch item at offset %s of " + _("Checksum mismatch in item at offset %s of " "length %s bytes in file %s"), apr_off_t_toa(pool, entry->offset), apr_off_t_toa(pool, entry->size), file_name); @@ -464,27 +570,30 @@ compare_p2l_to_rev(svn_fs_t *fs, void *cancel_baton, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; apr_pool_t *iterpool = svn_pool_create(pool); apr_off_t max_offset; apr_off_t offset = 0; - apr_file_t *rev_file; + svn_fs_x__revision_file_t *rev_file; /* 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, pool)); + SVN_ERR(svn_fs_x__open_pack_or_rev_file(&rev_file, fs, start, pool, + iterpool)); /* check file size vs. range covered by index */ - SVN_ERR(svn_io_file_seek(rev_file, APR_END, &offset, pool)); - SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, start, pool)); + SVN_ERR(svn_fs_x__auto_read_footer(rev_file)); + SVN_ERR(svn_fs_x__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, + if (rev_file->l2p_offset != 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(pool, offset), start, + apr_off_t_toa(pool, rev_file->l2p_offset), start, apr_off_t_toa(pool, max_offset)); - SVN_ERR(svn_io_file_aligned_seek(rev_file, ffd->block_size, NULL, 0, pool)); + SVN_ERR(svn_io_file_aligned_seek(rev_file->file, ffd->block_size, NULL, 0, + pool)); /* for all offsets in the file, get the P2L index entries and check them against the L2P index */ @@ -496,8 +605,14 @@ compare_p2l_to_rev(svn_fs_t *fs, svn_pool_clear(iterpool); /* get all entries for the current block */ - SVN_ERR(svn_fs_x__p2l_index_lookup(&entries, fs, start, offset, - ffd->p2l_page_size, iterpool)); + SVN_ERR(svn_fs_x__p2l_index_lookup(&entries, fs, rev_file, start, + offset, ffd->p2l_page_size, + iterpool, iterpool)); + + /* 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)); /* process all entries (and later continue with the next block) */ for (i = 0; i < entries->nelts; ++i) @@ -515,7 +630,7 @@ compare_p2l_to_rev(svn_fs_t *fs, /* p2l index must cover all rev / pack file offsets exactly once */ if (entry->offset != offset) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("p2l index entry for revision r%ld" " is non-contiguous between offsets " @@ -529,14 +644,16 @@ 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, entry->size, pool)); + SVN_ERR(read_all_nul(rev_file->file, entry->size, pool)); } - else if (entry->fnv1_checksum) + else { if (entry->size < STREAM_THRESHOLD) - SVN_ERR(expected_buffered_checksum(rev_file, entry, pool)); + SVN_ERR(expected_buffered_checksum(rev_file->file, entry, + pool)); else - SVN_ERR(expected_streamed_checksum(rev_file, entry, pool)); + SVN_ERR(expected_streamed_checksum(rev_file->file, entry, + pool)); } /* advance offset */ @@ -552,46 +669,126 @@ compare_p2l_to_rev(svn_fs_t *fs, return SVN_NO_ERROR; } -/* Verify that the log-to-phys indexes and phys-to-log indexes are - * consistent with each other. The function signature is similar to - * svn_fs_x__verify. +/* Verify that the revprops of the revisions START to END in FS can be + * accessed. Invoke CANCEL_FUNC with CANCEL_BATON at regular intervals. * * The values of START and END have already been auto-selected and - * verified. You may call this for format7 or higher repos. + * verified. */ static svn_error_t * -verify_index_consistency(svn_fs_t *fs, - svn_revnum_t start, - svn_revnum_t end, - svn_fs_progress_notify_func_t notify_func, - void *notify_baton, - svn_cancel_func_t cancel_func, - void *cancel_baton, - apr_pool_t *pool) +verify_revprops(svn_fs_t *fs, + svn_revnum_t start, + svn_revnum_t end, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; - svn_revnum_t revision, pack_start, pack_end; + svn_revnum_t revision; + apr_pool_t *iterpool = svn_pool_create(pool); + + for (revision = start; revision < end; ++revision) + { + svn_string_t *date; + apr_time_t timetemp; + + svn_pool_clear(iterpool); + + /* 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, iterpool)); + + /* The time stamp is the only revprop that, if given, needs to + * have a valid content. */ + if (date) + SVN_ERR(svn_time_from_cstring(&timetemp, date->data, iterpool)); + + if (cancel_func) + SVN_ERR(cancel_func(cancel_baton)); + } + + svn_pool_destroy(iterpool); + + return SVN_NO_ERROR; +} + +/* Verify that on-disk representation has not been tempered with (in a way + * that leaves the repository in a corrupted state). This compares log-to- + * phys with phys-to-log indexes, verifies the low-level checksums and + * checks that all revprops are available. The function signature is + * similar to svn_fs_x__verify. + * + * The values of START and END have already been auto-selected and + * verified. + */ +static svn_error_t * +verify_metadata_consistency(svn_fs_t *fs, + svn_revnum_t start, + svn_revnum_t end, + svn_fs_progress_notify_func_t notify_func, + void *notify_baton, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool) +{ + svn_error_t *err; + svn_fs_x__data_t *ffd = fs->fsap_data; + 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); + /* Check for external corruption to the indexes. */ + err = verify_index_checksums(fs, pack_start, cancel_func, + cancel_baton, iterpool); + /* two-way index check */ - SVN_ERR(compare_l2p_to_p2l_index(fs, pack_start, pack_end - pack_start, - cancel_func, cancel_baton, iterpool)); - SVN_ERR(compare_p2l_to_l2p_index(fs, pack_start, pack_end - pack_start, - cancel_func, cancel_baton, iterpool)); + if (!err) + err = compare_l2p_to_p2l_index(fs, pack_start, pack_end - pack_start, + cancel_func, cancel_baton, iterpool); + if (!err) + err = compare_p2l_to_l2p_index(fs, pack_start, pack_end - pack_start, + 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); + + /* ensure that revprops are available and accessible */ + if (!err) + err = verify_revprops(fs, pack_start, pack_end, + cancel_func, cancel_baton, 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)); - svn_pool_clear(iterpool); + /* 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); @@ -609,7 +806,7 @@ svn_fs_x__verify(svn_fs_t *fs, void *cancel_baton, apr_pool_t *pool) { - fs_x_data_t *ffd = fs->fsap_data; + svn_fs_x__data_t *ffd = fs->fsap_data; svn_revnum_t youngest = ffd->youngest_rev_cache; /* cache is current */ /* Input validation. */ @@ -622,9 +819,9 @@ svn_fs_x__verify(svn_fs_t *fs, /* log/phys index consistency. We need to check them first to make sure we can access the rev / pack files in format7. */ - SVN_ERR(verify_index_consistency(fs, start, end, - notify_func, notify_baton, - cancel_func, cancel_baton, pool)); + SVN_ERR(verify_metadata_consistency(fs, start, end, + notify_func, notify_baton, + cancel_func, cancel_baton, pool)); /* rep cache consistency */ SVN_ERR(verify_rep_cache(fs, start, end, notify_func, notify_baton, Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/blame.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/blame.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/blame.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/blame.c Sat Jan 3 14:00:41 2015 @@ -302,9 +302,8 @@ create_file_revs_body(serf_bucket_t **bo if (blame_ctx->include_merged_revisions) { - svn_ra_serf__add_tag_buckets(buckets, - "S:include-merged-revisions", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:include-merged-revisions", SVN_VA_NULL); } svn_ra_serf__add_tag_buckets(buckets, Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/commit.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/commit.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/commit.c Sat Jan 3 14:00:41 2015 @@ -226,7 +226,8 @@ create_checkout_body(serf_bucket_t **bkt svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href"); svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:activity-set"); - svn_ra_serf__add_tag_buckets(body_bkt, "D:apply-to-version", NULL, alloc); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:apply-to-version", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:checkout"); *bkt = body_bkt; Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/get_lock.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/get_lock.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/get_lock.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/get_lock.c Sat Jan 3 14:00:41 2015 @@ -243,7 +243,8 @@ create_getlock_body(serf_bucket_t **body "xmlns", "DAV:", SVN_VA_NULL); svn_ra_serf__add_open_tag_buckets(buckets, alloc, "prop", SVN_VA_NULL); - svn_ra_serf__add_tag_buckets(buckets, "lockdiscovery", NULL, alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "lockdiscovery", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(buckets, alloc, "prop"); svn_ra_serf__add_close_tag_buckets(buckets, alloc, "propfind"); Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/lock.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/lock.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/lock.c Sat Jan 3 14:00:41 2015 @@ -315,6 +315,19 @@ run_locks(svn_ra_serf__session_t *sess, && !SVN_ERR_IS_UNLOCK_ERROR(err) && !SVN_ERR_IS_LOCK_ERROR(err)) { + /* If the error that we are going to report is just about the + POST unlock hook, we should first report that the operation + succeeded, or the repository and working copy will be + out of sync... */ + + if (lock_func && + err->apr_err == SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED) + { + err = svn_error_compose_create( + err, lock_func(lock_baton, ctx->path, locking, + NULL, NULL, ctx->pool)); + } + return svn_error_trace(err); /* Don't go through callbacks */ } @@ -399,11 +412,11 @@ create_lock_body(serf_bucket_t **body_bk SVN_VA_NULL); svn_ra_serf__add_open_tag_buckets(buckets, alloc, "lockscope", SVN_VA_NULL); - svn_ra_serf__add_tag_buckets(buckets, "exclusive", NULL, alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, "exclusive", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(buckets, alloc, "lockscope"); svn_ra_serf__add_open_tag_buckets(buckets, alloc, "locktype", SVN_VA_NULL); - svn_ra_serf__add_tag_buckets(buckets, "write", NULL, alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, "write", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(buckets, alloc, "locktype"); if (ctx->lock->comment) Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/log.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/log.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/log.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/log.c Sat Jan 3 14:00:41 2015 @@ -442,23 +442,22 @@ create_log_body(serf_bucket_t **body_bkt if (log_ctx->changed_paths) { - svn_ra_serf__add_tag_buckets(buckets, - "S:discover-changed-paths", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:discover-changed-paths", + SVN_VA_NULL); } if (log_ctx->strict_node_history) { - svn_ra_serf__add_tag_buckets(buckets, - "S:strict-node-history", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:strict-node-history", SVN_VA_NULL); } if (log_ctx->include_merged_revisions) { - svn_ra_serf__add_tag_buckets(buckets, - "S:include-merged-revisions", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:include-merged-revisions", + SVN_VA_NULL); } if (log_ctx->revprops) @@ -473,16 +472,14 @@ create_log_body(serf_bucket_t **body_bkt } if (log_ctx->revprops->nelts == 0) { - svn_ra_serf__add_tag_buckets(buckets, - "S:no-revprops", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:no-revprops", SVN_VA_NULL); } } else { - svn_ra_serf__add_tag_buckets(buckets, - "S:all-revprops", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:all-revprops", SVN_VA_NULL); } if (log_ctx->paths) @@ -497,9 +494,8 @@ create_log_body(serf_bucket_t **body_bkt } } - svn_ra_serf__add_tag_buckets(buckets, - "S:encode-binary-props", NULL, - alloc); + svn_ra_serf__add_empty_tag_buckets(buckets, alloc, + "S:encode-binary-props", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(buckets, alloc, "S:log-report"); Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/merge.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/merge.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/merge.c Sat Jan 3 14:00:41 2015 @@ -358,15 +358,22 @@ create_merge_body(serf_bucket_t **bkt, svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:href"); svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:source"); - svn_ra_serf__add_tag_buckets(body_bkt, "D:no-auto-merge", NULL, alloc); - svn_ra_serf__add_tag_buckets(body_bkt, "D:no-checkout", NULL, alloc); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:no-auto-merge", SVN_VA_NULL); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:no-checkout", SVN_VA_NULL); svn_ra_serf__add_open_tag_buckets(body_bkt, alloc, "D:prop", SVN_VA_NULL); - svn_ra_serf__add_tag_buckets(body_bkt, "D:checked-in", NULL, alloc); - svn_ra_serf__add_tag_buckets(body_bkt, "D:" SVN_DAV__VERSION_NAME, NULL, alloc); - svn_ra_serf__add_tag_buckets(body_bkt, "D:resourcetype", NULL, alloc); - svn_ra_serf__add_tag_buckets(body_bkt, "D:" SVN_DAV__CREATIONDATE, NULL, alloc); - svn_ra_serf__add_tag_buckets(body_bkt, "D:creator-displayname", NULL, alloc); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:checked-in", SVN_VA_NULL); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:" SVN_DAV__VERSION_NAME, SVN_VA_NULL); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:resourcetype", SVN_VA_NULL); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:" SVN_DAV__CREATIONDATE, SVN_VA_NULL); + svn_ra_serf__add_empty_tag_buckets(body_bkt, alloc, + "D:creator-displayname", SVN_VA_NULL); svn_ra_serf__add_close_tag_buckets(body_bkt, alloc, "D:prop"); merge_lock_token_list(ctx->lock_tokens, NULL, body_bkt, alloc, pool); Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/ra_serf.h URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/ra_serf.h?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/ra_serf.h (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/ra_serf.h Sat Jan 3 14:00:41 2015 @@ -892,6 +892,16 @@ svn_ra_serf__add_close_tag_buckets(serf_ serf_bucket_alloc_t *bkt_alloc, const char *tag); +/* Add the appropriate serf buckets to AGG_BUCKET representing the XML + * open tag with name TAG, and then immediately closes the tag using the /> + * notation + */ +void +svn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket, + serf_bucket_alloc_t *bkt_alloc, + const char *tag, + ...) SVN_NEEDS_SENTINEL_NULL; + /* * Add the appropriate serf buckets to AGG_BUCKET with xml-escaped * version of DATA. Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/update.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/update.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/update.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/update.c Sat Jan 3 14:00:41 2015 @@ -752,22 +752,46 @@ get_best_connection(report_context_t *ct if (ctx->report_received && (ctx->sess->max_connections > 2)) first_conn = 0; - /* Currently, we just cycle connections. In the future we could - store the number of pending requests on each connection, or - perform other heuristics, to achieve better connection usage. - (As an optimization, if there's only one available auxiliary - connection to use, don't bother doing all the cur_conn math -- - just return that one connection.) */ + /* If there's only one available auxiliary connection to use, don't bother + doing all the cur_conn math -- just return that one connection. */ if (ctx->sess->num_conns - first_conn == 1) { conn = ctx->sess->conns[first_conn]; } else { +#if SERF_VERSION_AT_LEAST(1, 4, 0) + /* Often one connection is slower than others, e.g. because the server + process/thread has to do more work for the particular set of requests. + In the worst case, when REQUEST_COUNT_TO_RESUME requests are queued + on such a slow connection, ra_serf will completely stop sending + requests. + + The method used here selects the connection with the least amount of + pending requests, thereby giving more work to lightly loaded server + processes. + */ + int i, best_conn = first_conn; + unsigned int min = INT_MAX; + for (i = first_conn; i < ctx->sess->num_conns; i++) + { + serf_connection_t *sc = ctx->sess->conns[i]->conn; + unsigned int pending = serf_connection_pending_requests(sc); + if (pending < min) + { + min = pending; + best_conn = i; + } + } + conn = ctx->sess->conns[best_conn]; +#else + /* We don't know how many requests are pending per connection, so just + cycle them. */ conn = ctx->sess->conns[ctx->sess->cur_conn]; ctx->sess->cur_conn++; if (ctx->sess->cur_conn >= ctx->sess->num_conns) ctx->sess->cur_conn = first_conn; +#endif } return conn; } Modified: subversion/branches/authzperf/subversion/libsvn_ra_serf/xml.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_serf/xml.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_serf/xml.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_serf/xml.c Sat Jan 3 14:00:41 2015 @@ -324,6 +324,49 @@ svn_ra_serf__add_open_tag_buckets(serf_b } void +svn_ra_serf__add_empty_tag_buckets(serf_bucket_t *agg_bucket, + serf_bucket_alloc_t *bkt_alloc, + const char *tag, ...) +{ + va_list ap; + const char *key; + serf_bucket_t *tmp; + + tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + + tmp = SERF_BUCKET_SIMPLE_STRING(tag, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + + va_start(ap, tag); + while ((key = va_arg(ap, char *)) != NULL) + { + const char *val = va_arg(ap, const char *); + if (val) + { + tmp = SERF_BUCKET_SIMPLE_STRING_LEN(" ", 1, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + + tmp = SERF_BUCKET_SIMPLE_STRING(key, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + + tmp = SERF_BUCKET_SIMPLE_STRING_LEN("=\"", 2, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + + tmp = SERF_BUCKET_SIMPLE_STRING(val, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + + tmp = SERF_BUCKET_SIMPLE_STRING_LEN("\"", 1, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); + } + } + va_end(ap); + + tmp = SERF_BUCKET_SIMPLE_STRING_LEN("/>", 2, bkt_alloc); + serf_bucket_aggregate_append(agg_bucket, tmp); +} + +void svn_ra_serf__add_close_tag_buckets(serf_bucket_t *agg_bucket, serf_bucket_alloc_t *bkt_alloc, const char *tag) Modified: subversion/branches/authzperf/subversion/libsvn_ra_svn/client.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_svn/client.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_ra_svn/client.c (original) +++ subversion/branches/authzperf/subversion/libsvn_ra_svn/client.c Sat Jan 3 14:00:41 2015 @@ -368,15 +368,16 @@ ra_svn_get_reporter(svn_ra_svn__session_ /* --- RA LAYER IMPLEMENTATION --- */ -/* (Note: *ARGV is an output parameter.) */ +/* (Note: *ARGV_P is an output parameter.) */ static svn_error_t *find_tunnel_agent(const char *tunnel, const char *hostinfo, - const char ***argv, + const char ***argv_p, apr_hash_t *config, apr_pool_t *pool) { svn_config_t *cfg; const char *val, *var, *cmd; char **cmd_argv; + const char **argv; apr_size_t len; apr_status_t status; int n; @@ -430,16 +431,22 @@ static svn_error_t *find_tunnel_agent(co if (status != APR_SUCCESS) return svn_error_wrap_apr(status, _("Can't tokenize command '%s'"), cmd); - /* Append the fixed arguments to the result. */ + /* Calc number of the fixed arguments. */ for (n = 0; cmd_argv[n] != NULL; n++) ; - *argv = apr_palloc(pool, (n + 4) * sizeof(char *)); - memcpy(*argv, cmd_argv, n * sizeof(char *)); - (*argv)[n++] = svn_path_uri_decode(hostinfo, pool); - (*argv)[n++] = "svnserve"; - (*argv)[n++] = "-t"; - (*argv)[n] = NULL; + argv = apr_palloc(pool, (n + 4) * sizeof(char *)); + + /* Append the fixed arguments to the result. */ + for (n = 0; cmd_argv[n] != NULL; n++) + argv[n] = cmd_argv[n]; + + argv[n++] = svn_path_uri_decode(hostinfo, pool); + argv[n++] = "svnserve"; + argv[n++] = "-t"; + argv[n] = NULL; + + *argv_p = argv; return SVN_NO_ERROR; } Modified: subversion/branches/authzperf/subversion/libsvn_repos/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/deprecated.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/deprecated.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/deprecated.c Sat Jan 3 14:00:41 2015 @@ -998,6 +998,35 @@ svn_repos_load_fs(svn_repos_t *repos, } svn_error_t * +svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks, + void **parse_baton, + svn_repos_t *repos, + svn_revnum_t start_rev, + svn_revnum_t end_rev, + svn_boolean_t use_history, + svn_boolean_t validate_props, + enum svn_repos_load_uuid uuid_action, + const char *parent_dir, + svn_repos_notify_func_t notify_func, + void *notify_baton, + apr_pool_t *pool) +{ + SVN_ERR(svn_repos_get_fs_build_parser5(callbacks, parse_baton, + repos, + start_rev, end_rev, + use_history, + validate_props, + uuid_action, + parent_dir, + FALSE, FALSE, /*hooks */ + FALSE /*ignore_dates*/, + notify_func, + notify_baton, + pool)); + return SVN_NO_ERROR; +} + +svn_error_t * svn_repos_get_fs_build_parser3(const svn_repos_parse_fns2_t **callbacks, void **parse_baton, svn_repos_t *repos, Modified: subversion/branches/authzperf/subversion/libsvn_repos/dump.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/dump.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/dump.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/dump.c Sat Jan 3 14:00:41 2015 @@ -2245,16 +2245,26 @@ svn_repos_verify_fs3(svn_repos_t *repos, found_corruption = TRUE; notify_verification_error(SVN_INVALID_REVNUM, err, notify_func, notify_baton, iterpool); - svn_error_clear(err); + /* If we already reported the error, reset it. */ + if (notify_func) + { + svn_error_clear(err); + err = NULL; + } + + /* If we abort the verification now, combine yet unreported error + info with the generic one we return. */ if (!keep_going) /* ### Jump to "We're done" and so send the final notification, for consistency? */ - return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, NULL, + return svn_error_createf(SVN_ERR_REPOS_CORRUPTED, err, _("Repository '%s' failed to verify"), svn_dirent_local_style(svn_repos_path(repos, pool), pool)); + + svn_error_clear(err); } if (!metadata_only) Modified: subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c Sat Jan 3 14:00:41 2015 @@ -84,9 +84,9 @@ struct parse_baton SVN_INVALID_REVNUM. */ svn_revnum_t last_rev_mapped; - /* The oldest old revision loaded from the dump stream. If no revisions + /* The oldest revision loaded from the dump stream. If no revisions have been loaded yet, this is set to SVN_INVALID_REVNUM. */ - svn_revnum_t oldest_old_rev; + svn_revnum_t oldest_dumpstream_rev; }; struct revision_baton @@ -248,15 +248,15 @@ renumber_mergeinfo_revs(svn_string_t **f Remove mergeinfo older than the oldest revision in the dump stream and adjust its revisions by the difference between the head rev of the target repository and the current dump stream rev. */ - if (rb->pb->oldest_old_rev > 1) + if (rb->pb->oldest_dumpstream_rev > 1) { SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges( &predates_stream_mergeinfo, mergeinfo, - rb->pb->oldest_old_rev - 1, 0, + rb->pb->oldest_dumpstream_rev - 1, 0, TRUE, subpool, subpool)); SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges( &mergeinfo, mergeinfo, - rb->pb->oldest_old_rev - 1, 0, + rb->pb->oldest_dumpstream_rev - 1, 0, FALSE, subpool, subpool)); SVN_ERR(svn_mergeinfo__adjust_mergeinfo_rangelists( &predates_stream_mergeinfo, predates_stream_mergeinfo, @@ -285,7 +285,7 @@ renumber_mergeinfo_revs(svn_string_t **f { range->start = rev_from_map; } - else if (range->start == pb->oldest_old_rev - 1) + else if (range->start == pb->oldest_dumpstream_rev - 1) { /* Since the start revision of svn_merge_range_t are not inclusive there is one possible valid start revision that @@ -300,7 +300,7 @@ renumber_mergeinfo_revs(svn_string_t **f oldest rev from the load stream and subtract 1 to get the renumbered, non-inclusive, start revision. */ rev_from_map = get_revision_mapping(pb->rev_map, - pb->oldest_old_rev); + pb->oldest_dumpstream_rev); if (SVN_IS_VALID_REVNUM(rev_from_map)) range->start = rev_from_map - 1; } @@ -325,19 +325,12 @@ renumber_mergeinfo_revs(svn_string_t **f } if (predates_stream_mergeinfo) + { SVN_ERR(svn_mergeinfo_merge2(final_mergeinfo, predates_stream_mergeinfo, subpool, subpool)); + } - SVN_ERR(svn_mergeinfo_sort(final_mergeinfo, subpool)); - - /* Mergeinfo revision sources for r0 and r1 are invalid; you can't merge r0 - or r1. However, svndumpfilter can be abused to produce r1 merge source - revs. So if we encounter any, then strip them out, no need to put them - into the load target. */ - SVN_ERR(svn_mergeinfo__filter_mergeinfo_by_ranges(&final_mergeinfo, - final_mergeinfo, - 1, 0, FALSE, - subpool, subpool)); + SVN_ERR(svn_mergeinfo__canonicalize_ranges(final_mergeinfo, subpool)); SVN_ERR(svn_mergeinfo_to_string(final_val, final_mergeinfo, pool)); svn_pool_destroy(subpool); @@ -514,8 +507,8 @@ new_revision_record(void **revision_bato } /* Stash the oldest "old" revision committed from the load stream. */ - if (!SVN_IS_VALID_REVNUM(pb->oldest_old_rev)) - pb->oldest_old_rev = rb->rev; + if (!SVN_IS_VALID_REVNUM(pb->oldest_dumpstream_rev)) + pb->oldest_dumpstream_rev = rb->rev; } /* If we're skipping this revision, try to notify someone. */ @@ -753,6 +746,67 @@ set_revision_property(void *baton, } +/* Adjust mergeinfo: + * - normalize line endings (if all CRLF, change to LF; but error if mixed); + * - adjust revision numbers (see renumber_mergeinfo_revs()); + * - adjust paths (see prefix_mergeinfo_paths()). + */ +static svn_error_t * +adjust_mergeinfo_property(struct revision_baton *rb, + svn_string_t **new_value_p, + const svn_string_t *old_value, + apr_pool_t *result_pool) +{ + struct parse_baton *pb = rb->pb; + svn_string_t prop_val = *old_value; + + /* Tolerate mergeinfo with "\r\n" line endings because some + dumpstream sources might contain as much. If so normalize + the line endings to '\n' and notify that we have made this + correction. */ + if (strstr(prop_val.data, "\r")) + { + const char *prop_eol_normalized; + + SVN_ERR(svn_subst_translate_cstring2(prop_val.data, + &prop_eol_normalized, + "\n", /* translate to LF */ + FALSE, /* no repair */ + NULL, /* no keywords */ + FALSE, /* no expansion */ + result_pool)); + prop_val.data = prop_eol_normalized; + prop_val.len = strlen(prop_eol_normalized); + + if (pb->notify_func) + { + /* ### TODO: Use proper scratch pool instead of pb->notify_pool */ + svn_repos_notify_t *notify + = svn_repos_notify_create( + svn_repos_notify_load_normalized_mergeinfo, + pb->notify_pool); + + pb->notify_func(pb->notify_baton, notify, pb->notify_pool); + svn_pool_clear(pb->notify_pool); + } + } + + /* Renumber mergeinfo as appropriate. */ + SVN_ERR(renumber_mergeinfo_revs(new_value_p, &prop_val, rb, + result_pool)); + + if (pb->parent_dir) + { + /* Prefix the merge source paths with PB->parent_dir. */ + /* ASSUMPTION: All source paths are included in the dump stream. */ + SVN_ERR(prefix_mergeinfo_paths(new_value_p, *new_value_p, + pb->parent_dir, result_pool)); + } + + return SVN_NO_ERROR; +} + + static svn_error_t * set_node_property(void *baton, const char *name, @@ -766,55 +820,42 @@ set_node_property(void *baton, if (rb->skipped) return SVN_NO_ERROR; + /* Adjust mergeinfo. If this fails, presumably because the mergeinfo + property has an ill-formed value, then we must not fail to load + the repository (at least if it's a simple load with no revision + offset adjustments, path changes, etc.) so just warn and leave it + as it is. */ if (strcmp(name, SVN_PROP_MERGEINFO) == 0) { - svn_string_t prop_val = *value; - svn_string_t *renumbered_mergeinfo; + svn_string_t *new_value; + svn_error_t *err; - /* Tolerate mergeinfo with "\r\n" line endings because some - dumpstream sources might contain as much. If so normalize - the line endings to '\n' and make a notification to - PARSE_BATON->FEEDBACK_STREAM that we have made this - correction. */ - if (strstr(prop_val.data, "\r")) + err = adjust_mergeinfo_property(rb, &new_value, value, nb->pool); + if (err) { - const char *prop_eol_normalized; - - SVN_ERR(svn_subst_translate_cstring2(prop_val.data, - &prop_eol_normalized, - "\n", /* translate to LF */ - FALSE, /* no repair */ - NULL, /* no keywords */ - FALSE, /* no expansion */ - nb->pool)); - prop_val.data = prop_eol_normalized; - prop_val.len = strlen(prop_eol_normalized); - + if (pb->validate_props) + { + return svn_error_quick_wrap( + err, + _("Invalid svn:mergeinfo value")); + } if (pb->notify_func) { - /* ### TODO: Use proper scratch pool instead of pb->notify_pool */ svn_repos_notify_t *notify - = svn_repos_notify_create( - svn_repos_notify_load_normalized_mergeinfo, - pb->notify_pool); + = svn_repos_notify_create(svn_repos_notify_warning, + pb->notify_pool); + notify->warning = svn_repos_notify_warning_invalid_mergeinfo; + notify->warning_str = _("Invalid svn:mergeinfo value; " + "leaving unchanged"); pb->notify_func(pb->notify_baton, notify, pb->notify_pool); svn_pool_clear(pb->notify_pool); } + svn_error_clear(err); } - - /* Renumber mergeinfo as appropriate. */ - SVN_ERR(renumber_mergeinfo_revs(&renumbered_mergeinfo, &prop_val, rb, - nb->pool)); - value = renumbered_mergeinfo; - if (pb->parent_dir) + else { - /* Prefix the merge source paths with PB->parent_dir. */ - /* ASSUMPTION: All source paths are included in the dump stream. */ - svn_string_t *mergeinfo_val; - SVN_ERR(prefix_mergeinfo_paths(&mergeinfo_val, value, - pb->parent_dir, nb->pool)); - value = mergeinfo_val; + value = new_value; } } @@ -1082,7 +1123,7 @@ close_revision(void *baton) svn_error_t * -svn_repos_get_fs_build_parser4(const svn_repos_parse_fns3_t **callbacks, +svn_repos_get_fs_build_parser5(const svn_repos_parse_fns3_t **callbacks, void **parse_baton, svn_repos_t *repos, svn_revnum_t start_rev, @@ -1091,6 +1132,9 @@ svn_repos_get_fs_build_parser4(const svn svn_boolean_t validate_props, enum svn_repos_load_uuid uuid_action, const char *parent_dir, + svn_boolean_t use_pre_commit_hook, + svn_boolean_t use_post_commit_hook, + svn_boolean_t ignore_dates, svn_repos_notify_func_t notify_func, void *notify_baton, apr_pool_t *pool) @@ -1132,10 +1176,13 @@ svn_repos_get_fs_build_parser4(const svn pb->pool = pool; pb->notify_pool = svn_pool_create(pool); pb->rev_map = apr_hash_make(pool); - pb->oldest_old_rev = SVN_INVALID_REVNUM; + pb->oldest_dumpstream_rev = SVN_INVALID_REVNUM; pb->last_rev_mapped = SVN_INVALID_REVNUM; pb->start_rev = start_rev; pb->end_rev = end_rev; + pb->use_pre_commit_hook = use_pre_commit_hook; + pb->use_post_commit_hook = use_post_commit_hook; + pb->ignore_dates = ignore_dates; *callbacks = parser; *parse_baton = pb; @@ -1162,28 +1209,23 @@ svn_repos_load_fs5(svn_repos_t *repos, { const svn_repos_parse_fns3_t *parser; void *parse_baton; - struct parse_baton *pb; /* This is really simple. */ - SVN_ERR(svn_repos_get_fs_build_parser4(&parser, &parse_baton, + SVN_ERR(svn_repos_get_fs_build_parser5(&parser, &parse_baton, repos, start_rev, end_rev, TRUE, /* look for copyfrom revs */ validate_props, uuid_action, parent_dir, + use_pre_commit_hook, + use_post_commit_hook, + ignore_dates, notify_func, notify_baton, pool)); - /* Heh. We know this is a parse_baton. This file made it. So - cast away, and set our hook booleans. */ - pb = parse_baton; - pb->use_pre_commit_hook = use_pre_commit_hook; - pb->use_post_commit_hook = use_post_commit_hook; - pb->ignore_dates = ignore_dates; - return svn_repos_parse_dumpstream3(dumpstream, parser, parse_baton, FALSE, cancel_func, cancel_baton, pool); } Modified: subversion/branches/authzperf/subversion/libsvn_repos/log.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/log.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/log.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/log.c Sat Jan 3 14:00:41 2015 @@ -1135,6 +1135,7 @@ fill_log_entry(svn_log_entry_t *log_entr { apr_hash_t *r_props, *changed_paths = NULL; svn_boolean_t get_revprops = TRUE, censor_revprops = FALSE; + svn_boolean_t want_revprops = !revprops || revprops->nelts; /* Discover changed paths if the user requested them or if we need to check that they are readable. */ @@ -1176,7 +1177,7 @@ fill_log_entry(svn_log_entry_t *log_entr changed_paths = NULL; } - if (get_revprops) + if (get_revprops && want_revprops) { /* User is allowed to see at least some revprops. */ SVN_ERR(svn_fs_revision_proplist(&r_props, fs, rev, pool)); Modified: subversion/branches/authzperf/subversion/libsvn_repos/replay.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/replay.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/replay.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/replay.c Sat Jan 3 14:00:41 2015 @@ -548,6 +548,17 @@ path_driver_cb_func(void **dir_baton, svn_boolean_t src_readable; svn_fs_root_t *copyfrom_root; + /* E.g. when verifying corrupted repositories, their changed path + lists may contain an ADD for "/". The delta path driver will + call us with a NULL parent in that case. */ + if (*edit_path == 0) + return svn_error_create(SVN_ERR_FS_ALREADY_EXISTS, NULL, + _("Root directory already exists.")); + + /* A NULL parent_baton will cause a segfault. It should never be + NULL for non-root paths. */ + SVN_ERR_ASSERT(parent_baton); + /* Was this node copied? */ SVN_ERR(fill_copyfrom(©from_root, ©from_path, ©from_rev, &src_readable, root, change, Modified: subversion/branches/authzperf/subversion/libsvn_repos/repos.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/repos.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/repos.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/repos.c Sat Jan 3 14:00:41 2015 @@ -1690,7 +1690,7 @@ svn_repos_delete(const char *path, SVN_ERR(svn_fs_delete_fs(db_path, pool)); /* ...then blow away everything else. */ - return svn_io_remove_dir2(path, FALSE, NULL, NULL, pool); + return svn_error_trace(svn_io_remove_dir2(path, FALSE, NULL, NULL, pool)); } Modified: subversion/branches/authzperf/subversion/libsvn_repos/rev_hunt.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/rev_hunt.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_repos/rev_hunt.c (original) +++ subversion/branches/authzperf/subversion/libsvn_repos/rev_hunt.c Sat Jan 3 14:00:41 2015 @@ -984,7 +984,8 @@ struct path_revision svn_revnum_t revnum; const char *path; - /* Does this path_rev have merges to also be included? */ + /* Does this path_rev have merges to also be included? If so, this is + the union of both additions and (negated) deletions of mergeinfo. */ apr_hash_t *merged_mergeinfo; /* Is this a merged revision? */ @@ -993,6 +994,7 @@ struct path_revision /* Check for merges in OLD_PATH_REV->PATH at OLD_PATH_REV->REVNUM. Store the mergeinfo difference in *MERGED_MERGEINFO, allocated in POOL. The + difference is the union of both additions and (negated) deletions. The returned *MERGED_MERGEINFO will be NULL if there are no changes. */ static svn_error_t * get_merged_mergeinfo(apr_hash_t **merged_mergeinfo, @@ -1070,7 +1072,8 @@ get_merged_mergeinfo(apr_hash_t **merged else SVN_ERR(err); - /* Then calculate and merge the differences. */ + /* Then calculate and merge the differences, combining additions and + (negated) deletions as all positive changes in CHANGES. */ SVN_ERR(svn_mergeinfo_diff2(&deleted, &changed, prev_mergeinfo, curr_mergeinfo, FALSE, result_pool, scratch_pool)); Propchange: subversion/branches/authzperf/subversion/libsvn_subr/bit_array.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/branches/authzperf/subversion/libsvn_subr/cache-inprocess.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/cache-inprocess.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/cache-inprocess.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/cache-inprocess.c Sat Jan 3 14:00:41 2015 @@ -196,7 +196,8 @@ inprocess_cache_get_internal(char **buff /* duplicate the buffer entry */ *buffer = apr_palloc(result_pool, entry->size); - memcpy(*buffer, entry->value, entry->size); + if (entry->size) + memcpy(*buffer, entry->value, entry->size); *size = entry->size; } Modified: subversion/branches/authzperf/subversion/libsvn_subr/cache-membuffer.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/cache-membuffer.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/cache-membuffer.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/cache-membuffer.c Sat Jan 3 14:00:41 2015 @@ -203,20 +203,20 @@ typedef apr_uint64_t entry_key_t[2]; */ typedef struct entry_tag_t { - /* MD5 checksum over the serialized the item data. + /* MD5 checksum over the serialized item data. */ - unsigned char content_hash [APR_MD5_DIGESTSIZE]; + unsigned char content_hash[APR_MD5_DIGESTSIZE]; /* Hash value of the svn_cache_t instance that wrote the item * (i.e. a combination of type and repository) */ - unsigned char prefix_hash [APR_MD5_DIGESTSIZE]; + unsigned char prefix_hash[APR_MD5_DIGESTSIZE]; /* Note that this only covers the variable part of the key, * i.e. it will be different from the full key hash used for * cache indexing. */ - unsigned char key_hash [APR_MD5_DIGESTSIZE]; + unsigned char key_hash[APR_MD5_DIGESTSIZE]; /* Last letters from of the key in human readable format * (ends with the type identifier, e.g. "DAG") @@ -715,7 +715,7 @@ unlock_cache(svn_membuffer_t *cache, svn #if APR_HAS_THREADS # if USE_SIMPLE_MUTEX - return svn_mutex__unlock(cache->lock, SVN_NO_ERROR); + return svn_mutex__unlock(cache->lock, err); # else @@ -2398,6 +2398,8 @@ membuffer_cache_set_partial_internal(svn * We better drop that. */ drop_entry(cache, entry); + + return err; } else { Modified: subversion/branches/authzperf/subversion/libsvn_subr/cache_config.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/cache_config.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/cache_config.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/cache_config.c Sat Jan 3 14:00:41 2015 @@ -27,6 +27,7 @@ #include "private/svn_cache.h" #include "svn_pools.h" +#include "svn_sorts.h" /* The cache settings as a process-wide singleton. */ @@ -80,7 +81,13 @@ initialize_cache(void *baton, apr_pool_t svn_membuffer_t **cache_p = baton; svn_membuffer_t *cache = NULL; - apr_uint64_t cache_size = cache_settings.cache_size; + /* Limit the cache size to about half the available address space + * (typ. 1G under 32 bits). + */ + apr_uint64_t cache_size = MIN(cache_settings.cache_size, + (apr_uint64_t)SVN_MAX_OBJECT_SIZE / 2); + + /* Create caches at all? */ if (cache_size) { svn_error_t *err; Modified: subversion/branches/authzperf/subversion/libsvn_subr/cmdline.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/cmdline.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/cmdline.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/cmdline.c Sat Jan 3 14:00:41 2015 @@ -507,31 +507,50 @@ svn_cmdline_handle_exit_error(svn_error_ return EXIT_FAILURE; } +struct trust_server_cert_non_interactive_baton { + svn_boolean_t trust_server_cert_unknown_ca; + svn_boolean_t trust_server_cert_cn_mismatch; + svn_boolean_t trust_server_cert_expired; + svn_boolean_t trust_server_cert_not_yet_valid; + svn_boolean_t trust_server_cert_other_failure; +}; + /* This implements 'svn_auth_ssl_server_trust_prompt_func_t'. Don't actually prompt. Instead, set *CRED_P to valid credentials - iff FAILURES is empty or is exactly SVN_AUTH_SSL_UNKNOWNCA. If - there are any other failure bits, then set *CRED_P to null (that - is, reject the cert). + iff FAILURES is empty or may be accepted according to the flags + in BATON. If there are any other failure bits, then set *CRED_P + to null (that is, reject the cert). Ignore MAY_SAVE; we don't save certs we never prompted for. - Ignore BATON, REALM, and CERT_INFO, + Ignore REALM and CERT_INFO, Ignore any further films by George Lucas. */ static svn_error_t * -ssl_trust_unknown_server_cert - (svn_auth_cred_ssl_server_trust_t **cred_p, - void *baton, - const char *realm, - apr_uint32_t failures, - const svn_auth_ssl_server_cert_info_t *cert_info, - svn_boolean_t may_save, - apr_pool_t *pool) +trust_server_cert_non_interactive(svn_auth_cred_ssl_server_trust_t **cred_p, + void *baton, + const char *realm, + apr_uint32_t failures, + const svn_auth_ssl_server_cert_info_t + *cert_info, + svn_boolean_t may_save, + apr_pool_t *pool) { + struct trust_server_cert_non_interactive_baton *b = baton; *cred_p = NULL; - if (failures == 0 || failures == SVN_AUTH_SSL_UNKNOWNCA) + if (failures == 0 || + (b->trust_server_cert_unknown_ca && + (failures & SVN_AUTH_SSL_UNKNOWNCA)) || + (b->trust_server_cert_cn_mismatch && + (failures & SVN_AUTH_SSL_CNMISMATCH)) || + (b->trust_server_cert_expired && + (failures & SVN_AUTH_SSL_EXPIRED)) || + (b->trust_server_cert_not_yet_valid && + (failures & SVN_AUTH_SSL_NOTYETVALID)) || + (b->trust_server_cert_other_failure && + (failures & SVN_AUTH_SSL_OTHER))) { *cred_p = apr_pcalloc(pool, sizeof(**cred_p)); (*cred_p)->may_save = FALSE; @@ -542,17 +561,22 @@ ssl_trust_unknown_server_cert } svn_error_t * -svn_cmdline_create_auth_baton(svn_auth_baton_t **ab, - svn_boolean_t non_interactive, - const char *auth_username, - const char *auth_password, - const char *config_dir, - svn_boolean_t no_auth_cache, - svn_boolean_t trust_server_cert, - svn_config_t *cfg, - svn_cancel_func_t cancel_func, - void *cancel_baton, - apr_pool_t *pool) +svn_cmdline_create_auth_baton2(svn_auth_baton_t **ab, + svn_boolean_t non_interactive, + const char *auth_username, + const char *auth_password, + const char *config_dir, + svn_boolean_t no_auth_cache, + svn_boolean_t trust_server_cert_unknown_ca, + svn_boolean_t trust_server_cert_cn_mismatch, + svn_boolean_t trust_server_cert_expired, + svn_boolean_t trust_server_cert_not_yet_valid, + svn_boolean_t trust_server_cert_other_failure, + svn_config_t *cfg, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool) + { svn_boolean_t store_password_val = TRUE; svn_boolean_t store_auth_creds_val = TRUE; @@ -653,11 +677,22 @@ svn_cmdline_create_auth_baton(svn_auth_b APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; } } - else if (trust_server_cert) - { + else if (trust_server_cert_unknown_ca || trust_server_cert_cn_mismatch || + trust_server_cert_expired || trust_server_cert_not_yet_valid || + trust_server_cert_other_failure) + { + struct trust_server_cert_non_interactive_baton *b; + + b = apr_palloc(pool, sizeof(*b)); + b->trust_server_cert_unknown_ca = trust_server_cert_unknown_ca; + b->trust_server_cert_cn_mismatch = trust_server_cert_cn_mismatch; + b->trust_server_cert_expired = trust_server_cert_expired; + b->trust_server_cert_not_yet_valid = trust_server_cert_not_yet_valid; + b->trust_server_cert_other_failure = trust_server_cert_other_failure; + /* Remember, only register this provider if non_interactive. */ svn_auth_get_ssl_server_trust_prompt_provider - (&provider, ssl_trust_unknown_server_cert, NULL, pool); + (&provider, trust_server_cert_non_interactive, b, pool); APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider; } Modified: subversion/branches/authzperf/subversion/libsvn_subr/config.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/config.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/config.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/config.c Sat Jan 3 14:00:41 2015 @@ -534,14 +534,15 @@ make_string_from_option(const char **val expand_option_value(cfg, section, opt->value, &opt->x_value, tmp_pool); opt->expanded = TRUE; - if (!x_pool) + if (x_pool != cfg->x_pool) { /* Grab the fully expanded value from tmp_pool before its disappearing act. */ if (opt->x_value) opt->x_value = apr_pstrmemdup(cfg->x_pool, opt->x_value, strlen(opt->x_value)); - svn_pool_destroy(tmp_pool); + if (!x_pool) + svn_pool_destroy(tmp_pool); } } else Modified: subversion/branches/authzperf/subversion/libsvn_subr/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/deprecated.c?rev=1649205&r1=1649204&r2=1649205&view=diff ============================================================================== --- subversion/branches/authzperf/subversion/libsvn_subr/deprecated.c (original) +++ subversion/branches/authzperf/subversion/libsvn_subr/deprecated.c Sat Jan 3 14:00:41 2015 @@ -1504,3 +1504,33 @@ svn_auth_get_gpg_agent_simple_provider(s svn_auth__get_gpg_agent_simple_provider(provider, pool); } #endif /* !WIN32 */ + +svn_error_t * +svn_cmdline_create_auth_baton(svn_auth_baton_t **ab, + svn_boolean_t non_interactive, + const char *auth_username, + const char *auth_password, + const char *config_dir, + svn_boolean_t no_auth_cache, + svn_boolean_t trust_server_cert, + svn_config_t *cfg, + svn_cancel_func_t cancel_func, + void *cancel_baton, + apr_pool_t *pool) +{ + return svn_error_trace(svn_cmdline_create_auth_baton2(ab, + non_interactive, + auth_username, + auth_password, + config_dir, + no_auth_cache, + trust_server_cert, + FALSE, + FALSE, + FALSE, + FALSE, + cfg, + cancel_func, + cancel_baton, + pool)); +}