You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sv...@apache.org on 2012/03/27 06:02:37 UTC

svn commit: r1305727 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/dag.c subversion/libsvn_fs_fs/dag.h subversion/libsvn_fs_fs/tree.c subversion/tests/cmdline/svnadmin_tests.py subversion/tests/cmdline/svntest/main.py

Author: svn-role
Date: Tue Mar 27 04:02:36 2012
New Revision: 1305727

URL: http://svn.apache.org/viewvc?rev=1305727&view=rev
Log:
Merge the r1302399 group from trunk:

 * r1302399, r1302539, r1302591, r1302613
   Fix issue 4129, wrong predecessor count in FSFS revision files
   Justification:
     Repository corruption.
   Notes:
     r1302399 is a comment change.
     r1302539 and r1302591 add a test.
     r1302613 is the fix.
   Votes:
     +1: philip, danielsh, stsp

Modified:
    subversion/branches/1.7.x/   (props changed)
    subversion/branches/1.7.x/STATUS
    subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.c
    subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.h
    subversion/branches/1.7.x/subversion/libsvn_fs_fs/tree.c
    subversion/branches/1.7.x/subversion/tests/cmdline/svnadmin_tests.py
    subversion/branches/1.7.x/subversion/tests/cmdline/svntest/main.py

Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1302399,1302539,1302591,1302613

Modified: subversion/branches/1.7.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1305727&r1=1305726&r2=1305727&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Tue Mar 27 04:02:36 2012
@@ -134,14 +134,3 @@ Veto-blocked changes:
 
 Approved changes:
 =================
-
- * r1302399, r1302539, r1302591, r1302613
-   Fix issue 4129, wrong predecessor count in FSFS revision files
-   Justification:
-     Repository corruption.
-   Notes:
-     r1302399 is a comment change.
-     r1302539 and r1302591 add a test.
-     r1302613 is the fix.
-   Votes:
-     +1: philip, danielsh, stsp

Modified: subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.c?rev=1305727&r1=1305726&r2=1305727&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.c Tue Mar 27 04:02:36 2012
@@ -1296,3 +1296,27 @@ svn_fs_fs__dag_get_copyfrom_path(const c
 
   return SVN_NO_ERROR;
 }
+
+svn_error_t *
+svn_fs_fs__dag_update_ancestry(dag_node_t *target,
+                               dag_node_t *source,
+                               apr_pool_t *pool)
+{
+  node_revision_t *source_noderev, *target_noderev;
+
+  if (! svn_fs_fs__dag_check_mutable(target))
+    return svn_error_createf
+      (SVN_ERR_FS_NOT_MUTABLE, NULL,
+       _("Attempted to update ancestry of non-mutable node"));
+
+  SVN_ERR(get_node_revision(&source_noderev, source, pool));
+  SVN_ERR(get_node_revision(&target_noderev, target, pool));
+
+  target_noderev->predecessor_id = source->id;
+  target_noderev->predecessor_count = source_noderev->predecessor_count;
+  if (target_noderev->predecessor_count != -1)
+    target_noderev->predecessor_count++;
+
+  return svn_fs_fs__put_node_revision(target->fs, target->id, target_noderev,
+                                      FALSE, pool);
+}

Modified: subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.h?rev=1305727&r1=1305726&r2=1305727&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.h (original)
+++ subversion/branches/1.7.x/subversion/libsvn_fs_fs/dag.h Tue Mar 27 04:02:36 2012
@@ -603,6 +603,12 @@ svn_error_t *svn_fs_fs__dag_get_copyfrom
                                               dag_node_t *node,
                                               apr_pool_t *pool);
 
+/* Update *TARGET so that SOURCE is it's predecessor.
+ */
+svn_error_t *
+svn_fs_fs__dag_update_ancestry(dag_node_t *target,
+                               dag_node_t *source,
+                               apr_pool_t *pool);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/1.7.x/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_fs_fs/tree.c?rev=1305727&r1=1305726&r2=1305727&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_fs_fs/tree.c Tue Mar 27 04:02:36 2012
@@ -1142,30 +1142,6 @@ get_root(dag_node_t **node, svn_fs_root_
 }
 
 
