You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/10/19 14:14:42 UTC

svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Author: hwright
Date: Wed Oct 19 12:14:42 2011
New Revision: 1186144

URL: http://svn.apache.org/viewvc?rev=1186144&view=rev
Log:
Merge r1178280, r1178282 from trunk:

 * r1178280, r1178282
   Add a sanity check to FSFS.
   Justification:
     Detects a user-visible corruption seen on svn-master.apache.org.
   Votes:
     +1: danielsh, rhuijben, stsp

Modified:
    subversion/branches/1.7.x/   (props changed)
    subversion/branches/1.7.x/STATUS
    subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c

Propchange: subversion/branches/1.7.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Oct 19 12:14:42 2011
@@ -64,4 +64,4 @@
 /subversion/branches/tree-conflicts:868291-873154
 /subversion/branches/tree-conflicts-notify:873926-874008
 /subversion/branches/uris-as-urls:1060426-1064427
-/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147299,1147309,1147882,1148071,1148083,1148094,1148131,1148374,1148424,1148566,1148588,1148652,1148662,1148699,1148853,1148877,1148882,1148936,1149103,1149105,1149135,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149627,1149675,1149701,1149713,1150242,1150254,1150260-1150261,1150266,1150302,1150327,1150368,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151854,1151906,1151911,1152129,1152140,1152189-1152190,1152267,1152282,1152286,1152726,1152809,1153138,1153141,1153416,1153540,1153566,1153799,1153807,1153968,1154009,1154023,1154115,1154119,1154121,1154144,1154155,1154159,1154165,1154215,1154225,1154273,1154278,1154379,1154382,1154461,1154717-1154718,1154733,1154908,1154982,1155015,1155044,1155124,1155131,1155160,1155313,1155334,1155391,1155404,1156085,115
 6098,1156216,1156218,1156312,1156527,1156717,1156721,1156750,1156827,1156838,1157416,1158187,1158193-1158194,1158196,1158201,1158207,1158209-1158210,1158217,1158285,1158288,1158303,1158309,1158407,1158419,1158421,1158436,1158455,1158616-1158617,1158634,1158854,1158875,1158886,1158893,1158896,1158919,1158924,1158963,1159093,1159098,1159101,1159132,1159136,1159148,1159230,1159275,1159400,1159686,1159760,1159772,1160605,1160671,1160682,1160704-1160705,1160756,1161063,1161080,1161185,1161210,1161683,1161721,1162024,1162033,1162201,1162516,1162880,1162974,1162995,1163557,1163792,1163953,1164027,1164386,1164426,1164517,1164535,1164554,1164580,1164614,1164645,1164760,1164765,1166500,1166555,1166678,1167062,1167173,1167209,1167269,1167503,1167659,1167681,1169524,1169531,1169650,1171708,1173111,1173425,1173639,1174051,1174060,1174652,1174761,1174797-1174798,1174806,1175888,1176915,1176949,1177001,1177492,1179680,1179767,1181155,1181609,1181666,1182115,1182904,1182909,1183054,1183263,
 1183347,1185730
+/subversion/trunk:1146013,1146121,1146219,1146222,1146274,1146492,1146555,1146606,1146620,1146684,1146781,1146832,1146834,1146870,1146899,1146904,1147293,1147299,1147309,1147882,1148071,1148083,1148094,1148131,1148374,1148424,1148566,1148588,1148652,1148662,1148699,1148853,1148877,1148882,1148936,1149103,1149105,1149135,1149141,1149160,1149228,1149240,1149343,1149371-1149372,1149377,1149398,1149401,1149539,1149572,1149627,1149675,1149701,1149713,1150242,1150254,1150260-1150261,1150266,1150302,1150327,1150368,1150372,1150441,1150506,1150812,1150853,1151036,1151177,1151610,1151854,1151906,1151911,1152129,1152140,1152189-1152190,1152267,1152282,1152286,1152726,1152809,1153138,1153141,1153416,1153540,1153566,1153799,1153807,1153968,1154009,1154023,1154115,1154119,1154121,1154144,1154155,1154159,1154165,1154215,1154225,1154273,1154278,1154379,1154382,1154461,1154717-1154718,1154733,1154908,1154982,1155015,1155044,1155124,1155131,1155160,1155313,1155334,1155391,1155404,1156085,115
 6098,1156216,1156218,1156312,1156527,1156717,1156721,1156750,1156827,1156838,1157416,1158187,1158193-1158194,1158196,1158201,1158207,1158209-1158210,1158217,1158285,1158288,1158303,1158309,1158407,1158419,1158421,1158436,1158455,1158616-1158617,1158634,1158854,1158875,1158886,1158893,1158896,1158919,1158924,1158963,1159093,1159098,1159101,1159132,1159136,1159148,1159230,1159275,1159400,1159686,1159760,1159772,1160605,1160671,1160682,1160704-1160705,1160756,1161063,1161080,1161185,1161210,1161683,1161721,1162024,1162033,1162201,1162516,1162880,1162974,1162995,1163557,1163792,1163953,1164027,1164386,1164426,1164517,1164535,1164554,1164580,1164614,1164645,1164760,1164765,1166500,1166555,1166678,1167062,1167173,1167209,1167269,1167503,1167659,1167681,1169524,1169531,1169650,1171708,1173111,1173425,1173639,1174051,1174060,1174652,1174761,1174797-1174798,1174806,1175888,1176915,1176949,1177001,1177492,1178280,1178282,1179680,1179767,1181155,1181609,1181666,1182115,1182904,1182909,
 1183054,1183263,1183347,1185730

