You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/04/03 21:56:21 UTC

svn commit: r1584364 [2/2] - in /subversion/branches/remote-only-status: ./ subversion/include/ subversion/libsvn_fs/ subversion/libsvn_fs_base/ subversion/libsvn_fs_fs/ subversion/libsvn_fs_x/ subversion/libsvn_ra_local/ subversion/libsvn_ra_serf/ sub...

Modified: subversion/branches/remote-only-status/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/libsvn_repos/fs-wrap.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/remote-only-status/subversion/libsvn_repos/fs-wrap.c Thu Apr  3 19:56:20 2014
@@ -136,6 +136,8 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
   const char *txn_name;
   svn_string_t *author = svn_hash_gets(revprop_table, SVN_PROP_REVISION_AUTHOR);
   apr_hash_t *hooks_env;
+  svn_error_t *err;
+  svn_fs_txn_t *txn;
 
   /* Parse the hooks-env file (if any). */
   SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@@ -143,21 +145,30 @@ svn_repos_fs_begin_txn_for_commit2(svn_f
 
   /* Begin the transaction, ask for the fs to do on-the-fly lock checks.
      We fetch its name, too, so the start-commit hook can use it.  */
-  SVN_ERR(svn_fs_begin_txn2(txn_p, repos->fs, rev,
+  SVN_ERR(svn_fs_begin_txn2(&txn, repos->fs, rev,
                             SVN_FS_TXN_CHECK_LOCKS, pool));
-  SVN_ERR(svn_fs_txn_name(&txn_name, *txn_p, pool));
+  err = svn_fs_txn_name(&txn_name, txn, pool);
+  if (err)
+    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
 
   /* We pass the revision properties to the filesystem by adding them
      as properties on the txn.  Later, when we commit the txn, these
      properties will be copied into the newly created revision. */
   revprops = svn_prop_hash_to_array(revprop_table, pool);
-  SVN_ERR(svn_repos_fs_change_txn_props(*txn_p, revprops, pool));
+  err = svn_repos_fs_change_txn_props(txn, revprops, pool);
+  if (err)
+    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
 
   /* Run start-commit hooks. */
-  SVN_ERR(svn_repos__hooks_start_commit(repos, hooks_env,
-                                        author ? author->data : NULL,
-                                        repos->client_capabilities, txn_name,
-                                        pool));
+  err = svn_repos__hooks_start_commit(repos, hooks_env,
+                                      author ? author->data : NULL,
+                                      repos->client_capabilities, txn_name,
+                                      pool);
+  if (err)
+    return svn_error_compose_create(err, svn_fs_abort_txn(txn, pool));
+
+  /* We have API promise that *TXN_P is unaffected on faulure. */
+  *txn_p = txn;
   return SVN_NO_ERROR;
 }
 
@@ -496,28 +507,60 @@ svn_repos_fs_revision_proplist(apr_hash_
   return SVN_NO_ERROR;
 }
 
+struct lock_many_baton_t {
+  svn_boolean_t need_lock;
+  apr_array_header_t *paths;
+  svn_fs_lock_callback_t lock_callback;
+  void *lock_baton;
+  svn_error_t *cb_err;
+  apr_pool_t *pool;
+};
+
+/* Implements svn_fs_lock_callback_t.  Used by svn_repos_fs_lock_many
+   and svn_repos_fs_unlock_many to record the paths for use by post-
+   hooks, forward to the supplied callback and record any callback
+   error. */
+static svn_error_t *
+lock_many_cb(void *lock_baton,
+             const char *path,
+             const svn_lock_t *lock,
+             svn_error_t *fs_err,
+             apr_pool_t *pool)
+{
+  struct lock_many_baton_t *b = lock_baton;
+
+  if (!b->cb_err && b->lock_callback)
+    b->cb_err = b->lock_callback(b->lock_baton, path, lock, fs_err, pool);
+
+  if ((b->need_lock && lock) || (!b->need_lock && !fs_err))
+    APR_ARRAY_PUSH(b->paths, const char *) = apr_pstrdup(b->pool, path);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
-svn_repos_fs_lock2(apr_hash_t **results,
-                   svn_repos_t *repos,
-                   apr_hash_t *targets,
-                   const char *comment,
-                   svn_boolean_t is_dav_comment,
-                   apr_time_t expiration_date,
-                   svn_boolean_t steal_lock,
-                   apr_pool_t *result_pool,
-                   apr_pool_t *scratch_pool)
+svn_repos_fs_lock_many(svn_repos_t *repos,
+                       apr_hash_t *targets,
+                       const char *comment,
+                       svn_boolean_t is_dav_comment,
+                       apr_time_t expiration_date,
+                       svn_boolean_t steal_lock,
+                       svn_fs_lock_callback_t lock_callback,
+                       void *lock_baton,
+                       apr_pool_t *result_pool,
+                       apr_pool_t *scratch_pool)
 {
-  svn_error_t *err;
+  svn_error_t *err, *cb_err = SVN_NO_ERROR;
   svn_fs_access_t *access_ctx = NULL;
   const char *username = NULL;
   apr_hash_t *hooks_env;
   apr_hash_t *pre_targets = apr_hash_make(scratch_pool);
   apr_hash_index_t *hi;
-  apr_array_header_t *paths;
-  apr_hash_t *pre_results;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  struct lock_many_baton_t baton;
 
-  *results = apr_hash_make(result_pool);
+  if (!apr_hash_count(targets))
+    return SVN_NO_ERROR;
 
   /* Parse the hooks-env file (if any). */
   SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@@ -546,11 +589,10 @@ svn_repos_fs_lock2(apr_hash_t **results,
                                       username, comment, steal_lock, iterpool);
       if (err)
         {
-          svn_fs_lock_result_t *result
-            = apr_palloc(result_pool, sizeof(svn_fs_lock_result_t));
-          result->lock = NULL;
-          result->err = err;
-          svn_hash_sets(*results, path, result);
+          if (!cb_err && lock_callback)
+            cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
+          svn_error_clear(err);
+          
           continue;
         }
 
@@ -560,39 +602,62 @@ svn_repos_fs_lock2(apr_hash_t **results,
       svn_hash_sets(pre_targets, path, target);
     }
 
-  err = svn_fs_lock2(&pre_results, repos->fs, pre_targets, comment,
-                     is_dav_comment, expiration_date, steal_lock,
-                     result_pool, iterpool);
-
-  /* Combine results so the caller can handle all the errors. */
-  for (hi = apr_hash_first(iterpool, pre_results); hi; hi = apr_hash_next(hi))
-    svn_hash_sets(*results, svn__apr_hash_index_key(hi),
-                  svn__apr_hash_index_val(hi));
+  if (!apr_hash_count(pre_targets))
+    return svn_error_trace(cb_err);
 
-  /* If there are locks and an error should we return or run the post-lock? */
-  if (err)
-    return svn_error_trace(err);
+  baton.need_lock = TRUE;
+  baton.paths = apr_array_make(scratch_pool, apr_hash_count(pre_targets),
+                               sizeof(const char *));
+  baton.lock_callback = lock_callback;
+  baton.lock_baton = lock_baton;
+  baton.cb_err = cb_err;
+  baton.pool = scratch_pool;
+
+  err = svn_fs_lock_many(repos->fs, pre_targets, comment,
+                         is_dav_comment, expiration_date, steal_lock,
+                         lock_many_cb, &baton, result_pool, iterpool);
 
-  /* Extract paths that were successfully locked for the post-lock. */
-  paths = apr_array_make(iterpool, apr_hash_count(pre_results),
-                         sizeof(const char *));
-  for (hi = apr_hash_first(iterpool, pre_results); hi; hi = apr_hash_next(hi))
+  /* If there are locks and an error should we return or run the post-lock? */
+  if (!err && baton.paths->nelts)
     {
-      const char *path = svn__apr_hash_index_key(hi);
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-
-      if (result->lock)
-        APR_ARRAY_PUSH(paths, const char *) = path;
+      err = svn_repos__hooks_post_lock(repos, hooks_env, baton.paths, username,
+                                       iterpool);
+      if (err)
+        err = svn_error_create(SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED, err,
+                            _("Locking succeeded, but post-lock hook failed"));
     }
 
-  err = svn_repos__hooks_post_lock(repos, hooks_env, paths, username, iterpool);
-  if (err)
-    err = svn_error_create(SVN_ERR_REPOS_POST_LOCK_HOOK_FAILED, err,
-                           "Locking succeeded, but post-lock hook failed");
-
   svn_pool_destroy(iterpool);
 
-  return err;
+  if (err && cb_err)
+    svn_error_compose(err, cb_err);
+  else if (!err)
+    err = cb_err;
+
+  return svn_error_trace(err);
+}
+
+struct lock_baton_t {
+  const svn_lock_t *lock;
+  svn_error_t *fs_err;
+};
+
+/* Implements svn_fs_lock_callback_t.  Used by svn_repos_fs_lock and
+   svn_repos_fs_unlock to record the lock and error from
+   svn_repos_fs_lock_many and svn_repos_fs_unlock_many. */
+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;
+
+  b->lock = lock;
+  b->fs_err = svn_error_dup(fs_err);
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -607,55 +672,51 @@ svn_repos_fs_lock(svn_lock_t **lock,
                   svn_boolean_t steal_lock,
                   apr_pool_t *pool)
 {
-  apr_hash_t *targets = apr_hash_make(pool), *results;
+  apr_hash_t *targets = apr_hash_make(pool);
   svn_fs_lock_target_t target; 
   svn_error_t *err;
+  struct lock_baton_t baton = {0};
 
   target.token = token;
   target.current_rev = current_rev;
   svn_hash_sets(targets, path, &target);
 
-  err = svn_repos_fs_lock2(&results, repos, targets, comment, is_dav_comment,
-                           expiration_date, steal_lock,
-                           pool, pool);
+  err = svn_repos_fs_lock_many(repos, targets, comment, is_dav_comment,
+                               expiration_date, steal_lock, lock_cb, &baton,
+                               pool, pool);
 
-  if (apr_hash_count(results))
-    {
-      const svn_fs_lock_result_t *result
-        = svn__apr_hash_index_val(apr_hash_first(pool, results));
+  if (baton.lock)
+    *lock = (svn_lock_t*)baton.lock;
 
-      if (result->lock)
-        *lock = result->lock;
+  if (err && baton.fs_err)
+    svn_error_compose(err, baton.fs_err);
+  else if (!err)
+    err = baton.fs_err;
 
-      if (err && result->err)
-        svn_error_compose(err, result->err);
-      else if (!err)
-        err = result->err;
-    }
-
-  return err;
+  return svn_error_trace(err);
 }
 
 
 svn_error_t *
-svn_repos_fs_unlock2(apr_hash_t **results,
-                     svn_repos_t *repos,
-                     apr_hash_t *targets,
-                     svn_boolean_t break_lock,
-                     apr_pool_t *result_pool,
-                     apr_pool_t *scratch_pool)
+svn_repos_fs_unlock_many(svn_repos_t *repos,
+                         apr_hash_t *targets,
+                         svn_boolean_t break_lock,
+                         svn_fs_lock_callback_t lock_callback,
+                         void *lock_baton,
+                         apr_pool_t *result_pool,
+                         apr_pool_t *scratch_pool)
 {
-  svn_error_t *err;
+  svn_error_t *err, *cb_err = SVN_NO_ERROR;
   svn_fs_access_t *access_ctx = NULL;
   const char *username = NULL;
   apr_hash_t *hooks_env;
   apr_hash_t *pre_targets = apr_hash_make(scratch_pool);
   apr_hash_index_t *hi;
-  apr_array_header_t *paths;
-  apr_hash_t *pre_results;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  struct lock_many_baton_t baton;
 
-  *results = apr_hash_make(result_pool);
+  if (!apr_hash_count(targets))
+    return SVN_NO_ERROR;
 
   /* Parse the hooks-env file (if any). */
   SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@@ -671,7 +732,7 @@ svn_repos_fs_unlock2(apr_hash_t **result
        _("Cannot unlock, no authenticated username available"));
 
   /* Run pre-unlock hook.  This could throw error, preventing
-     svn_fs_unlock2() from happening for that path. */
+     svn_fs_unlock_many() from happening for that path. */
   for (hi = apr_hash_first(scratch_pool, targets); hi; hi = apr_hash_next(hi))
     {
       const char *path = svn__apr_hash_index_key(hi);
@@ -683,49 +744,47 @@ svn_repos_fs_unlock2(apr_hash_t **result
                                         break_lock, iterpool);
       if (err)
         {
-          svn_fs_lock_result_t *result
-            = apr_palloc(result_pool, sizeof(svn_fs_lock_result_t));
-          result->lock = NULL;
-          result->err = err;
-          svn_hash_sets(*results, path, result);
+          if (!cb_err && lock_callback)
+            cb_err = lock_callback(lock_baton, path, NULL, err, iterpool);
+          svn_error_clear(err);
+
           continue;
         }
 
       svn_hash_sets(pre_targets, path, token);
     }
 
-  err = svn_fs_unlock2(&pre_results, repos->fs, pre_targets, break_lock,
-                       result_pool, iterpool);
+  if (!apr_hash_count(pre_targets))
+    return svn_error_trace(cb_err);
 
-  /* Combine results for all paths. */
-  for (hi = apr_hash_first(iterpool, pre_results); hi; hi = apr_hash_next(hi))
-    svn_hash_sets(*results, svn__apr_hash_index_key(hi),
-                  svn__apr_hash_index_val(hi));
+  baton.need_lock = FALSE;
+  baton.paths = apr_array_make(scratch_pool, apr_hash_count(pre_targets),
+                               sizeof(const char *));
+  baton.lock_callback = lock_callback;
+  baton.lock_baton = lock_baton;
+  baton.cb_err = cb_err;
+  baton.pool = scratch_pool;
 
-  if (err)
-    return svn_error_trace(err);
+  err = svn_fs_unlock_many(repos->fs, pre_targets, break_lock,
+                           lock_many_cb, &baton, result_pool, iterpool);
 
-  /* Extract paths that were successfully unlocked for the post-unlock. */
-  paths = apr_array_make(iterpool, apr_hash_count(pre_results),
-                         sizeof(const char *));
-  for (hi = apr_hash_first(iterpool, pre_results); hi; hi = apr_hash_next(hi))
+  if (!err && baton.paths->nelts)
     {
-      const char *path = svn__apr_hash_index_key(hi);
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-
-      if (result->lock)
-        APR_ARRAY_PUSH(paths, const char *) = path;
-    }
-  
-
-  if ((err = svn_repos__hooks_post_unlock(repos, hooks_env, paths,
-                                          username, iterpool)))
-    err = svn_error_create(SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED, err,
+      err = svn_repos__hooks_post_unlock(repos, hooks_env, baton.paths,
+                                         username, iterpool);
+      if (err)
+        err = svn_error_create(SVN_ERR_REPOS_POST_UNLOCK_HOOK_FAILED, err,
                            _("Unlock succeeded, but post-unlock hook failed"));
+    }
 
   svn_pool_destroy(iterpool);
 
-  return err;
+  if (err && cb_err)
+    svn_error_compose(err, cb_err);
+  else if (!err)
+    err = cb_err;
+
+  return svn_error_trace(err);
 }
 
 svn_error_t *
@@ -735,28 +794,24 @@ svn_repos_fs_unlock(svn_repos_t *repos,
                     svn_boolean_t break_lock,
                     apr_pool_t *pool)
 {
-  apr_hash_t *targets = apr_hash_make(pool), *results;
+  apr_hash_t *targets = apr_hash_make(pool);
   svn_error_t *err;
+  struct lock_baton_t baton = {0};
 
   if (!token)
     token = "";
 
   svn_hash_sets(targets, path, token);
 
-  err = svn_repos_fs_unlock2(&results, repos, targets, break_lock, pool, pool);
+  err = svn_repos_fs_unlock_many(repos, targets, break_lock, lock_cb, &baton,
+                                 pool, pool);
 
-  if (apr_hash_count(results))
-    {
-      const svn_fs_lock_result_t *result
-        = svn__apr_hash_index_val(apr_hash_first(pool, results));
-
-      if (err && result->err)
-        svn_error_compose(err, result->err);
-      else if (!err)
-        err = result->err;
-    }
+  if (err && baton.fs_err)
+    svn_error_compose(err, baton.fs_err);
+  else if (!err)
+    err = baton.fs_err;
 
-  return err;
+  return svn_error_trace(err);
 }
 
 

Modified: subversion/branches/remote-only-status/subversion/libsvn_subr/error.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/libsvn_subr/error.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/libsvn_subr/error.c (original)
+++ subversion/branches/remote-only-status/subversion/libsvn_subr/error.c Thu Apr  3 19:56:20 2014
@@ -360,6 +360,9 @@ svn_error_dup(svn_error_t *err)
   apr_pool_t *pool;
   svn_error_t *new_err = NULL, *tmp_err = NULL;
 
+  if (!err)
+    return SVN_NO_ERROR;
+
   pool = svn_pool_create(NULL);
   if (!pool)
     abort();

Modified: subversion/branches/remote-only-status/subversion/mod_dav_svn/version.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/mod_dav_svn/version.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/mod_dav_svn/version.c (original)
+++ subversion/branches/remote-only-status/subversion/mod_dav_svn/version.c Thu Apr  3 19:56:20 2014
@@ -1354,6 +1354,23 @@ dav_svn__push_locks(dav_resource *resour
   return NULL;
 }
 
+/* Implements svn_fs_lock_callback_t. */
+static svn_error_t *
+unlock_many_cb(void *lock_baton,
+               const char *path,
+               const svn_lock_t *lock,
+               svn_error_t *fs_err,
+               apr_pool_t *pool)
+{
+  request_rec *r = lock_baton;
+
+  if (fs_err)
+    ap_log_rerror(APLOG_MARK, APLOG_ERR, fs_err->apr_err, r,
+                  "%s", fs_err->message);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* Helper for merge().  Free every lock in LOCKS.  The locks
    live in REPOS.  Log any errors for REQUEST.  Use POOL for temporary
@@ -1367,7 +1384,6 @@ release_locks(apr_hash_t *locks,
   apr_hash_index_t *hi;
   apr_pool_t *subpool = svn_pool_create(pool);
   apr_hash_t *targets = apr_hash_make(subpool);
-  apr_hash_t *results;
   svn_error_t *err;
 
   for (hi = apr_hash_first(subpool, locks); hi; hi = apr_hash_next(hi))
@@ -1378,16 +1394,9 @@ release_locks(apr_hash_t *locks,
       svn_hash_sets(targets, path, token);
     }
 
-  err = svn_repos_fs_unlock2(&results, repos, targets, FALSE, subpool, subpool);
+  err = svn_repos_fs_unlock_many(repos, targets, FALSE, unlock_many_cb, r,
+                                 subpool, subpool);
 
-  for (hi = apr_hash_first(subpool, results); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-      if (result->err)
-        ap_log_rerror(APLOG_MARK, APLOG_ERR, result->err->apr_err, r,
-                      "%s", result->err->message);
-      svn_error_clear(result->err);
-    }
   if (err) /* If we got an error, just log it and move along. */
     ap_log_rerror(APLOG_MARK, APLOG_ERR, err->apr_err, r,
                   "%s", err->message);

Modified: subversion/branches/remote-only-status/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/svnserve/serve.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/svnserve/serve.c (original)
+++ subversion/branches/remote-only-status/subversion/svnserve/serve.c Thu Apr  3 19:56:20 2014
@@ -1029,7 +1029,7 @@ static svn_error_t *write_prop_diffs(svn
 /* Write out a lock to the client. */
 static svn_error_t *write_lock(svn_ra_svn_conn_t *conn,
                                apr_pool_t *pool,
-                               svn_lock_t *lock)
+                               const svn_lock_t *lock)
 {
   const char *cdate, *edate;
 
@@ -1345,6 +1345,21 @@ static svn_error_t *add_lock_tokens(cons
   return SVN_NO_ERROR;
 }
 
+/* Implements svn_fs_lock_callback_t. */
+static svn_error_t *
+lock_cb(void *baton,
+        const char *path,
+        const svn_lock_t *lock,
+        svn_error_t *fs_err,
+        apr_pool_t *pool)
+{
+  server_baton_t *sb = baton;
+
+  log_error(fs_err, sb);
+
+  return SVN_NO_ERROR;
+}
+
 /* Unlock the paths with lock tokens in LOCK_TOKENS, ignoring any errors.
    LOCK_TOKENS contains svn_ra_svn_item_t elements, assumed to be lists. */
 static svn_error_t *unlock_paths(const apr_array_header_t *lock_tokens,
@@ -1354,8 +1369,6 @@ static svn_error_t *unlock_paths(const a
   int i;
   apr_pool_t *subpool = svn_pool_create(pool);
   apr_hash_t *targets = apr_hash_make(subpool);
-  apr_hash_t *results;
-  apr_hash_index_t *hi;
   svn_error_t *err;
 
   for (i = 0; i < lock_tokens->nelts; ++i)
@@ -1378,15 +1391,8 @@ static svn_error_t *unlock_paths(const a
 
   /* The lock may have become defunct after the commit, so ignore such
      errors. */
-  err = svn_repos_fs_unlock2(&results, sb->repository->repos, targets,
-                             FALSE, subpool, subpool);
-  for (hi = apr_hash_first(subpool, results); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-
-      log_error(result->err, sb);
-      svn_error_clear(result->err);
-    }
+  err = svn_repos_fs_unlock_many(sb->repository->repos, targets, FALSE,
+                                 lock_cb, sb, subpool, subpool);
   log_error(err, sb);
   svn_error_clear(err);
 
@@ -2706,6 +2712,48 @@ static svn_error_t *lock(svn_ra_svn_conn
   return SVN_NO_ERROR;
 }
 
+struct lock_result_t {
+  const svn_lock_t *lock;
+  svn_error_t *err;
+};
+
+struct lock_many_baton_t {
+  apr_hash_t *results;
+  apr_pool_t *pool;
+};
+
+/* Implements svn_fs_lock_callback_t. */
+static svn_error_t *
+lock_many_cb(void *baton,
+             const char *path,
+             const svn_lock_t *fs_lock,
+             svn_error_t *fs_err,
+             apr_pool_t *pool)
+{
+  struct lock_many_baton_t *b = baton;
+  struct lock_result_t *result = apr_palloc(b->pool,
+                                            sizeof(struct lock_result_t));
+
+  result->lock = fs_lock;
+  result->err = svn_error_dup(fs_err);
+  svn_hash_sets(b->results, apr_pstrdup(b->pool, path), result);
+
+  return SVN_NO_ERROR;
+}
+
+static void
+clear_lock_result_hash(apr_hash_t *results,
+                       apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+
+  for (hi = apr_hash_first(scratch_pool, results); hi; hi = apr_hash_next(hi))
+    {
+      struct lock_result_t *result = svn__apr_hash_index_val(hi);
+      svn_error_clear(result->err);
+    }
+}
+
 static svn_error_t *lock_many(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                               apr_array_header_t *params, void *baton)
 {
@@ -2718,8 +2766,8 @@ static svn_error_t *lock_many(svn_ra_svn
   svn_error_t *err, *write_err = SVN_NO_ERROR;
   apr_hash_t *targets = apr_hash_make(pool);
   apr_hash_t *authz_results = apr_hash_make(pool);
-  apr_hash_t *results;
   apr_hash_index_t *hi;
+  struct lock_many_baton_t lmb;
 
   SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?c)bl", &comment, &steal_lock,
                                   &path_revs));
@@ -2774,8 +2822,8 @@ static svn_error_t *lock_many(svn_ra_svn
 
       if (! lookup_access(subpool, b, svn_authz_write, full_path, TRUE))
         {
-          svn_fs_lock_result_t *result
-            = apr_palloc(pool, sizeof(svn_fs_lock_result_t));
+          struct lock_result_t *result
+            = apr_palloc(pool, sizeof(struct lock_result_t));
 
           result->lock = NULL;
           result->err = error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED,
@@ -2785,10 +2833,14 @@ static svn_error_t *lock_many(svn_ra_svn
         }
     }
 
-  err = svn_repos_fs_lock2(&results, b->repository->repos, targets,
-                           comment, FALSE,
-                           0, /* No expiration time. */
-                           steal_lock, pool, subpool);
+  lmb.results = apr_hash_make(pool);
+  lmb.pool = pool;
+
+  err = svn_repos_fs_lock_many(b->repository->repos, targets,
+                               comment, FALSE,
+                               0, /* No expiration time. */
+                               steal_lock, lock_many_cb, &lmb,
+                               pool, subpool);
 
   /* The client expects results in the same order as paths were supplied. */
   for (i = 0; i < path_revs->nelts; ++i)
@@ -2797,7 +2849,7 @@ static svn_error_t *lock_many(svn_ra_svn
       svn_revnum_t current_rev;
       svn_ra_svn_item_t *item = &APR_ARRAY_IDX(path_revs, i,
                                                svn_ra_svn_item_t);
-      svn_fs_lock_result_t *result;
+      struct lock_result_t *result;
 
       svn_pool_clear(subpool);
 
@@ -2810,7 +2862,7 @@ static svn_error_t *lock_many(svn_ra_svn
                                    svn_relpath_canonicalize(path, subpool),
                                    subpool);
 
-      result = svn_hash_gets(results, full_path);
+      result = svn_hash_gets(lmb.results, full_path);
       if (!result)
         result = svn_hash_gets(authz_results, full_path);
       if (!result)
@@ -2833,16 +2885,8 @@ static svn_error_t *lock_many(svn_ra_svn
         break;
     }
 
-  for (hi = apr_hash_first(subpool, authz_results); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-      svn_error_clear(result->err);
-    }
-  for (hi = apr_hash_first(subpool, results); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-      svn_error_clear(result->err);
-    }
+  clear_lock_result_hash(authz_results, subpool);
+  clear_lock_result_hash(lmb.results, subpool);
 
   svn_pool_destroy(subpool);
 
@@ -2895,8 +2939,8 @@ static svn_error_t *unlock_many(svn_ra_s
   svn_error_t *err = SVN_NO_ERROR, *write_err;
   apr_hash_t *targets = apr_hash_make(pool);
   apr_hash_t *authz_results = apr_hash_make(pool);
-  apr_hash_t *results;
   apr_hash_index_t *hi;
+  struct lock_many_baton_t lmb;
 
   SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "bl", &break_lock,
                                   &unlock_tokens));
@@ -2944,8 +2988,8 @@ static svn_error_t *unlock_many(svn_ra_s
       if (! lookup_access(subpool, b, svn_authz_write, full_path,
                           ! break_lock))
         {
-          svn_fs_lock_result_t *result
-            = apr_palloc(pool, sizeof(svn_fs_lock_result_t));
+          struct lock_result_t *result
+            = apr_palloc(pool, sizeof(struct lock_result_t));
 
           result->lock = NULL;
           result->err = error_create_and_log(SVN_ERR_RA_NOT_AUTHORIZED,
@@ -2955,8 +2999,12 @@ static svn_error_t *unlock_many(svn_ra_s
         }
     }
 
-  err = svn_repos_fs_unlock2(&results, b->repository->repos, targets,
-                             break_lock, pool, subpool);
+  lmb.results = apr_hash_make(pool);
+  lmb.pool = pool;
+
+  err = svn_repos_fs_unlock_many(b->repository->repos, targets,
+                                 break_lock, lock_many_cb, &lmb,
+                                 pool, subpool);
 
   /* Return results in the same order as the paths were supplied. */
   for (i = 0; i < unlock_tokens->nelts; ++i)
@@ -2964,7 +3012,7 @@ static svn_error_t *unlock_many(svn_ra_s
       const char *path, *token, *full_path;
       svn_ra_svn_item_t *item = &APR_ARRAY_IDX(unlock_tokens, i,
                                                svn_ra_svn_item_t);
-      svn_fs_lock_result_t *result;
+      struct lock_result_t *result;
 
       svn_pool_clear(subpool);
 
@@ -2977,7 +3025,7 @@ static svn_error_t *unlock_many(svn_ra_s
                                    svn_relpath_canonicalize(path, subpool),
                                    pool);
 
-      result = svn_hash_gets(results, full_path);
+      result = svn_hash_gets(lmb.results, full_path);
       if (!result)
         result = svn_hash_gets(authz_results, full_path);
       if (!result)
@@ -2993,16 +3041,8 @@ static svn_error_t *unlock_many(svn_ra_s
         break;
     }
 
-  for (hi = apr_hash_first(subpool, authz_results); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-      svn_error_clear(result->err);
-    }
-  for (hi = apr_hash_first(subpool, results); hi; hi = apr_hash_next(hi))
-    {
-      svn_fs_lock_result_t *result = svn__apr_hash_index_val(hi);
-      svn_error_clear(result->err);
-    }
+  clear_lock_result_hash(authz_results, subpool);
+  clear_lock_result_hash(lmb.results, subpool);
 
   svn_pool_destroy(subpool);
 

Modified: subversion/branches/remote-only-status/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/tests/cmdline/authz_tests.py?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/remote-only-status/subversion/tests/cmdline/authz_tests.py Thu Apr  3 19:56:20 2014
@@ -800,6 +800,36 @@ def authz_locking(sbox):
                                         None,
                                         mu_path)
 
+  # Lock two paths one of which fails. First add read access to '/' so
+  # that OPTIONS on common ancestor works.
+  write_authz_file(sbox, {"/": "jrandom = r", "/A": "jrandom = rw"})
+
+  # Two unlocked paths
+  svntest.actions.run_and_verify_info([{'Lock Token' : None}],
+                                      sbox.ospath('iota'))
+  svntest.actions.run_and_verify_info([{'Lock Token' : None}],
+                                      sbox.ospath('A/mu'))
+
+  ### Crazy serf SVN_ERR_FS_LOCK_OWNER_MISMATCH warning! Issue 3801?
+  if sbox.repo_url.startswith('http'):
+    expected_err = ".*svn: warning: W160039: Unlock.*[Ff]orbidden.*"
+    expected_status = 0
+
+  svntest.actions.run_and_verify_svn2(None,
+                                      None, expected_err, expected_status,
+                                      'lock',
+                                      '-m', 'lock msg',
+                                      mu_path,
+                                      iota_path)
+
+  # One path locked, one still unlocked
+  svntest.actions.run_and_verify_info([{'Lock Token' : None}],
+                                      sbox.ospath('iota'))
+  svntest.actions.run_and_verify_info([{'Lock Token' : 'opaquelocktoken:.*'}],
+                                      sbox.ospath('A/mu'))
+
+
+
 # test for issue #2712: if anon-access == read, svnserve should also check
 # authz to determine whether a checkout/update is actually allowed for
 # anonymous users, and, if not, attempt authentication.

Modified: subversion/branches/remote-only-status/subversion/tests/cmdline/commit_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/tests/cmdline/commit_tests.py?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/tests/cmdline/commit_tests.py (original)
+++ subversion/branches/remote-only-status/subversion/tests/cmdline/commit_tests.py Thu Apr  3 19:56:20 2014
@@ -2545,6 +2545,16 @@ def start_commit_hook_test(sbox):
                                            'STDERR',
                                            expected_stderr, actual_stderr)
 
+  # Now list the txns in the repo. The list should be empty.
+  exit_code, output, errput = svntest.main.run_svnadmin('lstxns',
+                                                        sbox.repo_dir)
+  svntest.verify.compare_and_display_lines(
+    "Error running 'svnadmin lstxns'.",
+    'STDERR', [], errput)
+  svntest.verify.compare_and_display_lines(
+    "Output of 'svnadmin lstxns' is unexpected.",
+    'STDOUT', [], output)
+
 #----------------------------------------------------------------------
 @Issue(3553)
 def pre_commit_hook_test(sbox):

Modified: subversion/branches/remote-only-status/subversion/tests/cmdline/lock_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/tests/cmdline/lock_tests.py?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/tests/cmdline/lock_tests.py (original)
+++ subversion/branches/remote-only-status/subversion/tests/cmdline/lock_tests.py Thu Apr  3 19:56:20 2014
@@ -2178,6 +2178,58 @@ def non_root_locks(sbox):
   expected_status.tweak('A/D/G/pi', writelocked=None)
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
+def many_locks_hooks(sbox):
+  "many locks with hooks"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Prevent locking '/A/D/G/pi'.
+  svntest.main.create_python_hook_script(os.path.join(sbox.repo_dir,
+                                                      'hooks', 'pre-lock'),
+                                         'import sys\n'
+                                         'if sys.argv[2] == "/A/D/G/pi":\n'
+                                         '  sys.exit(1)\n'
+                                         'sys.exit(0)\n')
+
+  # Prevent unlocking '/A/mu'.
+  svntest.main.create_python_hook_script(os.path.join(sbox.repo_dir,
+                                                      'hooks', 'pre-unlock'),
+                                         'import sys\n'
+                                         'if sys.argv[2] == "/A/mu":\n'
+                                         '  sys.exit(1)\n'
+                                         'sys.exit(0)\n')
+
+  svntest.actions.run_and_verify_svn2(None,
+                                      ".* locked",
+                                      "svn: warning: W165001: .*", 0,
+                                      'lock',
+                                      sbox.ospath('iota'),
+                                      sbox.ospath('A/mu'),
+                                      sbox.ospath('A/B/E/alpha'),
+                                      sbox.ospath('A/D/G/pi'),
+                                      sbox.ospath('A/D/G/rho'))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', 'A/mu', 'A/B/E/alpha', 'A/D/G/rho',
+                        writelocked='K')
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+  svntest.actions.run_and_verify_svn2(None,
+                                      ".* unlocked",
+                                      "svn: warning: W165001: .*", 0,
+                                      'unlock',
+                                      sbox.ospath('iota'),
+                                      sbox.ospath('A/mu'),
+                                      sbox.ospath('A/B/E/alpha'),
+                                      sbox.ospath('A/D/G/rho'))
+
+  expected_status.tweak('iota', 'A/B/E/alpha', 'A/D/G/rho',
+                        writelocked=None)
+  svntest.actions.run_and_verify_status(wc_dir, expected_status)
+
+
+
 ########################################################################
 # Run the tests
 
@@ -2238,6 +2290,7 @@ test_list = [ None,
               dav_lock_timeout,
               create_dav_lock_timeout,
               non_root_locks,
+              many_locks_hooks,
             ]
 
 if __name__ == '__main__':

Modified: subversion/branches/remote-only-status/subversion/tests/libsvn_fs/locks-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/tests/libsvn_fs/locks-test.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/tests/libsvn_fs/locks-test.c (original)
+++ subversion/branches/remote-only-status/subversion/tests/libsvn_fs/locks-test.c Thu Apr  3 19:56:20 2014
@@ -787,6 +787,10 @@ lock_out_of_date(const svn_test_opts_t *
   return SVN_NO_ERROR;
 }
 
+struct lock_result_t {
+  const svn_lock_t *lock;
+  svn_error_t *fs_err;
+};
 
 static svn_error_t *
 expect_lock(const char *path,
@@ -795,9 +799,9 @@ expect_lock(const char *path,
             apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
-  SVN_TEST_ASSERT(result && result->lock && !result->err);
+  SVN_TEST_ASSERT(result && result->lock && !result->fs_err);
   SVN_ERR(svn_fs_get_lock(&lock, fs, path, scratch_pool));
   SVN_TEST_ASSERT(lock);
   return SVN_NO_ERROR;
@@ -810,10 +814,10 @@ expect_error(const char *path,
              apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
-  SVN_TEST_ASSERT(result && !result->lock && result->err);
-  svn_error_clear(result->err);
+  SVN_TEST_ASSERT(result && !result->lock && result->fs_err);
+  svn_error_clear(result->fs_err);
   SVN_ERR(svn_fs_get_lock(&lock, fs, path, scratch_pool));
   SVN_TEST_ASSERT(!lock);
   return SVN_NO_ERROR;
@@ -826,9 +830,9 @@ expect_unlock(const char *path,
               apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
-  SVN_TEST_ASSERT(result && !result->err);
+  SVN_TEST_ASSERT(result && !result->fs_err);
   SVN_ERR(svn_fs_get_lock(&lock, fs, path, scratch_pool));
   SVN_TEST_ASSERT(!lock);
   return SVN_NO_ERROR;
@@ -841,15 +845,39 @@ expect_unlock_error(const char *path,
                     apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
-  SVN_TEST_ASSERT(result && result->err);
-  svn_error_clear(result->err);
+  SVN_TEST_ASSERT(result && result->fs_err);
+  svn_error_clear(result->fs_err);
   SVN_ERR(svn_fs_get_lock(&lock, fs, path, scratch_pool));
   SVN_TEST_ASSERT(lock);
   return SVN_NO_ERROR;
 }
 
+struct lock_many_baton_t {
+  apr_hash_t *results;
+  apr_pool_t *pool;
+};
+
+/* Implements svn_fs_lock_callback_t. */
+static svn_error_t *
+lock_many_cb(void *lock_baton,
+             const char *path,
+             const svn_lock_t *lock,
+             svn_error_t *fs_err,
+             apr_pool_t *pool)
+{
+  struct lock_many_baton_t *b = lock_baton;
+  struct lock_result_t *result = apr_palloc(b->pool,
+                                            sizeof(struct lock_result_t));
+
+  result->lock = lock;
+  result->fs_err = svn_error_dup(fs_err);
+  svn_hash_sets(b->results, apr_pstrdup(b->pool, path), result);
+
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 lock_multiple_paths(const svn_test_opts_t *opts,
                     apr_pool_t *pool)
@@ -861,8 +889,8 @@ lock_multiple_paths(const svn_test_opts_
   svn_revnum_t newrev;
   svn_fs_access_t *access;
   svn_fs_lock_target_t target;
-  apr_hash_t *lock_paths, *unlock_paths, *results;
-  svn_fs_lock_result_t *result;
+  struct lock_many_baton_t baton;
+  apr_hash_t *lock_paths, *unlock_paths;
   apr_hash_index_t *hi;
 
   SVN_ERR(create_greek_fs(&fs, &newrev, "test-lock-multiple-paths",
@@ -878,10 +906,13 @@ lock_multiple_paths(const svn_test_opts_
   SVN_ERR(svn_fs_copy(root, "/A/mu", txn_root, "/A/BBB/mu", pool));
   SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool));
 
+  baton.results = apr_hash_make(pool);
+  baton.pool = pool;
   lock_paths = apr_hash_make(pool);
   unlock_paths = apr_hash_make(pool);
   target.token = NULL;
   target.current_rev = newrev;
+
   svn_hash_sets(lock_paths, "/A/B/E/alpha", &target);
   svn_hash_sets(lock_paths, "/A/B/E/beta", &target);
   svn_hash_sets(lock_paths, "/A/B/E/zulu", &target);
@@ -893,81 +924,91 @@ lock_multiple_paths(const svn_test_opts_
   svn_hash_sets(lock_paths, "/X/zulu", &target);
 
   /* Lock some paths. */
-  SVN_ERR(svn_fs_lock2(&results, fs, lock_paths, "comment", 0, 0, 0,
-                       pool, pool));
-
-  SVN_ERR(expect_lock("/A/B/E/alpha", results, fs, pool));
-  SVN_ERR(expect_lock("/A/B/E/beta", results, fs, pool));
-  SVN_ERR(expect_error("/A/B/E/zulu", results, fs, pool));
-  SVN_ERR(expect_lock("/A/BB/mu", results, fs, pool));
-  SVN_ERR(expect_lock("/A/BBB/mu", results, fs, pool));
-  SVN_ERR(expect_lock("/A/D/G/pi", results, fs, pool));
-  SVN_ERR(expect_lock("/A/D/G/rho", results, fs, pool));
-  SVN_ERR(expect_lock("/A/mu", results, fs, pool));
-  SVN_ERR(expect_error("/X/zulu", results, fs, pool));
+  apr_hash_clear(baton.results);
+  SVN_ERR(svn_fs_lock_many(fs, lock_paths, "comment", 0, 0, 0,
+                           lock_many_cb, &baton,
+                           pool, pool));
+
+  SVN_ERR(expect_lock("/A/B/E/alpha", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/B/E/beta", baton.results, fs, pool));
+  SVN_ERR(expect_error("/A/B/E/zulu", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/BB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/BBB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/D/G/pi", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/D/G/rho", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/mu", baton.results, fs, pool));
+  SVN_ERR(expect_error("/X/zulu", baton.results, fs, pool));
 
   /* Unlock without force and wrong tokens. */
   for (hi = apr_hash_first(pool, lock_paths); hi; hi = apr_hash_next(hi))
     svn_hash_sets(unlock_paths, svn__apr_hash_index_key(hi), "wrong-token");
-  SVN_ERR(svn_fs_unlock2(&results, fs, unlock_paths, FALSE, pool, pool));
-
-  SVN_ERR(expect_unlock_error("/A/B/E/alpha", results, fs, pool));
-  SVN_ERR(expect_unlock_error("/A/B/E/beta", results, fs, pool));
-  SVN_ERR(expect_error("/A/B/E/zulu", results, fs, pool));
-  SVN_ERR(expect_unlock_error("/A/BB/mu", results, fs, pool));
-  SVN_ERR(expect_unlock_error("/A/BBB/mu", results, fs, pool));
-  SVN_ERR(expect_unlock_error("/A/D/G/pi", results, fs, pool));
-  SVN_ERR(expect_unlock_error("/A/D/G/rho", results, fs, pool));
-  SVN_ERR(expect_unlock_error("/A/mu", results, fs, pool));
-  SVN_ERR(expect_error("/X/zulu", results, fs, pool));
+  apr_hash_clear(baton.results);
+  SVN_ERR(svn_fs_unlock_many(fs, unlock_paths, FALSE, lock_many_cb, &baton,
+                             pool, pool));
+
+  SVN_ERR(expect_unlock_error("/A/B/E/alpha", baton.results, fs, pool));
+  SVN_ERR(expect_unlock_error("/A/B/E/beta", baton.results, fs, pool));
+  SVN_ERR(expect_error("/A/B/E/zulu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock_error("/A/BB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock_error("/A/BBB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock_error("/A/D/G/pi", baton.results, fs, pool));
+  SVN_ERR(expect_unlock_error("/A/D/G/rho", baton.results, fs, pool));
+  SVN_ERR(expect_unlock_error("/A/mu", baton.results, fs, pool));
+  SVN_ERR(expect_error("/X/zulu", baton.results, fs, pool));
 
   /* Force unlock. */
   for (hi = apr_hash_first(pool, lock_paths); hi; hi = apr_hash_next(hi))
     svn_hash_sets(unlock_paths, svn__apr_hash_index_key(hi), "");
-  SVN_ERR(svn_fs_unlock2(&results, fs, unlock_paths, TRUE, pool, pool));
-
-  SVN_ERR(expect_unlock("/A/B/E/alpha", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/B/E/beta", results, fs, pool));
-  SVN_ERR(expect_error("/A/B/E/zulu", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/BB/mu", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/BBB/mu", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/D/G/pi", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/D/G/rho", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/mu", results, fs, pool));
-  SVN_ERR(expect_error("/X/zulu", results, fs, pool));
+  apr_hash_clear(baton.results);
+  SVN_ERR(svn_fs_unlock_many(fs, unlock_paths, TRUE, lock_many_cb, &baton,
+                             pool, pool));
+
+  SVN_ERR(expect_unlock("/A/B/E/alpha", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/B/E/beta", baton.results, fs, pool));
+  SVN_ERR(expect_error("/A/B/E/zulu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/BB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/BBB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/D/G/pi", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/D/G/rho", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/mu", baton.results, fs, pool));
+  SVN_ERR(expect_error("/X/zulu", baton.results, fs, pool));
 
   /* Lock again. */
-  SVN_ERR(svn_fs_lock2(&results, fs, lock_paths, "comment", 0, 0, 0,
-                       pool, pool));
-
-  SVN_ERR(expect_lock("/A/B/E/alpha", results, fs, pool));
-  SVN_ERR(expect_lock("/A/B/E/beta", results, fs, pool));
-  SVN_ERR(expect_error("/A/B/E/zulu", results, fs, pool));
-  SVN_ERR(expect_lock("/A/BB/mu", results, fs, pool));
-  SVN_ERR(expect_lock("/A/BBB/mu", results, fs, pool));
-  SVN_ERR(expect_lock("/A/D/G/pi", results, fs, pool));
-  SVN_ERR(expect_lock("/A/D/G/rho", results, fs, pool));
-  SVN_ERR(expect_lock("/A/mu", results, fs, pool));
-  SVN_ERR(expect_error("/X/zulu", results, fs, pool));
+  apr_hash_clear(baton.results);
+  SVN_ERR(svn_fs_lock_many(fs, lock_paths, "comment", 0, 0, 0,
+                           lock_many_cb, &baton,
+                           pool, pool));
+
+  SVN_ERR(expect_lock("/A/B/E/alpha", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/B/E/beta", baton.results, fs, pool));
+  SVN_ERR(expect_error("/A/B/E/zulu", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/BB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/BBB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/D/G/pi", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/D/G/rho", baton.results, fs, pool));
+  SVN_ERR(expect_lock("/A/mu", baton.results, fs, pool));
+  SVN_ERR(expect_error("/X/zulu", baton.results, fs, pool));
 
   /* Unlock without force. */
-  for (hi = apr_hash_first(pool, results); hi; hi = apr_hash_next(hi))
+  for (hi = apr_hash_first(pool, baton.results); hi; hi = apr_hash_next(hi))
     {
-      result = svn__apr_hash_index_val(hi);
+      struct lock_result_t *result = svn__apr_hash_index_val(hi);
       svn_hash_sets(unlock_paths, svn__apr_hash_index_key(hi),
                     result->lock ? result->lock->token : "non-existent-token");
     }
-  SVN_ERR(svn_fs_unlock2(&results, fs, unlock_paths, FALSE, pool, pool));
-
-  SVN_ERR(expect_unlock("/A/B/E/alpha", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/B/E/beta", results, fs, pool));
-  SVN_ERR(expect_error("/A/B/E/zulu", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/BB/mu", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/BBB/mu", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/D/G/pi", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/D/G/rho", results, fs, pool));
-  SVN_ERR(expect_unlock("/A/mu", results, fs, pool));
-  SVN_ERR(expect_error("/X/zulu", results, fs, pool));
+  apr_hash_clear(baton.results);
+  SVN_ERR(svn_fs_unlock_many(fs, unlock_paths, FALSE, lock_many_cb, &baton,
+                             pool, pool));
+
+  SVN_ERR(expect_unlock("/A/B/E/alpha", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/B/E/beta", baton.results, fs, pool));
+  SVN_ERR(expect_error("/A/B/E/zulu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/BB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/BBB/mu", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/D/G/pi", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/D/G/rho", baton.results, fs, pool));
+  SVN_ERR(expect_unlock("/A/mu", baton.results, fs, pool));
+  SVN_ERR(expect_error("/X/zulu", baton.results, fs, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/remote-only-status/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/subversion/tests/libsvn_ra/ra-test.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/remote-only-status/subversion/tests/libsvn_ra/ra-test.c Thu Apr  3 19:56:20 2014
@@ -374,6 +374,11 @@ tunnel_callback_test(const svn_test_opts
   return SVN_NO_ERROR;
 }
 
+struct lock_result_t {
+  svn_lock_t *lock;
+  svn_error_t *err;
+};
+
 struct lock_baton_t {
   apr_hash_t *results;
   apr_pool_t *pool;
@@ -389,8 +394,8 @@ lock_cb(void *baton,
         apr_pool_t *pool)
 {
   struct lock_baton_t *b = baton;
-  svn_fs_lock_result_t *result = apr_palloc(b->pool,
-                                            sizeof(svn_fs_lock_result_t));
+  struct lock_result_t *result = apr_palloc(b->pool,
+                                            sizeof(struct lock_result_t));
 
   if (lock)
     {
@@ -417,7 +422,7 @@ expect_lock(const char *path,
             apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
   SVN_TEST_ASSERT(result && result->lock && !result->err);
   SVN_ERR(svn_ra_get_lock(session, &lock, path, scratch_pool));
@@ -432,7 +437,7 @@ expect_error(const char *path,
              apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
   SVN_TEST_ASSERT(result && !result->lock && result->err);
   SVN_ERR(svn_ra_get_lock(session, &lock, path, scratch_pool));
@@ -447,7 +452,7 @@ expect_unlock(const char *path,
               apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
   SVN_TEST_ASSERT(result && !result->err);
   SVN_ERR(svn_ra_get_lock(session, &lock, path, scratch_pool));
@@ -462,7 +467,7 @@ expect_unlock_error(const char *path,
                     apr_pool_t *scratch_pool)
 {
   svn_lock_t *lock;
-  svn_fs_lock_result_t *result = svn_hash_gets(results, path);
+  struct lock_result_t *result = svn_hash_gets(results, path);
 
   SVN_TEST_ASSERT(result && result->err);
   SVN_ERR(svn_ra_get_lock(session, &lock, path, scratch_pool));
@@ -479,7 +484,7 @@ lock_test(const svn_test_opts_t *opts,
   apr_hash_t *lock_targets = apr_hash_make(pool);
   apr_hash_t *unlock_targets = apr_hash_make(pool);
   svn_revnum_t rev = 1;
-  svn_fs_lock_result_t *result;
+  struct lock_result_t *result;
   struct lock_baton_t baton;
   apr_hash_index_t *hi;
 

Modified: subversion/branches/remote-only-status/tools/server-side/fsfs-stats.c
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/tools/server-side/fsfs-stats.c?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/tools/server-side/fsfs-stats.c (original)
+++ subversion/branches/remote-only-status/tools/server-side/fsfs-stats.c Thu Apr  3 19:56:20 2014
@@ -1405,6 +1405,7 @@ read_log_rev_or_packfile(fs_t *fs,
   apr_off_t offset = 0;
   int i;
   svn_fs_fs__revision_file_t *rev_file;
+  fs_fs_data_t *ffd = fs->fs->fsap_data;
 
   /* we will process every revision in the rev / pack file */
   for (i = 0; i < count; ++i)
@@ -1437,7 +1438,8 @@ read_log_rev_or_packfile(fs_t *fs,
 
       /* get all entries for the current block */
       SVN_ERR(svn_fs_fs__p2l_index_lookup(&entries, fs->fs, rev_file, base,
-                                          offset, iterpool));
+                                          offset, ffd->p2l_page_size,
+                                          iterpool));
 
       /* process all entries (and later continue with the next block) */
       for (i = 0; i < entries->nelts; ++i)

Modified: subversion/branches/remote-only-status/tools/server-side/svnpubsub/rc.d/svnpubsub.freebsd
URL: http://svn.apache.org/viewvc/subversion/branches/remote-only-status/tools/server-side/svnpubsub/rc.d/svnpubsub.freebsd?rev=1584364&r1=1584363&r2=1584364&view=diff
==============================================================================
--- subversion/branches/remote-only-status/tools/server-side/svnpubsub/rc.d/svnpubsub.freebsd (original)
+++ subversion/branches/remote-only-status/tools/server-side/svnpubsub/rc.d/svnpubsub.freebsd Thu Apr  3 19:56:20 2014
@@ -26,7 +26,7 @@ pidfile="${svnpubsub_pidfile}"
 export PYTHON_EGG_CACHE="/home/svn/.python-eggs"
 
 command="/usr/local/bin/twistd"
-command_interpreter="/usr/local/bin/${svnwcsub_cmd_int}"
+command_interpreter="/usr/local/bin/${svnpubsub_cmd_int}"
 command_args="-y /usr/local/svnpubsub/svnpubsub.tac \
             --logfile=/var/log/vc/svnpubsub.log \
             --pidfile=${pidfile} \