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 0354a1f5ffe9..c6074acee073 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); | 