Modified: subversion/branches/1.7.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1186144&r1=1186143&r2=1186144&view=diff
==============================================================================
--- subversion/branches/1.7.x/STATUS (original)
+++ subversion/branches/1.7.x/STATUS Wed Oct 19 12:14:42 2011
@@ -124,10 +124,3 @@ Approved changes:
      fix here than having to fix all clients.
    Votes:
      +1: rhuijben, pburba, stsp
-
- * r1178280, r1178282
-   Add a sanity check to FSFS.
-   Justification:
-     Detects a user-visible corruption seen on svn-master.apache.org.
-   Votes:
-     +1: danielsh, rhuijben, stsp

Modified: subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c?rev=1186144&r1=1186143&r2=1186144&view=diff
==============================================================================
--- subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c Wed Oct 19 12:14:42 2011
@@ -5873,6 +5873,29 @@ write_hash_rep(svn_filesize_t *size,
   return svn_stream_printf(whb->stream, pool, "ENDREP\n");
 }
 
+/* Sanity check ROOT_NODEREV, a candidate for being the root node-revision
+   of (not yet committed) revision REV.  Use OCEAN for temporary allocations.
+ */
+static APR_INLINE svn_error_t *
+validate_root_noderev(node_revision_t *root_noderev,
+                      svn_revnum_t rev)
+{
+  /* Bogosity seen on svn.apache.org; see
+       http://mid.gmane.org/20111002202833.GA12373@daniel3.local
+   */
+  if (root_noderev->predecessor_count != -1
+      && root_noderev->predecessor_count != rev)
+    {
+      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+                               _("predecessor count for "
+                                 "the root node-revision is wrong: "
+                                 "found %d, committing r%ld"),
+                                 root_noderev->predecessor_count, rev);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Copy a node-revision specified by id ID in fileystem FS from a
    transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
    pointer to the new node-id which will be allocated in POOL.
@@ -5890,6 +5913,10 @@ write_hash_rep(svn_filesize_t *size,
    If REPS_TO_CACHE is not NULL, append to it a copy (allocated in
    REPS_POOL) of each data rep that is new in this revision.
 
+   AT_ROOT is true if the node revision being written is the root
+   node-revision.  It is only controls additional sanity checking
+   logic.
+
    Temporary allocations are also from POOL. */
 static svn_error_t *
 write_final_rev(const svn_fs_id_t **new_id_p,
@@ -5902,6 +5929,7 @@ write_final_rev(const svn_fs_id_t **new_
                 apr_off_t initial_offset,
                 apr_array_header_t *reps_to_cache,
                 apr_pool_t *reps_pool,
+                svn_boolean_t at_root,
                 apr_pool_t *pool)
 {
   node_revision_t *noderev;
@@ -5938,7 +5966,7 @@ write_final_rev(const svn_fs_id_t **new_
           svn_pool_clear(subpool);
           SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
                                   start_node_id, start_copy_id, initial_offset,
-                                  reps_to_cache, reps_pool,
+                                  reps_to_cache, reps_pool, FALSE,
                                   subpool));
           if (new_id && (svn_fs_fs__id_rev(new_id) == rev))
             dirent->id = svn_fs_fs__id_copy(new_id, pool);
@@ -6036,6 +6064,8 @@ write_final_rev(const svn_fs_id_t **new_
   noderev->id = new_id;
 
   /* Write out our new node-revision. */
+  if (at_root)
+    SVN_ERR(validate_root_noderev(noderev, rev));
   SVN_ERR(svn_fs_fs__write_noderev(svn_stream_from_aprfile2(file, TRUE, pool),
                                    noderev, ffd->format,
                                    svn_fs_fs__fs_supports_mergeinfo(fs),
@@ -6315,7 +6345,7 @@ commit_body(void *baton, apr_pool_t *poo
   root_id = svn_fs_fs__id_txn_create("0", "0", cb->txn->id, pool);
   SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, root_id,
                           start_node_id, start_copy_id, initial_offset,
-                          cb->reps_to_cache, cb->reps_pool,
+                          cb->reps_to_cache, cb->reps_pool, TRUE,
                           pool));
 
   /* Write the changed-path information. */



Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Stefan Sperling wrote on Wed, Oct 19, 2011 at 15:40:30 +0200:
> On Wed, Oct 19, 2011 at 03:30:45PM +0200, Daniel Shahaf wrote:
> > The revision works as intended for new repositories.  But for
> > repositories where the predecessor count on "/" is already wrong, the
> > error doesn't fix itself...
> > 
> > If /@50's predecessor is /@20, then /@50's pred-count is 21; but /@51's
> > pred-count would be 22, not 51.
> > 
> > I'm working on a different fix that doesn't have this problem: checking
> > if 50 - 21 == 51 - 22, and erroring out if that's not the case.
> 
> I see. Should we reverse-merge r1186144 from 1.7.x until you have
> the fix or will it be done soon (as in, today)?

r1186231

Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Stefan Sperling <st...@elego.de>.
On Wed, Oct 19, 2011 at 03:30:45PM +0200, Daniel Shahaf wrote:
> The revision works as intended for new repositories.  But for
> repositories where the predecessor count on "/" is already wrong, the
> error doesn't fix itself...
> 
> If /@50's predecessor is /@20, then /@50's pred-count is 21; but /@51's
> pred-count would be 22, not 51.
> 
> I'm working on a different fix that doesn't have this problem: checking
> if 50 - 21 == 51 - 22, and erroring out if that's not the case.

I see. Should we reverse-merge r1186144 from 1.7.x until you have
the fix or will it be done soon (as in, today)?

Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Daniel Shahaf wrote on Wed, Oct 19, 2011 at 15:30:45 +0200:
> Stefan Sperling wrote on Wed, Oct 19, 2011 at 15:14:46 +0200:
> > On Wed, Oct 19, 2011 at 03:07:52PM +0200, Daniel Shahaf wrote:
> > > People who are bitten by this will not be able to commit anything with
> > > this revision applied.
> > 
> > Why? I thought this was some transient error, and that we prevent a bad
> > revision from enterting the repository.
> > 
> > > Should we add a way to turn off the new validation?
> > 
> > If you're saying that this can prevent people from committing new
> > revisions, because a wrong pred count in a transaction is a permanent,
> > rather than transient error condition, I think we should pull this
> > revision from 1.7.x.
> > 
> > But why do you think that every transaction will have a wrong pred
> > count once one transaction had a wrong pred count?
> 
> The revision works as intended for new repositories.  But for
> repositories where the predecessor count on "/" is already wrong, the
> error doesn't fix itself...
> 
> If /@50's predecessor is /@20, then /@50's pred-count is 21; but /@51's
> pred-count would be 22, not 51.
> 
> I'm working on a different fix that doesn't have this problem: checking
> if 50 - 21 == 51 - 22, and erroring out if that's not the case.

And here's the patch.  It passes basic_tests and I verified manually
that if I break the count: and pred: for /@2 then /@3 commits
successfully with consistently-wrong values.  If no objections I'll
commit this and nominate for backport.

(and yes, I'll fix the #define, too)

[[[
Index: subversion/libsvn_fs_fs/tree.c
===================================================================
--- subversion/libsvn_fs_fs/tree.c	(revision 1185907)
+++ subversion/libsvn_fs_fs/tree.c	(working copy)
@@ -870,11 +870,11 @@ add_change(svn_fs_t *fs,
 
 /* Get the id of a node referenced by path PATH in ROOT.  Return the
    id in *ID_P allocated in POOL. */
-static svn_error_t *
-fs_node_id(const svn_fs_id_t **id_p,
-           svn_fs_root_t *root,
-           const char *path,
-           apr_pool_t *pool)
+svn_error_t *
+svn_fs_fs__node_id(const svn_fs_id_t **id_p,
+                   svn_fs_root_t *root,
+                   const char *path,
+                   apr_pool_t *pool)
 {
   if ((! root->is_txn_root)
       && (path[0] == '\0' || ((path[0] == '/') && (path[1] == '\0'))))
@@ -895,6 +895,7 @@ add_change(svn_fs_t *fs,
     }
   return SVN_NO_ERROR;
 }
+#define fs_node_id svn_fs_fs__node_id
 
 
 svn_error_t *
Index: subversion/libsvn_fs_fs/tree.h
===================================================================
--- subversion/libsvn_fs_fs/tree.h	(revision 1185907)
+++ subversion/libsvn_fs_fs/tree.h	(working copy)
@@ -61,6 +61,13 @@ svn_fs_fs__check_path(svn_node_kind_t *kind_p,
                       const char *path,
                       apr_pool_t *pool);
 
+/* Implement root_vtable_t.node_id(). */
+svn_error_t *
+svn_fs_fs__node_id(const svn_fs_id_t **id_p,
+                   svn_fs_root_t *root,
+                   const char *path,
+                   apr_pool_t *pool);
+
 /* Set *REVISION to the revision in which PATH under ROOT was created.
    Use POOL for any temporary allocations.  If PATH is in an
    uncommitted transaction, *REVISION will be set to
Index: subversion/libsvn_fs_fs/fs_fs.c
===================================================================
--- subversion/libsvn_fs_fs/fs_fs.c	(revision 1185907)
+++ subversion/libsvn_fs_fs/fs_fs.c	(working copy)
@@ -5839,15 +5839,37 @@ write_hash_rep(svn_filesize_t *size,
 /* Sanity check ROOT_NODEREV, a candidate for being the root node-revision
    of (not yet committed) revision REV.  Use OCEAN for temporary allocations.
  */
-static APR_INLINE svn_error_t *
-validate_root_noderev(node_revision_t *root_noderev,
-                      svn_revnum_t rev)
+static svn_error_t *
+validate_root_noderev(svn_fs_t *fs,
+                      node_revision_t *root_noderev,
+                      svn_revnum_t rev,
+                      apr_pool_t *pool)
 {
+  svn_revnum_t head_revnum = rev-1;
+  int head_predecessor_count;
+
+  SVN_ERR_ASSERT(rev > 0);
+
+  {
+    svn_fs_root_t *head_revision;
+    const svn_fs_id_t *head_root_id;
+    node_revision_t *head_root_noderev;
+
+    /* Get /@HEAD's noderev. */
+    SVN_ERR(svn_fs_fs__revision_root(&head_revision, fs, head_revnum, pool));
+    SVN_ERR(svn_fs_fs__node_id(&head_root_id, head_revision, "/", pool));
+    SVN_ERR(svn_fs_fs__get_node_revision(&head_root_noderev, fs, head_root_id,
+                                         pool));
+
+    head_predecessor_count = head_root_noderev->predecessor_count;
+  }
+
   /* Bogosity seen on svn.apache.org; see
        http://mid.gmane.org/20111002202833.GA12373@daniel3.local
    */
   if (root_noderev->predecessor_count != -1
-      && root_noderev->predecessor_count != rev)
+      && (root_noderev->predecessor_count - head_predecessor_count)
+         != (rev - head_revnum))
     {
       return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
                                _("predecessor count for "
@@ -6028,7 +6050,7 @@ write_final_rev(const svn_fs_id_t **new_id_p,
 
   /* Write out our new node-revision. */
   if (at_root)
-    SVN_ERR(validate_root_noderev(noderev, rev));
+    SVN_ERR(validate_root_noderev(fs, noderev, rev, pool));
   SVN_ERR(svn_fs_fs__write_noderev(svn_stream_from_aprfile2(file, TRUE, pool),
                                    noderev, ffd->format,
                                    svn_fs_fs__fs_supports_mergeinfo(fs),
]]]

Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
Stefan Sperling wrote on Wed, Oct 19, 2011 at 15:14:46 +0200:
> On Wed, Oct 19, 2011 at 03:07:52PM +0200, Daniel Shahaf wrote:
> > People who are bitten by this will not be able to commit anything with
> > this revision applied.
> 
> Why? I thought this was some transient error, and that we prevent a bad
> revision from enterting the repository.
> 
> > Should we add a way to turn off the new validation?
> 
> If you're saying that this can prevent people from committing new
> revisions, because a wrong pred count in a transaction is a permanent,
> rather than transient error condition, I think we should pull this
> revision from 1.7.x.
> 
> But why do you think that every transaction will have a wrong pred
> count once one transaction had a wrong pred count?

The revision works as intended for new repositories.  But for
repositories where the predecessor count on "/" is already wrong, the
error doesn't fix itself...

If /@50's predecessor is /@20, then /@50's pred-count is 21; but /@51's
pred-count would be 22, not 51.

I'm working on a different fix that doesn't have this problem: checking
if 50 - 21 == 51 - 22, and erroring out if that's not the case.

Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Stefan Sperling <st...@elego.de>.
On Wed, Oct 19, 2011 at 03:07:52PM +0200, Daniel Shahaf wrote:
> People who are bitten by this will not be able to commit anything with
> this revision applied.

Why? I thought this was some transient error, and that we prevent a bad
revision from enterting the repository.

> Should we add a way to turn off the new validation?

If you're saying that this can prevent people from committing new
revisions, because a wrong pred count in a transaction is a permanent,
rather than transient error condition, I think we should pull this
revision from 1.7.x.

But why do you think that every transaction will have a wrong pred
count once one transaction had a wrong pred count?

Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
People who are bitten by this will not be able to commit anything with
this revision applied.  Should we add a way to turn off the new
validation?

For svn.a.o I'll just patch it locally, but I suppose not everyone who
runs servers also compiles them from source...

hwright@apache.org wrote on Wed, Oct 19, 2011 at 12:14:42 -0000:
> Author: hwright
> Date: Wed Oct 19 12:14:42 2011
> New Revision: 1186144
> 
> URL: http://svn.apache.org/viewvc?rev=1186144&view=rev
> Log:
> Merge r1178280, r1178282 from trunk:
> 
>  * r1178280, r1178282
>    Add a sanity check to FSFS.
>    Justification:
>      Detects a user-visible corruption seen on svn-master.apache.org.
>    Votes:
>      +1: danielsh, rhuijben, stsp
> 
> Modified:
>     subversion/branches/1.7.x/   (props changed)
>     subversion/branches/1.7.x/STATUS
>     subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c
> 
> Modified: subversion/branches/1.7.x/STATUS
> URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1186144&r1=1186143&r2=1186144&view=diff
> ==============================================================================
> --- subversion/branches/1.7.x/STATUS (original)
> +++ subversion/branches/1.7.x/STATUS Wed Oct 19 12:14:42 2011
> @@ -124,10 +124,3 @@ Approved changes:
>       fix here than having to fix all clients.
>     Votes:
>       +1: rhuijben, pburba, stsp
> -
> - * r1178280, r1178282
> -   Add a sanity check to FSFS.
> -   Justification:
> -     Detects a user-visible corruption seen on svn-master.apache.org.
> -   Votes:
> -     +1: danielsh, rhuijben, stsp
> 
> Modified: subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c
> URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c?rev=1186144&r1=1186143&r2=1186144&view=diff
> ==============================================================================
> --- subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c (original)
> +++ subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c Wed Oct 19 12:14:42 2011
> @@ -5873,6 +5873,29 @@ write_hash_rep(svn_filesize_t *size,
>    return svn_stream_printf(whb->stream, pool, "ENDREP\n");
>  }
>  
> +/* Sanity check ROOT_NODEREV, a candidate for being the root node-revision
> +   of (not yet committed) revision REV.  Use OCEAN for temporary allocations.
> + */
> +static APR_INLINE svn_error_t *
> +validate_root_noderev(node_revision_t *root_noderev,
> +                      svn_revnum_t rev)
> +{
> +  /* Bogosity seen on svn.apache.org; see
> +       http://mid.gmane.org/20111002202833.GA12373@daniel3.local
> +   */
> +  if (root_noderev->predecessor_count != -1
> +      && root_noderev->predecessor_count != rev)
> +    {
> +      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
> +                               _("predecessor count for "
> +                                 "the root node-revision is wrong: "
> +                                 "found %d, committing r%ld"),
> +                                 root_noderev->predecessor_count, rev);
> +    }
> +
> +  return SVN_NO_ERROR;
> +}
> +
>  /* Copy a node-revision specified by id ID in fileystem FS from a
>     transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
>     pointer to the new node-id which will be allocated in POOL.
> @@ -5890,6 +5913,10 @@ write_hash_rep(svn_filesize_t *size,
>     If REPS_TO_CACHE is not NULL, append to it a copy (allocated in
>     REPS_POOL) of each data rep that is new in this revision.
>  
> +   AT_ROOT is true if the node revision being written is the root
> +   node-revision.  It is only controls additional sanity checking
> +   logic.
> +
>     Temporary allocations are also from POOL. */
>  static svn_error_t *
>  write_final_rev(const svn_fs_id_t **new_id_p,
> @@ -5902,6 +5929,7 @@ write_final_rev(const svn_fs_id_t **new_
>                  apr_off_t initial_offset,
>                  apr_array_header_t *reps_to_cache,
>                  apr_pool_t *reps_pool,
> +                svn_boolean_t at_root,
>                  apr_pool_t *pool)
>  {
>    node_revision_t *noderev;
> @@ -5938,7 +5966,7 @@ write_final_rev(const svn_fs_id_t **new_
>            svn_pool_clear(subpool);
>            SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
>                                    start_node_id, start_copy_id, initial_offset,
> -                                  reps_to_cache, reps_pool,
> +                                  reps_to_cache, reps_pool, FALSE,
>                                    subpool));
>            if (new_id && (svn_fs_fs__id_rev(new_id) == rev))
>              dirent->id = svn_fs_fs__id_copy(new_id, pool);
> @@ -6036,6 +6064,8 @@ write_final_rev(const svn_fs_id_t **new_
>    noderev->id = new_id;
>  
>    /* Write out our new node-revision. */
> +  if (at_root)
> +    SVN_ERR(validate_root_noderev(noderev, rev));
>    SVN_ERR(svn_fs_fs__write_noderev(svn_stream_from_aprfile2(file, TRUE, pool),
>                                     noderev, ffd->format,
>                                     svn_fs_fs__fs_supports_mergeinfo(fs),
> @@ -6315,7 +6345,7 @@ commit_body(void *baton, apr_pool_t *poo
>    root_id = svn_fs_fs__id_txn_create("0", "0", cb->txn->id, pool);
>    SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, root_id,
>                            start_node_id, start_copy_id, initial_offset,
> -                          cb->reps_to_cache, cb->reps_pool,
> +                          cb->reps_to_cache, cb->reps_pool, TRUE,
>                            pool));
>  
>    /* Write the changed-path information. */
> 
> 

Re: svn commit: r1186144 - in /subversion/branches/1.7.x: ./ STATUS subversion/libsvn_fs_fs/fs_fs.c

Posted by Daniel Shahaf <d....@daniel.shahaf.name>.
People who are bitten by this will not be able to commit anything with
this revision applied.  Should we add a way to turn off the new
validation?

For svn.a.o I'll just patch it locally, but I suppose not everyone who
runs servers also compiles them from source...

hwright@apache.org wrote on Wed, Oct 19, 2011 at 12:14:42 -0000:
> Author: hwright
> Date: Wed Oct 19 12:14:42 2011
> New Revision: 1186144
> 
> URL: http://svn.apache.org/viewvc?rev=1186144&view=rev
> Log:
> Merge r1178280, r1178282 from trunk:
> 
>  * r1178280, r1178282
>    Add a sanity check to FSFS.
>    Justification:
>      Detects a user-visible corruption seen on svn-master.apache.org.
>    Votes:
>      +1: danielsh, rhuijben, stsp
> 
> Modified:
>     subversion/branches/1.7.x/   (props changed)
>     subversion/branches/1.7.x/STATUS
>     subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c
> 
> Modified: subversion/branches/1.7.x/STATUS
> URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/STATUS?rev=1186144&r1=1186143&r2=1186144&view=diff
> ==============================================================================
> --- subversion/branches/1.7.x/STATUS (original)
> +++ subversion/branches/1.7.x/STATUS Wed Oct 19 12:14:42 2011
> @@ -124,10 +124,3 @@ Approved changes:
>       fix here than having to fix all clients.
>     Votes:
>       +1: rhuijben, pburba, stsp
> -
> - * r1178280, r1178282
> -   Add a sanity check to FSFS.
> -   Justification:
> -     Detects a user-visible corruption seen on svn-master.apache.org.
> -   Votes:
> -     +1: danielsh, rhuijben, stsp
> 
> Modified: subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c
> URL: http://svn.apache.org/viewvc/subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c?rev=1186144&r1=1186143&r2=1186144&view=diff
> ==============================================================================
> --- subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c (original)
> +++ subversion/branches/1.7.x/subversion/libsvn_fs_fs/fs_fs.c Wed Oct 19 12:14:42 2011
> @@ -5873,6 +5873,29 @@ write_hash_rep(svn_filesize_t *size,
>    return svn_stream_printf(whb->stream, pool, "ENDREP\n");
>  }
>  
> +/* Sanity check ROOT_NODEREV, a candidate for being the root node-revision
> +   of (not yet committed) revision REV.  Use OCEAN for temporary allocations.
> + */
> +static APR_INLINE svn_error_t *
> +validate_root_noderev(node_revision_t *root_noderev,
> +                      svn_revnum_t rev)
> +{
> +  /* Bogosity seen on svn.apache.org; see
> +       http://mid.gmane.org/20111002202833.GA12373@daniel3.local
> +   */
> +  if (root_noderev->predecessor_count != -1
> +      && root_noderev->predecessor_count != rev)
> +    {
> +      return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
> +                               _("predecessor count for "
> +                                 "the root node-revision is wrong: "
> +                                 "found %d, committing r%ld"),
> +                                 root_noderev->predecessor_count, rev);
> +    }
> +
> +  return SVN_NO_ERROR;
> +}
> +
>  /* Copy a node-revision specified by id ID in fileystem FS from a
>     transaction into the proto-rev-file FILE.  Set *NEW_ID_P to a
>     pointer to the new node-id which will be allocated in POOL.
> @@ -5890,6 +5913,10 @@ write_hash_rep(svn_filesize_t *size,
>     If REPS_TO_CACHE is not NULL, append to it a copy (allocated in
>     REPS_POOL) of each data rep that is new in this revision.
>  
> +   AT_ROOT is true if the node revision being written is the root
> +   node-revision.  It is only controls additional sanity checking
> +   logic.
> +
>     Temporary allocations are also from POOL. */
>  static svn_error_t *
>  write_final_rev(const svn_fs_id_t **new_id_p,
> @@ -5902,6 +5929,7 @@ write_final_rev(const svn_fs_id_t **new_
>                  apr_off_t initial_offset,
>                  apr_array_header_t *reps_to_cache,
>                  apr_pool_t *reps_pool,
> +                svn_boolean_t at_root,
>                  apr_pool_t *pool)
>  {
>    node_revision_t *noderev;
> @@ -5938,7 +5966,7 @@ write_final_rev(const svn_fs_id_t **new_
>            svn_pool_clear(subpool);
>            SVN_ERR(write_final_rev(&new_id, file, rev, fs, dirent->id,
>                                    start_node_id, start_copy_id, initial_offset,
> -                                  reps_to_cache, reps_pool,
> +                                  reps_to_cache, reps_pool, FALSE,
>                                    subpool));
>            if (new_id && (svn_fs_fs__id_rev(new_id) == rev))
>              dirent->id = svn_fs_fs__id_copy(new_id, pool);
> @@ -6036,6 +6064,8 @@ write_final_rev(const svn_fs_id_t **new_
>    noderev->id = new_id;
>  
>    /* Write out our new node-revision. */
> +  if (at_root)
> +    SVN_ERR(validate_root_noderev(noderev, rev));
>    SVN_ERR(svn_fs_fs__write_noderev(svn_stream_from_aprfile2(file, TRUE, pool),
>                                     noderev, ffd->format,
>                                     svn_fs_fs__fs_supports_mergeinfo(fs),
> @@ -6315,7 +6345,7 @@ commit_body(void *baton, apr_pool_t *poo
>    root_id = svn_fs_fs__id_txn_create("0", "0", cb->txn->id, pool);
>    SVN_ERR(write_final_rev(&new_root_id, proto_file, new_rev, cb->fs, root_id,
>                            start_node_id, start_copy_id, initial_offset,
> -                          cb->reps_to_cache, cb->reps_pool,
> +                          cb->reps_to_cache, cb->reps_pool, TRUE,
>                            pool));
>  
>    /* Write the changed-path information. */
> 
>