diff options
Diffstat (limited to 'contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c')
-rw-r--r-- | contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c | 137 |
1 files changed, 85 insertions, 52 deletions
diff --git a/contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c b/contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c index 89816a8bcb6f..82acb3c96111 100644 --- a/contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c +++ b/contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c @@ -3988,17 +3988,23 @@ write_non_packed_revprop(const char **final_path, apr_hash_t *proplist, apr_pool_t *pool) { + apr_file_t *file; svn_stream_t *stream; *final_path = path_revprops(fs, rev, pool); /* ### do we have a directory sitting around already? we really shouldn't ### have to get the dirname here. */ - SVN_ERR(svn_stream_open_unique(&stream, tmp_path, - svn_dirent_dirname(*final_path, pool), - svn_io_file_del_none, pool, pool)); + SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, + svn_dirent_dirname(*final_path, pool), + svn_io_file_del_none, pool, pool)); + stream = svn_stream_from_aprfile2(file, TRUE, pool); SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, pool)); SVN_ERR(svn_stream_close(stream)); + /* Flush temporary file to disk and close it. */ + SVN_ERR(svn_io_file_flush_to_disk(file, pool)); + SVN_ERR(svn_io_file_close(file, pool)); + return SVN_NO_ERROR; } @@ -4085,7 +4091,7 @@ serialize_revprops_header(svn_stream_t *stream, return SVN_NO_ERROR; } -/* Writes the a pack file to FILE_STREAM. It copies the serialized data +/* Writes the a pack file to FILE. It copies the serialized data * from REVPROPS for the indexes [START,END) except for index CHANGED_INDEX. * * The data for the latter is taken from NEW_SERIALIZED. Note, that @@ -4103,7 +4109,7 @@ repack_revprops(svn_fs_t *fs, int changed_index, svn_stringbuf_t *new_serialized, apr_off_t new_total_size, - svn_stream_t *file_stream, + apr_file_t *file, apr_pool_t *pool) { fs_fs_data_t *ffd = fs->fsap_data; @@ -4151,9 +4157,11 @@ repack_revprops(svn_fs_t *fs, ? SVN_DELTA_COMPRESSION_LEVEL_DEFAULT : SVN_DELTA_COMPRESSION_LEVEL_NONE)); - /* finally, write the content to the target stream and close it */ - SVN_ERR(svn_stream_write(file_stream, compressed->data, &compressed->len)); - SVN_ERR(svn_stream_close(file_stream)); + /* finally, write the content to the target file, flush and close it */ + SVN_ERR(svn_io_file_write_full(file, compressed->data, compressed->len, + NULL, pool)); + SVN_ERR(svn_io_file_flush_to_disk(file, pool)); + SVN_ERR(svn_io_file_close(file, pool)); return SVN_NO_ERROR; } @@ -4161,23 +4169,22 @@ repack_revprops(svn_fs_t *fs, /* Allocate a new pack file name for revisions * [REVPROPS->START_REVISION + START, REVPROPS->START_REVISION + END - 1] * of REVPROPS->MANIFEST. Add the name of old file to FILES_TO_DELETE, - * auto-create that array if necessary. Return an open file stream to - * the new file in *STREAM allocated in POOL. + * auto-create that array if necessary. Return an open file *FILE that is + * allocated in POOL. */ static svn_error_t * -repack_stream_open(svn_stream_t **stream, - svn_fs_t *fs, - packed_revprops_t *revprops, - int start, - int end, - apr_array_header_t **files_to_delete, - apr_pool_t *pool) +repack_file_open(apr_file_t **file, + svn_fs_t *fs, + packed_revprops_t *revprops, + int start, + int end, + apr_array_header_t **files_to_delete, + apr_pool_t *pool) { apr_int64_t tag; const char *tag_string; svn_string_t *new_filename; int i; - apr_file_t *file; int manifest_offset = (int)(revprops->start_revision - revprops->manifest_start); @@ -4209,12 +4216,11 @@ repack_stream_open(svn_stream_t **stream, APR_ARRAY_IDX(revprops->manifest, i + manifest_offset, const char*) = new_filename->data; - /* create a file stream for the new file */ - SVN_ERR(svn_io_file_open(&file, svn_dirent_join(revprops->folder, - new_filename->data, - pool), + /* open the file */ + SVN_ERR(svn_io_file_open(file, svn_dirent_join(revprops->folder, + new_filename->data, + pool), APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool)); - *stream = svn_stream_from_aprfile2(file, FALSE, pool); return SVN_NO_ERROR; } @@ -4238,6 +4244,7 @@ write_packed_revprop(const char **final_path, packed_revprops_t *revprops; apr_int64_t generation = 0; svn_stream_t *stream; + apr_file_t *file; svn_stringbuf_t *serialized; apr_off_t new_total_size; int changed_index; @@ -4273,11 +4280,11 @@ write_packed_revprop(const char **final_path, *final_path = svn_dirent_join(revprops->folder, revprops->filename, pool); - SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder, - svn_io_file_del_none, pool, pool)); + SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder, + svn_io_file_del_none, pool, pool)); SVN_ERR(repack_revprops(fs, revprops, 0, revprops->sizes->nelts, changed_index, serialized, new_total_size, - stream, pool)); + file, pool)); } else { @@ -4323,50 +4330,53 @@ write_packed_revprop(const char **final_path, /* write the new, split files */ if (left_count) { - SVN_ERR(repack_stream_open(&stream, fs, revprops, 0, - left_count, files_to_delete, pool)); + SVN_ERR(repack_file_open(&file, fs, revprops, 0, + left_count, files_to_delete, pool)); SVN_ERR(repack_revprops(fs, revprops, 0, left_count, changed_index, serialized, new_total_size, - stream, pool)); + file, pool)); } if (left_count + right_count < revprops->sizes->nelts) { - SVN_ERR(repack_stream_open(&stream, fs, revprops, changed_index, - changed_index + 1, files_to_delete, - pool)); + SVN_ERR(repack_file_open(&file, fs, revprops, changed_index, + changed_index + 1, files_to_delete, + pool)); SVN_ERR(repack_revprops(fs, revprops, changed_index, changed_index + 1, changed_index, serialized, new_total_size, - stream, pool)); + file, pool)); } if (right_count) { - SVN_ERR(repack_stream_open(&stream, fs, revprops, - revprops->sizes->nelts - right_count, - revprops->sizes->nelts, - files_to_delete, pool)); + SVN_ERR(repack_file_open(&file, fs, revprops, + revprops->sizes->nelts - right_count, + revprops->sizes->nelts, + files_to_delete, pool)); SVN_ERR(repack_revprops(fs, revprops, revprops->sizes->nelts - right_count, revprops->sizes->nelts, changed_index, - serialized, new_total_size, stream, + serialized, new_total_size, file, pool)); } /* write the new manifest */ *final_path = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool); - SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder, - svn_io_file_del_none, pool, pool)); + SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder, + svn_io_file_del_none, pool, pool)); for (i = 0; i < revprops->manifest->nelts; ++i) { const char *filename = APR_ARRAY_IDX(revprops->manifest, i, const char*); - SVN_ERR(svn_stream_printf(stream, pool, "%s\n", filename)); + SVN_ERR(svn_io_file_write_full(file, filename, strlen(filename), + NULL, pool)); + SVN_ERR(svn_io_file_putc('\n', file, pool)); } - SVN_ERR(svn_stream_close(stream)); + SVN_ERR(svn_io_file_flush_to_disk(file, pool)); + SVN_ERR(svn_io_file_close(file, pool)); } return SVN_NO_ERROR; @@ -5062,9 +5072,11 @@ get_combined_window(svn_stringbuf_t **result, /* Maybe, we've got a PLAIN start representation. If we do, read as much data from it as the needed for the txdelta window's source view. - Note that BUF / SOURCE may only be NULL in the first iteration. */ + Note that BUF / SOURCE may only be NULL in the first iteration. + Also note that we may have short-cut reading the delta chain -- + in which case SRC_OPS is 0 and it might not be a PLAIN rep. */ source = buf; - if (source == NULL && rb->src_state != NULL) + if (source == NULL && rb->src_state != NULL && window->src_ops) SVN_ERR(read_plain_window(&source, rb->src_state, window->sview_len, pool)); @@ -6966,8 +6978,13 @@ svn_fs_fs__set_entry(svn_fs_t *fs, rep = apr_pcalloc(pool, sizeof(*rep)); rep->revision = SVN_INVALID_REVNUM; rep->txn_id = txn_id; - SVN_ERR(get_new_txn_node_id(&unique_suffix, fs, txn_id, pool)); - rep->uniquifier = apr_psprintf(pool, "%s/%s", txn_id, unique_suffix); + + if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT) + { + SVN_ERR(get_new_txn_node_id(&unique_suffix, fs, txn_id, pool)); + rep->uniquifier = apr_psprintf(pool, "%s/%s", txn_id, unique_suffix); + } + parent_noderev->data_rep = rep; SVN_ERR(svn_fs_fs__put_node_revision(fs, parent_noderev->id, parent_noderev, FALSE, pool)); @@ -7551,6 +7568,7 @@ rep_write_contents_close(void *baton) representation_t *rep; representation_t *old_rep; apr_off_t offset; + fs_fs_data_t *ffd = b->fs->fsap_data; rep = apr_pcalloc(b->parent_pool, sizeof(*rep)); rep->offset = b->rep_offset; @@ -7567,9 +7585,13 @@ rep_write_contents_close(void *baton) /* Fill in the rest of the representation field. */ rep->expanded_size = b->rep_size; rep->txn_id = svn_fs_fs__id_txn_id(b->noderev->id); - SVN_ERR(get_new_txn_node_id(&unique_suffix, b->fs, rep->txn_id, b->pool)); - rep->uniquifier = apr_psprintf(b->parent_pool, "%s/%s", rep->txn_id, - unique_suffix); + + if (ffd->format >= SVN_FS_FS__MIN_REP_SHARING_FORMAT) + { + SVN_ERR(get_new_txn_node_id(&unique_suffix, b->fs, rep->txn_id, b->pool)); + rep->uniquifier = apr_psprintf(b->parent_pool, "%s/%s", rep->txn_id, + unique_suffix); + } rep->revision = SVN_INVALID_REVNUM; /* Finalize the checksum. */ @@ -7842,7 +7864,7 @@ write_hash_rep(representation_t *rep, /* update the representation */ rep->size = whb->size; - rep->expanded_size = 0; + rep->expanded_size = whb->size; } return SVN_NO_ERROR; @@ -9070,7 +9092,9 @@ recover_find_max_ids(svn_fs_t *fs, svn_revnum_t rev, stored in the representation. */ baton.file = rev_file; baton.pool = pool; - baton.remaining = data_rep->expanded_size; + baton.remaining = data_rep->expanded_size + ? data_rep->expanded_size + : data_rep->size; stream = svn_stream_create(&baton, pool); svn_stream_set_read(stream, read_handler_recover); @@ -10912,6 +10936,9 @@ hotcopy_update_current(svn_revnum_t *dst_youngest, { apr_off_t root_offset; apr_file_t *rev_file; + char max_node_id[MAX_KEY_SIZE] = "0"; + char max_copy_id[MAX_KEY_SIZE] = "0"; + apr_size_t len; if (dst_ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT) SVN_ERR(update_min_unpacked_rev(dst_fs, scratch_pool)); @@ -10921,9 +10948,15 @@ hotcopy_update_current(svn_revnum_t *dst_youngest, SVN_ERR(get_root_changes_offset(&root_offset, NULL, rev_file, dst_fs, new_youngest, scratch_pool)); SVN_ERR(recover_find_max_ids(dst_fs, new_youngest, rev_file, - root_offset, next_node_id, next_copy_id, + root_offset, max_node_id, max_copy_id, scratch_pool)); SVN_ERR(svn_io_file_close(rev_file, scratch_pool)); + + /* We store the _next_ ids. */ + len = strlen(max_node_id); + svn_fs_fs__next_key(max_node_id, &len, next_node_id); + len = strlen(max_copy_id); + svn_fs_fs__next_key(max_copy_id, &len, next_copy_id); } /* Update 'current'. */ |