Author: svn-role
Date: Wed Dec 19 04:00:55 2018
New Revision: 1849266
URL: http://svn.apache.org/viewvc?rev=1849266&view=rev
Log:
Merge the r1847572 group from trunk:
* r1847572, r1847596
fsfs: Fix SVN-4791, an issue with the DAG open_path() that was causing
unexpected SVN_ERR_FS_NOT_DIRECTORY errors when attempting to open a path
with `open_path_node_only | open_path_allow_null` flags.
Justification:
Some valid FSFS read operations errored out. This could break some
end-user operations like 'update'.
Votes:
+1: julianfoad, brane, stefan2
Modified:
subversion/branches/1.11.x/ (props changed)
subversion/branches/1.11.x/STATUS
subversion/branches/1.11.x/subversion/libsvn_fs_fs/tree.c
subversion/branches/1.11.x/subversion/tests/libsvn_fs/fs-test.c
Propchange: subversion/branches/1.11.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Dec 19 04:00:55 2018
@@ -100,4 +100,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1840990-1840991,1840995,1840997,1841059,1841079,1841091,1841098,1841136,1841180,1841272,1841481,1841524-1841525,1841567,1841600-1841602,1841606,1841719,1841725,1841731,1841736,1841742-1841743,1841753-1841754,1841822,1841850,1841867,1842090,1842222-1842223,1842334,1842814,1842827,1842829,1842877,1843888,1844882,1844987,1845204,1845261,1845408,1845555-1845556,1845559,1845577,1846299,1846403,1846406,1846704,1847181-1847182,1847188,1847264
+/subversion/trunk:1840990-1840991,1840995,1840997,1841059,1841079,1841091,1841098,1841136,1841180,1841272,1841481,1841524-1841525,1841567,1841600-1841602,1841606,1841719,1841725,1841731,1841736,1841742-1841743,1841753-1841754,1841822,1841850,1841867,1842090,1842222-1842223,1842334,1842814,1842827,1842829,1842877,1843888,1844882,1844987,1845204,1845261,1845408,1845555-1845556,1845559,1845577,1846299,1846403,1846406,1846704,1847181-1847182,1847188,1847264,1847572,1847596
Modified: subversion/branches/1.11.x/STATUS
URL:
http://svn.apache.org/viewvc/subversion/branches/1.11.x/STATUS?rev=1849266&r1=1849265&r2=1849266&view=diff
==============================================================================
--- subversion/branches/1.11.x/STATUS (original)
+++ subversion/branches/1.11.x/STATUS Wed Dec 19 04:00:55 2018
@@ -47,14 +47,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1847572, r1847596
- fsfs: Fix SVN-4791, an issue with the DAG open_path() that was causing
- unexpected SVN_ERR_FS_NOT_DIRECTORY errors when attempting to open a path
- with `open_path_node_only | open_path_allow_null` flags.
- Justification:
- Some valid FSFS read operations errored out. This could break some
- end-user operations like 'update'.
- Votes:
- +1: julianfoad, brane, stefan2
-
Modified: subversion/branches/1.11.x/subversion/libsvn_fs_fs/tree.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.11.x/subversion/libsvn_fs_fs/tree.c?rev=1849266&r1=1849265&r2=1849266&view=diff
==============================================================================
--- subversion/branches/1.11.x/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/branches/1.11.x/subversion/libsvn_fs_fs/tree.c Wed Dec 19
04:00:55 2018
@@ -920,6 +920,25 @@ try_match_last_node(dag_node_t **node_p,
return SVN_NO_ERROR;
}
+/* Helper for open_path() that constructs and returns an appropriate
+ SVN_ERR_FS_NOT_DIRECTORY error. */
+static svn_error_t *
+err_not_directory(svn_fs_root_t *root,
+ const char *path,
+ apr_pool_t *scratch_pool)
+{
+ const char *msg;
+
+ msg = root->is_txn_root
+ ? apr_psprintf(scratch_pool,
+ _("Failure opening '%s' in transaction '%s'"),
+ path, root->txn)
+ : apr_psprintf(scratch_pool,
+ _("Failure opening '%s' in revision %ld"),
+ path, root->rev);
+
+ return svn_error_quick_wrap(SVN_FS__ERR_NOT_DIRECTORY(root->fs, path), msg);
+}
/* Open the node identified by PATH in ROOT, allocating in POOL. Set
*PARENT_PATH_P to a path from the node up to ROOT. The resulting
@@ -1016,12 +1035,26 @@ open_path(parent_path_t **parent_path_p,
SVN_ERR(dag_node_cache_get(&here, root, directory, pool));
/* Did the shortcut work? */
- if (here)
+ if (here && svn_fs_fs__dag_node_kind(here) == svn_node_dir)
{
apr_size_t dirname_len = strlen(directory);
path_so_far->len = dirname_len;
rest = path + dirname_len + 1;
}
+ else if (here)
+ {
+ /* The parent node is not a directory. We are looking for some
+ sub-path, so that sub-path will not exist. That will be o.k.
+ if we are just here to check for the path's existence, but
+ should result in an error otherwise. */
+ if (flags & open_path_allow_null)
+ {
+ *parent_path_p = NULL;
+ return SVN_NO_ERROR;
+ }
+ else
+ return svn_error_trace(err_not_directory(root, directory,
pool));
+ }
}
}
@@ -1144,8 +1177,6 @@ open_path(parent_path_t **parent_path_p,
/* The path isn't finished yet; we'd better be in a directory. */
if (svn_fs_fs__dag_node_kind(child) != svn_node_dir)
{
- const char *msg;
-
/* Since this is not a directory and we are looking for some
sub-path, that sub-path will not exist. That will be o.k.,
if we are just here to check for the path's existence. */
@@ -1156,14 +1187,8 @@ open_path(parent_path_t **parent_path_p,
}
/* It's really a problem ... */
- msg = root->is_txn_root
- ? apr_psprintf(iterpool,
- _("Failure opening '%s' in transaction '%s'"),
- path, root->txn)
- : apr_psprintf(iterpool,
- _("Failure opening '%s' in revision %ld"),
- path, root->rev);
- SVN_ERR_W(SVN_FS__ERR_NOT_DIRECTORY(fs, path_so_far->data), msg);
+ return svn_error_trace(
+ err_not_directory(root, path_so_far->data, iterpool));
}
rest = next;
Modified: subversion/branches/1.11.x/subversion/tests/libsvn_fs/fs-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.11.x/subversion/tests/libsvn_fs/fs-test.c?rev=1849266&r1=1849265&r2=1849266&view=diff
==============================================================================
--- subversion/branches/1.11.x/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/1.11.x/subversion/tests/libsvn_fs/fs-test.c Wed Dec 19
04:00:55 2018
@@ -7369,6 +7369,78 @@ closest_copy_test_svn_4677(const svn_tes
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_closest_copy_file_replaced_with_dir(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ svn_fs_t *fs;
+ svn_fs_txn_t *txn;
+ svn_fs_root_t *txn_root;
+ svn_fs_root_t *rev_root;
+ svn_revnum_t youngest_rev;
+ svn_fs_root_t *copy_root;
+ const char *copy_path;
+
+ /* Prepare a filesystem. */
+ SVN_ERR(svn_test__create_fs(&fs, "test-closest-copy-file-replaced-with-dir",
+ opts, pool));
+
+ youngest_rev = 0;
+
+ /* Modeled after the case described in the thread:
+ "[PATCH] A test for "Can't get entries" error"
+
https://lists.apache.org/thread.html/693a95b0da834387e78a7f08df2392b634397d32f37428c81c02f8c5@%3Cdev.subversion.apache.org%3E
+ */
+ /* r1: Add a directory with a file. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, youngest_rev, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "/A", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "/A/mu", pool));
+ SVN_ERR(test_commit_txn(&youngest_rev, txn, NULL, pool));
+ SVN_TEST_INT_ASSERT(youngest_rev, 1);
+
+ /* r2: Copy the directory. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, youngest_rev, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, 1, pool));
+ SVN_ERR(svn_fs_copy(rev_root, "/A", txn_root, "/B", pool));
+ SVN_ERR(test_commit_txn(&youngest_rev, txn, NULL, pool));
+ SVN_TEST_INT_ASSERT(youngest_rev, 2);
+
+ /* r3: Delete the file. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, youngest_rev, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_delete(txn_root, "/B/mu", pool));
+ SVN_ERR(test_commit_txn(&youngest_rev, txn, NULL, pool));
+ SVN_TEST_INT_ASSERT(youngest_rev, 3);
+
+ /* r4: Replace the file with a new directory containing a file. */
+ SVN_ERR(svn_fs_begin_txn2(&txn, fs, youngest_rev, 0, pool));
+ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+ SVN_ERR(svn_fs_make_dir(txn_root, "/B/mu", pool));
+ SVN_ERR(svn_fs_make_file(txn_root, "/B/mu/iota", pool));
+ SVN_ERR(test_commit_txn(&youngest_rev, txn, NULL, pool));
+ SVN_TEST_INT_ASSERT(youngest_rev, 4);
+
+ /* Test a couple of svn_fs_closest_copy() calls; the second call used
+ to fail with an unexpected SVN_ERR_FS_NOT_DIRECTORY error. */
+
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, 2, pool));
+ SVN_ERR(svn_fs_closest_copy(©_root, ©_path, rev_root, "/B/mu",
pool));
+
+ SVN_TEST_ASSERT(copy_root != NULL);
+ SVN_TEST_INT_ASSERT(svn_fs_revision_root_revision(copy_root), 2);
+ SVN_TEST_STRING_ASSERT(copy_path, "/B");
+
+ SVN_ERR(svn_fs_revision_root(&rev_root, fs, 4, pool));
+ SVN_ERR(svn_fs_closest_copy(©_root, ©_path, rev_root, "/B/mu/iota",
pool));
+
+ SVN_TEST_ASSERT(copy_root == NULL);
+ SVN_TEST_ASSERT(copy_path == NULL);
+
+ return SVN_NO_ERROR;
+}
+
/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -7513,6 +7585,8 @@ static struct svn_test_descriptor_t test
"test rep-sharing on content rather than SHA1"),
SVN_TEST_OPTS_PASS(closest_copy_test_svn_4677,
"test issue SVN-4677 regression"),
+ SVN_TEST_OPTS_PASS(test_closest_copy_file_replaced_with_dir,
+ "svn_fs_closest_copy after replacing file with dir"),
SVN_TEST_NULL
};