diff options
Diffstat (limited to 'subversion/libsvn_fs_fs/fs_fs.c')
-rw-r--r-- | subversion/libsvn_fs_fs/fs_fs.c | 57 |
1 files changed, 50 insertions, 7 deletions
diff --git a/subversion/libsvn_fs_fs/fs_fs.c b/subversion/libsvn_fs_fs/fs_fs.c index 0354a1f5ffe94..c6074acee0738 100644 --- a/subversion/libsvn_fs_fs/fs_fs.c +++ b/subversion/libsvn_fs_fs/fs_fs.c @@ -1467,6 +1467,12 @@ delete_revprops_shard(const char *shard_path, apr_pool_t *scratch_pool); /* In the filesystem FS, pack all revprop shards up to min_unpacked_rev. + * + * NOTE: Keep the old non-packed shards around until after the format bump. + * Otherwise, re-running upgrade will drop the packed revprop shard but + * have no unpacked data anymore. Call upgrade_cleanup_pack_revprops after + * the bump. + * * Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * @@ -1507,6 +1513,29 @@ upgrade_pack_revprops(svn_fs_t *fs, svn_pool_clear(iterpool); } + svn_pool_destroy(iterpool); + + return SVN_NO_ERROR; +} + +/* In the filesystem FS, remove all non-packed revprop shards up to + * min_unpacked_rev. Use SCRATCH_POOL for temporary allocations. + * See upgrade_pack_revprops for more info. + */ +static svn_error_t * +upgrade_cleanup_pack_revprops(svn_fs_t *fs, + apr_pool_t *scratch_pool) +{ + fs_fs_data_t *ffd = fs->fsap_data; + const char *revprops_shard_path; + apr_int64_t shard; + apr_int64_t first_unpacked_shard + = ffd->min_unpacked_rev / ffd->max_files_per_dir; + + apr_pool_t *iterpool = svn_pool_create(scratch_pool); + const char *revsprops_dir = svn_dirent_join(fs->path, PATH_REVPROPS_DIR, + scratch_pool); + /* delete the non-packed revprops shards afterwards */ for (shard = 0; shard < first_unpacked_shard; ++shard) { @@ -1531,6 +1560,7 @@ upgrade_body(void *baton, apr_pool_t *pool) int format, max_files_per_dir; const char *format_path = path_format(fs, pool); svn_node_kind_t kind; + svn_boolean_t needs_revprop_shard_cleanup = FALSE; /* Read the FS format number and max-files-per-dir setting. */ SVN_ERR(read_format(&format, &max_files_per_dir, format_path, pool)); @@ -1582,15 +1612,28 @@ upgrade_body(void *baton, apr_pool_t *pool) if (format < SVN_FS_FS__MIN_PACKED_FORMAT) SVN_ERR(svn_io_file_create(path_min_unpacked_rev(fs, pool), "0\n", pool)); - /* If the file system supports revision packing but not revprop packing, - pack the revprops up to the point that revision data has been packed. */ + /* If the file system supports revision packing but not revprop packing + *and* the FS has been sharded, pack the revprops up to the point that + revision data has been packed. However, keep the non-packed revprop + files around until after the format bump */ if ( format >= SVN_FS_FS__MIN_PACKED_FORMAT - && format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT) - SVN_ERR(upgrade_pack_revprops(fs, pool)); + && format < SVN_FS_FS__MIN_PACKED_REVPROP_FORMAT + && max_files_per_dir > 0) + { + needs_revprop_shard_cleanup = TRUE; + SVN_ERR(upgrade_pack_revprops(fs, pool)); + } /* Bump the format file. */ - return write_format(format_path, SVN_FS_FS__FORMAT_NUMBER, max_files_per_dir, - TRUE, pool); + SVN_ERR(write_format(format_path, SVN_FS_FS__FORMAT_NUMBER, + max_files_per_dir, TRUE, pool)); + + /* Now, it is safe to remove the redundant revprop files. */ + if (needs_revprop_shard_cleanup) + SVN_ERR(upgrade_cleanup_pack_revprops(fs, pool)); + + /* Done */ + return SVN_NO_ERROR; } @@ -3664,7 +3707,7 @@ parse_packed_revprops(svn_fs_t *fs, svn_string_t *compressed = svn_stringbuf__morph_into_string(revprops->packed_revprops); svn_stringbuf_t *uncompressed = svn_stringbuf_create_empty(pool); - SVN_ERR(svn__decompress(compressed, uncompressed, 0x1000000)); + SVN_ERR(svn__decompress(compressed, uncompressed, APR_SIZE_MAX)); /* read first revision number and number of revisions in the pack */ stream = svn_stream_from_stringbuf(uncompressed, scratch_pool); |