diff options
Diffstat (limited to 'subversion/libsvn_ra_local/ra_plugin.c')
-rw-r--r-- | subversion/libsvn_ra_local/ra_plugin.c | 429 |
1 files changed, 282 insertions, 147 deletions
diff --git a/subversion/libsvn_ra_local/ra_plugin.c b/subversion/libsvn_ra_local/ra_plugin.c index 4ccc86d..bb09162 100644 --- a/subversion/libsvn_ra_local/ra_plugin.c +++ b/subversion/libsvn_ra_local/ra_plugin.c @@ -87,7 +87,7 @@ get_username(svn_ra_session_t *session, { /* Get a username somehow, so we have some svn:author property to attach to a commit. */ - if (sess->callbacks->auth_baton) + if (sess->auth_baton) { void *creds; svn_auth_cred_username_t *username_creds; @@ -96,7 +96,7 @@ get_username(svn_ra_session_t *session, SVN_ERR(svn_auth_first_credentials(&creds, &iterstate, SVN_AUTH_CRED_USERNAME, sess->uuid, /* realmstring */ - sess->callbacks->auth_baton, + sess->auth_baton, scratch_pool)); /* No point in calling next_creds(), since that assumes that the @@ -241,7 +241,7 @@ reporter_link_path(void *reporter_baton, if (relpath[0] == '\0') fs_path = "/"; else - fs_path = apr_pstrcat(pool, "/", relpath, (char *)NULL); + fs_path = apr_pstrcat(pool, "/", relpath, SVN_VA_NULL); return svn_repos_link_path3(rbaton->report_baton, path, fs_path, revision, depth, start_empty, lock_token, pool); @@ -328,7 +328,7 @@ make_reporter(svn_ra_session_t *session, "'%s'"), other_url, sess->repos_url); other_fs_path = apr_pstrcat(scratch_pool, "/", other_relpath, - (char *)NULL); + SVN_VA_NULL); } /* Pass back our reporter */ @@ -360,8 +360,13 @@ make_reporter(svn_ra_session_t *session, edit_baton, NULL, NULL, - 1024 * 1024, /* process-local transfers - should be fast */ + 0, /* Disable zero-copy codepath, because + RA API users are unaware about the + zero-copy code path limitation (do + not access FSFS data structures + and, hence, caches). See notes + to svn_repos_begin_report3() for + additional details. */ result_pool)); /* Wrap the report baton given us by the repos layer with our own @@ -410,28 +415,29 @@ deltify_etc(const svn_commit_info_t *commit_info, /* Maybe unlock the paths. */ if (deb->lock_tokens) { - apr_pool_t *iterpool = svn_pool_create(scratch_pool); + apr_pool_t *subpool = svn_pool_create(scratch_pool); + apr_hash_t *targets = apr_hash_make(subpool); apr_hash_index_t *hi; - for (hi = apr_hash_first(scratch_pool, deb->lock_tokens); hi; + for (hi = apr_hash_first(subpool, deb->lock_tokens); hi; hi = apr_hash_next(hi)) { - const void *relpath = svn__apr_hash_index_key(hi); - const char *token = svn__apr_hash_index_val(hi); + const void *relpath = apr_hash_this_key(hi); + const char *token = apr_hash_this_val(hi); const char *fspath; - svn_pool_clear(iterpool); - - fspath = svn_fspath__join(deb->fspath_base, relpath, iterpool); - - /* We may get errors here if the lock was broken or stolen - after the commit succeeded. This is fine and should be - ignored. */ - svn_error_clear(svn_repos_fs_unlock(deb->repos, fspath, token, - FALSE, iterpool)); + fspath = svn_fspath__join(deb->fspath_base, relpath, subpool); + svn_hash_sets(targets, fspath, token); } - svn_pool_destroy(iterpool); + /* We may get errors here if the lock was broken or stolen + after the commit succeeded. This is fine and should be + ignored. */ + svn_error_clear(svn_repos_fs_unlock_many(deb->repos, targets, FALSE, + NULL, NULL, + subpool, subpool)); + + svn_pool_destroy(subpool); } /* But, deltification shouldn't be stopped just because someone's @@ -475,8 +481,8 @@ apply_lock_tokens(svn_fs_t *fs, for (hi = apr_hash_first(scratch_pool, lock_tokens); hi; hi = apr_hash_next(hi)) { - const void *relpath = svn__apr_hash_index_key(hi); - const char *token = svn__apr_hash_index_val(hi); + const void *relpath = apr_hash_this_key(hi); + const char *token = apr_hash_this_val(hi); const char *fspath; /* The path needs to live as long as ACCESS_CTX. */ @@ -536,23 +542,31 @@ ignore_warnings(void *baton, svn_error_t *err) { #ifdef SVN_DEBUG - SVN_DBG(("Ignoring FS warning %d\n", err ? err->apr_err : 0)); + SVN_DBG(("Ignoring FS warning %s\n", + svn_error_symbolic_name(err ? err->apr_err : 0))); #endif return; } +#define USER_AGENT "SVN/" SVN_VER_NUMBER " (" SVN_BUILD_TARGET ")" \ + " ra_local" + static svn_error_t * svn_ra_local__open(svn_ra_session_t *session, const char **corrected_url, const char *repos_URL, const svn_ra_callbacks2_t *callbacks, void *callback_baton, + svn_auth_baton_t *auth_baton, apr_hash_t *config, - apr_pool_t *pool) + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) { + const char *client_string; svn_ra_local__session_baton_t *sess; const char *fs_path; static volatile svn_atomic_t cache_init_state = 0; + apr_pool_t *pool = result_pool; /* Initialise the FSFS memory cache size. We can only do this once so one CONFIG will win the race and all others will be ignored @@ -567,16 +581,16 @@ svn_ra_local__open(svn_ra_session_t *session, sess = apr_pcalloc(pool, sizeof(*sess)); sess->callbacks = callbacks; sess->callback_baton = callback_baton; + sess->auth_baton = auth_baton; /* Look through the URL, figure out which part points to the repository, and which part is the path *within* the repository. */ - SVN_ERR_W(svn_ra_local__split_URL(&(sess->repos), - &(sess->repos_url), - &fs_path, - repos_URL, - session->pool), - _("Unable to open an ra_local session to URL")); + SVN_ERR(svn_ra_local__split_URL(&(sess->repos), + &(sess->repos_url), + &fs_path, + repos_URL, + session->pool)); sess->fs_path = svn_stringbuf_create(fs_path, session->pool); /* Cache the filesystem object from the repos here for @@ -592,11 +606,70 @@ svn_ra_local__open(svn_ra_session_t *session, /* Be sure username is NULL so we know to look it up / ask for it */ sess->username = NULL; + if (sess->callbacks->get_client_string != NULL) + SVN_ERR(sess->callbacks->get_client_string(sess->callback_baton, + &client_string, pool)); + else + client_string = NULL; + + if (client_string) + sess->useragent = apr_pstrcat(pool, USER_AGENT " ", + client_string, SVN_VA_NULL); + else + sess->useragent = USER_AGENT; + session->priv = sess; return SVN_NO_ERROR; } static svn_error_t * +svn_ra_local__dup_session(svn_ra_session_t *new_session, + svn_ra_session_t *session, + const char *new_session_url, + apr_pool_t *result_pool, + apr_pool_t *scratch_pool) +{ + svn_ra_local__session_baton_t *old_sess = session->priv; + svn_ra_local__session_baton_t *new_sess; + const char *fs_path; + + /* Allocate and stash the session_sess args we have already. */ + new_sess = apr_pcalloc(result_pool, sizeof(*new_sess)); + new_sess->callbacks = old_sess->callbacks; + new_sess->callback_baton = old_sess->callback_baton; + + /* ### Re-use existing FS handle? */ + + /* Reuse existing code */ + SVN_ERR(svn_ra_local__split_URL(&(new_sess->repos), + &(new_sess->repos_url), + &fs_path, + new_session_url, + result_pool)); + + new_sess->fs_path = svn_stringbuf_create(fs_path, result_pool); + + /* Cache the filesystem object from the repos here for + convenience. */ + new_sess->fs = svn_repos_fs(new_sess->repos); + + /* Ignore FS warnings. */ + svn_fs_set_warning_func(new_sess->fs, ignore_warnings, NULL); + + /* Cache the repository UUID as well */ + new_sess->uuid = apr_pstrdup(result_pool, old_sess->uuid); + + new_sess->username = old_sess->username + ? apr_pstrdup(result_pool, old_sess->username) + : NULL; + + new_sess->useragent = apr_pstrdup(result_pool, old_sess->useragent); + new_session->priv = new_sess; + + return SVN_NO_ERROR; +} + +static svn_error_t * svn_ra_local__reparent(svn_ra_session_t *session, const char *url, apr_pool_t *pool) @@ -728,6 +801,62 @@ svn_ra_local__rev_prop(svn_ra_session_t *session, NULL, NULL, pool); } +struct ccw_baton +{ + svn_commit_callback2_t original_callback; + void *original_baton; + + svn_ra_session_t *session; +}; + +/* Wrapper which populates the repos_root field of the commit_info struct */ +static svn_error_t * +commit_callback_wrapper(const svn_commit_info_t *commit_info, + void *baton, + apr_pool_t *scratch_pool) +{ + struct ccw_baton *ccwb = baton; + svn_commit_info_t *ci = svn_commit_info_dup(commit_info, scratch_pool); + + SVN_ERR(svn_ra_local__get_repos_root(ccwb->session, &ci->repos_root, + scratch_pool)); + + return svn_error_trace(ccwb->original_callback(ci, ccwb->original_baton, + scratch_pool)); +} + + +/* The repository layer does not correctly fill in REPOS_ROOT in + commit_info, as it doesn't know the url that is used to access + it. This hooks the callback to fill in the missing pieces. */ +static void +remap_commit_callback(svn_commit_callback2_t *callback, + void **callback_baton, + svn_ra_session_t *session, + svn_commit_callback2_t original_callback, + void *original_baton, + apr_pool_t *result_pool) +{ + if (original_callback == NULL) + { + *callback = NULL; + *callback_baton = NULL; + } + else + { + /* Allocate this in RESULT_POOL, since the callback will be called + long after this function has returned. */ + struct ccw_baton *ccwb = apr_palloc(result_pool, sizeof(*ccwb)); + + ccwb->session = session; + ccwb->original_callback = original_callback; + ccwb->original_baton = original_baton; + + *callback = commit_callback_wrapper; + *callback_baton = ccwb; + } +} + static svn_error_t * svn_ra_local__get_commit_editor(svn_ra_session_t *session, const svn_delta_editor_t **editor, @@ -742,6 +871,10 @@ svn_ra_local__get_commit_editor(svn_ra_session_t *session, svn_ra_local__session_baton_t *sess = session->priv; struct deltify_etc_baton *deb = apr_palloc(pool, sizeof(*deb)); + /* Set repos_root_url in commit info */ + remap_commit_callback(&callback, &callback_baton, session, + callback, callback_baton, pool); + /* Prepare the baton for deltify_etc() */ deb->fs = sess->fs; deb->repos = sess->repos; @@ -765,6 +898,8 @@ svn_ra_local__get_commit_editor(svn_ra_session_t *session, svn_string_create(sess->username, pool)); svn_hash_sets(revprop_table, SVN_PROP_TXN_CLIENT_COMPAT_VERSION, svn_string_create(SVN_VER_NUMBER, pool)); + svn_hash_sets(revprop_table, SVN_PROP_TXN_USER_AGENT, + svn_string_create(sess->useragent, pool)); /* Get the repos commit-editor */ return svn_repos_get_commit_editor5 @@ -1054,12 +1189,12 @@ svn_ra_local__stat(svn_ra_session_t *session, +/* Obtain the properties for a node, including its 'entry props */ static svn_error_t * get_node_props(apr_hash_t **props, - apr_array_header_t **inherited_props, - svn_ra_local__session_baton_t *sess, svn_fs_root_t *root, const char *path, + const char *uuid, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { @@ -1067,39 +1202,25 @@ get_node_props(apr_hash_t **props, const char *cmt_date, *cmt_author; /* Create a hash with props attached to the fs node. */ - if (props) - { - SVN_ERR(svn_fs_node_proplist(props, root, path, result_pool)); - } - - /* Get inherited properties if requested. */ - if (inherited_props) - { - SVN_ERR(svn_repos_fs_get_inherited_props(inherited_props, root, path, - NULL, NULL, NULL, - result_pool, scratch_pool)); - } + SVN_ERR(svn_fs_node_proplist(props, root, path, result_pool)); /* Now add some non-tweakable metadata to the hash as well... */ - if (props) - { - /* The so-called 'entryprops' with info about CR & friends. */ - SVN_ERR(svn_repos_get_committed_info(&cmt_rev, &cmt_date, - &cmt_author, root, path, - scratch_pool)); - - svn_hash_sets(*props, SVN_PROP_ENTRY_COMMITTED_REV, - svn_string_createf(result_pool, "%ld", cmt_rev)); - svn_hash_sets(*props, SVN_PROP_ENTRY_COMMITTED_DATE, cmt_date ? - svn_string_create(cmt_date, result_pool) :NULL); - svn_hash_sets(*props, SVN_PROP_ENTRY_LAST_AUTHOR, cmt_author ? - svn_string_create(cmt_author, result_pool) :NULL); - svn_hash_sets(*props, SVN_PROP_ENTRY_UUID, - svn_string_create(sess->uuid, result_pool)); - - /* We have no 'wcprops' in ra_local, but might someday. */ - } + /* The so-called 'entryprops' with info about CR & friends. */ + SVN_ERR(svn_repos_get_committed_info(&cmt_rev, &cmt_date, + &cmt_author, root, path, + scratch_pool)); + + svn_hash_sets(*props, SVN_PROP_ENTRY_COMMITTED_REV, + svn_string_createf(result_pool, "%ld", cmt_rev)); + svn_hash_sets(*props, SVN_PROP_ENTRY_COMMITTED_DATE, cmt_date ? + svn_string_create(cmt_date, result_pool) : NULL); + svn_hash_sets(*props, SVN_PROP_ENTRY_LAST_AUTHOR, cmt_author ? + svn_string_create(cmt_author, result_pool) : NULL); + svn_hash_sets(*props, SVN_PROP_ENTRY_UUID, + svn_string_create(uuid, result_pool)); + + /* We have no 'wcprops' in ra_local, but might someday. */ return SVN_NO_ERROR; } @@ -1171,7 +1292,7 @@ svn_ra_local__get_file(svn_ra_session_t *session, /* Handle props if requested. */ if (props) - SVN_ERR(get_node_props(props, NULL, sess, root, abs_path, pool, pool)); + SVN_ERR(get_node_props(props, root, abs_path, sess->uuid, pool, pool)); return SVN_NO_ERROR; } @@ -1194,7 +1315,6 @@ svn_ra_local__get_dir(svn_ra_session_t *session, apr_hash_t *entries; apr_hash_index_t *hi; svn_ra_local__session_baton_t *sess = session->priv; - apr_pool_t *subpool; const char *abs_path = svn_fspath__join(sess->fs_path->data, path, pool); /* Open the revision's root. */ @@ -1210,29 +1330,28 @@ svn_ra_local__get_dir(svn_ra_session_t *session, if (dirents) { + apr_pool_t *iterpool = svn_pool_create(pool); /* Get the dir's entries. */ SVN_ERR(svn_fs_dir_entries(&entries, root, abs_path, pool)); /* Loop over the fs dirents, and build a hash of general svn_dirent_t's. */ *dirents = apr_hash_make(pool); - subpool = svn_pool_create(pool); for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi)) { const void *key; void *val; - apr_hash_t *prophash; const char *datestring, *entryname, *fullpath; svn_fs_dirent_t *fs_entry; svn_dirent_t *entry = svn_dirent_create(pool); - svn_pool_clear(subpool); + svn_pool_clear(iterpool); apr_hash_this(hi, &key, NULL, &val); entryname = (const char *) key; fs_entry = (svn_fs_dirent_t *) val; - fullpath = svn_dirent_join(abs_path, entryname, subpool); + fullpath = svn_dirent_join(abs_path, entryname, iterpool); if (dirent_fields & SVN_DIRENT_KIND) { @@ -1247,15 +1366,15 @@ svn_ra_local__get_dir(svn_ra_session_t *session, entry->size = 0; else SVN_ERR(svn_fs_file_length(&(entry->size), root, - fullpath, subpool)); + fullpath, iterpool)); } if (dirent_fields & SVN_DIRENT_HAS_PROPS) { /* has_props? */ - SVN_ERR(svn_fs_node_proplist(&prophash, root, fullpath, - subpool)); - entry->has_props = (apr_hash_count(prophash) != 0); + SVN_ERR(svn_fs_node_has_props(&entry->has_props, + root, fullpath, + iterpool)); } if ((dirent_fields & SVN_DIRENT_TIME) @@ -1266,7 +1385,7 @@ svn_ra_local__get_dir(svn_ra_session_t *session, SVN_ERR(svn_repos_get_committed_info(&(entry->created_rev), &datestring, &(entry->last_author), - root, fullpath, subpool)); + root, fullpath, iterpool)); if (datestring) SVN_ERR(svn_time_from_cstring(&(entry->time), datestring, pool)); @@ -1277,12 +1396,12 @@ svn_ra_local__get_dir(svn_ra_session_t *session, /* Store. */ svn_hash_sets(*dirents, entryname, entry); } - svn_pool_destroy(subpool); + svn_pool_destroy(iterpool); } /* Handle props if requested. */ if (props) - SVN_ERR(get_node_props(props, NULL, sess, root, abs_path, pool, pool)); + SVN_ERR(get_node_props(props, root, abs_path, sess->uuid, pool, pool)); return SVN_NO_ERROR; } @@ -1322,6 +1441,35 @@ svn_ra_local__get_location_segments(svn_ra_session_t *session, NULL, NULL, pool); } +struct lock_baton_t { + svn_ra_lock_callback_t lock_func; + void *lock_baton; + const char *fs_path; + svn_boolean_t is_lock; + svn_error_t *cb_err; +}; + +/* Implements svn_fs_lock_callback_t. Used by svn_ra_local__lock and + svn_ra_local__unlock to forward to supplied callback and record any + callback error. */ +static svn_error_t * +lock_cb(void *lock_baton, + const char *path, + const svn_lock_t *lock, + svn_error_t *fs_err, + apr_pool_t *pool) +{ + struct lock_baton_t *b = lock_baton; + + if (b && !b->cb_err && b->lock_func) + { + path = svn_fspath__skip_ancestor(b->fs_path, path); + b->cb_err = b->lock_func(b->lock_baton, path, b->is_lock, lock, fs_err, + pool); + } + + return SVN_NO_ERROR; +} static svn_error_t * svn_ra_local__lock(svn_ra_session_t *session, @@ -1333,51 +1481,44 @@ svn_ra_local__lock(svn_ra_session_t *session, apr_pool_t *pool) { svn_ra_local__session_baton_t *sess = session->priv; + apr_hash_t *targets = apr_hash_make(pool); apr_hash_index_t *hi; - apr_pool_t *iterpool = svn_pool_create(pool); + svn_error_t *err; + struct lock_baton_t baton = {0}; /* A username is absolutely required to lock a path. */ SVN_ERR(get_username(session, pool)); for (hi = apr_hash_first(pool, path_revs); hi; hi = apr_hash_next(hi)) { - svn_lock_t *lock; - const void *key; - const char *path; - void *val; - svn_revnum_t *revnum; - const char *abs_path; - svn_error_t *err, *callback_err = NULL; - - svn_pool_clear(iterpool); - apr_hash_this(hi, &key, NULL, &val); - path = key; - revnum = val; - - abs_path = svn_fspath__join(sess->fs_path->data, path, iterpool); - - /* This wrapper will call pre- and post-lock hooks. */ - err = svn_repos_fs_lock(&lock, sess->repos, abs_path, NULL, comment, - FALSE /* not DAV comment */, - 0 /* no expiration */, *revnum, force, - iterpool); - - if (err && !SVN_ERR_IS_LOCK_ERROR(err)) - return err; - - if (lock_func) - callback_err = lock_func(lock_baton, path, TRUE, err ? NULL : lock, - err, iterpool); - - svn_error_clear(err); - - if (callback_err) - return callback_err; + const char *abs_path = svn_fspath__join(sess->fs_path->data, + apr_hash_this_key(hi), pool); + svn_revnum_t current_rev = *(svn_revnum_t *)apr_hash_this_val(hi); + svn_fs_lock_target_t *target = svn_fs_lock_target_create(NULL, + current_rev, + pool); + + svn_hash_sets(targets, abs_path, target); } - svn_pool_destroy(iterpool); + baton.lock_func = lock_func; + baton.lock_baton = lock_baton; + baton.fs_path = sess->fs_path->data; + baton.is_lock = TRUE; + baton.cb_err = SVN_NO_ERROR; - return SVN_NO_ERROR; + err = svn_repos_fs_lock_many(sess->repos, targets, comment, + FALSE /* not DAV comment */, + 0 /* no expiration */, force, + lock_cb, &baton, + pool, pool); + + if (err && baton.cb_err) + svn_error_compose(err, baton.cb_err); + else if (!err) + err = baton.cb_err; + + return svn_error_trace(err); } @@ -1390,51 +1531,38 @@ svn_ra_local__unlock(svn_ra_session_t *session, apr_pool_t *pool) { svn_ra_local__session_baton_t *sess = session->priv; + apr_hash_t *targets = apr_hash_make(pool); apr_hash_index_t *hi; - apr_pool_t *iterpool = svn_pool_create(pool); + svn_error_t *err; + struct lock_baton_t baton = {0}; /* A username is absolutely required to unlock a path. */ SVN_ERR(get_username(session, pool)); for (hi = apr_hash_first(pool, path_tokens); hi; hi = apr_hash_next(hi)) { - const void *key; - const char *path; - void *val; - const char *abs_path, *token; - svn_error_t *err, *callback_err = NULL; - - svn_pool_clear(iterpool); - apr_hash_this(hi, &key, NULL, &val); - path = key; - /* Since we can't store NULL values in a hash, we turn "" to - NULL here. */ - if (strcmp(val, "") != 0) - token = val; - else - token = NULL; - - abs_path = svn_fspath__join(sess->fs_path->data, path, iterpool); - - /* This wrapper will call pre- and post-unlock hooks. */ - err = svn_repos_fs_unlock(sess->repos, abs_path, token, force, - iterpool); + const char *abs_path = svn_fspath__join(sess->fs_path->data, + apr_hash_this_key(hi), pool); + const char *token = apr_hash_this_val(hi); - if (err && !SVN_ERR_IS_UNLOCK_ERROR(err)) - return err; - - if (lock_func) - callback_err = lock_func(lock_baton, path, FALSE, NULL, err, iterpool); + svn_hash_sets(targets, abs_path, token); + } - svn_error_clear(err); + baton.lock_func = lock_func; + baton.lock_baton = lock_baton; + baton.fs_path = sess->fs_path->data; + baton.is_lock = FALSE; + baton.cb_err = SVN_NO_ERROR; - if (callback_err) - return callback_err; - } + err = svn_repos_fs_unlock_many(sess->repos, targets, force, lock_cb, &baton, + pool, pool); - svn_pool_destroy(iterpool); + if (err && baton.cb_err) + svn_error_compose(err, baton.cb_err); + else if (!err) + err = baton.cb_err; - return SVN_NO_ERROR; + return svn_error_trace(err); } @@ -1597,8 +1725,11 @@ svn_ra_local__get_inherited_props(svn_ra_session_t *session, _("'%s' path not found"), abs_path); } - return svn_error_trace(get_node_props(NULL, iprops, sess, root, abs_path, - result_pool, scratch_pool)); + return svn_error_trace( + svn_repos_fs_get_inherited_props(iprops, root, abs_path, + NULL /* propname */, + NULL, NULL /* auth */, + result_pool, scratch_pool)); } static svn_error_t * @@ -1631,6 +1762,9 @@ svn_ra_local__get_commit_ev2(svn_editor_t **editor, svn_ra_local__session_baton_t *sess = session->priv; struct deltify_etc_baton *deb = apr_palloc(result_pool, sizeof(*deb)); + remap_commit_callback(&commit_cb, &commit_baton, session, + commit_cb, commit_baton, result_pool); + /* NOTE: the RA callbacks are ignored. We pass everything directly to the REPOS editor. */ @@ -1682,6 +1816,7 @@ static const svn_ra__vtable_t ra_local_vtable = svn_ra_local__get_description, svn_ra_local__get_schemes, svn_ra_local__open, + svn_ra_local__dup_session, svn_ra_local__reparent, svn_ra_local__get_session_url, svn_ra_local__get_latest_revnum, @@ -1749,8 +1884,8 @@ svn_ra_local__init(const svn_version_t *loader_version, SVN_ERR(svn_ver_check_list2(ra_local_version(), checklist, svn_ver_equal)); #ifndef SVN_LIBSVN_CLIENT_LINKS_RA_LOCAL - /* This assumes that POOL was the pool used to load the dso. */ - SVN_ERR(svn_fs_initialize(pool)); + /* This means the library was loaded as a DSO, so use the DSO pool. */ + SVN_ERR(svn_fs_initialize(svn_dso__pool())); #endif *vtable = &ra_local_vtable; |