Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs.h Sat May 23 14:16:56 2020 @@ -188,6 +188,18 @@ extern "C" { /* The minimum format number that supports svndiff version 2. */ #define SVN_FS_FS__MIN_SVNDIFF2_FORMAT 8 +/* The minimum format number that supports the special notation ("-") + for optional values that are not present in the representation strings, + such as SHA1 or the uniquifier. For example: + + 15 0 563 7809 28ef320a82e7bd11eebdf3502d69e608 - 14-g/_5 + */ +#define SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT 8 + + /* The minimum format number that supports V2 schema of the rep-cache.db + database. */ +#define SVN_FS_FS__MIN_REP_CACHE_SCHEMA_V2_FORMAT 8 + /* On most operating systems apr implements file locks per process, not per file. On Windows apr implements the locking as per file handle locks, so we don't have to add our own mutex for just in-process
Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.c Sat May 23 14:16:56 2020 @@ -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" @@ -1151,8 +1152,8 @@ write_config(svn_fs_t *fs, "[" CONFIG_SECTION_DEBUG "]" NL "###" NL "### Whether to verify each new revision immediately before finalizing" NL -"### the commit. The default is false in release-mode builds, and true" NL -"### in debug-mode builds." NL +"### the commit. This is disabled by default except in maintainer-mode" NL +"### builds." NL "# " CONFIG_OPTION_VERIFY_BEFORE_COMMIT " = false" NL ; #undef NL @@ -1470,7 +1471,10 @@ svn_fs_fs__min_unpacked_rev(svn_revnum_t { fs_fs_data_t *ffd = fs->fsap_data; - SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool)); + /* Calling this for pre-v4 repos is illegal. */ + if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT) + SVN_ERR(svn_fs_fs__update_min_unpacked_rev(fs, pool)); + *min_unpacked = ffd->min_unpacked_rev; return SVN_NO_ERROR; @@ -2340,3 +2344,181 @@ svn_fs_fs__info_config_files(apr_array_h result_pool); return SVN_NO_ERROR; } + +/* If no SHA1 checksum is stored in REP->SHA1_DIGEST yet, compute the + * SHA1 checksum and fill it in. Use POOL for temporary allocations. */ +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; +} + +/* Recursively index (in the rep-cache) the filesystem node with the + * given ID, located in revision REV and its matching REV_FILE (if the + * node ID cannot be found in this revision, do nothing). + * Compute the SHA1 checksum of the node's representation and add + * a corresponding entry to the repository's rep-cache. + * If the node represents a directory this function will recurse and + * index all children of this directory as well. */ +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; +} Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/fs_fs.h Sat May 23 14:16:56 2020 @@ -304,4 +304,75 @@ svn_fs_fs__initialize_txn_caches(svn_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 Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/hotcopy.c Sat May 23 14:16:56 2020 @@ -922,7 +922,7 @@ hotcopy_body(void *baton, apr_pool_t *po SVN_ERR(cancel_func(cancel_baton)); /* Split the logic for new and old FS formats. The latter is much simpler - * due to the absense of sharding and packing. However, it requires special + * due to the absence of sharding and packing. However, it requires special * care when updating the 'current' file (which contains not just the * revision number, but also the next-ID counters). */ if (src_ffd->format >= SVN_FS_FS__MIN_NO_GLOBAL_IDS_FORMAT) Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/id.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/id.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/id.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/id.c Sat May 23 14:16:56 2020 @@ -591,7 +591,8 @@ svn_fs_fs__id_parse(const svn_fs_id_t ** 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; Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/index.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/index.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/index.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/index.c Sat May 23 14:16:56 2020 @@ -2522,8 +2522,8 @@ get_p2l_page(apr_array_header_t **entrie * MIN_OFFSET. Set *END to TRUE if the caller should stop refeching. * * *BATON will be updated with the selected page's info and SCRATCH_POOL - * will be used for temporary allocations. If the data is alread in the - * cache, descrease *LEAKING_BUCKET and increase it otherwise. With that + * will be used for temporary allocations. If the data is already in the + * cache, decrease *LEAKING_BUCKET and increase it otherwise. With that * pattern we will still read all pages from the block even if some of * them survived in the cached. */ @@ -2681,7 +2681,7 @@ append_p2l_entries(apr_array_header_t *e } } -/* Auxilliary struct passed to p2l_entries_func selecting the relevant +/* Auxiliary struct passed to p2l_entries_func selecting the relevant * data range. */ typedef struct p2l_entries_baton_t { @@ -3191,9 +3191,9 @@ compare_p2l_entry_revision(const void *l 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; Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/load-index.c Sat May 23 14:16:56 2020 @@ -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 *l 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; Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/low_level.c Sat May 23 14:16:56 2020 @@ -248,16 +248,16 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o rev)); *p2l_offset = (apr_off_t)val; - /* The P2L indes follows the L2P index */ + /* The P2L index follows the L2P index */ if (*p2l_offset <= *l2p_offset) return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, "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 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 *s } if (terminate_list) - svn_stream_puts(stream, "\n"); + SVN_ERR(svn_stream_puts(stream, "\n")); svn_pool_destroy(iterpool); @@ -741,6 +741,9 @@ read_header_block(apr_hash_t **headers, return SVN_NO_ERROR; } +/* ### Ouch! The implementation of this function currently modifies + ### the input string when tokenizing it (so the input cannot be + ### used after that). */ svn_error_t * svn_fs_fs__parse_representation(representation_t **rep_p, svn_stringbuf_t *text, @@ -811,13 +814,21 @@ svn_fs_fs__parse_representation(represen if (str == NULL) return SVN_NO_ERROR; - /* Read the SHA1 hash. */ - if (strlen(str) != (APR_SHA1_DIGESTSIZE * 2)) - return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, - _("Malformed text representation offset line in node-rev")); + /* Is the SHA1 hash present? */ + if (str[0] == '-' && str[1] == 0) + { + checksum = NULL; + } + else + { + /* Read the SHA1 hash. */ + if (strlen(str) != (APR_SHA1_DIGESTSIZE * 2)) + return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, + _("Malformed text representation offset line in node-rev")); - SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str, - scratch_pool)); + SVN_ERR(svn_checksum_parse_hex(&checksum, svn_checksum_sha1, str, + scratch_pool)); + } /* We do have a valid SHA1 but it might be all 0. We cannot be sure where that came from (Alas! legacy), so let's not @@ -829,21 +840,36 @@ svn_fs_fs__parse_representation(represen if (checksum) memcpy(rep->sha1_digest, checksum->digest, sizeof(rep->sha1_digest)); - /* Read the uniquifier. */ - str = svn_cstring_tokenize("/", &string); + str = svn_cstring_tokenize(" ", &string); if (str == NULL) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Malformed text representation offset line in node-rev")); - SVN_ERR(svn_fs_fs__id_txn_parse(&rep->uniquifier.noderev_txn_id, str)); + /* Is the uniquifier present? */ + if (str[0] == '-' && str[1] == 0) + { + end = string; + } + else + { + char *substring = str; - str = svn_cstring_tokenize(" ", &string); - if (str == NULL || *str != '_') - return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, - _("Malformed text representation offset line in node-rev")); + /* Read the uniquifier. */ + str = svn_cstring_tokenize("/", &substring); + if (str == NULL) + return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, + _("Malformed text representation offset line in node-rev")); + + SVN_ERR(svn_fs_fs__id_txn_parse(&rep->uniquifier.noderev_txn_id, str)); + + str = svn_cstring_tokenize(" ", &substring); + if (str == NULL || *str != '_') + return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, + _("Malformed text representation offset line in node-rev")); - ++str; - rep->uniquifier.number = svn__base36toui64(&end, str); + ++str; + rep->uniquifier.number = svn__base36toui64(&end, str); + } if (*end) return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, @@ -1034,25 +1060,37 @@ svn_fs_fs__read_noderev(node_revision_t } /* Return a textual representation of the DIGEST of given KIND. - * If IS_NULL is TRUE, no digest is available. * Allocate the result in RESULT_POOL. */ static const char * format_digest(const unsigned char *digest, svn_checksum_kind_t kind, - svn_boolean_t is_null, apr_pool_t *result_pool) { svn_checksum_t checksum; checksum.digest = digest; checksum.kind = kind; - if (is_null) - return "(null)"; - return svn_checksum_to_cstring_display(&checksum, result_pool); } +/* Return a textual representation of the uniquifier represented + * by NODEREV_TXN_ID and NUMBER. Use POOL for the allocations. + */ +static const char * +format_uniquifier(const svn_fs_fs__id_part_t *noderev_txn_id, + apr_uint64_t number, + apr_pool_t *pool) +{ + char buf[SVN_INT64_BUFFER_SIZE]; + const char *txn_id_str; + + txn_id_str = svn_fs_fs__id_txn_unparse(noderev_txn_id, pool); + svn__ui64tobase36(buf, number); + + return apr_psprintf(pool, "%s/_%s", txn_id_str, buf); +} + svn_stringbuf_t * svn_fs_fs__unparse_representation(representation_t *rep, int format, @@ -1060,32 +1098,80 @@ svn_fs_fs__unparse_representation(repres apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - char buffer[SVN_INT64_BUFFER_SIZE]; + svn_stringbuf_t *str; + const char *sha1_str; + const char *uniquifier_str; + if (svn_fs_fs__id_txn_used(&rep->txn_id) && mutable_rep_truncated) return svn_stringbuf_ncreate("-1", 2, result_pool); - if (format < SVN_FS_FS__MIN_REP_SHARING_FORMAT || !rep->has_sha1) - return svn_stringbuf_createf - (result_pool, "%ld %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT - " %" SVN_FILESIZE_T_FMT " %s", - rep->revision, rep->item_index, rep->size, - rep->expanded_size, - format_digest(rep->md5_digest, svn_checksum_md5, FALSE, - scratch_pool)); - - svn__ui64tobase36(buffer, rep->uniquifier.number); - return svn_stringbuf_createf - (result_pool, "%ld %" APR_UINT64_T_FMT " %" SVN_FILESIZE_T_FMT - " %" SVN_FILESIZE_T_FMT " %s %s %s/_%s", - rep->revision, rep->item_index, rep->size, - rep->expanded_size, - format_digest(rep->md5_digest, svn_checksum_md5, - FALSE, scratch_pool), - format_digest(rep->sha1_digest, svn_checksum_sha1, - !rep->has_sha1, scratch_pool), - svn_fs_fs__id_txn_unparse(&rep->uniquifier.noderev_txn_id, - scratch_pool), - buffer); + /* Format of the string: + <rev> <item_index> <size> <expanded-size> <md5> [<sha1>] [<uniquifier>] + */ + str = svn_stringbuf_createf( + result_pool, + "%ld" + " %" APR_UINT64_T_FMT + " %" SVN_FILESIZE_T_FMT + " %" SVN_FILESIZE_T_FMT + " %s", + rep->revision, + rep->item_index, + rep->size, + rep->expanded_size, + format_digest(rep->md5_digest, svn_checksum_md5, scratch_pool)); + + /* Compatibility: these formats don't understand <sha1> and <uniquifier>. */ + if (format < SVN_FS_FS__MIN_REP_SHARING_FORMAT) + return str; + + if (format < SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT) + { + /* Compatibility: these formats can only have <sha1> and <uniquifier> + present simultaneously, or don't have them at all. */ + if (rep->has_sha1) + { + sha1_str = format_digest(rep->sha1_digest, svn_checksum_sha1, + scratch_pool); + uniquifier_str = format_uniquifier(&rep->uniquifier.noderev_txn_id, + rep->uniquifier.number, + scratch_pool); + svn_stringbuf_appendbyte(str, ' '); + svn_stringbuf_appendcstr(str, sha1_str); + svn_stringbuf_appendbyte(str, ' '); + svn_stringbuf_appendcstr(str, uniquifier_str); + } + return str; + } + + /* The most recent formats support optional <sha1> and <uniquifier> values. */ + if (rep->has_sha1) + { + sha1_str = format_digest(rep->sha1_digest, svn_checksum_sha1, + scratch_pool); + } + else + sha1_str = "-"; + + if (rep->uniquifier.number == 0 && + rep->uniquifier.noderev_txn_id.number == 0 && + rep->uniquifier.noderev_txn_id.revision == 0) + { + uniquifier_str = "-"; + } + else + { + uniquifier_str = format_uniquifier(&rep->uniquifier.noderev_txn_id, + rep->uniquifier.number, + scratch_pool); + } + + svn_stringbuf_appendbyte(str, ' '); + svn_stringbuf_appendcstr(str, sha1_str); + svn_stringbuf_appendbyte(str, ' '); + svn_stringbuf_appendcstr(str, uniquifier_str); + + return str; } Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/pack.c Sat May 23 14:16:56 2020 @@ -315,12 +315,12 @@ initialize_pack_context(pack_context_t * 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 */ @@ -1701,7 +1701,7 @@ svn_fs_fs__get_packed_offset(apr_off_t * return svn_cache__set(ffd->packed_offset_cache, &shard, manifest, pool); } -/* Packing logic for physical addresssing mode: +/* Packing logic for physical addressing mode: * Simply concatenate all revision contents. * * Pack the revision shard starting at SHARD_REV containing exactly @@ -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; } Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/recovery.c Sat May 23 14:16:56 2020 @@ -471,9 +471,15 @@ recover_body(void *baton, apr_pool_t *po } /* 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; Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache-db.sql Sat May 23 14:16:56 2020 @@ -21,7 +21,7 @@ * ==================================================================== */ --- STMT_CREATE_SCHEMA +-- STMT_CREATE_SCHEMA_V1 /* A table mapping representation hashes to locations in a rev file. */ CREATE TABLE rep_cache ( hash TEXT NOT NULL PRIMARY KEY, @@ -33,36 +33,63 @@ CREATE TABLE rep_cache ( PRAGMA USER_VERSION = 1; +-- STMT_CREATE_SCHEMA_V2 +/* A table mapping representation hashes to locations in a rev file. + Same as in V1 schema, except that it uses the `WITHOUT ROWID` optimization: + https://sqlite.org/withoutrowid.html + + Note that this optimization is only supported starting from SQLite version + 3.8.2 (2013-12-06). To keep compatibility with existing binaries, it is + only used for newer filesystem formats that were released together with + bumping the minimum required SQLite version. + */ +CREATE TABLE rep_cache ( + hash TEXT NOT NULL PRIMARY KEY, + revision INTEGER NOT NULL, + offset INTEGER NOT NULL, + size INTEGER NOT NULL, + expanded_size INTEGER NOT NULL + ) WITHOUT ROWID; + +PRAGMA USER_VERSION = 2; -- STMT_GET_REP +/* Works for both V1 and V2 schemas. */ SELECT revision, offset, size, expanded_size FROM rep_cache WHERE hash = ?1 -- STMT_SET_REP -INSERT OR FAIL INTO rep_cache (hash, revision, offset, size, expanded_size) +/* Works for both V1 and V2 schemas. */ +INSERT OR IGNORE INTO rep_cache (hash, revision, offset, size, expanded_size) VALUES (?1, ?2, ?3, ?4, ?5) -- STMT_GET_REPS_FOR_RANGE +/* Works for both V1 and V2 schemas. */ SELECT hash, revision, offset, size, expanded_size FROM rep_cache WHERE revision >= ?1 AND revision <= ?2 -- STMT_GET_MAX_REV +/* Works for both V1 and V2 schemas. */ SELECT MAX(revision) FROM rep_cache -- STMT_DEL_REPS_YOUNGER_THAN_REV +/* Works for both V1 and V2 schemas. */ DELETE FROM rep_cache WHERE revision > ?1 /* An INSERT takes an SQLite reserved lock that prevents other writes but doesn't block reads. The incomplete transaction means that no permanent change is made to the database and the transaction is - removed when the database is closed. */ + removed when the database is closed. + + Works for both V1 and V2 schemas. */ -- STMT_LOCK_REP BEGIN TRANSACTION; INSERT INTO rep_cache VALUES ('dummy', 0, 0, 0, 0) -- STMT_UNLOCK_REP +/* Works for both V1 and V2 schemas. */ ROLLBACK TRANSACTION; Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/rep-cache.c Sat May 23 14:16:56 2020 @@ -36,9 +36,6 @@ #include "rep-cache-db.h" -/* A few magic values */ -#define REP_CACHE_SCHEMA_FORMAT 1 - REP_CACHE_DB_SQL_DECLARE_STATEMENTS(statements); @@ -102,13 +99,17 @@ open_rep_cache(void *baton, SVN_SQLITE__ERR_CLOSE(svn_sqlite__read_schema_version(&version, sdb, pool), sdb); - if (version < REP_CACHE_SCHEMA_FORMAT) + /* If we have an uninitialized database, go ahead and create the schema. */ + if (version <= 0) { - /* Must be 0 -- an uninitialized (no schema) database. Create - the schema. Results in schema version of 1. */ - SVN_SQLITE__ERR_CLOSE(svn_sqlite__exec_statements(sdb, - STMT_CREATE_SCHEMA), - sdb); + int stmt; + + if (ffd->format >= SVN_FS_FS__MIN_REP_CACHE_SCHEMA_V2_FORMAT) + stmt = STMT_CREATE_SCHEMA_V2; + else + stmt = STMT_CREATE_SCHEMA_V1; + + SVN_SQLITE__ERR_CLOSE(svn_sqlite__exec_statements(sdb, stmt), sdb); } /* This is used as a flag that the database is available so don't @@ -327,7 +328,6 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f { 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; @@ -350,28 +350,7 @@ svn_fs_fs__set_rep_reference(svn_fs_t *f (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; } Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.c Sat May 23 14:16:56 2020 @@ -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. @@ -671,6 +671,64 @@ read_pack_revprop(packed_revprops_t **re 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. * Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/revprops.h Sat May 23 14:16:56 2020 @@ -62,6 +62,15 @@ svn_fs_fs__upgrade_cleanup_pack_revprops 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. * Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/stats.c Sat May 23 14:16:56 2020 @@ -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 **repre } } - 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 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; +} Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/structure URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/structure?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/structure (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/structure Sat May 23 14:16:56 2020 @@ -118,7 +118,7 @@ representation checksum and location map hash text as the primary key, mapped to the representation revision, offset, size and expanded size. This file is only consulted during writes and never during reads. Consequently, it is not required, and may be removed at an -abritrary time, with the subsequent loss of rep-sharing capabilities for +arbitrary time, with the subsequent loss of rep-sharing capabilities for revisions written thereafter. Filesystem formats @@ -568,6 +568,9 @@ defined: ### in formats >=4, also present: <sha1-digest> gives hex SHA1 digest of expanded rep <uniquifier> see representation_t->uniquifier in fs.h + ### Starting from format 8, a special notation "-" + can be used for optional values that are not present + (<sha1-digest> and <uniquifier>). cpath FS pathname node was created at copyfrom "<rev> <path>" of copyfrom data copyroot "<rev> <created-path>" of the root of this copy Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.c Sat May 23 14:16:56 2020 @@ -38,7 +38,7 @@ #include "cached_data.h" /* Utility to encode a signed NUMBER into a variable-length sequence of - * 8-bit chars in KEY_BUFFER and return the last writen position. + * 8-bit chars in KEY_BUFFER and return the last written position. * * Numbers will be stored in 7 bits / byte and using byte values above * 32 (' ') to make them combinable with other string by simply separating @@ -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); Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/temp_serializer.h Sat May 23 14:16:56 2020 @@ -53,13 +53,16 @@ svn_fs_fs__noderev_deserialize(void *buf /** * 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; /* the offset within the representation right after reading the window */ apr_off_t end_offset; + + /* svndiff version */ + int ver; } svn_fs_fs__raw_cached_window_t; /** @@ -86,7 +89,7 @@ svn_fs_fs__deserialize_raw_window(void * * #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; @@ -374,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 */ Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/transaction.c Sat May 23 14:16:56 2020 @@ -587,7 +587,7 @@ unparse_dir_entry(svn_fs_dirent_t *diren : 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 @@ -3336,6 +3336,24 @@ write_final_rev(const svn_fs_id_t **new_ if (noderev->data_rep && noderev->kind == svn_node_dir) noderev->data_rep->has_sha1 = FALSE; + /* Compatibility: while we don't need to serialize SHA1 for props (it is + not used), older formats can only have representation strings that either + have both the SHA1 value *and* the uniquifier, or don't have them at all. + For such formats, both values get written to the disk only if the SHA1 + is present. + + We cannot omit the uniquifier, as doing so breaks svn_fs_props_changed() + for properties with shared representations, see issues #4623 and #4700. + Therefore, we skip writing SHA1, but only for the newer formats where + this dependency is untied and we can write the uniquifier to the disk + without the SHA1. + */ + if (ffd->format >= SVN_FS_FS__MIN_REP_STRING_OPTIONAL_VALUES_FORMAT && + noderev->prop_rep) + { + noderev->prop_rep->has_sha1 = FALSE; + } + /* Workaround issue #4031: is-fresh-txn-root in revision files. */ noderev->is_fresh_txn_root = FALSE; @@ -3695,7 +3713,7 @@ promote_cached_directories(svn_fs_t *fs, /* Currently, the entry for KEY - if it still exists - is marked * as "stale" and would not be used. Mark it as current for in- - * revison data. */ + * revision data. */ SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key, svn_fs_fs__reset_txn_filesize, NULL, iterpool)); Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/tree.c Sat May 23 14:16:56 2020 @@ -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; @@ -3123,7 +3148,7 @@ struct text_baton_t * svn_fs_apply_text() ==> ... ==> txn_body_fulltext_finalize_edits() */ -/* Write function for the publically returned stream. */ +/* Write function for the publicly returned stream. */ static svn_error_t * text_stream_writer(void *baton, const char *data, @@ -3135,7 +3160,7 @@ text_stream_writer(void *baton, return svn_stream_write(tb->file_stream, data, len); } -/* Close function for the publically returned stream. */ +/* Close function for the publicly returned stream. */ static svn_error_t * text_stream_closer(void *baton) { @@ -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)); Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/util.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/util.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/util.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/util.h Sat May 23 14:16:56 2020 @@ -316,7 +316,7 @@ svn_error_t * svn_fs_fs__update_min_unpacked_rev(svn_fs_t *fs, apr_pool_t *pool); -/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed +/* Atomically update the 'min-unpacked-rev' file in FS to hold the specified * REVNUM. Perform temporary allocations in SCRATCH_POOL. */ svn_error_t * @@ -336,7 +336,7 @@ svn_fs_fs__read_current(svn_revnum_t *re svn_fs_t *fs, apr_pool_t *pool); -/* Atomically update the 'current' file to hold the specifed REV, +/* Atomically update the 'current' file to hold the specified REV, NEXT_NODE_ID, and NEXT_COPY_ID. (The two next-ID parameters are ignored and may be 0 if the FS format does not use them.) Perform temporary allocations in POOL. */ Modified: subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_fs/verify.c Sat May 23 14:16:56 2020 @@ -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. */ Propchange: subversion/branches/addremove/subversion/libsvn_fs_x/ ------------------------------------------------------------------------------ Merged /subversion/branches/swig-py3/subversion/libsvn_fs_x:r1813660-1869353 Merged /subversion/trunk/subversion/libsvn_fs_x:r1802696-1878056 Modified: subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/cached_data.c Sat May 23 14:16:56 2020 @@ -394,7 +394,7 @@ svn_fs_x__get_mergeinfo_count(apr_int64_ { svn_fs_x__noderev_t *noderev; - /* If we want a full acccess log, we need to provide full data and + /* If we want a full access log, we need to provide full data and cannot take shortcuts here. */ #if !defined(SVN_FS_X__LOG_ACCESS) @@ -951,7 +951,7 @@ typedef struct rep_read_baton_t /* Used for temporary allocations during the read. */ apr_pool_t *scratch_pool; - /* Pool used to store file handles and other data that is persistant + /* Pool used to store file handles and other data that is persistent for the entire stream read. */ apr_pool_t *filehandle_pool; } rep_read_baton_t; @@ -1518,7 +1518,7 @@ get_combined_window(svn_stringbuf_t **re return SVN_NO_ERROR; } -/* Returns whether or not the expanded fulltext of the file is cachable +/* Returns whether or not the expanded fulltext of the file is cacheable * based on its size SIZE. The decision depends on the cache used by FFD. */ static svn_boolean_t @@ -2229,7 +2229,7 @@ svn_fs_x__get_contents_from_file(svn_str rb->filehandle_pool, rb->scratch_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. */ @@ -2585,7 +2585,7 @@ parse_dir_entries(apr_array_header_t **e } /* For directory NODEREV in FS, return the *FILESIZE of its in-txn - * representation. If the directory representation is comitted data, + * representation. If the directory representation is committed data, * set *FILESIZE to SVN_INVALID_FILESIZE. Use SCRATCH_POOL for temporaries. */ static svn_error_t * Modified: subversion/branches/addremove/subversion/libsvn_fs_x/caching.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/caching.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/caching.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/caching.c Sat May 23 14:16:56 2020 @@ -415,7 +415,7 @@ svn_fs_x__initialize_caches(svn_fs_t *fs * (e.g. fulltexts etc.) * - Index data required to find any of the other data has high prio * (e.g. noderevs, L2P and P2L index pages) - * - everthing else should use default prio + * - everything else should use default prio */ #ifdef SVN_DEBUG_CACHE_DUMP_STATS Modified: subversion/branches/addremove/subversion/libsvn_fs_x/changes.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/changes.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/changes.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/changes.c Sat May 23 14:16:56 2020 @@ -184,7 +184,7 @@ svn_fs_x__changes_append_list(apr_size_t /* simply append the list and all changes */ for (i = 0; i < list->nelts; ++i) - append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t *)); + SVN_ERR(append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t *))); /* terminate the list by storing the next changes offset */ APR_ARRAY_PUSH(changes->offsets, int) = changes->changes->nelts; Modified: subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.c Sat May 23 14:16:56 2020 @@ -807,7 +807,7 @@ get_copy_inheritance(svn_fs_x__copy_id_i or if it is a branch point that we are accessing via its original copy destination path. */ svn_fs_x__dag_get_copyroot(©root_rev, ©root_path, child->node); - SVN_ERR(svn_fs_x__revision_root(©root_root, fs, copyroot_rev, + SVN_ERR(svn_fs_x__revision_root(©root_root, fs, copyroot_rev, scratch_pool)); SVN_ERR(svn_fs_x__get_temp_dag_node(©root_node, copyroot_root, copyroot_path, scratch_pool)); @@ -833,7 +833,7 @@ get_copy_inheritance(svn_fs_x__copy_id_i } /* Allocate a new svn_fs_x__dag_path_t node from RESULT_POOL, containing - NODE, ENTRY and PARENT, all copied into RESULT_POOL as well. */ + NODE, ENTRY and PARENT; NODE and ENTRY are copied into RESULT_POOL. */ static svn_fs_x__dag_path_t * make_parent_path(dag_node_t *node, const svn_stringbuf_t *entry, @@ -909,7 +909,7 @@ svn_fs_x__get_dag_path(svn_fs_x__dag_pat { /* If this was the last path component, and the caller said it was optional, then don't return an error; - just put a NULL node pointer in the path. + just put a NULL node pointer in the path. */ if ((flags & svn_fs_x__dag_path_last_optional) && (path_len == path.len)) Modified: subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/dag_cache.h Sat May 23 14:16:56 2020 @@ -103,7 +103,7 @@ typedef struct svn_fs_x__dag_path_t IS_TXN_PATH must be set. If IS_TXN_PATH is FALSE, no copy ID inheritance information will be calculated for the *PARENT_PATH_P chain. - If FLAGS & open_path_last_optional is zero, return the error + If FLAGS & svn_fs_x__dag_path_last_optional is zero, return the error SVN_ERR_FS_NOT_FOUND if the node PATH refers to does not exist. If non-zero, require all the parent directories to exist as normal, but if the final path component doesn't exist, simply return a path Modified: subversion/branches/addremove/subversion/libsvn_fs_x/fs.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/fs.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/fs.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/fs.c Sat May 23 14:16:56 2020 @@ -310,7 +310,8 @@ static fs_vtable_t fs_vtable = { x_info, svn_fs_x__verify_root, x_freeze, - x_set_errcall + x_set_errcall, + NULL /* ioctl */ }; @@ -641,7 +642,8 @@ static fs_library_vtable_t library_vtabl x_logfiles, NULL /* parse_id */, x_set_svn_fs_open, - x_info_dup + x_info_dup, + NULL /* ioctl */ }; svn_error_t * Modified: subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/fs_x.c Sat May 23 14:16:56 2020 @@ -951,7 +951,7 @@ write_revision_zero(svn_fs_t *fs, SVN_ERR(svn_io_file_open(&apr_file, svn_fs_x__path_revprops(fs, 0, scratch_pool), - APR_WRITE | APR_CREATE, APR_OS_DEFAULT, + APR_WRITE | APR_CREATE, APR_OS_DEFAULT, scratch_pool)); SVN_ERR(svn_fs_x__write_non_packed_revprops(apr_file, proplist, scratch_pool)); Modified: subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/hotcopy.c Sat May 23 14:16:56 2020 @@ -625,7 +625,7 @@ hotcopy_body(void *baton, SVN_ERR(cancel_func(cancel_baton)); /* Split the logic for new and old FS formats. The latter is much simpler - * due to the absense of sharding and packing. However, it requires special + * due to the absence of sharding and packing. However, it requires special * care when updating the 'current' file (which contains not just the * revision number, but also the next-ID counters). */ SVN_ERR(hotcopy_revisions(src_fs, dst_fs, src_youngest, dst_youngest, Modified: subversion/branches/addremove/subversion/libsvn_fs_x/id.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/id.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/id.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/id.h Sat May 23 14:16:56 2020 @@ -37,7 +37,7 @@ typedef apr_int64_t svn_fs_x__txn_id_t; /* Change set is the umbrella term for transaction and revision in FSX. * Revision numbers (>=0) map 1:1 onto change sets while txns are mapped - * onto the negatve value range. */ + * onto the negative value range. */ typedef apr_int64_t svn_fs_x__change_set_t; /* Invalid / unused change set number. */ Modified: subversion/branches/addremove/subversion/libsvn_fs_x/index.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/index.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/index.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/index.c Sat May 23 14:16:56 2020 @@ -2742,8 +2742,8 @@ get_p2l_page(apr_array_header_t **entrie * Set *END to TRUE if the caller should stop refeching. * * *BATON will be updated with the selected page's info and SCRATCH_POOL - * will be used for temporary allocations. If the data is alread in the - * cache, descrease *LEAKING_BUCKET and increase it otherwise. With that + * will be used for temporary allocations. If the data is already in the + * cache, decrease *LEAKING_BUCKET and increase it otherwise. With that * pattern we will still read all pages from the block even if some of * them survived in the cached. */ @@ -2919,7 +2919,7 @@ append_p2l_entries(apr_array_header_t *e } } -/* Auxilliary struct passed to p2l_entries_func selecting the relevant +/* Auxiliary struct passed to p2l_entries_func selecting the relevant * data range. */ typedef struct p2l_entries_baton_t { Modified: subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/low_level.c Sat May 23 14:16:56 2020 @@ -161,16 +161,16 @@ svn_fs_x__parse_footer(apr_off_t *l2p_of rev)); *p2l_offset = (apr_off_t)val; - /* The P2L indes follows the L2P index */ + /* The P2L index follows the L2P index */ if (*p2l_offset <= *l2p_offset) return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, "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); @@ -998,7 +998,7 @@ svn_fs_x__read_changes(apr_array_header_ SVN_ERR(read_change(&change, stream, result_pool, iterpool)); if (!change) break; - + APR_ARRAY_PUSH(*changes, svn_fs_x__change_t*) = change; } svn_pool_destroy(iterpool); @@ -1131,7 +1131,7 @@ svn_fs_x__write_changes(svn_stream_t *st } if (terminate_list) - svn_stream_puts(stream, "\n"); + SVN_ERR(svn_stream_puts(stream, "\n")); svn_pool_destroy(iterpool); Modified: subversion/branches/addremove/subversion/libsvn_fs_x/pack.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/pack.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/pack.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/pack.c Sat May 23 14:16:56 2020 @@ -1461,7 +1461,7 @@ copy_reps_from_temp(pack_context_t *cont SVN_ERR(store_items(context, temp_file, reps, initial_reps_count, scratch_pool)); - /* vaccum ENTRIES array: eliminate NULL entries */ + /* vacuum ENTRIES array: eliminate NULL entries */ for (i = 0, k = 0; i < reps->nelts; ++i) { svn_fs_x__p2l_entry_t *entry @@ -1686,7 +1686,7 @@ write_l2p_index(pack_context_t *context, context->reps, pool, scratch_pool)); - /* Append newly written segment to exisiting proto index file. */ + /* Append newly written segment to existing proto index file. */ SVN_ERR(svn_io_file_name_get(&proto_index, context->proto_l2p_index, scratch_pool)); @@ -2204,9 +2204,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, scratch_pool); + SVN_ERR(pb->notify_func(pb->notify_baton, + ffd->min_unpacked_rev / ffd->max_files_per_dir, + svn_fs_pack_notify_noop, scratch_pool)); return SVN_NO_ERROR; } @@ -2258,9 +2258,9 @@ svn_fs_x__pack(svn_fs_t *fs, svn_fs_x__data_t *ffd = fs->fsap_data; if (notify_func) - (*notify_func)(notify_baton, - ffd->min_unpacked_rev / ffd->max_files_per_dir, - svn_fs_pack_notify_noop, scratch_pool); + SVN_ERR(notify_func(notify_baton, + ffd->min_unpacked_rev / ffd->max_files_per_dir, + svn_fs_pack_notify_noop, scratch_pool)); return SVN_NO_ERROR; } Modified: subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/rev_file.c Sat May 23 14:16:56 2020 @@ -66,7 +66,7 @@ struct svn_fs_x__revision_file_t svn_fs_x__index_info_t p2l_info; /* Pool used for all sub-structure allocations (file, streams etc.). - A sub-pool of OWNER. NULL until the lazily initilized. */ + A sub-pool of OWNER. NULL until the lazily initialized. */ apr_pool_t *pool; /* Pool that this structure got allocated in. */ Modified: subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/revprops.c Sat May 23 14:16:56 2020 @@ -449,7 +449,7 @@ verify_checksum(svn_stringbuf_t *content content->len, scratch_pool)); if (!svn_checksum_match(actual, expected)) - SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool, + SVN_ERR(svn_checksum_mismatch_err(expected, actual, scratch_pool, "checksum mismatch")); return SVN_NO_ERROR; @@ -1203,7 +1203,7 @@ repack_file_open(apr_file_t **file, if (revprops->entry.start_rev == start_rev) APR_ARRAY_IDX(revprops->manifest, idx, manifest_entry_t) = new_entry; else - svn_sort__array_insert(revprops->manifest, &new_path, idx + 1); + SVN_ERR(svn_sort__array_insert2(revprops->manifest, &new_path, idx + 1)); /* open the file */ new_path = get_revprop_pack_filepath(revprops, &new_entry, scratch_pool); @@ -1424,7 +1424,7 @@ svn_fs_x__set_revision_proplist(svn_fs_t scratch_pool)); else SVN_ERR(write_non_packed_revprop(&final_path, &tmp_path, - fs, rev, proplist, batch, + fs, rev, proplist, batch, scratch_pool, scratch_pool)); /* We use the rev file of this revision as the perms reference, Modified: subversion/branches/addremove/subversion/libsvn_fs_x/structure URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/structure?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/structure (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/structure Sat May 23 14:16:56 2020 @@ -112,7 +112,7 @@ representation checksum and location map hash text as the primary key, mapped to the representation revision, offset, size and expanded size. This file is only consulted during writes and never during reads. Consequently, it is not required, and may be removed at an -abritrary time, with the subsequent loss of rep-sharing capabilities for +arbitrary time, with the subsequent loss of rep-sharing capabilities for revisions written thereafter. Filesystem formats Modified: subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/temp_serializer.c Sat May 23 14:16:56 2020 @@ -38,7 +38,7 @@ #include "cached_data.h" /* Utility to encode a signed NUMBER into a variable-length sequence of - * 8-bit chars in KEY_BUFFER and return the last writen position. + * 8-bit chars in KEY_BUFFER and return the last written position. * * Numbers will be stored in 7 bits / byte and using byte values above * 32 (' ') to make them combinable with other string by simply separating @@ -183,7 +183,7 @@ svn_fs_x__deserialize_apr_array(void *bu (*array)->pool = result_pool; } -/* auxilliary structure representing the content of a directory array */ +/* auxiliary structure representing the content of a directory array */ typedef struct dir_data_t { /* number of entries in the directory @@ -925,13 +925,13 @@ slowly_replace_dir_entry(void **data, APR_ARRAY_IDX(entries, idx, svn_fs_x__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_x__serialize_dir_entries(data, data_len, dir, pool); Modified: subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/transaction.c Sat May 23 14:16:56 2020 @@ -881,7 +881,7 @@ unparse_dir_entry(svn_fs_x__dirent_t *di apr_size_t to_write; apr_size_t name_len = strlen(dirent->name); - /* A buffer with sufficient space for + /* A buffer with sufficient space for * - entry name + 1 terminating NUL * - 1 byte for the node kind * - 2 numbers in 7b/8b encoding for the noderev-id @@ -1259,7 +1259,7 @@ get_and_increment_txn_key_body(void *bat SVN_ERR(svn_io_check_path(txn_dir, &kind, iterpool)); if (kind == svn_node_none) { - svn_io_dir_make(txn_dir, APR_OS_DEFAULT, iterpool); + SVN_ERR(svn_io_dir_make(txn_dir, APR_OS_DEFAULT, iterpool)); break; } @@ -3066,7 +3066,7 @@ get_final_id(svn_fs_x__id_t *part, part->change_set = svn_fs_x__change_set_by_rev(revision); } -/* Copy a node-revision specified by id ID in fileystem FS from a +/* Copy a node-revision specified by id ID in filesystem FS from a transaction into the proto-rev-file FILE. Set *NEW_ID_P to a pointer to the new noderev-id. If this is a directory, copy all children as well. @@ -3738,7 +3738,7 @@ promote_cached_directories(svn_fs_t *fs, /* Currently, the entry for KEY - if it still exists - is marked * as "stale" and would not be used. Mark it as current for in- - * revison data. */ + * revision data. */ SVN_ERR(svn_cache__set_partial(ffd->dir_cache, key, svn_fs_x__reset_txn_filesize, NULL, iterpool)); Modified: subversion/branches/addremove/subversion/libsvn_fs_x/tree.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/tree.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/tree.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/tree.c Sat May 23 14:16:56 2020 @@ -2060,7 +2060,7 @@ typedef struct text_baton_t * svn_fs_apply_text() ==> ... ==> txn_body_fulltext_finalize_edits() */ -/* Write function for the publically returned stream. */ +/* Write function for the publicly returned stream. */ static svn_error_t * text_stream_writer(void *baton, const char *data, @@ -2072,7 +2072,7 @@ text_stream_writer(void *baton, return svn_stream_write(tb->file_stream, data, len); } -/* Close function for the publically returned stream. */ +/* Close function for the publicly returned stream. */ static svn_error_t * text_stream_closer(void *baton) { Modified: subversion/branches/addremove/subversion/libsvn_fs_x/util.h URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/util.h?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/util.h (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/util.h Sat May 23 14:16:56 2020 @@ -384,7 +384,7 @@ svn_error_t * svn_fs_x__update_min_unpacked_rev(svn_fs_t *fs, apr_pool_t *scratch_pool); -/* Atomically update the 'min-unpacked-rev' file in FS to hold the specifed +/* Atomically update the 'min-unpacked-rev' file in FS to hold the specified * REVNUM. Perform temporary allocations in SCRATCH_POOL. */ svn_error_t * @@ -400,7 +400,7 @@ svn_fs_x__read_current(svn_revnum_t *rev svn_fs_t *fs, apr_pool_t *scratch_pool); -/* Atomically update the 'current' file to hold the specifed REV. +/* Atomically update the 'current' file to hold the specified REV. Perform temporary allocations in SCRATCH_POOL. */ svn_error_t * svn_fs_x__write_current(svn_fs_t *fs, Modified: subversion/branches/addremove/subversion/libsvn_fs_x/verify.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_fs_x/verify.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_fs_x/verify.c (original) +++ subversion/branches/addremove/subversion/libsvn_fs_x/verify.c Sat May 23 14:16:56 2020 @@ -179,7 +179,7 @@ verify_index_checksum(svn_fs_x__revision SVN_ERR(svn_fs_x__rev_file_name(&file_name, file, scratch_pool)); SVN_ERR(svn_checksum_mismatch_err(index_info->checksum, actual, - scratch_pool, + scratch_pool, _("%s checksum mismatch in file %s"), name, file_name)); } Modified: subversion/branches/addremove/subversion/libsvn_ra/compat.c URL: http://svn.apache.org/viewvc/subversion/branches/addremove/subversion/libsvn_ra/compat.c?rev=1878061&r1=1878060&r2=1878061&view=diff ============================================================================== --- subversion/branches/addremove/subversion/libsvn_ra/compat.c (original) +++ subversion/branches/addremove/subversion/libsvn_ra/compat.c Sat May 23 14:16:56 2020 @@ -942,7 +942,7 @@ svn_ra__get_inherited_props_walk(svn_ra_ parent_url, result_pool); new_iprop->prop_hash = final_hash; - svn_sort__array_insert(*inherited_props, &new_iprop, 0); + SVN_ERR(svn_sort__array_insert2(*inherited_props, &new_iprop, 0)); } }