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 2016/04/29 20:38:56 UTC

svn commit: r1741682 [14/26] - in /subversion/branches/authzperf: ./ build/ build/ac-macros/ build/generator/ contrib/server-side/svncutter/ notes/ notes/api-errata/1.9/ notes/move-tracking/ subversion/ subversion/bindings/ctypes-python/ subversion/bin...

Modified: subversion/branches/authzperf/subversion/libsvn_ra_svn/editorp.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_svn/editorp.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_ra_svn/editorp.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_ra_svn/editorp.c Fri Apr 29 18:38:53 2016
@@ -542,7 +542,7 @@ ra_svn_handle_target_rev(svn_ra_svn_conn
 {
   svn_revnum_t rev;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "r", &rev));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "r", &rev));
   SVN_CMD_ERR(ds->editor->set_target_revision(ds->edit_baton, rev, pool));
   return SVN_NO_ERROR;
 }
@@ -558,7 +558,7 @@ ra_svn_handle_open_root(svn_ra_svn_conn_
   svn_string_t *token;
   void *root_baton;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "(?r)s", &rev, &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "(?r)s", &rev, &token));
   subpool = svn_pool_create(ds->pool);
   SVN_CMD_ERR(ds->editor->open_root(ds->edit_baton, rev, subpool,
                                     &root_baton));
