You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/02/04 21:48:13 UTC
svn commit: r1442344 [12/39] - in /subversion/branches/fsfs-format7: ./
build/ build/ac-macros/ build/generator/ build/generator/templates/
build/win32/ contrib/client-side/emacs/
contrib/server-side/fsfsfixer/fixer/ contrib/server-side/svncutter/ doc/...
Modified: subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_fs_fs/tree.c Mon Feb 4 20:48:05 2013
@@ -321,7 +321,7 @@ auto_clear_dag_cache(fs_fs_dag_cache_t*
{
if (cache->first_lock == NULL && cache->insertions > BUCKET_COUNT)
{
- apr_pool_clear(cache->pool);
+ svn_pool_clear(cache->pool);
memset(cache->buckets, 0, sizeof(cache->buckets));
cache->insertions = 0;
@@ -499,6 +499,9 @@ dag_node_cache_set(svn_fs_root_t *root,
SVN_ERR_ASSERT(*path == '/');
+ /* Do *not* attempt to dup and put the node into L1.
+ * dup() is twice as expensive as an L2 lookup (which will set also L1).
+ */
locate_cache(&cache, &key, root, path, pool);
return svn_cache__set(cache, key, node, pool);
@@ -849,8 +852,19 @@ typedef enum open_path_flags_t {
directories must exist, as usual.) If the last component doesn't
exist, simply leave the `node' member of the bottom parent_path
component zero. */
- open_path_last_optional = 1
+ open_path_last_optional = 1,
+ /* When this flag is set, don't bother to lookup the DAG node in
+ our caches because we already tried this. Ignoring this flag
+ has no functional impact. */
+ open_path_uncached = 2,
+
+ /* Assume that the path parameter is already in canonical form. */
+ open_path_is_canonical = 4,
+
+ /* The caller does not care about the parent node chain but only
+ the final DAG node. */
+ open_path_node_only = 8
} open_path_flags_t;
@@ -873,6 +887,10 @@ typedef enum open_path_flags_t {
callers that create new nodes --- we find the parent directory for
them, and tell them whether the entry exists already.
+ The remaining bits in FLAGS are hints that allow this function
+ to take shortcuts based on knowledge that the caller provides,
+ such as the fact that PATH is already in canonical form.
+
NOTE: Public interfaces which only *read* from the filesystem
should not call this function directly, but should instead use
get_dag().
@@ -886,23 +904,47 @@ open_path(parent_path_t **parent_path_p,
apr_pool_t *pool)
{
svn_fs_t *fs = root->fs;
- dag_node_t *here; /* The directory we're currently looking at. */
- parent_path_t *parent_path; /* The path from HERE up to the root. */
+ dag_node_t *here = NULL; /* The directory we're currently looking at. */
+ parent_path_t *parent_path; /* The path from HERE up to the root. */
const char *rest; /* The portion of PATH we haven't traversed yet. */
- const char *canon_path = svn_fs__is_canonical_abspath(path)
+
+ /* ensure a canonical path representation */
+ const char *canon_path = ( (flags & open_path_is_canonical)
+ || svn_fs__is_canonical_abspath(path))
? path
: svn_fs__canonicalize_abspath(path, pool);
const char *path_so_far = "/";
apr_pool_t *iterpool = svn_pool_create(pool);
- /* Make a parent_path item for the root node, using its own current
- copy id. */
- SVN_ERR(root_node(&here, root, pool));
+ /* callers often traverse the tree in some path-based order. That means
+ a sibbling of PATH has been resently accessed. Try to start the lookup
+ directly at the parent node, if the caller did not requested the full
+ parent chain. */
+ const char *directory;
+ if (flags & open_path_node_only)
+ {
+ directory = svn_dirent_dirname(canon_path, pool);
+ if (directory[1] != 0) /* root nodes are covered anyway */
+ SVN_ERR(dag_node_cache_get(&here, root, directory, TRUE, pool));
+ }
+
+ /* did the shortcut work? */
+ if (here)
+ {
+ path_so_far = directory;
+ rest = canon_path + strlen(directory) + 1;
+ }
+ else
+ {
+ /* Make a parent_path item for the root node, using its own current
+ copy id. */
+ SVN_ERR(root_node(&here, root, pool));
+ rest = canon_path + 1; /* skip the leading '/', it saves in iteration */
+ }
+
parent_path = make_parent_path(here, 0, 0, pool);
parent_path->copy_inherit = copy_id_inherit_self;
- rest = canon_path + 1; /* skip the leading '/', it saves in iteration */
-
/* Whenever we are at the top of this loop:
- HERE is our current directory,
- ID is the node revision ID of HERE,
@@ -935,13 +977,16 @@ open_path(parent_path_t **parent_path_p,
copy_id_inherit_t inherit;
const char *copy_path = NULL;
svn_error_t *err = SVN_NO_ERROR;
- dag_node_t *cached_node;
+ dag_node_t *cached_node = NULL;
/* If we found a directory entry, follow it. First, we
check our node cache, and, failing that, we hit the DAG
- layer. */
- SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far, TRUE,
- pool));
+ layer. Don't bother to contact the cache for the last
+ element if we already know the lookup to fail for the
+ complete path. */
+ if (next || !(flags & open_path_uncached))
+ SVN_ERR(dag_node_cache_get(&cached_node, root, path_so_far,
+ TRUE, pool));
if (cached_node)
child = cached_node;
else
@@ -974,14 +1019,22 @@ open_path(parent_path_t **parent_path_p,
/* Other errors we return normally. */
SVN_ERR(err);
- /* Now, make a parent_path item for CHILD. */
- parent_path = make_parent_path(child, entry, parent_path, pool);
- if (txn_id)
+ if (flags & open_path_node_only)
+ {
+ /* Shortcut: the caller only wan'ts the final DAG node. */
+ parent_path->node = child;
+ }
+ else
{
- SVN_ERR(get_copy_inheritance(&inherit, ©_path,
- fs, parent_path, txn_id, iterpool));
- parent_path->copy_inherit = inherit;
- parent_path->copy_src_path = apr_pstrdup(pool, copy_path);
+ /* Now, make a parent_path item for CHILD. */
+ parent_path = make_parent_path(child, entry, parent_path, pool);
+ if (txn_id)
+ {
+ SVN_ERR(get_copy_inheritance(&inherit, ©_path, fs,
+ parent_path, txn_id, iterpool));
+ parent_path->copy_inherit = inherit;
+ parent_path->copy_src_path = apr_pstrdup(pool, copy_path);
+ }
}
/* Cache the node we found (if it wasn't already cached). */
@@ -1144,7 +1197,9 @@ get_dag(dag_node_t **dag_node_p,
{
/* Call open_path with no flags, as we want this to return an
* error if the node for which we are searching doesn't exist. */
- SVN_ERR(open_path(&parent_path, root, path, 0, NULL, pool));
+ SVN_ERR(open_path(&parent_path, root, path,
+ open_path_uncached | open_path_is_canonical
+ | open_path_node_only, NULL, pool));
node = parent_path->node;
/* No need to cache our find -- open_path() will do that for us. */
@@ -3164,7 +3219,7 @@ static svn_error_t *fs_closest_copy(svn_
if (kind == svn_node_none)
return SVN_NO_ERROR;
SVN_ERR(open_path(©_dst_parent_path, copy_dst_root, path,
- 0, NULL, pool));
+ open_path_node_only, NULL, pool));
copy_dst_node = copy_dst_parent_path->node;
if (! svn_fs_fs__id_check_related(svn_fs_fs__dag_get_id(copy_dst_node),
svn_fs_fs__dag_get_id(parent_path->node)))
@@ -3245,7 +3300,7 @@ prev_location(const char **prev_path,
*/
SVN_ERR(fs_copied_from(©_src_rev, ©_src_path,
copy_root, copy_path, pool));
- remainder_path = svn_relpath_skip_ancestor(copy_path, path);
+ remainder_path = svn_fspath__skip_ancestor(copy_path, path);
*prev_path = svn_fspath__join(copy_src_path, remainder_path, pool);
*prev_rev = copy_src_rev;
return SVN_NO_ERROR;
@@ -3777,7 +3832,8 @@ get_mergeinfo_for_path_internal(svn_merg
path = svn_fs__canonicalize_abspath(path, scratch_pool);
- SVN_ERR(open_path(&parent_path, rev_root, path, 0, NULL, scratch_pool));
+ SVN_ERR(open_path(&parent_path, rev_root, path, open_path_is_canonical,
+ NULL, scratch_pool));
if (inherit == svn_mergeinfo_nearest_ancestor && ! parent_path->parent)
return SVN_NO_ERROR;
@@ -4285,8 +4341,6 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
/* Verify explicitly the predecessor of the root. */
{
const svn_fs_id_t *pred_id;
- dag_node_t *pred;
- svn_revnum_t pred_rev;
/* Only r0 should have no predecessor. */
SVN_ERR(svn_fs_fs__dag_get_predecessor_id(&pred_id, frd->root_dir));
@@ -4302,8 +4356,7 @@ svn_fs_fs__verify_root(svn_fs_root_t *ro
/* Check the predecessor's revision. */
if (pred_id)
{
- SVN_ERR(svn_fs_fs__dag_get_node(&pred, root->fs, pred_id, pool));
- SVN_ERR(svn_fs_fs__dag_get_revision(&pred_rev, pred, pool));
+ svn_revnum_t pred_rev = svn_fs_fs__id_rev(pred_id);
if (pred_rev+1 != root->rev)
/* Issue #4129. */
return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/compat.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/compat.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/compat.c Mon Feb 4 20:48:05 2013
@@ -630,7 +630,6 @@ fr_log_message_receiver(void *baton,
{
struct fr_log_message_baton *lmb = baton;
struct rev *rev;
- apr_hash_index_t *hi;
rev = apr_palloc(lmb->pool, sizeof(*rev));
rev->revision = log_entry->revision;
@@ -639,17 +638,7 @@ fr_log_message_receiver(void *baton,
lmb->eldest = rev;
/* Duplicate log_entry revprops into rev->props */
- rev->props = apr_hash_make(lmb->pool);
- for (hi = apr_hash_first(pool, log_entry->revprops); hi;
- hi = apr_hash_next(hi))
- {
- void *val;
- const void *key;
-
- apr_hash_this(hi, &key, NULL, &val);
- apr_hash_set(rev->props, apr_pstrdup(lmb->pool, key), APR_HASH_KEY_STRING,
- svn_string_dup(val, lmb->pool));
- }
+ rev->props = svn_prop_hash_dup(log_entry->revprops, lmb->pool);
return prev_log_path(&lmb->path, &lmb->action,
&lmb->copyrev, log_entry->changed_paths2,
@@ -946,7 +935,9 @@ svn_ra__get_inherited_props_walk(svn_ra_
{
svn_prop_inherited_item_t *new_iprop =
apr_palloc(result_pool, sizeof(*new_iprop));
- new_iprop->path_or_url = apr_pstrdup(result_pool, parent_url);
+ new_iprop->path_or_url = svn_uri_skip_ancestor(repos_root_url,
+ parent_url,
+ result_pool);
new_iprop->prop_hash = final_hash;
svn_sort__array_insert(&new_iprop, *inherited_props, 0);
}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.h?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/deprecated.h Mon Feb 4 20:48:05 2013
@@ -28,7 +28,8 @@
#include <apr_hash.h>
-#include "svn_editor.h"
+#include "private/svn_editor.h"
+
#ifdef __cplusplus
extern "C" {
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/editor.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/editor.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/editor.c Mon Feb 4 20:48:05 2013
@@ -27,11 +27,11 @@
#include "svn_pools.h"
#include "svn_ra.h"
#include "svn_delta.h"
-#include "svn_editor.h"
#include "svn_dirent_uri.h"
#include "private/svn_ra_private.h"
#include "private/svn_delta_private.h"
+#include "private/svn_editor.h"
#include "ra_loader.h"
#include "svn_private_config.h"
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.c Mon Feb 4 20:48:05 2013
@@ -140,8 +140,8 @@ load_ra_module(svn_ra__init_func_t *func
const char *compat_funcname;
apr_status_t status;
- libname = apr_psprintf(pool, "libsvn_ra_%s-%d.so.0",
- ra_name, SVN_VER_MAJOR);
+ libname = apr_psprintf(pool, "libsvn_ra_%s-%d.so.%d",
+ ra_name, SVN_VER_MAJOR, SVN_SOVERSION);
funcname = apr_psprintf(pool, "svn_ra_%s__init", ra_name);
compat_funcname = apr_psprintf(pool, "svn_ra_%s_init", ra_name);
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.h?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra/ra_loader.h Mon Feb 4 20:48:05 2013
@@ -496,11 +496,11 @@ svn_ra__get_deleted_rev_from_log(svn_ra_
/**
- * Fallback logic for svn_ra_get_fileX and svn_ra_get_dirX when those APIs
+ * Fallback logic for svn_ra_get_inherited_props() when that API
* need to find PATH's inherited properties on a legacy server that
* doesn't have the SVN_RA_CAPABILITY_INHERITED_PROPS capability.
*
- * All arguments are as per the two aforementioned APIs.
+ * All arguments are as per svn_ra_get_inherited_props().
*/
svn_error_t *
svn_ra__get_inherited_props_walk(svn_ra_session_t *session,
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_local/ra_plugin.c Mon Feb 4 20:48:05 2013
@@ -1058,22 +1058,12 @@ get_node_props(apr_hash_t **props,
SVN_ERR(svn_fs_node_proplist(props, root, path, result_pool));
}
- /* Turn FS-path keys into URLs. */
+ /* Get inherited properties if requested. */
if (inherited_props)
{
- int i;
-
SVN_ERR(svn_repos_fs_get_inherited_props(inherited_props, root, path,
- NULL, NULL,
+ NULL, NULL, NULL,
result_pool, scratch_pool));
-
- for (i = 0; i < (*inherited_props)->nelts; i++)
- {
- svn_prop_inherited_item_t *i_props =
- APR_ARRAY_IDX(*inherited_props, i, svn_prop_inherited_item_t *);
- i_props->path_or_url = svn_path_url_add_component2(
- sess->repos_url, i_props->path_or_url, result_pool);
- }
}
/* Now add some non-tweakable metadata to the hash as well... */
@@ -1230,7 +1220,7 @@ svn_ra_local__get_dir(svn_ra_session_t *
apr_hash_t *prophash;
const char *datestring, *entryname, *fullpath;
svn_fs_dirent_t *fs_entry;
- svn_dirent_t *entry = apr_pcalloc(pool, sizeof(*entry));
+ svn_dirent_t *entry = svn_dirent_create(pool);
svn_pool_clear(subpool);
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/commit.c Mon Feb 4 20:48:05 2013
@@ -1294,9 +1294,9 @@ open_root(void *edit_baton,
{
post_response_ctx_t *prc;
const char *rel_path;
- svn_boolean_t post_with_revprops =
- apr_hash_get(ctx->session->supported_posts, "create-txn-with-props",
- APR_HASH_KEY_STRING) ? TRUE : FALSE;
+ svn_boolean_t post_with_revprops
+ = (apr_hash_get(ctx->session->supported_posts, "create-txn-with-props",
+ APR_HASH_KEY_STRING) != NULL);
/* Create our activity URL now on the server. */
handler = apr_pcalloc(ctx->pool, sizeof(*handler));
@@ -1466,16 +1466,10 @@ open_root(void *edit_baton,
for (hi = apr_hash_first(ctx->pool, ctx->revprop_table); hi;
hi = apr_hash_next(hi))
{
- const void *key;
- void *val;
- const char *name;
- svn_string_t *value;
+ const char *name = svn__apr_hash_index_key(hi);
+ svn_string_t *value = svn__apr_hash_index_val(hi);
const char *ns;
- apr_hash_this(hi, &key, NULL, &val);
- name = key;
- value = val;
-
if (strncmp(name, SVN_PROP_PREFIX, sizeof(SVN_PROP_PREFIX) - 1) == 0)
{
ns = SVN_DAV_PROP_NS_SVN;
@@ -2267,7 +2261,6 @@ svn_ra_serf__get_commit_editor(svn_ra_se
svn_ra_serf__session_t *session = ra_session->priv;
svn_delta_editor_t *editor;
commit_context_t *ctx;
- apr_hash_index_t *hi;
const char *repos_root;
const char *base_relpath;
svn_boolean_t supports_ephemeral_props;
@@ -2279,17 +2272,7 @@ svn_ra_serf__get_commit_editor(svn_ra_se
ctx->session = session;
ctx->conn = session->conns[0];
- ctx->revprop_table = apr_hash_make(pool);
- for (hi = apr_hash_first(pool, revprop_table); hi; hi = apr_hash_next(hi))
- {
- const void *key;
- apr_ssize_t klen;
- void *val;
-
- apr_hash_this(hi, &key, &klen, &val);
- apr_hash_set(ctx->revprop_table, apr_pstrdup(pool, key), klen,
- svn_string_dup(val, pool));
- }
+ ctx->revprop_table = svn_prop_hash_dup(revprop_table, pool);
/* If the server supports ephemeral properties, add some carrying
interesting version information. */
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/locks.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/locks.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/locks.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/locks.c Mon Feb 4 20:48:05 2013
@@ -261,7 +261,7 @@ handle_lock(serf_request_t *request,
request, response, ctx->handler, pool));
}
- if (ctx->read_headers == FALSE)
+ if (!ctx->read_headers)
{
serf_bucket_t *headers;
const char *val;
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/options.c Mon Feb 4 20:48:05 2013
@@ -211,6 +211,14 @@ capabilities_headers_iterator_callback(v
SVN_RA_CAPABILITY_EPHEMERAL_TXNPROPS, APR_HASH_KEY_STRING,
capability_yes);
}
+ if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_INLINE_PROPS, vals))
+ {
+ session->supports_inline_props = TRUE;
+ }
+ if (svn_cstring_match_list(SVN_DAV_NS_DAV_SVN_REPLAY_REV_RESOURCE, vals))
+ {
+ session->supports_rev_rsrc_replay = TRUE;
+ }
}
/* SVN-specific headers -- if present, server supports HTTP protocol v2 */
@@ -280,6 +288,10 @@ capabilities_headers_iterator_callback(v
{
opt_ctx->youngest_rev = SVN_STR_TO_REV(val);
}
+ else if (svn_cstring_casecmp(key, SVN_DAV_ALLOW_BULK_UPDATES) == 0)
+ {
+ session->server_allows_bulk = apr_pstrdup(session->pool, val);
+ }
else if (svn_cstring_casecmp(key, SVN_DAV_SUPPORTED_POSTS_HEADER) == 0)
{
/* May contain multiple values, separated by commas. */
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/property.c Mon Feb 4 20:48:05 2013
@@ -526,7 +526,7 @@ create_propfind_body(serf_bucket_t **bkt
}
/* If we're not doing an allprop, add <prop> tags. */
- if (requested_allprop == FALSE)
+ if (!requested_allprop)
{
tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<prop>",
sizeof("<prop>")-1,
@@ -540,7 +540,7 @@ create_propfind_body(serf_bucket_t **bkt
serf_bucket_aggregate_prepend(body_bkt, tmp);
- if (requested_allprop == FALSE)
+ if (!requested_allprop)
{
tmp = SERF_BUCKET_SIMPLE_STRING_LEN("</prop>",
sizeof("</prop>")-1,
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/ra_serf.h Mon Feb 4 20:48:05 2013
@@ -94,10 +94,12 @@ typedef struct svn_ra_serf__connection_t
} svn_ra_serf__connection_t;
-/** Max. number of connctions we'll open to the server.
- * Note: minimum 2 connections are required for ra_serf to function correctly!
+/** Maximum value we'll allow for the http-max-connections config option.
+ *
+ * Note: minimum 2 connections are required for ra_serf to function
+ * correctly!
*/
-#define MAX_NR_OF_CONNS 4
+#define SVN_RA_SERF__MAX_CONNECTIONS_LIMIT 8
/*
* The master serf RA session.
@@ -111,6 +113,10 @@ struct svn_ra_serf__session_t {
/* The current context */
serf_context_t *context;
+ /* The maximum number of connections we'll use for parallelized
+ fetch operations (updates, etc.) */
+ apr_int64_t max_connections;
+
/* Are we using ssl */
svn_boolean_t using_ssl;
@@ -121,7 +127,7 @@ struct svn_ra_serf__session_t {
const char *useragent;
/* The current connection */
- svn_ra_serf__connection_t *conns[MAX_NR_OF_CONNS];
+ svn_ra_serf__connection_t *conns[SVN_RA_SERF__MAX_CONNECTIONS_LIMIT];
int num_conns;
int cur_conn;
@@ -223,6 +229,26 @@ struct svn_ra_serf__session_t {
/*** End HTTP v2 stuff ***/
svn_ra_serf__blncache_t *blncache;
+
+ /* Trisate flag that indicates user preference for using bulk updates
+ (svn_tristate_true) with all the properties and content in the
+ update-report response. If svn_tristate_false, request a skelta
+ update-report with inlined properties. If svn_tristate_unknown then use
+ server preference. */
+ svn_tristate_t bulk_updates;
+
+ /* Indicates if the server wants bulk update requests (Prefer) or only
+ accepts skelta requests (Off). If this value is On both options are
+ allowed. */
+ const char *server_allows_bulk;
+
+ /* Indicates if the server supports sending inlined props in update editor
+ * in skelta mode (send-all == 'false'). */
+ svn_boolean_t supports_inline_props;
+
+ /* Indicates whether the server supports issuing replay REPORTs
+ against rev resources (children of `rev_stub', elsestruct). */
+ svn_boolean_t supports_rev_rsrc_replay;
};
#define SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(sess) ((sess)->me_resource != NULL)
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/replay.c Mon Feb 4 20:48:05 2013
@@ -107,16 +107,17 @@ typedef struct replay_context_t {
const svn_delta_editor_t *editor;
void *editor_baton;
- /* current revision */
+ /* Path and revision used to filter replayed changes. If
+ INCLUDE_PATH is non-NULL, REVISION is unnecessary and will not be
+ included in the replay REPORT. (Because the REPORT is being
+ aimed an HTTP v2 revision resource.) */
+ const char *include_path;
svn_revnum_t revision;
/* Information needed to create the replay report body */
svn_revnum_t low_water_mark;
svn_boolean_t send_deltas;
- /* Cached report target url */
- const char *report_target;
-
/* Target and revision to fetch revision properties on */
const char *revprop_target;
svn_revnum_t revprop_rev;
@@ -128,8 +129,9 @@ typedef struct replay_context_t {
/* Keep a reference to the XML parser ctx to report any errors. */
svn_ra_serf__xml_parser_t *parser_ctx;
- /* The propfind for the revision properties of the current revision */
+ /* Handlers for the PROPFIND and REPORT for the current revision. */
svn_ra_serf__handler_t *propfind_handler;
+ svn_ra_serf__handler_t *report_handler;
} replay_context_t;
@@ -602,10 +604,22 @@ create_replay_body(serf_bucket_t **bkt,
"xmlns:S", SVN_XML_NAMESPACE,
NULL);
- svn_ra_serf__add_tag_buckets(body_bkt,
- "S:revision",
- apr_ltoa(ctx->src_rev_pool, ctx->revision),
- alloc);
+ /* If we have a non-NULL include path, we add it to the body and
+ omit the revision; otherwise, the reverse. */
+ if (ctx->include_path)
+ {
+ svn_ra_serf__add_tag_buckets(body_bkt,
+ "S:include-path",
+ ctx->include_path,
+ alloc);
+ }
+ else
+ {
+ svn_ra_serf__add_tag_buckets(body_bkt,
+ "S:revision",
+ apr_ltoa(ctx->src_rev_pool, ctx->revision),
+ alloc);
+ }
svn_ra_serf__add_tag_buckets(body_bkt,
"S:low-water-mark",
apr_ltoa(ctx->src_rev_pool, ctx->low_water_mark),
@@ -648,14 +662,13 @@ svn_ra_serf__replay(svn_ra_session_t *ra
replay_ctx->revision = revision;
replay_ctx->low_water_mark = low_water_mark;
replay_ctx->send_deltas = send_deltas;
- replay_ctx->report_target = report_target;
replay_ctx->revs_props = apr_hash_make(replay_ctx->src_rev_pool);
handler = apr_pcalloc(pool, sizeof(*handler));
handler->handler_pool = pool;
handler->method = "REPORT";
- handler->path = session->session_url_str;
+ handler->path = session->session_url.path;
handler->body_delegate = create_replay_body;
handler->body_delegate_baton = replay_ctx;
handler->body_type = "text/xml";
@@ -676,12 +689,17 @@ svn_ra_serf__replay(svn_ra_session_t *ra
/* This is only needed to handle errors during XML parsing. */
replay_ctx->parser_ctx = parser_ctx;
+ replay_ctx->report_handler = handler; /* unused */
svn_ra_serf__request_create(handler);
err = svn_ra_serf__context_run_wait(&replay_ctx->done, session, pool);
- SVN_ERR(err);
+ SVN_ERR(svn_error_compose_create(
+ svn_ra_serf__error_on_status(handler->sline.code,
+ handler->path,
+ handler->location),
+ err));
return SVN_NO_ERROR;
}
@@ -698,8 +716,8 @@ svn_ra_serf__replay(svn_ra_session_t *ra
* optimally. Originally we used 5 as the max. number of outstanding
* requests, but this turned out to be too low.
*
- * Serf doesn't exit out of the serf_context_run loop as long as it
- * has data to send or receive. With small responses (revs of a few
+ * Serf doesn't exit out of the svn_ra_serf__context_run_wait loop as long as
+ * it has data to send or receive. With small responses (revs of a few
* kB), serf doesn't come out of this loop at all. So with
* MAX_OUTSTANDING_REQUESTS set to a low number, there's a big chance
* that serf handles those requests completely in its internal loop,
@@ -732,14 +750,41 @@ svn_ra_serf__replay_range(svn_ra_session
svn_revnum_t rev = start_revision;
const char *report_target;
int active_reports = 0;
- apr_interval_time_t waittime_left = session->timeout;
+ const char *include_path;
SVN_ERR(svn_ra_serf__report_resource(&report_target, session, NULL, pool));
+ /* Prior to 1.8, mod_dav_svn expect to get replay REPORT requests
+ aimed at the session URL. But that's incorrect -- these reports
+ aren't about specific resources -- they are above revisions. The
+ path-based filtering offered by this API is just that: a filter
+ applied to the full set of changes made in the revision. As
+ such, the correct target for these REPORT requests is the "me
+ resource" (or, pre-http-v2, the default VCC).
+
+ Our server should have told us if it supported this protocol
+ correction. If so, we aimed our report at the correct resource
+ and include the filtering path as metadata within the report
+ body. Otherwise, we fall back to the pre-1.8 behavior and just
+ wish for the best.
+
+ See issue #4287:
+ http://subversion.tigris.org/issues/show_bug.cgi?id=4287
+ */
+ if (session->supports_rev_rsrc_replay)
+ {
+ SVN_ERR(svn_ra_serf__get_relative_path(&include_path,
+ session->session_url.path,
+ session, session->conns[0],
+ pool));
+ }
+ else
+ {
+ include_path = NULL;
+ }
+
while (active_reports || rev <= end_revision)
{
- apr_status_t status;
- svn_error_t *err;
svn_ra_serf__list_t *done_list;
svn_ra_serf__list_t *done_reports = NULL;
replay_context_t *replay_ctx;
@@ -754,6 +799,7 @@ svn_ra_serf__replay_range(svn_ra_session
svn_ra_serf__handler_t *handler;
svn_ra_serf__xml_parser_t *parser_ctx;
apr_pool_t *ctx_pool = svn_pool_create(pool);
+ const char *replay_target;
replay_ctx = apr_pcalloc(ctx_pool, sizeof(*replay_ctx));
replay_ctx->src_rev_pool = ctx_pool;
@@ -761,19 +807,20 @@ svn_ra_serf__replay_range(svn_ra_session
replay_ctx->revfinish_func = revfinish_func;
replay_ctx->replay_baton = replay_baton;
replay_ctx->done = FALSE;
+ replay_ctx->include_path = include_path;
replay_ctx->revision = rev;
replay_ctx->low_water_mark = low_water_mark;
replay_ctx->send_deltas = send_deltas;
replay_ctx->done_item.data = replay_ctx;
+
/* Request all properties of a certain revision. */
- replay_ctx->report_target = report_target;
replay_ctx->revs_props = apr_hash_make(replay_ctx->src_rev_pool);
if (SVN_RA_SERF__HAVE_HTTPV2_SUPPORT(session))
- {
- replay_ctx->revprop_target = apr_psprintf(pool, "%s/%ld",
- session->rev_stub, rev);
- replay_ctx->revprop_rev = SVN_INVALID_REVNUM;
+ {
+ replay_ctx->revprop_target = apr_psprintf(pool, "%s/%ld",
+ session->rev_stub, rev);
+ replay_ctx->revprop_rev = SVN_INVALID_REVNUM;
}
else
{
@@ -793,12 +840,22 @@ svn_ra_serf__replay_range(svn_ra_session
/* Spin up the serf request for the PROPFIND. */
svn_ra_serf__request_create(replay_ctx->propfind_handler);
- /* Send the replay report request. */
+ /* Send the replay REPORT request. */
+ if (session->supports_rev_rsrc_replay)
+ {
+ replay_target = apr_psprintf(pool, "%s/%ld",
+ session->rev_stub, rev);
+ }
+ else
+ {
+ replay_target = session->session_url.path;
+ }
+
handler = apr_pcalloc(replay_ctx->src_rev_pool, sizeof(*handler));
handler->handler_pool = replay_ctx->src_rev_pool;
handler->method = "REPORT";
- handler->path = session->session_url_str;
+ handler->path = replay_target;
handler->body_delegate = create_replay_body;
handler->body_delegate_baton = replay_ctx;
handler->conn = session->conns[0];
@@ -824,6 +881,7 @@ svn_ra_serf__replay_range(svn_ra_session
parser_ctx->done_item = &replay_ctx->done_item;
handler->response_handler = svn_ra_serf__handle_xml_parser;
handler->response_baton = parser_ctx;
+ replay_ctx->report_handler = handler;
/* This is only needed to handle errors during XML parsing. */
replay_ctx->parser_ctx = parser_ctx;
@@ -834,62 +892,8 @@ svn_ra_serf__replay_range(svn_ra_session
active_reports++;
}
- /* Run the serf loop, send outgoing and process incoming requests.
- This request will block when there are no more requests to send or
- responses to receive, so we have to be careful on our bookkeeping.
-
- ### we should probably adjust this timeout. if we get (say) 3
- ### requests completed, then we want to exit immediately rather
- ### than block for a few seconds. that will allow us to clear up
- ### those 3 requests. if we have queued all of our revisions,
- ### then we may want to block until timeout since we really don't
- ### have much work other than destroying memory. (though that
- ### is important, as we could end up with 50 src_rev_pool pools)
-
- ### idea: when a revision is marked DONE, we can probably destroy
- ### most of the memory. that will reduce pressue to have serf
- ### return control to us, to complete the major memory disposal.
-
- ### theoretically, we should use an iterpool here, but it turns
- ### out that serf doesn't even use the pool param. if we grow
- ### an iterpool in this loop for other purposes, then yeah: go
- ### ahead and apply it here, too, in case serf eventually uses
- ### that parameter.
- */
- status = serf_context_run(session->context,
- SVN_RA_SERF__CONTEXT_RUN_DURATION,
- pool);
-
- err = session->pending_error;
- session->pending_error = NULL;
-
- /* If the context duration timeout is up, we'll subtract that
- duration from the total time alloted for such things. If
- there's no time left, we fail with a message indicating that
- the connection timed out. */
- if (APR_STATUS_IS_TIMEUP(status))
- {
- svn_error_clear(err);
- err = SVN_NO_ERROR;
- status = 0;
-
- if (session->timeout)
- {
- if (waittime_left > SVN_RA_SERF__CONTEXT_RUN_DURATION)
- {
- waittime_left -= SVN_RA_SERF__CONTEXT_RUN_DURATION;
- }
- else
- {
- return svn_error_create(SVN_ERR_RA_DAV_CONN_TIMEOUT, NULL,
- _("Connection timed out"));
- }
- }
- }
- else
- {
- waittime_left = session->timeout;
- }
+ /* Run the serf loop. */
+ SVN_ERR(svn_ra_serf__context_run_wait(&replay_ctx->done, session, pool));
/* Substract the number of completely handled responses from our
total nr. of open requests', so we'll know when to stop this loop.
@@ -898,18 +902,16 @@ svn_ra_serf__replay_range(svn_ra_session
while (done_list)
{
replay_context_t *ctx = (replay_context_t *)done_list->data;
+ svn_ra_serf__handler_t *done_handler = ctx->report_handler;
done_list = done_list->next;
+ SVN_ERR(svn_ra_serf__error_on_status(done_handler->sline.code,
+ done_handler->path,
+ done_handler->location));
svn_pool_destroy(ctx->src_rev_pool);
active_reports--;
}
- SVN_ERR(err);
- if (status)
- {
- return svn_ra_serf__wrap_err(status,
- _("Error retrieving replay REPORT"));
- }
done_reports = NULL;
}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/serf.c Mon Feb 4 20:48:05 2013
@@ -148,7 +148,6 @@ load_config(svn_ra_serf__session_t *sess
const char *timeout_str = NULL;
const char *exceptions;
apr_port_t proxy_port;
- svn_boolean_t is_exception = FALSE;
if (config_hash)
{
@@ -188,16 +187,11 @@ load_config(svn_ra_serf__session_t *sess
/* Use the default proxy-specific settings if and only if
"http-proxy-exceptions" is not set to exclude this host. */
svn_config_get(config, &exceptions, SVN_CONFIG_SECTION_GLOBAL,
- SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS, NULL);
- if (exceptions)
+ SVN_CONFIG_OPTION_HTTP_PROXY_EXCEPTIONS, "");
+ if (! svn_cstring_match_glob_list(session->session_url.hostname,
+ svn_cstring_split(exceptions, ",",
+ TRUE, pool)))
{
- apr_array_header_t *l = svn_cstring_split(exceptions, ",", TRUE, pool);
- is_exception = svn_cstring_match_glob_list(session->session_url.hostname,
- l);
- }
- if (! is_exception)
- {
- /* Load the global proxy server settings, if set. */
svn_config_get(config, &proxy_host, SVN_CONFIG_SECTION_GLOBAL,
SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
svn_config_get(config, &port_str, SVN_CONFIG_SECTION_GLOBAL,
@@ -218,6 +212,20 @@ load_config(svn_ra_serf__session_t *sess
svn_config_get(config, &session->ssl_authorities, SVN_CONFIG_SECTION_GLOBAL,
SVN_CONFIG_OPTION_SSL_AUTHORITY_FILES, NULL);
+ /* If set, read the flag that tells us to do bulk updates or not. Defaults
+ to skelta updates. */
+ SVN_ERR(svn_config_get_tristate(config, &session->bulk_updates,
+ SVN_CONFIG_SECTION_GLOBAL,
+ SVN_CONFIG_OPTION_HTTP_BULK_UPDATES,
+ "auto",
+ svn_tristate_unknown));
+
+ /* Load the maximum number of parallel session connections. */
+ svn_config_get_int64(config, &session->max_connections,
+ SVN_CONFIG_SECTION_GLOBAL,
+ SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
+ SVN_CONFIG_DEFAULT_OPTION_HTTP_MAX_CONNECTIONS);
+
if (config)
server_group = svn_config_find_group(config,
session->session_url.hostname,
@@ -237,24 +245,51 @@ load_config(svn_ra_serf__session_t *sess
svn_auth_set_parameter(session->wc_callbacks->auth_baton,
SVN_AUTH_PARAM_SERVER_GROUP, server_group);
- /* Load the group proxy server settings, overriding global settings. */
+ /* Load the group proxy server settings, overriding global
+ settings. We intentionally ignore 'http-proxy-exceptions'
+ here because, well, if this site was an exception, why is
+ there a per-server proxy configuration for it? */
svn_config_get(config, &proxy_host, server_group,
- SVN_CONFIG_OPTION_HTTP_PROXY_HOST, NULL);
+ SVN_CONFIG_OPTION_HTTP_PROXY_HOST, proxy_host);
svn_config_get(config, &port_str, server_group,
- SVN_CONFIG_OPTION_HTTP_PROXY_PORT, NULL);
+ SVN_CONFIG_OPTION_HTTP_PROXY_PORT, port_str);
svn_config_get(config, &session->proxy_username, server_group,
- SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME, NULL);
+ SVN_CONFIG_OPTION_HTTP_PROXY_USERNAME,
+ session->proxy_username);
svn_config_get(config, &session->proxy_password, server_group,
- SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD, NULL);
+ SVN_CONFIG_OPTION_HTTP_PROXY_PASSWORD,
+ session->proxy_password);
/* Load the group ssl settings. */
SVN_ERR(svn_config_get_bool(config, &session->trust_default_ca,
server_group,
SVN_CONFIG_OPTION_SSL_TRUST_DEFAULT_CA,
- TRUE));
+ session->trust_default_ca));
svn_config_get(config, &session->ssl_authorities, server_group,
- SVN_CONFIG_OPTION_SSL_AUTHORITY_FILES, NULL);
- }
+ SVN_CONFIG_OPTION_SSL_AUTHORITY_FILES,
+ session->ssl_authorities);
+
+ /* Load the group bulk updates flag. */
+ SVN_ERR(svn_config_get_tristate(config, &session->bulk_updates,
+ server_group,
+ SVN_CONFIG_OPTION_HTTP_BULK_UPDATES,
+ "auto",
+ session->bulk_updates));
+
+ /* Load the maximum number of parallel session connections,
+ overriding global values. */
+ svn_config_get_int64(config, &session->max_connections,
+ server_group, SVN_CONFIG_OPTION_HTTP_MAX_CONNECTIONS,
+ session->max_connections);
+ }
+
+ /* Don't allow the http-max-connections value to be larger than our
+ compiled-in limit, or to be too small to operate. Broken
+ functionality and angry administrators are equally undesirable. */
+ if (session->max_connections > SVN_RA_SERF__MAX_CONNECTIONS_LIMIT)
+ session->max_connections = SVN_RA_SERF__MAX_CONNECTIONS_LIMIT;
+ if (session->max_connections < 2)
+ session->max_connections = 2;
/* Parse the connection timeout value, if any. */
session->timeout = apr_time_from_sec(DEFAULT_HTTP_TIMEOUT);
@@ -294,7 +329,9 @@ load_config(svn_ra_serf__session_t *sess
proxy_port = (apr_port_t) port;
}
else
- proxy_port = 80;
+ {
+ proxy_port = 80;
+ }
if (proxy_host)
{
@@ -314,7 +351,9 @@ load_config(svn_ra_serf__session_t *sess
serf_config_proxy(session->context, proxy_addr);
}
else
- session->using_proxy = FALSE;
+ {
+ session->using_proxy = FALSE;
+ }
/* Setup authentication. */
SVN_ERR(load_http_auth_types(pool, config, server_group,
@@ -763,7 +802,7 @@ path_dirent_walker(void *baton,
{
const char *base_name;
- entry = apr_pcalloc(pool, sizeof(*entry));
+ entry = svn_dirent_create(pool);
apr_hash_set(dirents->full_paths, path, path_len, entry);
@@ -881,7 +920,7 @@ svn_ra_serf__stat(svn_ra_session_t *ra_s
return svn_error_trace(err);
}
- dwb.entry = apr_pcalloc(pool, sizeof(*dwb.entry));
+ dwb.entry = svn_dirent_create(pool);
dwb.supports_deadprop_count = &deadprop_count;
dwb.result_pool = pool;
SVN_ERR(svn_ra_serf__walk_node_props(props, dirent_walker, &dwb, pool));
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/update.c Mon Feb 4 20:48:05 2013
@@ -74,7 +74,8 @@ typedef enum report_state_e {
ABSENT_FILE,
PROP,
IGNORE_PROP_NAME,
- NEED_PROP_NAME
+ NEED_PROP_NAME,
+ TXDELTA
} report_state_e;
@@ -228,6 +229,8 @@ typedef struct report_info_t
const char *final_sha1_checksum;
svn_txdelta_window_handler_t textdelta;
void *textdelta_baton;
+ svn_stream_t *svndiff_decoder;
+ svn_stream_t *base64_decoder;
/* Checksum for close_file */
const char *final_checksum;
@@ -318,6 +321,9 @@ struct report_context_t {
/* Do we want the server to send copyfrom args or not? */
svn_boolean_t send_copyfrom_args;
+ /* Is the server sending everything in one response? */
+ svn_boolean_t send_all_mode;
+
/* Is the server including properties inline for newly added
files/dirs? */
svn_boolean_t add_props_included;
@@ -357,6 +363,10 @@ struct report_context_t {
/* completed PROPFIND requests (contains svn_ra_serf__handler_t) */
svn_ra_serf__list_t *done_propfinds;
+ svn_ra_serf__list_t *done_dir_propfinds;
+
+ /* list of outstanding prop changes (contains report_dir_t) */
+ svn_ra_serf__list_t *active_dir_propfinds;
/* list of files that only have prop changes (contains report_info_t) */
svn_ra_serf__list_t *file_propchanges_only;
@@ -493,26 +503,42 @@ update_cdata(svn_ra_serf__xml_estate_t *
static svn_ra_serf__connection_t *
get_best_connection(report_context_t *ctx)
{
- svn_ra_serf__connection_t * conn;
- int first_conn;
+ svn_ra_serf__connection_t *conn;
+ int first_conn = 1;
/* Skip the first connection if the REPORT response hasn't been completely
- received yet. */
- first_conn = ctx->report_received ? 0: 1;
-
+ received yet or if we're being told to limit our connections to
+ 2 (because this could be an attempt to ensure that we do all our
+ auxiliary GETs/PROPFINDs on a single connection).
+
+ ### FIXME: This latter requirement (max_connections > 2) is
+ ### really just a hack to work around the fact that some update
+ ### editor implementations (such as svnrdump's dump editor)
+ ### simply can't handle the way ra_serf violates the editor v1
+ ### drive ordering requirements.
+ ###
+ ### See http://subversion.tigris.org/issues/show_bug.cgi?id=4116.
+ */
+ if (ctx->report_received && (ctx->sess->max_connections > 2))
+ first_conn = 0;
+
+ /* Currently, we just cycle connections. In the future we could
+ store the number of pending requests on each connection, or
+ perform other heuristics, to achieve better connection usage.
+ (As an optimization, if there's only one available auxiliary
+ connection to use, don't bother doing all the cur_conn math --
+ just return that one connection.) */
if (ctx->sess->num_conns - first_conn == 1)
- return ctx->sess->conns[first_conn];
-
- /* Currently just cycle connections. In future we could store number of
- * pending requests on each connection for better connection usage. */
- conn = ctx->sess->conns[ctx->sess->cur_conn];
-
- /* Switch our connection. */
- ctx->sess->cur_conn++;
-
- if (ctx->sess->cur_conn >= ctx->sess->num_conns)
- ctx->sess->cur_conn = first_conn;
-
+ {
+ conn = ctx->sess->conns[first_conn];
+ }
+ else
+ {
+ conn = ctx->sess->conns[ctx->sess->cur_conn];
+ ctx->sess->cur_conn++;
+ if (ctx->sess->cur_conn >= ctx->sess->num_conns)
+ ctx->sess->cur_conn = first_conn;
+ }
return conn;
}
@@ -909,7 +935,7 @@ cancel_fetch(serf_request_t *request,
*/
if (fetch_ctx->read_headers)
{
- if (fetch_ctx->aborted_read == FALSE && fetch_ctx->read_size)
+ if (!fetch_ctx->aborted_read && fetch_ctx->read_size)
{
fetch_ctx->aborted_read = TRUE;
fetch_ctx->aborted_read_size = fetch_ctx->read_size;
@@ -1063,7 +1089,7 @@ handle_fetch(serf_request_t *request,
/* ### new field. make sure we didn't miss some initialization. */
SVN_ERR_ASSERT(fetch_ctx->handler != NULL);
- if (fetch_ctx->read_headers == FALSE)
+ if (!fetch_ctx->read_headers)
{
serf_bucket_t *hdrs;
const char *val;
@@ -1347,6 +1373,27 @@ maybe_close_dir_chain(report_dir_t *dir)
{
report_dir_t *parent = cur_dir->parent_dir;
report_context_t *report_context = cur_dir->report_context;
+ svn_boolean_t propfind_in_done_list = FALSE;
+ svn_ra_serf__list_t *done_list;
+
+ /* Make sure there are no references to this dir in the
+ active_dir_propfinds list. If there are, don't close the
+ directory -- which would delete the pool from which the
+ relevant active_dir_propfinds list item is allocated -- and
+ of course don't crawl upward to check the parents for
+ a closure opportunity, either. */
+ done_list = report_context->active_dir_propfinds;
+ while (done_list)
+ {
+ if (done_list->data == cur_dir)
+ {
+ propfind_in_done_list = TRUE;
+ break;
+ }
+ done_list = done_list->next;
+ }
+ if (propfind_in_done_list)
+ break;
SVN_ERR(close_dir(cur_dir));
if (parent)
@@ -1377,6 +1424,10 @@ handle_propchange_only(report_info_t *in
info->dir->ref_count--;
+ /* See if the parent directory of this file (and perhaps even
+ parents of that) can be closed now. */
+ SVN_ERR(maybe_close_dir_chain(info->dir));
+
return SVN_NO_ERROR;
}
@@ -1401,6 +1452,10 @@ handle_local_content(report_info_t *info
info->dir->ref_count--;
+ /* See if the parent directory of this fetched item (and
+ perhaps even parents of that) can be closed now. */
+ SVN_ERR(maybe_close_dir_chain(info->dir));
+
return SVN_NO_ERROR;
}
@@ -1415,17 +1470,6 @@ fetch_file(report_context_t *ctx, report
/* What connection should we go on? */
conn = get_best_connection(ctx);
- /* go fetch info->name from DAV:checked-in */
- info->url = svn_ra_serf__get_ver_prop(info->props, info->base_name,
- info->base_rev, "DAV:", "checked-in");
-
- if (!info->url)
- {
- return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
- _("The REPORT or PROPFIND response did not "
- "include the requested checked-in value"));
- }
-
/* If needed, create the PROPFIND to retrieve the file's properties. */
info->propfind_handler = NULL;
if (info->fetch_props)
@@ -1565,12 +1609,7 @@ fetch_file(report_context_t *ctx, report
}
else
{
- /* No propfind or GET request. Just handle the prop changes now.
-
- Note: we'll use INFO->POOL for the scratch_pool here since it will
- be destroyed at the end of handle_propchange_only(). That pool
- would be quite fine, but it is unclear how long INFO->POOL will
- stick around since its lifetime and usage are unclear. */
+ /* No propfind or GET request. Just handle the prop changes now. */
SVN_ERR(handle_propchange_only(info, info->pool));
}
@@ -1597,9 +1636,20 @@ start_report(svn_ra_serf__xml_parser_t *
if (state == NONE && strcmp(name.name, "update-report") == 0)
{
- const char *val = svn_xml_get_attr_value("inline-props", attrs);
+ const char *val;
+
+ val = svn_xml_get_attr_value("inline-props", attrs);
if (val && (strcmp(val, "true") == 0))
ctx->add_props_included = TRUE;
+
+ val = svn_xml_get_attr_value("send-all", attrs);
+ if (val && (strcmp(val, "true") == 0))
+ {
+ ctx->send_all_mode = TRUE;
+
+ /* All properties are included in send-all mode. */
+ ctx->add_props_included = TRUE;
+ }
}
else if (state == NONE && strcmp(name.name, "target-revision") == 0)
{
@@ -1802,7 +1852,11 @@ start_report(svn_ra_serf__xml_parser_t *
info = push_state(parser, ctx, ADD_FILE);
info->base_rev = SVN_INVALID_REVNUM;
- info->fetch_file = TRUE;
+
+ /* If the server isn't in "send-all" mode, we should expect to
+ fetch contents for added files. */
+ if (! ctx->send_all_mode)
+ info->fetch_file = TRUE;
/* If the server isn't included properties for added items,
we'll need to fetch them ourselves. */
@@ -2042,7 +2096,31 @@ start_report(svn_ra_serf__xml_parser_t *
addition to <fetch-file>s and such) when *not* in
"send-all" mode. As a client, we're smart enough to know
that's wrong, so we'll just ignore these tags. */
- ;
+ if (ctx->send_all_mode)
+ {
+ const svn_delta_editor_t *update_editor = ctx->update_editor;
+
+ info = push_state(parser, ctx, TXDELTA);
+
+ if (! info->file_baton)
+ {
+ SVN_ERR(open_updated_file(info, FALSE, info->pool));
+ }
+
+ info->base_checksum = svn_xml_get_attr_value("base-checksum",
+ attrs);
+ SVN_ERR(update_editor->apply_textdelta(info->file_baton,
+ info->base_checksum,
+ info->editor_pool,
+ &info->textdelta,
+ &info->textdelta_baton));
+ info->svndiff_decoder = svn_txdelta_parse_svndiff(
+ info->textdelta,
+ info->textdelta_baton,
+ TRUE, info->pool);
+ info->base64_decoder = svn_base64_decode(info->svndiff_decoder,
+ info->pool);
+ }
}
else
{
@@ -2126,13 +2204,15 @@ end_report(svn_ra_serf__xml_parser_t *pa
*/
if (info->dir->fetch_props)
{
+ svn_ra_serf__list_t *list_item;
+
SVN_ERR(svn_ra_serf__deliver_props(&info->dir->propfind_handler,
info->dir->props, ctx->sess,
get_best_connection(ctx),
info->dir->url,
ctx->target_rev, "0",
all_props,
- &ctx->done_propfinds,
+ &ctx->done_dir_propfinds,
info->dir->pool));
SVN_ERR_ASSERT(info->dir->propfind_handler);
@@ -2141,6 +2221,11 @@ end_report(svn_ra_serf__xml_parser_t *pa
ctx->num_active_propfinds++;
+ list_item = apr_pcalloc(info->dir->pool, sizeof(*list_item));
+ list_item->data = info->dir;
+ list_item->next = ctx->active_dir_propfinds;
+ ctx->active_dir_propfinds = list_item;
+
if (ctx->num_active_fetches + ctx->num_active_propfinds
> REQUEST_COUNT_TO_PAUSE)
ctx->parser_ctx->paused = TRUE;
@@ -2150,6 +2235,12 @@ end_report(svn_ra_serf__xml_parser_t *pa
info->dir->propfind_handler = NULL;
}
+ /* See if this directory (and perhaps even parents of that) can
+ be closed now. This is likely to be the case only if we
+ didn't need to contact the server for supplemental
+ information required to handle any of this directory's
+ children. */
+ SVN_ERR(maybe_close_dir_chain(info->dir));
svn_ra_serf__xml_pop_state(parser);
}
else if (state == OPEN_FILE && strcmp(name.name, "open-file") == 0)
@@ -2166,7 +2257,7 @@ end_report(svn_ra_serf__xml_parser_t *pa
info->lock_token = apr_hash_get(ctx->lock_path_tokens, info->name,
APR_HASH_KEY_STRING);
- if (info->lock_token && info->fetch_props == FALSE)
+ if (info->lock_token && !info->fetch_props)
info->fetch_props = TRUE;
/* If possible, we'd like to fetch only a delta against a
@@ -2223,13 +2314,89 @@ end_report(svn_ra_serf__xml_parser_t *pa
info->delta_base = value ? value->data : NULL;
}
- SVN_ERR(fetch_file(ctx, info));
+ /* go fetch info->name from DAV:checked-in */
+ info->url = svn_ra_serf__get_ver_prop(info->props, info->base_name,
+ info->base_rev, "DAV:", "checked-in");
+ if (!info->url)
+ {
+ return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("The REPORT or PROPFIND response did not "
+ "include the requested checked-in value"));
+ }
+
+ /* If the server is in "send-all" mode, we might have opened the
+ file when we started seeing content for it. If we didn't get
+ any content for it, we still need to open the file. But in
+ any case, we can then immediately close it. */
+ if (ctx->send_all_mode)
+ {
+ if (! info->file_baton)
+ {
+ SVN_ERR(open_updated_file(info, FALSE, info->pool));
+ }
+ SVN_ERR(close_updated_file(info, info->pool));
+ info->dir->ref_count--;
+ }
+ /* Otherwise, if the server is *not* in "send-all" mode, we
+ should be at a point where we can queue up any auxiliary
+ content-fetching requests. */
+ else
+ {
+ SVN_ERR(fetch_file(ctx, info));
+ }
+
svn_ra_serf__xml_pop_state(parser);
}
else if (state == ADD_FILE && strcmp(name.name, "add-file") == 0)
{
- /* We should have everything we need to fetch the file. */
- SVN_ERR(fetch_file(ctx, parser->state->private));
+ report_info_t *info = parser->state->private;
+
+ /* go fetch info->name from DAV:checked-in */
+ info->url = svn_ra_serf__get_ver_prop(info->props, info->base_name,
+ info->base_rev, "DAV:", "checked-in");
+ if (!info->url)
+ {
+ return svn_error_create(SVN_ERR_RA_DAV_MALFORMED_DATA, NULL,
+ _("The REPORT or PROPFIND response did not "
+ "include the requested checked-in value"));
+ }
+
+ /* If the server is in "send-all" mode, we might have opened the
+ file when we started seeing content for it. If we didn't get
+ any content for it, we still need to open the file. But in
+ any case, we can then immediately close it. */
+ if (ctx->send_all_mode)
+ {
+ if (! info->file_baton)
+ {
+ SVN_ERR(open_updated_file(info, FALSE, info->pool));
+ }
+ SVN_ERR(close_updated_file(info, info->pool));
+ info->dir->ref_count--;
+ }
+ /* Otherwise, if the server is *not* in "send-all" mode, we
+ should be at a point where we can queue up any auxiliary
+ content-fetching requests. */
+ else
+ {
+ SVN_ERR(fetch_file(ctx, info));
+ }
+
+ svn_ra_serf__xml_pop_state(parser);
+ }
+ else if (state == TXDELTA && strcmp(name.name, "txdelta") == 0)
+ {
+ report_info_t *info = parser->state->private;
+
+ /* Pre 1.2, mod_dav_svn was using <txdelta> tags (in addition to
+ <fetch-file>s and such) when *not* in "send-all" mode. As a
+ client, we're smart enough to know that's wrong, so when not
+ in "receiving-all" mode, we'll ignore these tags. */
+ if (ctx->send_all_mode)
+ {
+ SVN_ERR(svn_stream_close(info->base64_decoder));
+ }
+
svn_ra_serf__xml_pop_state(parser);
}
else if (state == PROP)
@@ -2356,6 +2523,27 @@ cdata_report(svn_ra_serf__xml_parser_t *
svn_stringbuf_appendbytes(info->prop_value, data, len);
}
+ else if (parser->state->current_state == TXDELTA)
+ {
+ /* Pre 1.2, mod_dav_svn was using <txdelta> tags (in addition to
+ <fetch-file>s and such) when *not* in "send-all" mode. As a
+ client, we're smart enough to know that's wrong, so when not
+ in "receiving-all" mode, we'll ignore these tags. */
+ if (ctx->send_all_mode)
+ {
+ apr_size_t nlen = len;
+ report_info_t *info = parser->state->private;
+
+ SVN_ERR(svn_stream_write(info->base64_decoder, data, &nlen));
+ if (nlen != len)
+ {
+ /* Short write without associated error? "Can't happen." */
+ return svn_error_createf(SVN_ERR_STREAM_UNEXPECTED_EOF, NULL,
+ _("Error writing to '%s': unexpected EOF"),
+ info->name);
+ }
+ }
+ }
return SVN_NO_ERROR;
}
@@ -2550,6 +2738,28 @@ create_update_report_body(serf_bucket_t
return SVN_NO_ERROR;
}
+/* Serf callback to setup update request headers. */
+static svn_error_t *
+setup_update_report_headers(serf_bucket_t *headers,
+ void *baton,
+ apr_pool_t *pool)
+{
+ report_context_t *report = baton;
+
+ if (report->sess->using_compression)
+ {
+ serf_bucket_headers_setn(headers, "Accept-Encoding",
+ "gzip;svndiff1;q=0.9,svndiff;q=0.8");
+ }
+ else
+ {
+ serf_bucket_headers_setn(headers, "Accept-Encoding",
+ "svndiff1;q=0.9,svndiff;q=0.8");
+ }
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
finish_report(void *report_baton,
apr_pool_t *pool)
@@ -2595,6 +2805,9 @@ finish_report(void *report_baton,
handler->body_delegate = create_update_report_body;
handler->body_delegate_baton = report;
handler->body_type = "text/xml";
+ handler->custom_accept_encoding = TRUE;
+ handler->header_delegate = setup_update_report_headers;
+ handler->header_delegate_baton = report;
handler->conn = sess->conns[0];
handler->session = sess;
@@ -2691,14 +2904,16 @@ finish_report(void *report_baton,
}
/* Open extra connections if we have enough requests to send. */
- if (sess->num_conns < MAX_NR_OF_CONNS)
+ if (sess->num_conns < sess->max_connections)
SVN_ERR(open_connection_if_needed(sess, report->num_active_fetches +
report->num_active_propfinds));
- /* prune our propfind list if they are done. */
+ /* Prune completed file PROPFINDs. */
done_list = report->done_propfinds;
while (done_list)
{
+ svn_ra_serf__list_t *next_done = done_list->next;
+
svn_pool_clear(iterpool_inner);
report->num_active_propfinds--;
@@ -2733,39 +2948,46 @@ finish_report(void *report_baton,
{
report_info_t *info = cur->data;
- /* If we've got cached file content for this file,
- take care of the locally collected properties and
- file content at once. Otherwise, just deal with
- the collected properties. */
- if (info->cached_contents)
+ if (!prev)
{
- SVN_ERR(handle_local_content(info, iterpool_inner));
+ report->file_propchanges_only = cur->next;
}
else
{
- SVN_ERR(handle_propchange_only(info, iterpool_inner));
+ prev->next = cur->next;
}
- if (!prev)
+ /* If we've got cached file content for this file,
+ take care of the locally collected properties and
+ file content at once. Otherwise, just deal with
+ the collected properties.
+
+ NOTE: These functions below could delete
+ info->dir->pool (via maybe_close_dir_chain()),
+ from which is allocated the list item in
+ report->file_propchanges_only.
+ */
+ if (info->cached_contents)
{
- report->file_propchanges_only = cur->next;
+ SVN_ERR(handle_local_content(info, iterpool_inner));
}
else
{
- prev->next = cur->next;
+ SVN_ERR(handle_propchange_only(info, iterpool_inner));
}
}
}
- done_list = done_list->next;
+ done_list = next_done;
}
report->done_propfinds = NULL;
- /* Prune completely fetches from our list. */
+ /* Prune completed fetches from our list. */
done_list = report->done_fetches;
while (done_list)
{
report_fetch_t *done_fetch = done_list->data;
+ svn_ra_serf__list_t *next_done = done_list->next;
report_dir_t *cur_dir;
/* Decrease the refcount in the parent directory of the file
@@ -2776,14 +2998,77 @@ finish_report(void *report_baton,
/* Decrement our active fetch count. */
report->num_active_fetches--;
- done_list = done_list->next;
-
/* See if the parent directory of this fetched item (and
- perhaps even parents of that) can be closed now. */
+ perhaps even parents of that) can be closed now.
+
+ NOTE: This could delete cur_dir->pool, from which is
+ allocated the list item in report->done_fetches.
+ */
SVN_ERR(maybe_close_dir_chain(cur_dir));
+
+ done_list = next_done;
}
report->done_fetches = NULL;
+ /* Prune completed directory PROPFINDs. */
+ done_list = report->done_dir_propfinds;
+ while (done_list)
+ {
+ svn_ra_serf__list_t *next_done = done_list->next;
+
+ report->num_active_propfinds--;
+
+ if (report->active_dir_propfinds)
+ {
+ svn_ra_serf__list_t *cur, *prev;
+
+ prev = NULL;
+ cur = report->active_dir_propfinds;
+
+ while (cur)
+ {
+ report_dir_t *item = cur->data;
+
+ if (item->propfind_handler == done_list->data)
+ {
+ break;
+ }
+
+ prev = cur;
+ cur = cur->next;
+ }
+ SVN_ERR_ASSERT(cur); /* we expect to find a matching propfind! */
+
+ /* If we found a match, set the new props and remove this
+ * propchange from our list.
+ */
+ if (cur)
+ {
+ report_dir_t *cur_dir = cur->data;
+
+ if (!prev)
+ {
+ report->active_dir_propfinds = cur->next;
+ }
+ else
+ {
+ prev->next = cur->next;
+ }
+
+ /* See if this directory (and perhaps even parents of that)
+ can be closed now.
+
+ NOTE: This could delete cur_dir->pool, from which is
+ allocated the list item in report->active_dir_propfinds.
+ */
+ SVN_ERR(maybe_close_dir_chain(cur_dir));
+ }
+ }
+
+ done_list = next_done;
+ }
+ report->done_dir_propfinds = NULL;
+
/* If the parser is paused, and the number of active requests has
dropped far enough, then resume parsing. */
if (parser_ctx->paused
@@ -2811,7 +3096,7 @@ finish_report(void *report_baton,
{
/* Ensure that we opened and closed our root dir and that we closed
* all of our children. */
- if (report->closed_root == FALSE && report->root_dir != NULL)
+ if (!report->closed_root && report->root_dir != NULL)
{
SVN_ERR(close_all_dirs(report->root_dir));
}
@@ -2876,6 +3161,7 @@ make_update_reporter(svn_ra_session_t *r
svn_boolean_t server_supports_depth;
svn_ra_serf__session_t *sess = ra_session->priv;
svn_stringbuf_t *buf = NULL;
+ svn_boolean_t use_bulk_updates;
SVN_ERR(svn_ra_serf__has_capability(ra_session, &server_supports_depth,
SVN_RA_CAPABILITY_DEPTH, scratch_pool));
@@ -2922,9 +3208,74 @@ make_update_reporter(svn_ra_session_t *r
svn_io_file_del_on_pool_cleanup,
report->pool, scratch_pool));
- svn_xml_make_open_tag(&buf, scratch_pool, svn_xml_normal, "S:update-report",
- "xmlns:S", SVN_XML_NAMESPACE,
- NULL);
+ if (sess->bulk_updates == svn_tristate_true)
+ {
+ /* User would like to use bulk updates. */
+ use_bulk_updates = TRUE;
+ }
+ else if (sess->bulk_updates == svn_tristate_false)
+ {
+ /* User doesn't want bulk updates. */
+ use_bulk_updates = FALSE;
+ }
+ else
+ {
+ /* User doesn't have any preferences on bulk updates. Decide on server
+ preferences and capabilities. */
+ if (sess->server_allows_bulk)
+ {
+ if (apr_strnatcasecmp(sess->server_allows_bulk, "off") == 0)
+ {
+ /* Server doesn't want bulk updates */
+ use_bulk_updates = FALSE;
+ }
+ else if (apr_strnatcasecmp(sess->server_allows_bulk, "prefer") == 0)
+ {
+ /* Server prefers bulk updates, and we respect that */
+ use_bulk_updates = TRUE;
+ }
+ else
+ {
+ /* Server allows bulk updates, but doesn't dictate its use. Do
+ whatever is the default. */
+ use_bulk_updates = FALSE;
+ }
+ }
+ else
+ {
+ /* Pre-1.8 server didn't send the bulk_updates header. Check if server
+ supports inlining properties in update editor report. */
+ if (sess->supports_inline_props)
+ {
+ /* Inline props supported: do not use bulk updates. */
+ use_bulk_updates = FALSE;
+ }
+ else
+ {
+ /* Inline props are not supported: use bulk updates to avoid
+ * PROPFINDs for every added node. */
+ use_bulk_updates = TRUE;
+ }
+ }
+ }
+
+ if (use_bulk_updates)
+ {
+ svn_xml_make_open_tag(&buf, scratch_pool, svn_xml_normal,
+ "S:update-report",
+ "xmlns:S", SVN_XML_NAMESPACE, "send-all", "true",
+ NULL);
+ }
+ else
+ {
+ svn_xml_make_open_tag(&buf, scratch_pool, svn_xml_normal,
+ "S:update-report",
+ "xmlns:S", SVN_XML_NAMESPACE,
+ NULL);
+ /* Subversion 1.8+ servers can be told to send properties for newly
+ added items inline even when doing a skelta response. */
+ make_simple_xml_tag(&buf, "S:include-props", "yes", scratch_pool);
+ }
make_simple_xml_tag(&buf, "S:src-path", report->source, scratch_pool);
@@ -2963,9 +3314,20 @@ make_update_reporter(svn_ra_session_t *r
make_simple_xml_tag(&buf, "S:recursive", "no", scratch_pool);
}
- /* Subversion 1.8+ servers can be told to send properties for newly
- added items inline even when doing a skelta response. */
- make_simple_xml_tag(&buf, "S:include-props", "yes", scratch_pool);
+ /* When in 'send-all' mode, mod_dav_svn will assume that it should
+ calculate and transmit real text-deltas (instead of empty windows
+ that merely indicate "text is changed") unless it finds this
+ element.
+
+ NOTE: Do NOT count on servers actually obeying this, as some exist
+ which obey send-all, but do not check for this directive at all!
+
+ NOTE 2: When not in 'send-all' mode, mod_dav_svn can still be configured to
+ override our request and send text-deltas. */
+ if (! text_deltas)
+ {
+ make_simple_xml_tag(&buf, "S:text-deltas", "no", scratch_pool);
+ }
make_simple_xml_tag(&buf, "S:depth", svn_depth_to_word(depth), scratch_pool);
@@ -3123,7 +3485,9 @@ try_get_wc_contents(svn_boolean_t *found
if (wc_stream)
{
- SVN_ERR(svn_stream_copy3(wc_stream, dst_stream, NULL, NULL, pool));
+ SVN_ERR(svn_stream_copy3(wc_stream,
+ svn_stream_disown(dst_stream, pool),
+ NULL, NULL, pool));
*found_p = TRUE;
}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_serf/util.c Mon Feb 4 20:48:05 2013
@@ -1559,7 +1559,7 @@ svn_ra_serf__handle_xml_parser(serf_requ
}
/* Woo-hoo. Nothing here to see. */
- if (sl.code == 404 && ctx->ignore_errors == FALSE)
+ if (sl.code == 404 && !ctx->ignore_errors)
{
err = handle_server_error(request, response, pool);
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/client.c Mon Feb 4 20:48:05 2013
@@ -1274,7 +1274,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
&name, &kind, &size, &has_props,
&crev, &cdate, &cauthor));
name = svn_relpath_canonicalize(name, pool);
- dirent = apr_palloc(pool, sizeof(*dirent));
+ dirent = svn_dirent_create(pool);
dirent->kind = svn_node_kind_from_word(kind);
dirent->size = size;/* FIXME: svn_filesize_t */
dirent->has_props = has_props;
@@ -1304,7 +1304,7 @@ static svn_error_t *ra_svn_get_dir(svn_r
static svn_tristate_t
optbool_to_tristate(apr_uint64_t v)
{
- if (v == TRUE)
+ if (v == TRUE) /* not just non-zero but exactly equal to 'TRUE' */
return svn_tristate_true;
if (v == FALSE)
return svn_tristate_false;
@@ -1748,7 +1748,7 @@ static svn_error_t *ra_svn_stat(svn_ra_s
&kind, &size, &has_props,
&crev, &cdate, &cauthor));
- the_dirent = apr_palloc(pool, sizeof(*the_dirent));
+ the_dirent = svn_dirent_create(pool);
the_dirent->kind = svn_node_kind_from_word(kind);
the_dirent->size = size;/* FIXME: svn_filesize_t */
the_dirent->has_props = has_props;
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/cyrus_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/cyrus_auth.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/cyrus_auth.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/cyrus_auth.c Mon Feb 4 20:48:05 2013
@@ -179,7 +179,7 @@ svn_ra_svn__sasl_common_init(apr_pool_t
sasl_mutex_unlock_cb,
sasl_mutex_free_cb);
free_mutexes = apr_array_make(sasl_pool, 0, sizeof(svn_mutex__t *));
- return svn_mutex__init(&array_mutex, TRUE, sasl_pool);
+ SVN_ERR(svn_mutex__init(&array_mutex, TRUE, sasl_pool));
#endif /* APR_HAS_THREADS */
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/editorp.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/editorp.c Mon Feb 4 20:48:05 2013
@@ -39,6 +39,7 @@
#include "svn_private_config.h"
#include "private/svn_fspath.h"
+#include "private/svn_editor.h"
#include "ra_svn.h"
@@ -975,7 +976,7 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
else
{
err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
- _("Unknown command '%s'"), cmd);
+ _("Unknown editor command '%s'"), cmd);
err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
}
}
Modified: subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/marshal.c?rev=1442344&r1=1442343&r2=1442344&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/fsfs-format7/subversion/libsvn_ra_svn/marshal.c Mon Feb 4 20:48:05 2013
@@ -1799,7 +1799,7 @@ svn_error_t *svn_ra_svn_handle_commands2
else
{
err = svn_error_createf(SVN_ERR_RA_SVN_UNKNOWN_CMD, NULL,
- _("Unknown command '%s'"), cmdname);
+ _("Unknown editor command '%s'"), cmdname);
err = svn_error_create(SVN_ERR_RA_SVN_CMD_ERR, err, NULL);
}