Author: danielsh Date: Wed Apr 24 20:20:51 2013 New Revision: 1471638 URL: http://svn.apache.org/r1471638 Log: Redesign the svn_fs_info() API.
* subversion/include/svn_fs.h (SVN_FS_FSFS_INFO_SHARDED, SVN_FS_FSFS_INFO_REP_CACHE_PATH, SVN_FS_FSFS_INFO_MIN_UNPACKED_REV, svn_fs_info_t): Delete. (svn_fs_info, svn_fs_info_dup): Rewrite. (svn_fs_fsfs_info_t): New. * subversion/libsvn_fs/fs-loader.c (svn_fs_info, svn_fs_info_dup): Implement as the new signature. * subversion/libsvn_fs/fs-loader.h (fs_library_vtable_t.info_fsap_dup): New vtable member. (fs_vtable_t.info_fsap): New vtable member. * subversion/libsvn_fs_base/fs.c (fs_vtable, library_vtable): Provide NULL for the new vtable members. * subversion/libsvn_fs_fs/fs.c (fs_info, fs_info_dup): New functions. (fs_vtable, library_vtable): Pass them for the new vtable members. * subversion/tests/libsvn_fs_fs/fs-pack-test.c (test_info): New test. (test_funcs): Run it, passing. Modified: subversion/trunk/subversion/include/svn_fs.h subversion/trunk/subversion/libsvn_fs/fs-loader.c subversion/trunk/subversion/libsvn_fs/fs-loader.h subversion/trunk/subversion/libsvn_fs_base/fs.c subversion/trunk/subversion/libsvn_fs_fs/fs.c subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c Modified: subversion/trunk/subversion/include/svn_fs.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1471638&r1=1471637&r2=1471638&view=diff ============================================================================== --- subversion/trunk/subversion/include/svn_fs.h (original) +++ subversion/trunk/subversion/include/svn_fs.h Wed Apr 24 20:20:51 2013 @@ -2568,68 +2568,72 @@ svn_fs_verify_root(svn_fs_root_t *root, /** * A structure that provides some information about a filesystem. - * Returned by svn_fs_info(). + * Returned by svn_fs_info() for #SVN_FS_TYPE_FSFS filesystems. * * @note Fields may be added to the end of this structure in future * versions. Therefore, users shouldn't allocate structures of this * type, to preserve binary compatibility. * - * @since New in 1.8. + * @since New in 1.9. */ -typedef struct svn_fs_info_t { +typedef struct svn_fs_fsfs_info_t { -#if 0 - /* Potential future feature. */ - svn_boolean_t is_write_locked; -#endif - - /** Filesystem backend (#fs_type) -specific information. - * @see SVN_FS_FSFS_INFO_* */ - apr_hash_t *fsap_info; + /** Filesystem backend (#fs_type), i.e., the string #SVN_FS_TYPE_FSFS. */ + const char *fs_type; -} svn_fs_info_t; + /** Shard size, or 0 if the filesystem is not currently sharded. */ + int shard_size; + + /** The smallest revision (as #svn_revnum_t) which is not in a pack file. + * @note Zero (0) if (but not iff) the format does not support packing. */ + svn_revnum_t min_unpacked_rev; + + /* ### TODO: information about fsfs.conf? rep-cache.db? write locks? */ + + /* If you add fields here, check whether you need to extend svn_fs_info() + or svn_fs_info_dup(). */ +} svn_fs_fsfs_info_t; + +/** @see svn_fs_info() + * @since New in 1.9. */ +typedef struct svn_fs_info_placeholder_t { + /** @see svn_fs_type() */ + const char *fs_type; + + /* Do not add new fields here, to maintain compatibility with the first + released version of svn_fs_fsfs_info_t. */ +} svn_fs_info_placeholder_t; /** - * Set @a *info to an info struct describing @a fs. + * Set @a *fs_info to a struct describing @a fs. The type of the + * struct depends on the backend: for #SVN_FS_TYPE_FSFS, the struct will be + * of type #svn_fs_fsfs_info_t; otherwise, the struct is guaranteed to be + * (compatible with) #svn_fs_info_placeholder_t. * - * @see #svn_fs_info_t + * @see #svn_fs_fsfs_info_t * - * @since New in 1.8. + * @since New in 1.9. */ svn_error_t * -svn_fs_info(const svn_fs_info_t **info, +svn_fs_info(const svn_fs_info_placeholder_t **fs_info, svn_fs_t *fs, apr_pool_t *result_pool, apr_pool_t *scratch_pool); /** - * Return a duplicate of @a info, allocated in @a pool. No part of the new - * structure will be shared with @a info. + * Return a duplicate of @a info, allocated in @a pool. The returned struct + * will be of the same type as the passed-in struct, which itself must have + * been returned from svn_fs_info() or svn_fs_info_dup(). No part of the new + * structure will be shared with @a info (except static string constants). * - * @since New in 1.8. - */ -svn_fs_info_t * -svn_fs_info_dup(const svn_fs_info_t *info, - apr_pool_t *result_pool); - -/** @name FSFS-specific #svn_fs_info_t information. - * @since New in 1.8. - * @{ - */ - -/** Value: shard size (as int), or 0 if the filesystem is - * not currently sharded. */ -#define SVN_FS_FSFS_INFO_SHARDED "sharded" - -/** Value: abspath to rep-cache.db, or absent if that doesn't exist. - @note Do not modify the db schema or tables! + * @see #svn_fs_info_placeholder_t, #svn_fs_fsfs_info_t + * + * @since New in 1.9. */ -#define SVN_FS_FSFS_INFO_REP_CACHE_PATH "rep-cache-path" - -/** The smallest revision (as #svn_revnum_t) which is not in a pack file. - * @note Zero (0) if (but not iff) the format does not support packing. */ -#define SVN_FS_FSFS_INFO_MIN_UNPACKED_REV "min-unpacked-rev" -/** @} */ +void * +svn_fs_info_dup(const void *info, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); /** @} */ #endif /* SVN_FS_INFO */ Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.c?rev=1471638&r1=1471637&r2=1471638&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_fs/fs-loader.c (original) +++ subversion/trunk/subversion/libsvn_fs/fs-loader.c Wed Apr 24 20:20:51 2013 @@ -1630,21 +1630,40 @@ svn_fs_version(void) #ifdef SVN_FS_INFO /** info **/ svn_error_t * -svn_fs_info(const svn_fs_info_t **info, +svn_fs_info(const svn_fs_info_placeholder_t **info_p, svn_fs_t *fs, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { - SVN__NOT_IMPLEMENTED(); + if (fs->vtable->info_fsap) + { + SVN_ERR(fs->vtable->info_fsap((const void **)info_p, fs, + result_pool, scratch_pool)); + } + else + { + svn_fs_info_placeholder_t *info = apr_palloc(result_pool, sizeof(*info)); + /* ### Ask the disk(!), since svn_fs_t doesn't cache the answer. */ + SVN_ERR(svn_fs_type(&info->fs_type, fs->path, result_pool)); + *info_p = info; + } + return SVN_NO_ERROR; } -svn_fs_info_t * -svn_fs_info_dup(const svn_fs_info_t *info, - apr_pool_t *result_pool) +void * +svn_fs_info_dup(const void *info_void, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { - /* Not implemented. */ - SVN_ERR_MALFUNCTION_NO_RETURN(); - return NULL; + const svn_fs_info_placeholder_t *info = info_void; + fs_library_vtable_t *vtable; + + SVN_ERR(get_library_vtable(&vtable, info->fs_type, scratch_pool)); + + if (vtable->info_fsap_dup) + return vtable->info_fsap_dup(info_void, result_pool); + else + return apr_pmemdup(result_pool, info, sizeof(*info)); } #endif Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.h URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.h?rev=1471638&r1=1471637&r2=1471638&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_fs/fs-loader.h (original) +++ subversion/trunk/subversion/libsvn_fs/fs-loader.h Wed Apr 24 20:20:51 2013 @@ -131,7 +131,9 @@ typedef struct fs_library_vtable_t const char *, apr_hash_t *, apr_pool_t *)); - + /* For svn_fs_info_fsfs_dup(). */ + void *(*info_fsap_dup)(const void *fsap_info, + apr_pool_t *result_pool); } fs_library_vtable_t; /* This is the type of symbol an FS module defines to fetch the @@ -221,6 +223,11 @@ typedef struct fs_vtable_t svn_fs_t *fs, apr_pool_t *result_pool, apr_pool_t *scratch_pool); + svn_error_t *(*info_fsap)(const void **fsap_info, + svn_fs_t *fs, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool); + /* info_fsap_dup is in the library vtable. */ svn_error_t *(*verify_root)(svn_fs_root_t *root, apr_pool_t *pool); svn_error_t *(*freeze)(svn_fs_t *fs, Modified: subversion/trunk/subversion/libsvn_fs_base/fs.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/fs.c?rev=1471638&r1=1471637&r2=1471638&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_fs_base/fs.c (original) +++ subversion/trunk/subversion/libsvn_fs_base/fs.c Wed Apr 24 20:20:51 2013 @@ -562,6 +562,7 @@ static fs_vtable_t fs_vtable = { svn_fs_base__get_locks, base_bdb_info_format, base_bdb_info_config_files, + NULL /* info_fsap */, base_bdb_verify_root, base_bdb_freeze, base_bdb_set_errcall, @@ -1462,7 +1463,8 @@ static fs_library_vtable_t library_vtabl base_bdb_pack, base_bdb_logfiles, svn_fs_base__id_parse, - base_set_svn_fs_open + base_set_svn_fs_open, + NULL /* info_fsap_dup */ }; svn_error_t * Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.c?rev=1471638&r1=1471637&r2=1471638&view=diff ============================================================================== --- subversion/trunk/subversion/libsvn_fs_fs/fs.c (original) +++ subversion/trunk/subversion/libsvn_fs_fs/fs.c Wed Apr 24 20:20:51 2013 @@ -164,6 +164,21 @@ fs_freeze(svn_fs_t *fs, return SVN_NO_ERROR; } +static svn_error_t * +fs_info(const void **fsfs_info, + svn_fs_t *fs, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + fs_fs_data_t *ffd = fs->fsap_data; + svn_fs_fsfs_info_t *info = apr_palloc(result_pool, sizeof(*info)); + info->fs_type = SVN_FS_TYPE_FSFS; + info->shard_size = ffd->max_files_per_dir; + info->min_unpacked_rev = ffd->min_unpacked_rev; + *fsfs_info = info; + return SVN_NO_ERROR; +} + /* The vtable associated with a specific open filesystem. */ @@ -186,6 +201,7 @@ static fs_vtable_t fs_vtable = { svn_fs_fs__get_locks, svn_fs_fs__info_format, svn_fs_fs__info_config_files, + fs_info, svn_fs_fs__verify_root, fs_freeze, fs_set_errcall @@ -414,6 +430,15 @@ fs_set_svn_fs_open(svn_fs_t *fs, return SVN_NO_ERROR; } +static void * +fs_info_dup(const void *fsfs_info_void, + apr_pool_t *result_pool) +{ + /* All fields are either ints or static strings. */ + const svn_fs_fsfs_info_t *fsfs_info = fsfs_info_void; + return apr_pmemdup(result_pool, fsfs_info, sizeof(*fsfs_info)); +} + /* Base FS library vtable, used by the FS loader library. */ @@ -431,7 +456,8 @@ static fs_library_vtable_t library_vtabl fs_pack, fs_logfiles, NULL /* parse_id */, - fs_set_svn_fs_open + fs_set_svn_fs_open, + fs_info_dup }; svn_error_t * Modified: subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c?rev=1471638&r1=1471637&r2=1471638&view=diff ============================================================================== --- subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c (original) +++ subversion/trunk/subversion/tests/libsvn_fs_fs/fs-pack-test.c Wed Apr 24 20:20:51 2013 @@ -788,6 +788,50 @@ file_hint_at_shard_boundary(const svn_te #undef SHARD_SIZE /* ------------------------------------------------------------------------ */ +#define REPO_NAME "test-repo-fsfs-info" +#define SHARD_SIZE 3 +#define MAX_REV 5 +static svn_error_t * +test_info(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_fs_t *fs; + const svn_fs_fsfs_info_t *fsfs_info; + const svn_fs_info_placeholder_t *info; + + SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE, + pool)); + + SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool)); + SVN_ERR(svn_fs_info(&info, fs, pool, pool)); + info = svn_fs_info_dup(info, pool, pool); + + SVN_TEST_STRING_ASSERT(opts->fs_type, info->fs_type); + + /* Bail (with success) on known-untestable scenarios */ + if (strcmp(opts->fs_type, "fsfs") != 0) + return SVN_NO_ERROR; + + fsfs_info = (void *)info; + if (opts->server_minor_version && (opts->server_minor_version < 6)) + { + SVN_TEST_ASSERT(fsfs_info->shard_size == 0); + SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev == 0); + } + else + { + SVN_TEST_ASSERT(fsfs_info->shard_size == SHARD_SIZE); + SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev + == (MAX_REV + 1) / SHARD_SIZE * SHARD_SIZE); + } + + return SVN_NO_ERROR; +} +#undef REPO_NAME +#undef SHARD_SIZE +#undef MAX_REV + +/* ------------------------------------------------------------------------ */ /* The test table. */ @@ -812,5 +856,7 @@ struct svn_test_descriptor_t test_funcs[ "recover a fully packed filesystem"), SVN_TEST_OPTS_PASS(file_hint_at_shard_boundary, "test file hint at shard boundary"), + SVN_TEST_OPTS_PASS(test_info, + "test svn_fs_info"), SVN_TEST_NULL };