-static svn_error_t *
-update_ancestry(svn_fs_t *fs,
-                const svn_fs_id_t *source_id,
-                const svn_fs_id_t *target_id,
-                const char *target_path,
-                int source_pred_count,
-                apr_pool_t *pool)
-{
-  node_revision_t *noderev;
-
-  if (svn_fs_fs__id_txn_id(target_id) == NULL)
-    return svn_error_createf
-      (SVN_ERR_FS_NOT_MUTABLE, NULL,
-       _("Unexpected immutable node at '%s'"), target_path);
-
-  SVN_ERR(svn_fs_fs__get_node_revision(&noderev, fs, target_id, pool));
-  noderev->predecessor_id = source_id;
-  noderev->predecessor_count = source_pred_count;
-  if (noderev->predecessor_count != -1)
-    noderev->predecessor_count++;
-  return svn_fs_fs__put_node_revision(fs, target_id, noderev, FALSE, pool);
-}
-
-
 /* Set the contents of CONFLICT_PATH to PATH, and return an
    SVN_ERR_FS_CONFLICT error that indicates that there was a conflict
    at PATH.  Perform all allocations in POOL (except the allocation of
@@ -1217,7 +1193,6 @@ merge(svn_stringbuf_t *conflict_p,
   apr_hash_index_t *hi;
   svn_fs_t *fs;
   apr_pool_t *iterpool;
-  int pred_count;
   apr_int64_t mergeinfo_increment = 0;
 
   /* Make sure everyone comes from the same filesystem. */
@@ -1541,9 +1516,7 @@ merge(svn_stringbuf_t *conflict_p,
     }
   svn_pool_destroy(iterpool);
 
-  SVN_ERR(svn_fs_fs__dag_get_predecessor_count(&pred_count, source, pool));
-  SVN_ERR(update_ancestry(fs, source_id, target_id, target_path,
-                          pred_count, pool));
+  SVN_ERR(svn_fs_fs__dag_update_ancestry(target, source, pool));
 
   if (svn_fs_fs__fs_supports_mergeinfo(fs))
     SVN_ERR(svn_fs_fs__dag_increment_mergeinfo_count(target,

Modified: subversion/branches/1.7.x/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/tests/cmdline/svnadmin_tests.py?rev=1305727&r1=1305726&r2=1305727&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/1.7.x/subversion/tests/cmdline/svnadmin_tests.py Tue Mar 27 04:02:36 2012
@@ -28,6 +28,7 @@
 import os
 import shutil
 import sys
+import threading
 
 # Our testing module
 import svntest
@@ -1381,6 +1382,47 @@ def verify_non_utf8_paths(sbox):
     'STDERR', expected_stderr, errput):
     raise svntest.Failure
 
+@SkipUnless(svntest.main.is_threaded_python)
+@Issue(4129)
+def mergeinfo_race(sbox):
+  "concurrent mergeinfo commits invalidate pred-count"
+  sbox.build()
+
+  wc_dir = sbox.wc_dir
+  wc2_dir = sbox.add_wc_path('2')
+
+  ## Create wc2.
+  svntest.main.run_svn(None, 'checkout', '-q', sbox.repo_url, wc2_dir)
+
+  ## Some random edits.
+  svntest.main.run_svn(None, 'mkdir', sbox.ospath('d1', wc_dir))
+  svntest.main.run_svn(None, 'mkdir', sbox.ospath('d2', wc2_dir))
+
+  ## Set random mergeinfo properties.
+  svntest.main.run_svn(None, 'ps', 'svn:mergeinfo', '/P:42', sbox.ospath('A', wc_dir))
+  svntest.main.run_svn(None, 'ps', 'svn:mergeinfo', '/Q:42', sbox.ospath('iota', wc2_dir))
+
+  def makethread(some_wc_dir):
+    def worker():
+      svntest.main.run_svn(None, 'commit', '-mm', some_wc_dir)
+    return worker
+
+  t1 = threading.Thread(None, makethread(wc_dir))
+  t2 = threading.Thread(None, makethread(wc2_dir))
+
+  # t2 will trigger the issue #4129 sanity check in fs_fs.c
+  t1.start(); t2.start();
+
+  t1.join(); t2.join();
+
+  # Crude attempt to make sure everything worked.
+  # TODO: better way to catch exceptions in the thread
+  if svntest.actions.run_and_parse_info(sbox.repo_url)[0]['Revision'] != '3':
+    raise svntest.Failure("one or both commits failed")
+
+
+
+
 ########################################################################
 # Run the tests
 
@@ -1410,6 +1452,7 @@ test_list = [ None,
               hotcopy_symlink,
               load_bad_props,
               verify_non_utf8_paths,
+              mergeinfo_race,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/1.7.x/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/tests/cmdline/svntest/main.py?rev=1305727&r1=1305726&r2=1305727&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/1.7.x/subversion/tests/cmdline/svntest/main.py Tue Mar 27 04:02:36 2012
@@ -1121,6 +1121,9 @@ def is_os_darwin():
 def is_fs_case_insensitive():
   return (is_os_darwin() or is_os_windows())
 
+def is_threaded_python():
+  return True
+
 def server_has_mergeinfo():
   return options.server_minor_version >= 5