aboutsummaryrefslogtreecommitdiff
path: root/contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c')
-rw-r--r--contrib/subversion/subversion/libsvn_fs_fs/fs_fs.c137
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'. */