@@ -577,7 +577,7 @@ ra_svn_handle_delete_entry(svn_ra_svn_co
   svn_revnum_t rev;
   ra_svn_token_entry_t *entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "c(?r)s",
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "c(?r)s",
                                   &path, &rev, &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   path = svn_relpath_canonicalize(path, pool);
@@ -598,7 +598,7 @@ ra_svn_handle_add_dir(svn_ra_svn_conn_t
   apr_pool_t *subpool;
   void *child_baton;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?cr)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "css(?cr)", &path, &token,
                                   &child_token, &copy_path, &copy_rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   subpool = svn_pool_create(entry->pool);
@@ -633,7 +633,7 @@ ra_svn_handle_open_dir(svn_ra_svn_conn_t
   apr_pool_t *subpool;
   void *child_baton;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?r)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "css(?r)", &path, &token,
                                   &child_token, &rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   subpool = svn_pool_create(entry->pool);
@@ -655,7 +655,7 @@ ra_svn_handle_change_dir_prop(svn_ra_svn
   svn_string_t *value;
   ra_svn_token_entry_t *entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "sc(?s)", &token, &name,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "sc(?s)", &token, &name,
                                   &value));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   SVN_CMD_ERR(ds->editor->change_dir_prop(entry->baton, name, value,
@@ -673,7 +673,7 @@ ra_svn_handle_close_dir(svn_ra_svn_conn_
   ra_svn_token_entry_t *entry;
 
   /* Parse and look up the directory token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s", &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "s", &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
 
   /* Close the directory and destroy the baton. */
@@ -694,7 +694,7 @@ ra_svn_handle_absent_dir(svn_ra_svn_conn
   ra_svn_token_entry_t *entry;
 
   /* Parse parameters and look up the directory token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &path, &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "cs", &path, &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
 
   /* Call the editor. */
@@ -713,7 +713,7 @@ ra_svn_handle_add_file(svn_ra_svn_conn_t
   svn_revnum_t copy_rev;
   ra_svn_token_entry_t *entry, *file_entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?cr)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "css(?cr)", &path, &token,
                                   &file_token, &copy_path, &copy_rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   ds->file_refs++;
@@ -749,7 +749,7 @@ ra_svn_handle_open_file(svn_ra_svn_conn_
   svn_revnum_t rev;
   ra_svn_token_entry_t *entry, *file_entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "css(?r)", &path, &token,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "css(?r)", &path, &token,
                                   &file_token, &rev));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
   ds->file_refs++;
@@ -777,7 +777,7 @@ ra_svn_handle_apply_textdelta(svn_ra_svn
   char *base_checksum;
 
   /* Parse arguments and look up the token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s(?c)",
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "s(?c)",
                                   &token, &base_checksum));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   if (entry->dstream)
@@ -801,7 +801,7 @@ ra_svn_handle_textdelta_chunk(svn_ra_svn
   svn_string_t *str;
 
   /* Parse arguments and look up the token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "ss", &token, &str));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "ss", &token, &str));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   if (!entry->dstream)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -820,7 +820,7 @@ ra_svn_handle_textdelta_end(svn_ra_svn_c
   ra_svn_token_entry_t *entry;
 
   /* Parse arguments and look up the token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s", &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "s", &token));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   if (!entry->dstream)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -841,7 +841,7 @@ ra_svn_handle_change_file_prop(svn_ra_sv
   svn_string_t *token, *value;
   ra_svn_token_entry_t *entry;
 
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "sc(?s)", &token, &name,
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "sc(?s)", &token, &name,
                                   &value));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
   SVN_CMD_ERR(ds->editor->change_file_prop(entry->baton, name, value, pool));
@@ -859,7 +859,7 @@ ra_svn_handle_close_file(svn_ra_svn_conn
   const char *text_checksum;
 
   /* Parse arguments and look up the file token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "s(?c)",
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "s(?c)",
                                   &token, &text_checksum));
   SVN_ERR(lookup_token(ds, token, TRUE, &entry));
 
@@ -882,7 +882,7 @@ ra_svn_handle_absent_file(svn_ra_svn_con
   ra_svn_token_entry_t *entry;
 
   /* Parse parameters and look up the parent directory token. */
-  SVN_ERR(svn_ra_svn__parse_tuple(params, pool, "cs", &path, &token));
+  SVN_ERR(svn_ra_svn__parse_tuple(params, "cs", &path, &token));
   SVN_ERR(lookup_token(ds, token, FALSE, &entry));
 
   /* Call the editor. */
@@ -1106,6 +1106,10 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
   while (!state.done)
     {
       svn_pool_clear(subpool);
+
+      /* WRT to applying I/O limits, treat each editor command as a separate
+       * protocol command. */
+      svn_ra_svn__reset_command_io_counters(conn);
       if (editor)
         {
           cmd_handler_t handler;
@@ -1121,7 +1125,7 @@ svn_error_t *svn_ra_svn_drive_editor2(sv
                 command */
               if (aborted)
                 *aborted = TRUE;
-              err = svn_ra_svn__handle_failure_status(params, pool);
+              err = svn_ra_svn__handle_failure_status(params);
               return svn_error_compose_create(
                                 err,
                                 editor->abort_edit(edit_baton, subpool));

Modified: subversion/branches/authzperf/subversion/libsvn_ra_svn/internal_auth.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_svn/internal_auth.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_ra_svn/internal_auth.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_ra_svn/internal_auth.c Fri Apr 29 18:38:53 2016
@@ -46,7 +46,7 @@ svn_boolean_t svn_ra_svn__find_mech(cons
   for (i = 0; i < mechlist->nelts; i++)
     {
       elt = &SVN_RA_SVN__LIST_ITEM(mechlist, i);
-      if (elt->kind == SVN_RA_SVN_WORD && strcmp(elt->u.word, mech) == 0)
+      if (elt->kind == SVN_RA_SVN_WORD && strcmp(elt->u.word.data, mech) == 0)
         return TRUE;
     }
   return FALSE;

Modified: subversion/branches/authzperf/subversion/libsvn_ra_svn/marshal.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_svn/marshal.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_ra_svn/marshal.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_ra_svn/marshal.c Fri Apr 29 18:38:53 2016
@@ -72,6 +72,10 @@
  */
 #define ITEM_NESTING_LIMIT 64
 
+/* The protocol words for booleans. */
+static const svn_string_t str_true = SVN__STATIC_STRING("true");
+static const svn_string_t str_false = SVN__STATIC_STRING("false");
+
 /* Return the APR socket timeout to be used for the connection depending
  * on whether there is a blockage handler or zero copy has been activated. */
 static apr_interval_time_t
@@ -97,7 +101,7 @@ svn_ra_svn__to_public_item(svn_ra_svn_it
         target->u.number = source->u.number;
         break;
       case SVN_RA_SVN_WORD:
-        target->u.word = source->u.word;
+        target->u.word = source->u.word.data;
         break;
       case SVN_RA_SVN_LIST:
         target->u.list = svn_ra_svn__to_public_array(&source->u.list,
@@ -140,7 +144,8 @@ svn_ra_svn__to_private_item(svn_ra_svn__
         target->u.number = source->u.number;
         break;
       case SVN_RA_SVN_WORD:
-        target->u.word = source->u.word;
+        target->u.word.data = source->u.word;
+        target->u.word.len = strlen(source->u.word);
         break;
       case SVN_RA_SVN_LIST:
         target->u.list = *svn_ra_svn__to_private_array(source->u.list,
@@ -174,12 +179,14 @@ svn_ra_svn__to_private_array(const apr_a
 
 /* --- CONNECTION INITIALIZATION --- */
 
-svn_ra_svn_conn_t *svn_ra_svn_create_conn4(apr_socket_t *sock,
+svn_ra_svn_conn_t *svn_ra_svn_create_conn5(apr_socket_t *sock,
                                            svn_stream_t *in_stream,
                                            svn_stream_t *out_stream,
                                            int compression_level,
                                            apr_size_t zero_copy_limit,
                                            apr_size_t error_check_interval,
+                                           apr_uint64_t max_in,
+                                           apr_uint64_t max_out,
                                            apr_pool_t *result_pool)
 {
   svn_ra_svn_conn_t *conn;
@@ -199,6 +206,10 @@ svn_ra_svn_conn_t *svn_ra_svn_create_con
   conn->written_since_error_check = 0;
   conn->error_check_interval = error_check_interval;
   conn->may_check_for_error = error_check_interval == 0;
+  conn->max_in = max_in;
+  conn->current_in = 0;
+  conn->max_out = max_out;
+  conn->current_out = 0;
   conn->block_handler = NULL;
   conn->block_baton = NULL;
   conn->capabilities = apr_hash_make(result_pool);
@@ -248,8 +259,8 @@ svn_ra_svn__set_capabilities(svn_ra_svn_
       if (item->kind != SVN_RA_SVN_WORD)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Capability entry is not a word"));
-      word = apr_pstrdup(conn->pool, item->u.word);
-      svn_hash_sets(conn->capabilities, word, word);
+      word = apr_pstrmemdup(conn->pool, item->u.word.data, item->u.word.len);
+      apr_hash_set(conn->capabilities, word, item->u.word.len, word);
     }
   return SVN_NO_ERROR;
 }
@@ -307,8 +318,33 @@ svn_error_t *svn_ra_svn__data_available(
   return svn_ra_svn__stream_data_available(conn->stream, data_available);
 }
 
+void
+svn_ra_svn__reset_command_io_counters(svn_ra_svn_conn_t *conn)
+{
+  conn->current_in = 0;
+  conn->current_out = 0;
+}
+
+
 /* --- WRITE BUFFER MANAGEMENT --- */
 
+/* Return an error object if CONN exceeded its send or receive limits. */
+static svn_error_t *
+check_io_limits(svn_ra_svn_conn_t *conn)
+{
+  if (conn->max_in && (conn->current_in > conn->max_in))
+    return svn_error_create(SVN_ERR_RA_SVN_REQUEST_SIZE, NULL,
+                            "The client request size exceeds the "
+                            "configured limit");
+
+  if (conn->max_out && (conn->current_out > conn->max_out))
+    return svn_error_create(SVN_ERR_RA_SVN_RESPONSE_SIZE, NULL,
+                            "The server response size exceeds the "
+                            "configured limit");
+
+  return SVN_NO_ERROR;
+}
+
 /* Write data to socket or output file as appropriate. */
 static svn_error_t *writebuf_output(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                     const char *data, apr_size_t len)
@@ -318,6 +354,12 @@ static svn_error_t *writebuf_output(svn_
   apr_pool_t *subpool = NULL;
   svn_ra_svn__session_baton_t *session = conn->session;
 
+  /* Limit the size of the response, if a limit has been configured.
+   * This is to limit the server load in case users e.g. accidentally ran
+   * an export on the root folder. */
+  conn->current_out += len;
+  SVN_ERR(check_io_limits(conn));
+
   while (data < end)
     {
       count = end - data;
@@ -436,12 +478,19 @@ static svn_error_t *readbuf_input(svn_ra
 {
   svn_ra_svn__session_baton_t *session = conn->session;
 
+  /* First, give the user a chance to cancel the request before we do. */
   if (session && session->callbacks && session->callbacks->cancel_func)
     SVN_ERR((session->callbacks->cancel_func)(session->callbacks_baton));
 
+  /* Limit our memory usage, if a limit has been configured.  Note that
+   * we first read the whole request into memory before process it. */
+  SVN_ERR(check_io_limits(conn));
+
+  /* Actually fill the buffer. */
   SVN_ERR(svn_ra_svn__stream_read(conn->stream, data, len));
   if (*len == 0)
     return svn_error_create(SVN_ERR_RA_SVN_CONNECTION_CLOSED, NULL, NULL);
+  conn->current_in += *len;
 
   if (session)
     {
@@ -487,9 +536,13 @@ static svn_error_t *readbuf_fill(svn_ra_
   apr_size_t len;
 
   SVN_ERR_ASSERT(conn->read_ptr == conn->read_end);
+
+  /* Make sure we tell the other side everything we have to say before
+   * reading / waiting for an answer. */
   if (conn->write_pos)
     SVN_ERR(writebuf_flush(conn, pool));
 
+  /* Fill (some of the) buffer. */
   len = sizeof(conn->read_buf);
   SVN_ERR(readbuf_input(conn, conn->read_buf, &len, pool));
   conn->read_ptr = conn->read_buf;
@@ -655,11 +708,15 @@ svn_ra_svn__write_ncstring(svn_ra_svn_co
                            const char *s,
                            apr_size_t len)
 {
-  apr_size_t needed = SVN_INT64_BUFFER_SIZE + len + 1;
+  /* Apart from LEN bytes of string contents, we need room for a number,
+     a colon and a space. */
+  apr_size_t max_fill = sizeof(conn->write_buf) - SVN_INT64_BUFFER_SIZE - 2;
 
   /* In most cases, there is enough left room in the WRITE_BUF
-     the we can serialize directly into it. */
-  if (conn->write_pos + needed < sizeof(conn->write_buf))
+     the we can serialize directly into it.  On platforms with
+     segmented memory, LEN might actually be close to APR_SIZE_MAX.
+     Blindly doing arithmetic on it might cause an overflow. */
+  if ((len <= max_fill) && (conn->write_pos <= max_fill - len))
     {
       /* Quick path. */
       conn->write_pos = write_ncstring_quick(conn->write_buf
@@ -907,20 +964,23 @@ write_tuple_string_opt_list(svn_ra_svn_c
                             apr_pool_t *pool,
                             const svn_string_t *str)
 {
-  apr_size_t needed;
+  apr_size_t max_fill;
 
   /* Special case. */
   if (!str)
     return writebuf_write(conn, pool, "( ) ", 4);
 
-  /* If there is at least this much the room left in the WRITE_BUF,
-     we can serialize directly into it. */
-  needed = 2                       /* open list */
-         + SVN_INT64_BUFFER_SIZE   /* string length + separator */
-         + str->len                /* string contents */
-         + 2;                      /* close list */
-
-  if (conn->write_pos + needed <= sizeof(conn->write_buf))
+  /* If this how far we can fill the WRITE_BUF with string data and still
+     guarantee that the length info will fit in as well. */
+  max_fill = sizeof(conn->write_buf)
+           - 2                       /* open list */
+           - SVN_INT64_BUFFER_SIZE   /* string length + separator */
+           - 2;                      /* close list */
+
+   /* On platforms with segmented memory, STR->LEN might actually be
+      close to APR_SIZE_MAX.  Blindly doing arithmetic on it might
+      cause an overflow. */
+  if ((str->len <= max_fill) && (conn->write_pos <= max_fill - str->len))
     {
       /* Quick path. */
       /* Open list. */
@@ -1134,15 +1194,17 @@ static svn_error_t *read_string(svn_ra_s
   apr_size_t len = (apr_size_t)len64;
   apr_size_t readbuf_len;
   char *dest;
+  apr_size_t buflen;
 
   /* We can't store strings longer than the maximum size of apr_size_t,
-   * so check for wrapping */
+   * so check before using the truncated value. */
   if (len64 > APR_SIZE_MAX)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("String length larger than maximum"));
 
+  buflen = conn->read_end - conn->read_ptr;
   /* Shorter strings can be copied directly from the read buffer. */
-  if (conn->read_ptr + len <= conn->read_end)
+  if (len <= buflen)
     {
       item->kind = SVN_RA_SVN_STRING;
       item->u.string.data = apr_pstrmemdup(pool, conn->read_ptr, len);
@@ -1151,6 +1213,16 @@ static svn_error_t *read_string(svn_ra_s
     }
   else
     {
+      svn_stringbuf_t *stringbuf;
+
+      /* Don't even attempt to read anything that exceeds the I/O limit.
+       * So, we can terminate the transfer at an early point, saving
+       * everybody's time and resources. */
+      if (conn->max_in && (conn->max_in < len64))
+        return svn_error_create(SVN_ERR_RA_SVN_REQUEST_SIZE, NULL,
+                                "The client request size exceeds the "
+                                "configured limit");
+
       /* Read the string in chunks.  The chunk size is large enough to avoid
        * re-allocation in typical cases, and small enough to ensure we do
        * not pre-allocate an unreasonable amount of memory if (perhaps due
@@ -1159,7 +1231,7 @@ static svn_error_t *read_string(svn_ra_s
        * start small and wait for all that data to actually show up.  This
        * does not fully prevent DOS attacks but makes them harder (you have
        * to actually send gigabytes of data). */
-      svn_stringbuf_t *stringbuf = svn_stringbuf_create_empty(pool);
+      stringbuf = svn_stringbuf_create_empty(pool);
 
       /* Read string data directly into the string structure.
        * Do it iteratively.  */
@@ -1289,8 +1361,10 @@ static svn_error_t *read_item(svn_ra_svn
       c = *p;
       *p = '\0';
 
+      /* Store the word in ITEM. */
       item->kind = SVN_RA_SVN_WORD;
-      item->u.word = buffer;
+      item->u.word.data = buffer;
+      item->u.word.len = p - buffer;
     }
   else if (c == '(')
     {
@@ -1507,7 +1581,6 @@ svn_ra_svn__skip_leading_garbage(svn_ra_
  * tuple specification and advance AP by the corresponding arguments. */
 static svn_error_t *
 vparse_tuple(const svn_ra_svn__list_t *items,
-             apr_pool_t *pool,
              const char **fmt,
              va_list *ap)
 {
@@ -1523,19 +1596,19 @@ vparse_tuple(const svn_ra_svn__list_t *i
       if (**fmt == '(' && elt->kind == SVN_RA_SVN_LIST)
         {
           (*fmt)++;
-          SVN_ERR(vparse_tuple(&elt->u.list, pool, fmt, ap));
+          SVN_ERR(vparse_tuple(&elt->u.list, fmt, ap));
         }
       else if (**fmt == 'c' && elt->kind == SVN_RA_SVN_STRING)
         *va_arg(*ap, const char **) = elt->u.string.data;
       else if (**fmt == 's' && elt->kind == SVN_RA_SVN_STRING)
         *va_arg(*ap, svn_string_t **) = &elt->u.string;
       else if (**fmt == 'w' && elt->kind == SVN_RA_SVN_WORD)
-        *va_arg(*ap, const char **) = elt->u.word;
+        *va_arg(*ap, const char **) = elt->u.word.data;
       else if (**fmt == 'b' && elt->kind == SVN_RA_SVN_WORD)
         {
-          if (strcmp(elt->u.word, "true") == 0)
+          if (svn_string_compare(&elt->u.word, &str_true))
             *va_arg(*ap, svn_boolean_t *) = TRUE;
-          else if (strcmp(elt->u.word, "false") == 0)
+          else if (svn_string_compare(&elt->u.word, &str_false))
             *va_arg(*ap, svn_boolean_t *) = FALSE;
           else
             break;
@@ -1546,18 +1619,18 @@ vparse_tuple(const svn_ra_svn__list_t *i
         *va_arg(*ap, svn_revnum_t *) = (svn_revnum_t) elt->u.number;
       else if (**fmt == 'B' && elt->kind == SVN_RA_SVN_WORD)
         {
-          if (strcmp(elt->u.word, "true") == 0)
+          if (svn_string_compare(&elt->u.word, &str_true))
             *va_arg(*ap, apr_uint64_t *) = TRUE;
-          else if (strcmp(elt->u.word, "false") == 0)
+          else if (svn_string_compare(&elt->u.word, &str_false))
             *va_arg(*ap, apr_uint64_t *) = FALSE;
           else
             break;
         }
       else if (**fmt == '3' && elt->kind == SVN_RA_SVN_WORD)
         {
-          if (strcmp(elt->u.word, "true") == 0)
+          if (svn_string_compare(&elt->u.word, &str_true))
             *va_arg(*ap, svn_tristate_t *) = svn_tristate_true;
-          else if (strcmp(elt->u.word, "false") == 0)
+          else if (svn_string_compare(&elt->u.word, &str_false))
             *va_arg(*ap, svn_tristate_t *) = svn_tristate_false;
           else
             break;
@@ -1618,14 +1691,13 @@ vparse_tuple(const svn_ra_svn__list_t *i
 
 svn_error_t *
 svn_ra_svn__parse_tuple(const svn_ra_svn__list_t *list,
-                        apr_pool_t *pool,
                         const char *fmt, ...)
 {
   svn_error_t *err;
   va_list ap;
 
   va_start(ap, fmt);
-  err = vparse_tuple(list, pool, &fmt, &ap);
+  err = vparse_tuple(list, &fmt, &ap);
   va_end(ap);
   return err;
 }
@@ -1644,7 +1716,7 @@ svn_ra_svn__read_tuple(svn_ra_svn_conn_t
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                             _("Malformed network data"));
   va_start(ap, fmt);
-  err = vparse_tuple(&item->u.list, pool, &fmt, &ap);
+  err = vparse_tuple(&item->u.list, &fmt, &ap);
   va_end(ap);
   return err;
 }
@@ -1679,8 +1751,7 @@ svn_ra_svn__parse_proplist(const svn_ra_
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Proplist element not a list"));
-      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, pool, "ss",
-                                      &name, &value));
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, "ss", &name, &value));
       apr_hash_set(*props, name->data, name->len, value);
     }
 
@@ -1706,15 +1777,13 @@ svn_error_t *svn_ra_svn__locate_real_err
 }
 
 svn_error_t *
-svn_ra_svn__handle_failure_status(const svn_ra_svn__list_t *params,
-                                  apr_pool_t *pool)
+svn_ra_svn__handle_failure_status(const svn_ra_svn__list_t *params)
 {
   const char *message, *file;
   svn_error_t *err = NULL;
   svn_ra_svn__item_t *elt;
   int i;
   apr_uint64_t apr_err, line;
-  apr_pool_t *subpool = svn_pool_create(pool);
 
   if (params->nelts == 0)
     return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -1723,12 +1792,11 @@ svn_ra_svn__handle_failure_status(const
   /* Rebuild the error list from the end, to avoid reversing the order. */
   for (i = params->nelts - 1; i >= 0; i--)
     {
-      svn_pool_clear(subpool);
       elt = &SVN_RA_SVN__LIST_ITEM(params, i);
       if (elt->kind != SVN_RA_SVN_LIST)
         return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
                                 _("Malformed error list"));
-      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, subpool, "nccn",
+      SVN_ERR(svn_ra_svn__parse_tuple(&elt->u.list, "nccn",
                                       &apr_err, &message, &file, &line));
       /* The message field should have been optional, but we can't
          easily change that, so "" means a nonexistent message. */
@@ -1747,8 +1815,6 @@ svn_ra_svn__handle_failure_status(const
         }
     }
 
-  svn_pool_destroy(subpool);
-
   /* If we get here, then we failed to find a real error in the error
      chain that the server proported to be sending us.  That's bad. */
   if (! err)
@@ -1772,13 +1838,13 @@ svn_ra_svn__read_cmd_response(svn_ra_svn
   if (strcmp(status, "success") == 0)
     {
       va_start(ap, fmt);
-      err = vparse_tuple(params, pool, &fmt, &ap);
+      err = vparse_tuple(params, &fmt, &ap);
       va_end(ap);
       return err;
     }
   else if (strcmp(status, "failure") == 0)
     {
-      return svn_error_trace(svn_ra_svn__handle_failure_status(params, pool));
+      return svn_error_trace(svn_ra_svn__handle_failure_status(params));
     }
 
   return svn_error_createf(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,
@@ -1792,7 +1858,12 @@ svn_ra_svn__has_command(svn_boolean_t *h
                         svn_ra_svn_conn_t *conn,
                         apr_pool_t *pool)
 {
-  svn_error_t *err = svn_ra_svn__has_item(has_command, conn, pool);
+  svn_error_t *err;
+
+  /* Don't make whitespace between commands trigger I/O limitiations. */
+  svn_ra_svn__reset_command_io_counters(conn);
+
+  err = svn_ra_svn__has_item(has_command, conn, pool);
   if (err && err->apr_err == SVN_ERR_RA_SVN_CONNECTION_CLOSED)
     {
       *terminated = TRUE;
@@ -1818,6 +1889,10 @@ svn_ra_svn__handle_command(svn_boolean_t
   const svn_ra_svn__cmd_entry_t *command;
 
   *terminate = FALSE;
+
+  /* Limit I/O for every command separately. */
+  svn_ra_svn__reset_command_io_counters(conn);
+
   err = svn_ra_svn__read_tuple(conn, pool, "wl", &cmdname, &params);
   if (err)
     {
@@ -1849,6 +1924,13 @@ svn_ra_svn__handle_command(svn_boolean_t
                                                baton);
         }
 
+      /* The command implementation may have swallowed or wrapped the I/O
+       * error not knowing that we may no longer be able to send data.
+       *
+       * So, check again for the limit violations and exit the command
+       * processing quickly if we may have truncated data. */
+      err = svn_error_compose_create(check_io_limits(conn), err);
+
       *terminate = command->terminate;
     }
   else
@@ -2687,19 +2769,19 @@ changed_path_flags(svn_node_kind_t node_
                    svn_boolean_t text_modified,
                    svn_boolean_t props_modified)
 {
-  const static svn_string_t file_flags[4]
+  static const svn_string_t file_flags[4]
     = { STATIC_SVN_STRING(" ) ( 4:file false false ) ) "),
         STATIC_SVN_STRING(" ) ( 4:file false true ) ) "),
         STATIC_SVN_STRING(" ) ( 4:file true false ) ) "),
         STATIC_SVN_STRING(" ) ( 4:file true true ) ) ") };
 
-  const static svn_string_t dir_flags[4]
+  static const svn_string_t dir_flags[4]
     = { STATIC_SVN_STRING(" ) ( 3:dir false false ) ) "),
         STATIC_SVN_STRING(" ) ( 3:dir false true ) ) "),
         STATIC_SVN_STRING(" ) ( 3:dir true false ) ) "),
         STATIC_SVN_STRING(" ) ( 3:dir true true ) ) ") };
 
-  const static svn_string_t no_flags = STATIC_SVN_STRING("");
+  static const svn_string_t no_flags = STATIC_SVN_STRING("");
 
   /* Select the array based on the NODE_KIND. */
   const svn_string_t *flags;
@@ -2722,7 +2804,7 @@ changed_path_flags(svn_node_kind_t node_
 svn_error_t *
 svn_ra_svn__write_data_log_changed_path(svn_ra_svn_conn_t *conn,
                                         apr_pool_t *pool,
-                                        const char *path,
+                                        const svn_string_t *path,
                                         char action,
                                         const char *copyfrom_path,
                                         svn_revnum_t copyfrom_rev,
@@ -2730,25 +2812,31 @@ svn_ra_svn__write_data_log_changed_path(
                                         svn_boolean_t text_modified,
                                         svn_boolean_t props_modified)
 {
-  apr_size_t path_len = strlen(path);
+  apr_size_t path_len = path->len;
   apr_size_t copyfrom_len = copyfrom_path ? strlen(copyfrom_path) : 0;
   const svn_string_t *flags_str = changed_path_flags(node_kind,
                                                      text_modified,
                                                      props_modified);
+  apr_size_t flags_len = flags_str->len;
 
-  /* How much buffer space do we need (worst case)? */
-  apr_size_t needed = 2                 /* list start */
-                    + path_len + SVN_INT64_BUFFER_SIZE
-                                        /* path */
-                    + 2                 /* action */
-                    + 2 + copyfrom_len + 2 * SVN_INT64_BUFFER_SIZE
-                                        /* list start + copy-from info */
-                    + flags_str->len;   /* flags and closing lists */
+  /* How much buffer space can we use for non-string data (worst case)? */
+  apr_size_t max_fill = sizeof(conn->write_buf)
+                      - 2                          /* list start */
+                      - 2 - SVN_INT64_BUFFER_SIZE  /* path */
+                      - 2                          /* action */
+                      - 2                          /* list start */
+                      - 2 - SVN_INT64_BUFFER_SIZE  /* copy-from path */
+                      - 1 - SVN_INT64_BUFFER_SIZE; /* copy-from rev */
 
   /* If the remaining buffer is big enough and we've got all parts,
-     directly copy into the buffer. */
-  if (   (conn->write_pos + needed <= sizeof(conn->write_buf))
-      && (flags_str->len > 0))
+     directly copy into the buffer.   On platforms with segmented memory,
+     PATH_LEN + COPYFROM_LEN might actually be close to APR_SIZE_MAX.
+     Blindly doing arithmetic on them might cause an overflow.
+     The sum in here cannot overflow because WRITE_BUF is small, i.e.
+     MAX_FILL and WRITE_POS are much smaller than APR_SIZE_MAX. */
+  if (   (path_len <= max_fill) && (copyfrom_len <= max_fill)
+      && (conn->write_pos + path_len + copyfrom_len + flags_len <= max_fill)
+      && (flags_len > 0))
     {
       /* Quick path. */
       /* Open list. */
@@ -2757,7 +2845,7 @@ svn_ra_svn__write_data_log_changed_path(
       p[1] = ' ';
 
       /* Write path. */
-      p = write_ncstring_quick(p + 2, path, path_len);
+      p = write_ncstring_quick(p + 2, path->data, path_len);
 
       /* Action */
       p[0] = action;
@@ -2785,7 +2873,7 @@ svn_ra_svn__write_data_log_changed_path(
       /* Standard code path (fallback). */
       SVN_ERR(write_tuple_start_list(conn, pool));
 
-      SVN_ERR(svn_ra_svn__write_ncstring(conn, pool, path, path_len));
+      SVN_ERR(svn_ra_svn__write_ncstring(conn, pool, path->data, path_len));
       SVN_ERR(writebuf_writechar(conn, pool, action));
       SVN_ERR(writebuf_writechar(conn, pool, ' '));
       SVN_ERR(write_tuple_start_list(conn, pool));
@@ -2869,7 +2957,7 @@ svn_ra_svn__read_word(const svn_ra_svn__
 {
   svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(items, idx);
   CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
-  *result = elt->u.word;
+  *result = elt->u.word.data;
 
   return SVN_NO_ERROR;
 }
@@ -2897,9 +2985,9 @@ svn_ra_svn__read_boolean(const svn_ra_sv
 {
   svn_ra_svn__item_t *elt = &SVN_RA_SVN__LIST_ITEM(items, idx);
   CHECK_PROTOCOL_COND(elt->kind == SVN_RA_SVN_WORD);
-  if (elt->u.word[0] == 't' && strcmp(elt->u.word, "true") == 0)
+  if (svn_string_compare(&elt->u.word, &str_true))
     *result = TRUE;
-  else if (strcmp(elt->u.word, "false") == 0)
+  else if (svn_string_compare(&elt->u.word, &str_false))
     *result = FALSE;
   else
     CHECK_PROTOCOL_COND(FALSE);

Modified: subversion/branches/authzperf/subversion/libsvn_ra_svn/ra_svn.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_ra_svn/ra_svn.h?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_ra_svn/ra_svn.h (original)
+++ subversion/branches/authzperf/subversion/libsvn_ra_svn/ra_svn.h Fri Apr 29 18:38:53 2016
@@ -96,6 +96,12 @@ struct svn_ra_svn_conn_st {
   apr_size_t error_check_interval;
   svn_boolean_t may_check_for_error;
 
+  /* I/O limits and tracking */
+  apr_uint64_t max_in;
+  apr_uint64_t current_in;
+  apr_uint64_t max_out;
+  apr_uint64_t current_out;
+
   /* repository info */
   const char *uuid;
   const char *repos_root;
@@ -151,6 +157,12 @@ void svn_ra_svn__set_block_handler(svn_r
 svn_error_t *svn_ra_svn__data_available(svn_ra_svn_conn_t *conn,
                                        svn_boolean_t *data_available);
 
+/* Signal a new request / response pair on CONN.  That resets the I/O
+ * counters we use to limit the size of individual requests / response pairs.
+ */
+void
+svn_ra_svn__reset_command_io_counters(svn_ra_svn_conn_t *conn);
+
 /* CRAM-MD5 client implementation. */
 svn_error_t *svn_ra_svn__cram_client(svn_ra_svn_conn_t *conn, apr_pool_t *pool,
                                      const char *user, const char *password,
@@ -163,11 +175,9 @@ svn_error_t *svn_ra_svn__locate_real_err
 
 /* Return an error chain based on @a params (which contains a
  * command response indicating failure).  The error chain will be
- * in the same order as the errors indicated in @a params.  Use
- * @a pool for temporary allocations. */
+ * in the same order as the errors indicated in @a params. */
 svn_error_t *
-svn_ra_svn__handle_failure_status(const svn_ra_svn__list_t *params,
-                                  apr_pool_t *pool);
+svn_ra_svn__handle_failure_status(const svn_ra_svn__list_t *params);
 
 /* Returns a stream that reads/writes from/to SOCK. */
 svn_ra_svn__stream_t *svn_ra_svn__stream_from_sock(apr_socket_t *sock,

Modified: subversion/branches/authzperf/subversion/libsvn_repos/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/commit.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_repos/commit.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_repos/commit.c Fri Apr 29 18:38:53 2016
@@ -210,15 +210,16 @@ invoke_commit_cb(svn_commit_callback2_t
   /* const */ svn_string_t *date;
   /* const */ svn_string_t *author;
   svn_commit_info_t *commit_info;
+  apr_hash_t *revprops;
 
   if (commit_cb == NULL)
     return SVN_NO_ERROR;
 
-  SVN_ERR(svn_fs_revision_prop(&date, fs, revision, SVN_PROP_REVISION_DATE,
-                               scratch_pool));
-  SVN_ERR(svn_fs_revision_prop(&author, fs, revision,
-                               SVN_PROP_REVISION_AUTHOR,
-                               scratch_pool));
+  SVN_ERR(svn_fs_revision_proplist2(&revprops, fs, revision,
+                                    TRUE, scratch_pool, scratch_pool));
+
+  date = svn_hash_gets(revprops, SVN_PROP_REVISION_DATE);
+  author = svn_hash_gets(revprops, SVN_PROP_REVISION_AUTHOR);
 
   commit_info = svn_create_commit_info(scratch_pool);
 
@@ -324,7 +325,6 @@ add_file_or_directory(const char *path,
       const char *fs_path;
       svn_fs_root_t *copy_root;
       svn_node_kind_t kind;
-      size_t repos_url_len;
       svn_repos_authz_access_t required;
 
       /* Copy requires recursive write access to the destination path
@@ -346,14 +346,12 @@ add_file_or_directory(const char *path,
       /* For now, require that the url come from the same repository
          that this commit is operating on. */
       copy_path = svn_path_uri_decode(copy_path, subpool);
-      repos_url_len = strlen(eb->repos_url_decoded);
-      if (strncmp(copy_path, eb->repos_url_decoded, repos_url_len) != 0)
+      fs_path = svn_cstring_skip_prefix(copy_path, eb->repos_url_decoded);
+      if (!fs_path)
         return svn_error_createf
           (SVN_ERR_FS_GENERAL, NULL,
            _("Source url '%s' is from different repository"), copy_path);
 
-      fs_path = apr_pstrdup(subpool, copy_path + repos_url_len);
-
       /* Now use the "fs_path" as an absolute path within the
          repository to make the copy from. */
       SVN_ERR(svn_fs_revision_root(&copy_root, eb->fs,

Modified: subversion/branches/authzperf/subversion/libsvn_repos/delta.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/delta.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_repos/delta.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_repos/delta.c Fri Apr 29 18:38:53 2016
@@ -266,6 +266,13 @@ svn_repos_dir_delta2(svn_fs_root_t *src_
        _("Invalid editor anchoring; at least one of the "
          "input paths is not a directory and there was no source entry"));
 
+  /* Don't report / compare stale revprops.  However, revprop changes that
+   * are made by a 3rd party outside this delta operation, may not be
+   * detected as per our visibility guarantees.  Reset the revprop caches
+   * for both roots in case they belong to different svn_fs_t instances. */
+  SVN_ERR(svn_fs_refresh_revision_props(svn_fs_root_fs(tgt_root), pool));
+  SVN_ERR(svn_fs_refresh_revision_props(svn_fs_root_fs(src_root), pool));
+
   /* Set the global target revision if one can be determined. */
   if (svn_fs_is_revision_root(tgt_root))
     {
@@ -491,8 +498,8 @@ delta_proplists(struct context *c,
           SVN_ERR(change_fn(c, object, SVN_PROP_ENTRY_COMMITTED_REV,
                             cr_str, subpool));
 
-          SVN_ERR(svn_fs_revision_proplist(&r_props, fs, committed_rev,
-                                           pool));
+          SVN_ERR(svn_fs_revision_proplist2(&r_props, fs, committed_rev,
+                                            FALSE, pool, subpool));
 
           /* Transmit the committed-date. */
           committed_date = svn_hash_gets(r_props, SVN_PROP_REVISION_DATE);
@@ -596,19 +603,6 @@ send_text_delta(struct context *c,
     }
 }
 
-svn_error_t *
-svn_repos__compare_files(svn_boolean_t *changed_p,
-                         svn_fs_root_t *root1,
-                         const char *path1,
-                         svn_fs_root_t *root2,
-                         const char *path2,
-                         apr_pool_t *pool)
-{
-  return svn_error_trace(svn_fs_contents_different(changed_p, root1, path1,
-                                                   root2, path2, pool));
-}
-
-
 /* Make the appropriate edits on FILE_BATON to change its contents and
    properties from those in SOURCE_PATH to those in TARGET_PATH. */
 static svn_error_t *

Modified: subversion/branches/authzperf/subversion/libsvn_repos/dump.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/dump.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_repos/dump.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_repos/dump.c Fri Apr 29 18:38:53 2016
@@ -326,7 +326,7 @@ store_delta(apr_file_t **tempfile, svn_f
             svn_fs_root_t *newroot, const char *newpath, apr_pool_t *pool)
 {
   svn_stream_t *temp_stream;
-  apr_off_t offset = 0;
+  apr_off_t offset;
   svn_txdelta_stream_t *delta_stream;
   svn_txdelta_window_handler_t wh;
   void *whb;
@@ -346,7 +346,7 @@ store_delta(apr_file_t **tempfile, svn_f
   SVN_ERR(svn_txdelta_send_txstream(delta_stream, wh, whb, pool));
 
   /* Get the length of the temporary file and rewind it. */
-  SVN_ERR(svn_io_file_seek(*tempfile, APR_CUR, &offset, pool));
+  SVN_ERR(svn_io_file_get_offset(&offset, *tempfile, pool));
   *len = offset;
   offset = 0;
   return svn_io_file_seek(*tempfile, APR_SET, &offset, pool);
@@ -1164,13 +1164,13 @@ dump_node(struct edit_baton *eb,
                                    svn_fs_root_fs(eb->fs_root),
                                    compare_rev, pool));
 
-      SVN_ERR(svn_fs_props_different(&must_dump_props,
-                                     compare_root, compare_path,
-                                     eb->fs_root, path, pool));
+      SVN_ERR(svn_fs_props_changed(&must_dump_props,
+                                   compare_root, compare_path,
+                                   eb->fs_root, path, pool));
       if (kind == svn_node_file)
-        SVN_ERR(svn_fs_contents_different(&must_dump_text,
-                                          compare_root, compare_path,
-                                          eb->fs_root, path, pool));
+        SVN_ERR(svn_fs_contents_changed(&must_dump_text,
+                                        compare_root, compare_path,
+                                        eb->fs_root, path, pool));
       break;
 
     case svn_node_action_delete:
@@ -1293,16 +1293,16 @@ dump_node(struct edit_baton *eb,
 
           /* Need to decide if the copied node had any extra textual or
              property mods as well.  */
-          SVN_ERR(svn_fs_props_different(&must_dump_props,
-                                         compare_root, compare_path,
-                                         eb->fs_root, path, pool));
+          SVN_ERR(svn_fs_props_changed(&must_dump_props,
+                                       compare_root, compare_path,
+                                       eb->fs_root, path, pool));
           if (kind == svn_node_file)
             {
               svn_checksum_t *checksum;
               const char *hex_digest;
-              SVN_ERR(svn_fs_contents_different(&must_dump_text,
-                                                compare_root, compare_path,
-                                                eb->fs_root, path, pool));
+              SVN_ERR(svn_fs_contents_changed(&must_dump_text,
+                                              compare_root, compare_path,
+                                              eb->fs_root, path, pool));
 
               SVN_ERR(svn_fs_file_checksum(&checksum, svn_checksum_md5,
                                            compare_root, compare_path,
@@ -1934,7 +1934,7 @@ write_revision_record(svn_stream_t *stre
 
   if (include_revprops)
     {
-      SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, pool));
+      SVN_ERR(svn_fs_revision_proplist2(&props, fs, rev, FALSE, pool, pool));
 
       /* Run revision date properties through the time conversion to
         canonicalize them. */
@@ -1991,6 +1991,10 @@ svn_repos_dump_fs4(svn_repos_t *repos,
   svn_boolean_t found_old_mergeinfo = FALSE;
   svn_repos_notify_t *notify;
 
+  /* Make sure we catch up on the latest revprop changes.  This is the only
+   * time we will refresh the revprop data in this query. */
+  SVN_ERR(svn_fs_refresh_revision_props(fs, pool));
+
   /* Determine the current youngest revision of the filesystem. */
   SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
 
@@ -2325,7 +2329,8 @@ verify_one_revision(svn_fs_t *fs,
      do this for completeness. */
   SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, scratch_pool));
 
-  SVN_ERR(svn_fs_revision_proplist(&props, fs, rev, scratch_pool));
+  SVN_ERR(svn_fs_revision_proplist2(&props, fs, rev, FALSE, scratch_pool,
+                                    scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -2405,6 +2410,10 @@ svn_repos_verify_fs3(svn_repos_t *repos,
   struct verify_fs_notify_func_baton_t *verify_notify_baton = NULL;
   svn_error_t *err;
 
+  /* Make sure we catch up on the latest revprop changes.  This is the only
+   * time we will refresh the revprop data in this query. */
+  SVN_ERR(svn_fs_refresh_revision_props(fs, pool));
+
   /* Determine the current youngest revision of the filesystem. */
   SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
 

Modified: subversion/branches/authzperf/subversion/libsvn_repos/fs-wrap.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/fs-wrap.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_repos/fs-wrap.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_repos/fs-wrap.c Fri Apr 29 18:38:53 2016
@@ -58,6 +58,8 @@ svn_repos_fs_commit_txn(const char **con
   apr_hash_t *hooks_env;
 
   *new_rev = SVN_INVALID_REVNUM;
+  if (conflict_p)
+    *conflict_p = NULL;
 
   /* Parse the hooks-env file (if any). */
   SVN_ERR(svn_repos__parse_hooks_env(&hooks_env, repos->hooks_env_path,
@@ -378,7 +380,8 @@ svn_repos_fs_change_rev_prop4(svn_repos_
            * to the hooks to be accurate. */
           svn_string_t *old_value2;
 
-          SVN_ERR(svn_fs_revision_prop(&old_value2, repos->fs, rev, name, pool));
+          SVN_ERR(svn_fs_revision_prop2(&old_value2, repos->fs, rev, name,
+                                        TRUE, pool, pool));
           old_value = old_value2;
         }
 
@@ -448,12 +451,13 @@ svn_repos_fs_revision_prop(svn_string_t
         *value_p = NULL;
 
       else
-        SVN_ERR(svn_fs_revision_prop(value_p, repos->fs,
-                                     rev, propname, pool));
+        SVN_ERR(svn_fs_revision_prop2(value_p, repos->fs,
+                                      rev, propname, TRUE, pool, pool));
     }
   else /* wholly readable revision */
     {
-      SVN_ERR(svn_fs_revision_prop(value_p, repos->fs, rev, propname, pool));
+      SVN_ERR(svn_fs_revision_prop2(value_p, repos->fs, rev, propname, TRUE,
+                                    pool, pool));
     }
 
   return SVN_NO_ERROR;
@@ -486,7 +490,8 @@ svn_repos_fs_revision_proplist(apr_hash_
       svn_string_t *value;
 
       /* Produce two property hashtables, both in POOL. */
-      SVN_ERR(svn_fs_revision_proplist(&tmphash, repos->fs, rev, pool));
+      SVN_ERR(svn_fs_revision_proplist2(&tmphash, repos->fs, rev, TRUE,
+                                        pool, pool));
       *table_p = apr_hash_make(pool);
 
       /* If they exist, we only copy svn:author and svn:date into the
@@ -501,7 +506,8 @@ svn_repos_fs_revision_proplist(apr_hash_
     }
   else /* wholly readable revision */
     {
-      SVN_ERR(svn_fs_revision_proplist(table_p, repos->fs, rev, pool));
+      SVN_ERR(svn_fs_revision_proplist2(table_p, repos->fs, rev, TRUE,
+                                        pool, pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c?rev=1741682&r1=1741681&r2=1741682&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_repos/load-fs-vtable.c Fri Apr 29 18:38:53 2016
@@ -1014,7 +1014,8 @@ close_revision(void *baton)
           apr_array_header_t *diff;
           int i;
 
-          SVN_ERR(svn_fs_revision_proplist(&orig_props, pb->fs, 0, rb->pool));
+          SVN_ERR(svn_fs_revision_proplist2(&orig_props, pb->fs, 0, TRUE,
+                                            rb->pool, rb->pool));
           new_props = svn_prop_array_to_hash(rb->revprops, rb->pool);
           SVN_ERR(svn_prop_diffs(&diff, new_props, orig_props, rb->pool));
 
@@ -1334,7 +1335,8 @@ revprops_close_revision(void *baton)
       prop->value = NULL;
     }
 
-  SVN_ERR(svn_fs_revision_proplist(&orig_props, pb->fs, rb->rev, rb->pool));
+  SVN_ERR(svn_fs_revision_proplist2(&orig_props, pb->fs, rb->rev, TRUE,
+                                    rb->pool, rb->pool));
   new_props = svn_prop_array_to_hash(rb->revprops, rb->pool);
   SVN_ERR(svn_prop_diffs(&diff, new_props, orig_props, rb->pool));