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