Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_fs/verify.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_fs/verify.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_fs/verify.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_fs/verify.c Sun Oct 19 13:55:35 2014 @@ -159,6 +159,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_fs__revision_file_t *rev_file; + + /* Open the rev / pack file and read the footer */ + SVN_ERR(svn_fs_fs__open_pack_or_rev_file(&rev_file, fs, start, + scratch_pool, scratch_pool)); + SVN_ERR(svn_fs_fs__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_fs__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 @@ -182,7 +269,8 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, iterpool)); /* determine the range of items to check for each revision */ - SVN_ERR(svn_fs_fs__l2p_get_max_ids(&max_ids, fs, start, count, pool)); + SVN_ERR(svn_fs_fs__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) @@ -205,10 +293,11 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, /* find the corresponding P2L entry */ SVN_ERR(svn_fs_fs__p2l_entry_lookup(&p2l_entry, fs, rev_file, - revision, offset, iterpool)); + revision, offset, iterpool, + iterpool)); if (p2l_entry == 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 %s returned by " @@ -218,7 +307,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, if ( p2l_entry->item.number != k || p2l_entry->item.revision != revision) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("p2l index info LOG r%ld:i%ld" " does not match " @@ -282,9 +371,9 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, /* get all entries for the current block */ SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, rev_file, start, offset, ffd->p2l_page_size, - iterpool)); + 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"), @@ -301,7 +390,24 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, = &APR_ARRAY_IDX(entries, i, svn_fs_fs__p2l_entry_t); /* check all sub-items for consist entries in the L2P index */ - if (entry->type != SVN_FS_FS__ITEM_TYPE_UNUSED) + if (entry->type == SVN_FS_FS__ITEM_TYPE_UNUSED) + { + /* There is no L2P entry for unused rev file sections. + * And its P2L index data is hardly ever used. But we + * should still check whether someone tempered with it. */ + if ( entry->item.revision != SVN_INVALID_REVNUM + && ( entry->item.revision < start + || entry->item.revision >= start + count)) + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, + NULL, + _("Empty P2L entry for PHYS %s " + "refers to revision %ld outside " + "the rev / pack file (%ld-%ld)"), + apr_off_t_toa(pool, entry->offset), + entry->item.number, + start, start + count - 1); + } + else { apr_off_t l2p_offset; SVN_ERR(svn_fs_fs__item_offset(&l2p_offset, fs, rev_file, @@ -309,7 +415,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, entry->item.number, iterpool)); if (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 %s" "does not match p2l index value " @@ -416,7 +522,7 @@ expected_checksum(apr_file_t *file, 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); @@ -511,7 +617,7 @@ compare_p2l_to_rev(svn_fs_t *fs, pool)); if (rev_file->l2p_offset != max_offset) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, NULL, + 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, rev_file->l2p_offset), start, @@ -532,7 +638,12 @@ compare_p2l_to_rev(svn_fs_t *fs, /* get all entries for the current block */ SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs, rev_file, start, offset, ffd->p2l_page_size, - iterpool)); + 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) @@ -550,7 +661,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 " @@ -566,7 +677,7 @@ compare_p2l_to_rev(svn_fs_t *fs, if (entry->offset != max_offset) 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->file, entry, @@ -592,16 +703,6 @@ compare_p2l_to_rev(svn_fs_t *fs, } static svn_revnum_t -packed_base_rev(svn_fs_t *fs, svn_revnum_t rev) -{ - fs_fs_data_t *ffd = fs->fsap_data; - - return rev < ffd->min_unpacked_rev - ? rev - (rev % ffd->max_files_per_dir) - : rev; -} - -static svn_revnum_t pack_size(svn_fs_t *fs, svn_revnum_t rev) { fs_fs_data_t *ffd = fs->fsap_data; @@ -635,7 +736,7 @@ verify_index_consistency(svn_fs_t *fs, svn_error_t *err = SVN_NO_ERROR; svn_revnum_t count = pack_size(fs, revision); - svn_revnum_t pack_start = packed_base_rev(fs, revision); + svn_revnum_t pack_start = svn_fs_fs__packed_base_rev(fs, revision); svn_revnum_t pack_end = pack_start + count; svn_pool_clear(iterpool); @@ -643,9 +744,14 @@ verify_index_consistency(svn_fs_t *fs, 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 */ - err = compare_l2p_to_p2l_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); @@ -668,7 +774,7 @@ verify_index_consistency(svn_fs_t *fs, /* We could simply assign revision here but the code below is more intuitive to maintainers. */ - next_revision = packed_base_rev(fs, revision); + next_revision = svn_fs_fs__packed_base_rev(fs, revision); } else {
Propchange: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/ ------------------------------------------------------------------------------ Merged /subversion/trunk/subversion/libsvn_fs_fs:r1631115,1631171,1631180 Merged /subversion/trunk/subversion/libsvn_fs_x:r1619780-1632905 Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/cached_data.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/cached_data.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/cached_data.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/cached_data.c Sun Oct 19 13:55:35 2014 @@ -772,13 +772,18 @@ svn_fs_x__rep_chain_length(int *chain_le svn_revnum_t shard_size = ffd->max_files_per_dir ? ffd->max_files_per_dir : 1; - apr_pool_t *sub_pool = svn_pool_create(pool); svn_boolean_t is_delta = FALSE; int count = 0; int shards = 1; svn_revnum_t revision = svn_fs_x__get_revnum(rep->id.change_set); svn_revnum_t last_shard = revision / shard_size; - + + /* Note that this iteration pool will be used in a non-standard way. + * To reuse open file handles between iterations (e.g. while within the + * same pack file), we only clear this pool once in a while instead of + * at the start of each iteration. */ + apr_pool_t *iterpool = svn_pool_create(pool); + /* Check whether the length of the deltification chain is acceptable. * Otherwise, shared reps may form a non-skipping delta chain in * extreme cases. */ @@ -806,7 +811,7 @@ svn_fs_x__rep_chain_length(int *chain_le &file_hint, &base_rep, fs, - sub_pool)); + iterpool)); base_rep.id.change_set = svn_fs_x__change_set_by_rev(header->base_revision); @@ -814,18 +819,28 @@ svn_fs_x__rep_chain_length(int *chain_le base_rep.size = header->base_length; is_delta = header->type == svn_fs_x__rep_delta; + /* Clear it the ITERPOOL once in a while. Doing it too frequently + * renders the FILE_HINT ineffective. Doing too infrequently, may + * leave us with too many open file handles. + * + * Note that this is mostly about efficiency, with larger values + * being more efficient, and any non-zero value is legal here. When + * reading deltified contents, we may keep 10s of rev files open at + * the same time and the system has to cope with that. Thus, the + * limit of 16 chosen below is in the same ballpark. + */ ++count; if (count % 16 == 0) { file_hint = NULL; - svn_pool_clear(sub_pool); + svn_pool_clear(iterpool); } } while (is_delta && base_rep.id.change_set); *chain_length = count; *shard_count = shards; - svn_pool_destroy(sub_pool); + svn_pool_destroy(iterpool); return SVN_NO_ERROR; } @@ -3116,7 +3131,7 @@ block_read(void **result, key.revision = svn_fs_x__get_revnum(entry->items[0].change_set); key.second = entry->items[0].number; - SVN_ERR(svn_io_file_seek(revision_file, SEEK_SET, + SVN_ERR(svn_io_file_seek(revision_file, APR_SET, &entry->offset, iterpool)); switch (entry->type) { Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/index.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/index.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/index.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/index.c Sun Oct 19 13:55:35 2014 @@ -200,7 +200,7 @@ stream_error_create(packed_number_stream apr_off_t offset = 0; SVN_ERR(svn_io_file_name_get(&file_name, stream->file, stream->pool)); - SVN_ERR(svn_io_file_seek(stream->file, SEEK_CUR, &offset, stream->pool)); + SVN_ERR(svn_io_file_seek(stream->file, APR_CUR, &offset, stream->pool)); return svn_error_createf(err, NULL, message, file_name, (apr_uint64_t)offset); @@ -292,7 +292,7 @@ packed_stream_read(packed_number_stream_ /* let's catch corrupted data early. It would surely cause * havoc further down the line. */ if SVN__PREDICT_FALSE(shift > 8 * sizeof(value)) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_CORRUPTION, NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL, _("Corrupt index: number too large")); } } @@ -718,7 +718,7 @@ svn_fs_x__l2p_index_create(svn_fs_t *fs, /* Paranoia check that makes later casting to int32 safe. * The current implementation is limited to 2G entries per page. */ if (ffd->l2p_page_size > APR_INT32_MAX) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL, _("L2P index page size %s" " exceeds current limit of 2G entries"), apr_psprintf(local_pool, "%" APR_UINT64_T_FMT, @@ -781,7 +781,7 @@ svn_fs_x__l2p_index_create(svn_fs_t *fs, l2p_page_entry_t page_entry = { 0 }; if (proto_entry.item_index > APR_INT32_MAX) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL, _("Item index %s too large " "in l2p proto index for revision %ld"), apr_psprintf(local_pool, @@ -808,7 +808,7 @@ svn_fs_x__l2p_index_create(svn_fs_t *fs, /* Paranoia check that makes later casting to int32 safe. * The current implementation is limited to 2G pages per index. */ if (page_counts->nelts > APR_INT32_MAX) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL, _("L2P index page count %d" " exceeds current limit of 2G pages"), page_counts->nelts); @@ -915,7 +915,7 @@ l2p_header_copy(l2p_page_info_baton_t *b /* revision offset within the index file */ apr_size_t rel_revision = baton->revision - header->first_revision; if (rel_revision >= header->revision_count) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_REVISION , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_REVISION , NULL, _("Revision %ld not covered by item index"), baton->revision); @@ -941,7 +941,7 @@ l2p_header_copy(l2p_page_info_baton_t *b max_item_index = (apr_uint64_t)header->page_size * (last_entry - first_entry); if (baton->item_index >= max_item_index) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL, _("Item index %s exceeds l2p limit " "of %s for revision %ld"), apr_psprintf(scratch_pool, @@ -1070,7 +1070,7 @@ get_l2p_header_body(l2p_header_t **heade if (result->first_revision > revision || result->first_revision + result->revision_count <= revision) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_CORRUPTION, NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_CORRUPTION, NULL, _("Corrupt L2P index for r%ld only covers r%ld:%ld"), revision, result->first_revision, result->first_revision + result->revision_count); @@ -1292,7 +1292,7 @@ l2p_page_get_offset(l2p_page_baton_t *ba { /* overflow check */ if (page->entry_count <= baton->page_offset) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL, _("Item index %s too large in" " revision %ld"), apr_psprintf(pool, "%" APR_UINT64_T_FMT, @@ -1843,7 +1843,7 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, = svn_spillbuf__create(0x10000, 0x1000000, local_pool); /* for loop temps ... */ - apr_pool_t *iter_pool = svn_pool_create(pool); + apr_pool_t *iterpool = svn_pool_create(pool); /* start at the beginning of the source file */ SVN_ERR(svn_io_file_open(&proto_index, proto_file_name, @@ -1861,20 +1861,20 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, svn_revnum_t last_revision = revision; apr_uint64_t last_number = 0; - svn_pool_clear(iter_pool); + svn_pool_clear(iterpool); /* (attempt to) read the next entry from the source */ SVN_ERR(svn_io_file_read_full2(proto_index, &entry, sizeof(entry), - &read, &eof, iter_pool)); + &read, &eof, iterpool)); SVN_ERR_ASSERT(eof || read == sizeof(entry)); if (entry.item_count && !eof) { to_read = entry.item_count * sizeof(*entry.items); - entry.items = apr_palloc(iter_pool, to_read); + entry.items = apr_palloc(iterpool, to_read); SVN_ERR(svn_io_file_read_full2(proto_index, entry.items, to_read, - &read, &eof, iter_pool)); + &read, &eof, iterpool)); SVN_ERR_ASSERT(eof || read == to_read); } @@ -1884,7 +1884,7 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, apr_size_t entry_size; to_read = sizeof(entry_size); SVN_ERR(svn_io_file_read_full2(proto_index, &entry_size, to_read, - &read, &eof, iter_pool)); + &read, &eof, iterpool)); SVN_ERR_ASSERT(eof || read == to_read); } @@ -1925,20 +1925,20 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, { SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded, encode_uint(encoded, entry.offset), - iter_pool)); + iterpool)); last_revision = revision; } /* write simple item / container entry */ SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded, encode_uint(encoded, entry.size), - iter_pool)); + iterpool)); SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded, encode_uint(encoded, entry.type + entry.item_count * 16), - iter_pool)); + iterpool)); SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded, encode_uint(encoded, entry.fnv1_checksum), - iter_pool)); + iterpool)); /* container contents (only one for non-container items) */ for (sub_item = 0; sub_item < entry.item_count; ++sub_item) @@ -1948,7 +1948,7 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, apr_int64_t diff = item_rev - last_revision; SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded, encode_int(encoded, diff), - iter_pool)); + iterpool)); last_revision = item_rev; } @@ -1957,7 +1957,7 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, apr_int64_t diff = entry.items[sub_item].number - last_number; SVN_ERR(svn_spillbuf__write(buffer, (const char *)encoded, encode_int(encoded, diff), - iter_pool)); + iterpool)); last_number = entry.items[sub_item].number; } @@ -2007,7 +2007,7 @@ svn_fs_x__p2l_index_create(svn_fs_t *fs, SVN_ERR(svn_io_file_close(index_file, local_pool)); SVN_ERR(svn_io_set_file_read_only(file_name, FALSE, local_pool)); - svn_pool_destroy(iter_pool); + svn_pool_destroy(iterpool); svn_pool_destroy(local_pool); return SVN_NO_ERROR; @@ -2438,7 +2438,7 @@ get_p2l_keys(p2l_page_info_baton_t *page if (page_info.page_count <= page_info.page_no) { SVN_ERR(packed_stream_close(*stream)); - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_OVERFLOW , NULL, + return svn_error_createf(SVN_ERR_FS_INDEX_OVERFLOW , NULL, _("Offset %s too large in revision %ld"), apr_off_t_toa(pool, offset), revision); } Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/noderevs.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/noderevs.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/noderevs.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/noderevs.c Sun Oct 19 13:55:35 2014 @@ -60,8 +60,6 @@ typedef struct binary_id_t } binary_id_t; /* Our internal representation of an representation. - * We simply omit the uniquifier, which allows us to share instances of - * binary_representation_t and uniquify them in a shared_representation_t. */ typedef struct binary_representation_t { Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/pack.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/pack.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/pack.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/pack.c Sun Oct 19 13:55:35 2014 @@ -483,7 +483,7 @@ copy_item_to_temp(pack_context_t *contex svn_fs_x__p2l_entry_t *new_entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool); new_entry->offset = 0; - SVN_ERR(svn_io_file_seek(temp_file, SEEK_CUR, &new_entry->offset, pool)); + SVN_ERR(svn_io_file_seek(temp_file, APR_CUR, &new_entry->offset, pool)); APR_ARRAY_PUSH(entries, svn_fs_x__p2l_entry_t *) = new_entry; SVN_ERR(copy_file_data(context, temp_file, rev_file, entry->size, pool)); @@ -573,7 +573,7 @@ copy_rep_to_temp(pack_context_t *context * store it in CONTEXT */ entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool); entry->offset = 0; - SVN_ERR(svn_io_file_seek(context->reps_file, SEEK_CUR, &entry->offset, + SVN_ERR(svn_io_file_seek(context->reps_file, APR_CUR, &entry->offset, pool)); add_item_rep_mapping(context, entry); @@ -596,7 +596,7 @@ copy_rep_to_temp(pack_context_t *context } /* copy the whole rep (including header!) to our temp file */ - SVN_ERR(svn_io_file_seek(rev_file, SEEK_SET, &source_offset, pool)); + SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &source_offset, pool)); SVN_ERR(copy_file_data(context, context->reps_file, rev_file, entry->size, pool)); @@ -699,12 +699,12 @@ copy_node_to_temp(pack_context_t *contex * store it in CONTEXT */ entry = svn_fs_x__p2l_entry_dup(entry, context->info_pool); entry->offset = 0; - SVN_ERR(svn_io_file_seek(context->reps_file, SEEK_CUR, + SVN_ERR(svn_io_file_seek(context->reps_file, APR_CUR, &entry->offset, pool)); add_item_rep_mapping(context, entry); /* copy the noderev to our temp file */ - SVN_ERR(svn_io_file_seek(rev_file, SEEK_SET, &source_offset, pool)); + SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &source_offset, pool)); SVN_ERR(copy_file_data(context, context->reps_file, rev_file, entry->size, pool)); @@ -1245,7 +1245,7 @@ write_reps_container(pack_context_t *con SVN_ERR(svn_fs_x__write_reps_container(pack_stream, container, pool)); SVN_ERR(svn_stream_close(pack_stream)); - SVN_ERR(svn_io_file_seek(context->pack_file, SEEK_CUR, &offset, pool)); + SVN_ERR(svn_io_file_seek(context->pack_file, APR_CUR, &offset, pool)); container_entry.offset = context->pack_offset; container_entry.size = offset - container_entry.offset; @@ -1327,7 +1327,7 @@ write_reps_containers(pack_context_t *co /* select the change list in the source file, parse it and add it to * the container */ - SVN_ERR(svn_io_file_seek(temp_file, SEEK_SET, &entry->offset, + SVN_ERR(svn_io_file_seek(temp_file, APR_SET, &entry->offset, iterpool)); SVN_ERR(svn_fs_x__get_representation_length(&representation.size, &representation.expanded_size, @@ -1414,7 +1414,7 @@ store_items(pack_context_t *context, /* select the item in the source file and copy it into the target * pack file */ - SVN_ERR(svn_io_file_seek(temp_file, SEEK_SET, &entry->offset, + SVN_ERR(svn_io_file_seek(temp_file, APR_SET, &entry->offset, iterpool)); SVN_ERR(copy_file_data(context, context->pack_file, temp_file, entry->size, iterpool)); @@ -1558,7 +1558,7 @@ write_changes_container(pack_context_t * container, pool)); SVN_ERR(svn_stream_close(pack_stream)); - SVN_ERR(svn_io_file_seek(context->pack_file, SEEK_CUR, &offset, pool)); + SVN_ERR(svn_io_file_seek(context->pack_file, APR_CUR, &offset, pool)); container_entry.offset = context->pack_offset; container_entry.size = offset - container_entry.offset; @@ -1654,7 +1654,7 @@ write_changes_containers(pack_context_t /* select the change list in the source file, parse it and add it to * the container */ - SVN_ERR(svn_io_file_seek(temp_file, SEEK_SET, &entry->offset, + SVN_ERR(svn_io_file_seek(temp_file, APR_SET, &entry->offset, iterpool)); SVN_ERR(svn_fs_x__read_changes(&changes, temp_stream, iterpool)); SVN_ERR(svn_fs_x__changes_append_list(&list_index, container, changes)); @@ -1880,7 +1880,7 @@ pack_range(pack_context_t *context, offset = entry->offset; if (offset < finfo.size) { - SVN_ERR(svn_io_file_seek(rev_file, SEEK_SET, &offset, + SVN_ERR(svn_io_file_seek(rev_file, APR_SET, &offset, iterpool)); if (entry->type == SVN_FS_X__ITEM_TYPE_CHANGES) Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/transaction.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/transaction.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/transaction.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/transaction.c Sun Oct 19 13:55:35 2014 @@ -649,7 +649,7 @@ auto_truncate_proto_rev(svn_fs_t *fs, if (indexed_length < actual_length) SVN_ERR(svn_io_file_trunc(proto_rev, indexed_length, pool)); else if (indexed_length > actual_length) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("p2l proto index offset %s beyond proto" "rev file size %s for TXN %s"), @@ -857,47 +857,37 @@ unparse_dir_entries(apr_array_header_t * return SVN_NO_ERROR; } -/* Copy the contents of NEW_CHANGE into OLD_CHANGE assuming that both - belong to the same path. Allocate copies in POOL. +/* Return a deep copy of SOURCE and allocate it in RESULT_POOL. */ -static void -replace_change(svn_fs_path_change2_t *old_change, - const svn_fs_path_change2_t *new_change, - apr_pool_t *pool) -{ - /* An add at this point must be following a previous delete, - so treat it just like a replace. */ - old_change->node_kind = new_change->node_kind; - old_change->node_rev_id = svn_fs_x__id_copy(new_change->node_rev_id, pool); - old_change->text_mod = new_change->text_mod; - old_change->prop_mod = new_change->prop_mod; - old_change->mergeinfo_mod = new_change->mergeinfo_mod; - if (new_change->copyfrom_rev == SVN_INVALID_REVNUM) - { - old_change->copyfrom_rev = SVN_INVALID_REVNUM; - old_change->copyfrom_path = NULL; - } - else - { - old_change->copyfrom_rev = new_change->copyfrom_rev; - old_change->copyfrom_path = apr_pstrdup(pool, - new_change->copyfrom_path); - } +static svn_fs_path_change2_t * +path_change_dup(const svn_fs_path_change2_t *source, + apr_pool_t *result_pool) +{ + svn_fs_path_change2_t *result = apr_pmemdup(result_pool, source, + sizeof(*source)); + result->node_rev_id = svn_fs_x__id_copy(source->node_rev_id, result_pool); + if (source->copyfrom_path) + result->copyfrom_path = apr_pstrdup(result_pool, source->copyfrom_path); + + return result; } /* Merge the internal-use-only CHANGE into a hash of public-FS - svn_fs_path_change2_t CHANGES, collapsing multiple changes into a - single summarical (is that real word?) change per path. */ + svn_fs_path_change2_t CHANGED_PATHS, collapsing multiple changes into a + single summarical (is that real word?) change per path. DELETIONS is + also a path->svn_fs_path_change2_t hash and contains all the deletions + that got turned into a replacement. */ static svn_error_t * -fold_change(apr_hash_t *changes, +fold_change(apr_hash_t *changed_paths, + apr_hash_t *deletions, const change_t *change) { - apr_pool_t *pool = apr_hash_pool_get(changes); + apr_pool_t *pool = apr_hash_pool_get(changed_paths); svn_fs_path_change2_t *old_change, *new_change; const svn_string_t *path = &change->path; const svn_fs_path_change2_t *info = &change->info; - if ((old_change = apr_hash_get(changes, path->data, path->len))) + if ((old_change = apr_hash_get(changed_paths, path->data, path->len))) { /* This path already exists in the hash, so we have to merge this change into the already existing one. */ @@ -921,7 +911,7 @@ fold_change(apr_hash_t *changes, _("Invalid change ordering: new node revision ID " "without delete")); - /* Sanity check: an add, replacement, move, or reset must be the first + /* Sanity check: an add, replacement, or reset must be the first thing to follow a deletion. */ if ((old_change->change_kind == svn_fs_path_change_delete) && (! ((info->change_kind == svn_fs_path_change_replace) @@ -946,7 +936,7 @@ fold_change(apr_hash_t *changes, case svn_fs_path_change_reset: /* A reset here will simply remove the path change from the hash. */ - old_change = NULL; + apr_hash_set(changed_paths, path->data, path->len, NULL); break; case svn_fs_path_change_delete: @@ -954,60 +944,65 @@ fold_change(apr_hash_t *changes, { /* If the path was introduced in this transaction via an add, and we are deleting it, just remove the path - altogether. */ - old_change = NULL; + altogether. (The caller will delete any child paths.) */ + apr_hash_set(changed_paths, path->data, path->len, NULL); + } + else if (old_change->change_kind == svn_fs_path_change_replace) + { + /* A deleting a 'replace' restore the original deletion. */ + new_change = apr_hash_get(deletions, path->data, path->len); + SVN_ERR_ASSERT(new_change); + apr_hash_set(changed_paths, path->data, path->len, new_change); } else { - /* A deletion overrules all previous changes. */ - old_change->change_kind = svn_fs_path_change_delete; - old_change->text_mod = info->text_mod; - old_change->prop_mod = info->prop_mod; - old_change->mergeinfo_mod = info->mergeinfo_mod; - old_change->copyfrom_rev = SVN_INVALID_REVNUM; - old_change->copyfrom_path = NULL; + /* A deletion overrules a previous change (modify). */ + new_change = path_change_dup(info, pool); + apr_hash_set(changed_paths, path->data, path->len, new_change); } break; case svn_fs_path_change_add: case svn_fs_path_change_replace: /* An add at this point must be following a previous delete, - so treat it just like a replace. */ - replace_change(old_change, info, pool); - old_change->change_kind = svn_fs_path_change_replace; + so treat it just like a replace. Remember the original + deletion such that we are able to delete this path again + (the replacement may have changed node kind and id). */ + new_change = path_change_dup(info, pool); + new_change->change_kind = svn_fs_path_change_replace; + + apr_hash_set(changed_paths, path->data, path->len, new_change); + + /* Remember the original change. + * Make sure to allocate the hash key in a durable pool. */ + apr_hash_set(deletions, + apr_pstrmemdup(apr_hash_pool_get(deletions), + path->data, path->len), + path->len, old_change); break; case svn_fs_path_change_modify: default: + /* If the new change modifies some attribute of the node, set + the corresponding flag, whether it already was set or not. + Note: We do not reset a flag to FALSE if a change is undone. */ if (info->text_mod) old_change->text_mod = TRUE; if (info->prop_mod) old_change->prop_mod = TRUE; - if (info->mergeinfo_mod) + if (info->mergeinfo_mod == svn_tristate_true) old_change->mergeinfo_mod = svn_tristate_true; break; } - - /* remove old_change from the cache if it is no longer needed. */ - if (old_change == NULL) - apr_hash_set(changes, path->data, path->len, NULL); } else { - /* This change is new to the hash, so make a new public change - structure from the internal one (in the hash's pool), and dup - the path into the hash's pool, too. */ - new_change = apr_pmemdup(pool, info, sizeof(*new_change)); - new_change->node_rev_id = svn_fs_x__id_copy(info->node_rev_id, pool); - if (info->copyfrom_path) - new_change->copyfrom_path = apr_pstrdup(pool, info->copyfrom_path); - /* Add this path. The API makes no guarantees that this (new) key - will not be retained. Thus, we copy the key into the target pool - to ensure a proper lifetime. */ - apr_hash_set(changes, + will not be retained. Thus, we copy the key into the target pool + to ensure a proper lifetime. */ + apr_hash_set(changed_paths, apr_pstrmemdup(pool, path->data, path->len), path->len, - new_change); + path_change_dup(info, pool)); } return SVN_NO_ERROR; @@ -1016,13 +1011,14 @@ fold_change(apr_hash_t *changes, /* Examine all the changed path entries in CHANGES and store them in *CHANGED_PATHS. Folding is done to remove redundant or unnecessary - data. Do all allocations in POOL. */ + data. Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * process_changes(apr_hash_t *changed_paths, apr_array_header_t *changes, - apr_pool_t *pool) + apr_pool_t *scratch_pool) { - apr_pool_t *iterpool = svn_pool_create(pool); + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + apr_hash_t *deletions = svn_hash__make(scratch_pool); int i; /* Read in the changes one by one, folding them into our local hash @@ -1035,7 +1031,7 @@ process_changes(apr_hash_t *changed_path */ change_t *change = APR_ARRAY_IDX(changes, i, change_t *); - SVN_ERR(fold_change(changed_paths, change)); + SVN_ERR(fold_change(changed_paths, deletions, change)); /* Now, if our change was a deletion or replacement, we have to blow away any changes thus far on paths that are (or, were) @@ -1513,7 +1509,7 @@ allocate_item_index(apr_uint64_t *item_i to_write = svn__ui64toa(buffer, *item_index + 1); /* write it back to disk */ - SVN_ERR(svn_io_file_seek(file, SEEK_SET, &offset, pool)); + SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, pool)); SVN_ERR(svn_io_file_write_full(file, buffer, to_write, NULL, pool)); SVN_ERR(svn_io_file_close(file, pool)); Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/verify.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/verify.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/verify.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_fs_x/verify.c Sun Oct 19 13:55:35 2014 @@ -181,7 +181,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, offset, sub_item, 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 " @@ -190,7 +190,7 @@ compare_l2p_to_p2l_index(svn_fs_t *fs, (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, + return svn_error_createf(SVN_ERR_FS_INDEX_INCONSISTENT, NULL, _("p2l index info LOG r%ld:i%ld" " does not match " @@ -247,7 +247,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, SVN_ERR(svn_fs_x__p2l_index_lookup(&entries, fs, start, offset, ffd->p2l_page_size, 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"), @@ -277,7 +277,7 @@ compare_p2l_to_l2p_index(svn_fs_t *fs, 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 " @@ -478,7 +478,7 @@ compare_p2l_to_rev(svn_fs_t *fs, SVN_ERR(svn_fs_x__p2l_get_max_offset(&max_offset, fs, start, pool)); if (offset != max_offset) - return svn_error_createf(SVN_ERR_FS_ITEM_INDEX_INCONSISTENT, NULL, + 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, @@ -515,7 +515,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 " Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/blame.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/blame.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/blame.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/blame.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_serf/commit.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/commit.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/commit.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/commit.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_serf/get_lock.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/get_lock.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/get_lock.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/get_lock.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_serf/lock.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/lock.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/lock.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/lock.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_serf/log.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/log.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/log.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/log.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_serf/merge.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/merge.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/merge.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/merge.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_serf/ra_serf.h URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/ra_serf.h?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/ra_serf.h (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/ra_serf.h Sun Oct 19 13:55:35 2014 @@ -144,13 +144,6 @@ struct svn_ra_serf__session_t { i.e. is there a (reverse) proxy that does not support them? */ svn_boolean_t detect_chunking; - /* Can serf use HTTP pipelining, or should it send requests one by one. - HTTP pipelining is enabled by default. The only known case where it should - be disabled is when the server triggers SSL renegotiations in the middle - of HTTP traffic on a connection, which OpenSSL currently doesn't handle - well. See serf issue #135. */ - svn_boolean_t http_pipelining; - /* Our Version-Controlled-Configuration; may be NULL until we know it. */ const char *vcc_url; @@ -899,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/revprop-caching-ng/subversion/libsvn_ra_serf/serf.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/serf.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/serf.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/serf.c Sun Oct 19 13:55:35 2014 @@ -244,12 +244,6 @@ load_config(svn_ra_serf__session_t *sess SVN_CONFIG_OPTION_HTTP_CHUNKED_REQUESTS, "auto", svn_tristate_unknown)); - /* Should we use HTTP pipelining. */ - SVN_ERR(svn_config_get_bool(config, &session->http_pipelining, - SVN_CONFIG_SECTION_GLOBAL, - SVN_CONFIG_OPTION_HTTP_PIPELINING, - TRUE)); - #if SERF_VERSION_AT_LEAST(1, 4, 0) && !defined(SVN_SERF_NO_LOGGING) SVN_ERR(svn_config_get_int64(config, &log_components, SVN_CONFIG_SECTION_GLOBAL, @@ -317,12 +311,6 @@ load_config(svn_ra_serf__session_t *sess SVN_CONFIG_OPTION_HTTP_CHUNKED_REQUESTS, "auto", chunked_requests)); - /* Should we use HTTP pipelining. */ - SVN_ERR(svn_config_get_bool(config, &session->http_pipelining, - server_group, - SVN_CONFIG_OPTION_HTTP_PIPELINING, - session->http_pipelining)); - #if SERF_VERSION_AT_LEAST(1, 4, 0) && !defined(SVN_SERF_NO_LOGGING) SVN_ERR(svn_config_get_int64(config, &log_components, server_group, @@ -582,10 +570,6 @@ svn_ra_serf__open(svn_ra_session_t *sess if (status) return svn_ra_serf__wrap_err(status, NULL); - if (!serf_sess->http_pipelining) { - serf_connection_set_max_outstanding_requests(serf_sess->conns[0]->conn, 1); - } - /* Set the progress callback. */ serf_context_set_progress_cb(serf_sess->context, svn_ra_serf__progress, serf_sess); @@ -787,10 +771,6 @@ ra_serf_dup_session(svn_ra_session_t *ne if (status) return svn_ra_serf__wrap_err(status, NULL); - if (!new_sess->http_pipelining) { - serf_connection_set_max_outstanding_requests(new_sess->conns[0]->conn, 1); - } - /* Set the progress callback. */ serf_context_set_progress_cb(new_sess->context, svn_ra_serf__progress, new_sess); Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/update.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/update.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/update.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/update.c Sun Oct 19 13:55:35 2014 @@ -723,11 +723,6 @@ open_connection_if_needed(svn_ra_serf__s if (status) return svn_ra_serf__wrap_err(status, NULL); - if (!sess->http_pipelining) { - serf_connection_set_max_outstanding_requests(sess->conns[cur]->conn, - 1); - } - sess->num_conns++; } @@ -757,22 +752,45 @@ 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. + */ + unsigned int i, min = INT_MAX, best_conn = first_conn; + 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/revprop-caching-ng/subversion/libsvn_ra_serf/xml.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/xml.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/xml.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_serf/xml.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_ra_svn/client.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_ra_svn/client.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_ra_svn/client.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_ra_svn/client.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_repos/dump.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_repos/dump.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_repos/dump.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_repos/dump.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_repos/replay.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_repos/replay.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_repos/replay.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_repos/replay.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_repos/repos.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_repos/repos.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_repos/repos.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_repos/repos.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_repos/rev_hunt.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_repos/rev_hunt.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_repos/rev_hunt.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_repos/rev_hunt.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_subr/bit_array.c ------------------------------------------------------------------------------ svn:eol-style = native Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cache-inprocess.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cache-inprocess.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cache-inprocess.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cache-inprocess.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_subr/cmdline.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cmdline.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cmdline.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_subr/cmdline.c Sun Oct 19 13:55:35 2014 @@ -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/revprop-caching-ng/subversion/libsvn_subr/config_file.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_subr/config_file.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_subr/config_file.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_subr/config_file.c Sun Oct 19 13:55:35 2014 @@ -940,15 +940,6 @@ svn_config_ensure(const char *config_dir "### HTTP operation." NL "### http-chunked-requests Whether to use chunked transfer" NL "### encoding for HTTP requests body." NL - "### http-pipelining Whether to use HTTP pipelining " NL - "### or send requests one by one." NL - "### Pipelining is enabled by default." NL - "### The only known case where it should" - NL - "### be disabled is when the server" NL - "### triggers SSL renegotiations in the"NL - "### middle of HTTP traffic, resulting" NL - "### in SSL communication errors." NL "### neon-debug-mask Debug mask for Neon HTTP library" NL "### ssl-authority-files List of files, each of a trusted CA" NL Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_subr/deprecated.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_subr/deprecated.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_subr/deprecated.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_subr/deprecated.c Sun Oct 19 13:55:35 2014 @@ -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)); +} Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_subr/gpg_agent.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_subr/gpg_agent.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_subr/gpg_agent.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_subr/gpg_agent.c Sun Oct 19 13:55:35 2014 @@ -108,7 +108,7 @@ escape_blanks(char *str) * to other password caching mechanisms. */ static svn_error_t * get_cache_id(const char **cache_id_p, const char *realmstring, - apr_pool_t *scratch_pool, apr_pool_t *result_pool) + apr_pool_t *result_pool, apr_pool_t *scratch_pool) { const char *cache_id = NULL; svn_checksum_t *digest = NULL; Modified: subversion/branches/revprop-caching-ng/subversion/libsvn_subr/io.c URL: http://svn.apache.org/viewvc/subversion/branches/revprop-caching-ng/subversion/libsvn_subr/io.c?rev=1632906&r1=1632905&r2=1632906&view=diff ============================================================================== --- subversion/branches/revprop-caching-ng/subversion/libsvn_subr/io.c (original) +++ subversion/branches/revprop-caching-ng/subversion/libsvn_subr/io.c Sun Oct 19 13:55:35 2014 @@ -3662,7 +3662,7 @@ svn_io_file_aligned_seek(apr_file_t *fil buffer and no I/O will actually happen in the FILL_BUFFER section below. */ - SVN_ERR(svn_io_file_seek(file, SEEK_CUR, ¤t, pool)); + SVN_ERR(svn_io_file_seek(file, APR_CUR, ¤t, pool)); fill_buffer = aligned_offset + file_buffer_size <= current || current <= aligned_offset; } @@ -3673,7 +3673,7 @@ svn_io_file_aligned_seek(apr_file_t *fil apr_status_t status; /* seek to the start of the block and cause APR to read 1 block */ - SVN_ERR(svn_io_file_seek(file, SEEK_SET, &aligned_offset, pool)); + SVN_ERR(svn_io_file_seek(file, APR_SET, &aligned_offset, pool)); status = apr_file_getc(&dummy, file); /* read may fail if we seek to or behind EOF. That's ok then. */ @@ -3686,7 +3686,7 @@ svn_io_file_aligned_seek(apr_file_t *fil /* finally, seek to the OFFSET the caller wants */ desired_offset = offset; - SVN_ERR(svn_io_file_seek(file, SEEK_SET, &offset, pool)); + SVN_ERR(svn_io_file_seek(file, APR_SET, &offset, pool)); if (desired_offset != offset) return do_io_file_wrapper_cleanup(file, APR_EOF, N_("Can't seek in file '%s'"),
