Author: stefan2
Date: Wed May 27 10:47:54 2015
New Revision: 1681963
URL: http://svn.apache.org/r1681963
Log:
On the 1.10-cache-improvements branch:
Catch up with /trunk up to and including r1681961.
Resolve a trivial text conflict in cache-membuffer.c .
Modified:
subversion/branches/1.10-cache-improvements/ (props changed)
subversion/branches/1.10-cache-improvements/CHANGES
subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h
subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h
subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c
subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c
subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c
subversion/branches/1.10-cache-improvements/subversion/svn/svn.c
subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/
(props changed)
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
subversion/branches/1.10-cache-improvements/subversion/tests/svn_test_fs.c
Propchange: subversion/branches/1.10-cache-improvements/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed May 27 10:47:54 2015
@@ -90,4 +90,4 @@
/subversion/branches/verify-at-commit:1462039-1462408
/subversion/branches/verify-keep-going:1439280-1546110
/subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1669166-1679916
+/subversion/trunk:1669166-1681961
Modified: subversion/branches/1.10-cache-improvements/CHANGES
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/CHANGES?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/CHANGES (original)
+++ subversion/branches/1.10-cache-improvements/CHANGES Wed May 27 10:47:54 2015
@@ -192,6 +192,10 @@ http://svn.apache.org/repos/asf/subversi
* status: now accept '-r' argument (r1671164, 1672578, 1673228)
* ls: improve performance of '-v' on tag directories (r1673153)
* resolve: improve conflict prompts for binary files (r1667228 et al)
+ * fsfs: improve error messages for parsing errors (r1678147, r1678149)
+ * warn when the '--config-option' FILE:SECTION:OPTION combination may
+ be invalid. (r1674301 et al)
+ * ensure full key matching in membuffer cache (r1678950 et al)
- Client-side bugfixes:
* export: fix problem exporting symlinks on windows (r1476093)
@@ -245,8 +249,6 @@ http://svn.apache.org/repos/asf/subversi
* windows: avoid delay when user profile isn't writable (r1617926)
* merge: display the correct node kinds for tree conflicts (r1618024,
r1619418, r1619717)
- * diff: show properties of a copied dir as diffs against copy, rather than
- as adds (r1619380)
* diff: show the correct revisions in the header (r1619452)
* diff: fix missing header for files with only property changes (r1619476)
* update: raise a tree conflict rather than an obstruction when an
@@ -280,12 +282,7 @@ http://svn.apache.org/repos/asf/subversi
* update: fix a case where we reported an error rather than a tree conflict
(r1655017)
* info: Use local platform style paths in all cases (r1659283)
- * ra_serf: don't abort commits that have already succeeded in some corner
- cases (r1659867)
- * delete conflict markers of a moved file in the right location (r1660220)
* handle lack of a configuration file properly (r1660369)
- * wc: don't treat foreign repos copy as an intra-repos copy (r1660593)
- * upgrade: fix corner cases found in wc upgrades (r1660646 et al)
* update: resolve issues with tree conflicts caused by an incoming
delete removing a mixed revision tree (r1660742)
* don't hold onto locks of deleted paths in the client on commit (r1661363)
@@ -307,6 +304,8 @@ http://svn.apache.org/repos/asf/subversi
status (r1663671, r1666832)
* update: allow a real file to replace a file external (r1664035)
* merge: raise a tree conflict on root of obstructing dir (r1666690)
+ * cp: fix 'svn cp ^/A/D/H@1 ^/A' to properly create A (r1674455, r1674456)
+ * status: fix incorrect output with file externals (issue #4580)
- Server-side bugfixes:
* svnserve: don't ignore socket initialization errors (r1544253)
@@ -330,8 +329,6 @@ http://svn.apache.org/repos/asf/subversi
* mod_dav_svn: fix some pool lifetime issues with error messages (r1553868)
* mod_dav_svn: avoid setting option headers multiple times (r1557103)
* fsfs: prevent some commits that could cause future corruption (r1560673)
- * fsfs: fix a problem verifying pre-1.4 repos used with 1.8 (r1561419)
- * fsfs: fix hotcopy for pre-1.4 repositories (r1561427)
* cache: fix premature eviction due to 64-bit underflows (r1567996 et al)
* svnserve: fix potential integer overflow in Cyrus SASL support (r1570434)
* bdb: fix potential integer overflow and underflow (r1570701)
@@ -390,6 +387,9 @@ http://svn.apache.org/repos/asf/subversi
* mod_dav_svn: emit the first few log items as soon as they are available
(r1666965, r1667120)
* mod_dav_svn: prevent a tree walk on copy sources (issue #4351)
+ * fsfs: fix 'EOF found' error when reading repo (issue #4577)
+ * svnadmin freeze: unlock rep-cache.db as part of unfreezing
+ (r1679169, r1679287)
- Client-side and server-side bugfixes:
* use less memory when retrieving extension from filename (r1548480)
@@ -455,7 +455,6 @@ http://svn.apache.org/repos/asf/subversi
* improve windows build to use pre-built dependencies
* optimize ramdrive usage in the windows test runner (r1504511)
* SVN_CMDLINE_DISABLE_CRASH_HANDLER env var added for Windows (r1506507)
- * stop including some headers in win32 resource compile (r1532287)
* gen-make.py: support Visual Studio 2013 by --vsnet-version=2013
(r1533907)
* windows: don't require APR source when building (r1534037, et al)
* don't compile SQLite amalgamation twice (r1536364)
@@ -709,7 +708,6 @@ http://svn.apache.org/repos/asf/subversi
* javahl: expose whitespace diff parameters to blame method (issue #4475)
* javahl: update ConflictDescriptor (r1655842)
* javahl: update FileRevision to provide textDelta (r1656911)
- * swig: partial fix for complication problems wigh SWIG 3.0.x (r1658347)
* swig-pl: install into prefix (r1658459)
* javahl: expose the metadataOnly option to copy support (r1661451)
* swig-py: add support for svn_fs_lock_many(), svn_fs_unlock_many(),
@@ -718,6 +716,10 @@ http://svn.apache.org/repos/asf/subversi
* javahl: allow java callbacks to throw errors back to the svn code
(r1664938, r1664939, r1664940, r1664978, r1664984)
* swig-pl: fix some stack memory problems (r1668618, 1671388)
+ * swig: warn on using SWIG 3.x as we have compatibility problems
+ with newer versions of SWIG (1675149)
+ * javahl: requires Java 1.6 (r1677003)
+ * javahl: on OS X use /usr/libexec/java_home to find the JDK (r1675774)
Version 1.8.13
Modified:
subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/include/private/svn_wc_private.h
Wed May 27 10:47:54 2015
@@ -82,6 +82,8 @@ svn_wc__get_file_external_editor(const s
const char *recorded_url,
const svn_opt_revision_t *recorded_peg_rev,
const svn_opt_revision_t *recorded_rev,
+ svn_wc_conflict_resolver_func2_t
conflict_func,
+ void *conflict_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
Modified:
subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h
(original)
+++ subversion/branches/1.10-cache-improvements/subversion/include/svn_io.h Wed
May 27 10:47:54 2015
@@ -2175,6 +2175,18 @@ svn_io_file_info_get(apr_finfo_t *finfo,
apr_pool_t *pool);
+/** Set @a *filesize_p to the size of @a file. Use @a pool for temporary
+ * allocations.
+ *
+ * @note Use svn_io_file_info_get() to get more information about
+ * apr_file_t.
+ *
+ * @since New in 1.10
+ */
+svn_error_t *
+svn_io_file_size_get(svn_filesize_t *filesize_p, apr_file_t *file,
+ apr_pool_t *pool);
+
/** Wrapper for apr_file_read(). */
svn_error_t *
svn_io_file_read(apr_file_t *file,
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_client/externals.c
Wed May 27 10:47:54 2015
@@ -538,6 +538,8 @@ switch_file_external(const char *local_a
record_url,
record_peg_revision,
record_revision,
+ ctx->conflict_func2,
+ ctx->conflict_baton2,
ctx->cancel_func,
ctx->cancel_baton,
ctx->notify_func2,
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/binary_diff.c
Wed May 27 10:47:54 2015
@@ -56,7 +56,7 @@ create_compressed(apr_file_t **result,
if (original_stream)
do
{
- char buffer[SVN_STREAM_CHUNK_SIZE];
+ char buffer[SVN__STREAM_CHUNK_SIZE];
rd = sizeof(buffer);
if (cancel_func)
@@ -67,7 +67,7 @@ create_compressed(apr_file_t **result,
bytes_read += rd;
SVN_ERR(svn_stream_write(compressed, buffer, &rd));
}
- while(rd == SVN_STREAM_CHUNK_SIZE);
+ while(rd == SVN__STREAM_CHUNK_SIZE);
else
{
apr_size_t zero = 0;
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_diff/diff_file.c
Wed May 27 10:47:54 2015
@@ -777,7 +777,6 @@ datasources_open(void *baton,
{
svn_diff__file_baton_t *file_baton = baton;
struct file_info files[4];
- apr_finfo_t finfo[4];
apr_off_t length[4];
#ifndef SVN_DISABLE_PREFIX_SUFFIX_SCANNING
svn_boolean_t reached_one_eof;
@@ -792,14 +791,15 @@ datasources_open(void *baton,
/* Open datasources and read first chunk */
for (i = 0; i < datasources_len; i++)
{
+ apr_finfo_t finfo;
struct file_info *file
= &file_baton->files[datasource_to_index(datasources[i])];
SVN_ERR(svn_io_file_open(&file->file, file->path,
APR_READ, APR_OS_DEFAULT, file_baton->pool));
- SVN_ERR(svn_io_file_info_get(&finfo[i], APR_FINFO_SIZE,
- file->file, file_baton->pool));
- file->size = finfo[i].size;
- length[i] = finfo[i].size > CHUNK_SIZE ? CHUNK_SIZE : finfo[i].size;
+ SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, file->file,
+ file_baton->pool));
+ file->size = finfo.size;
+ length[i] = finfo.size > CHUNK_SIZE ? CHUNK_SIZE : finfo.size;
file->buffer = apr_palloc(file_baton->pool, (apr_size_t) length[i]);
SVN_ERR(read_chunk(file->file, file->buffer,
length[i], 0, file_baton->pool));
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/cached_data.c
Wed May 27 10:47:54 2015
@@ -2524,11 +2524,43 @@ read_dir_entries(apr_array_header_t *ent
return SVN_NO_ERROR;
}
-/* Fetch the contents of a directory into ENTRIES. Values are stored
+/* For directory NODEREV in FS, return the *FILENAME and *FILESIZE of its
+ * in-txn representation. If the directory representation is comitted data,
+ * set *FILENAME to NULL and *FILESIZE to SVN_INVALID_FILESIZE. Allocate
+ * *FILENAME in RESULT_POOL and use SCRATCH_POOL for temporaries. */
+static svn_error_t *
+get_txn_dir_info(const char **filename,
+ svn_filesize_t *filesize,
+ svn_fs_t *fs,
+ node_revision_t *noderev,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ const svn_io_dirent2_t *dirent;
+
+ if (noderev->data_rep && svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
+ {
+ *filename = svn_fs_fs__path_txn_node_children(fs, noderev->id,
+ result_pool);
+
+ SVN_ERR(svn_io_stat_dirent2(&dirent, *filename, FALSE, FALSE,
+ scratch_pool, scratch_pool));
+ *filesize = dirent->filesize;
+ }
+ else
+ {
+ *filename = NULL;
+ *filesize = SVN_INVALID_FILESIZE;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+/* Fetch the contents of a directory into DIR. Values are stored
as filename to string mappings; further conversion is necessary to
convert them into svn_fs_dirent_t values. */
static svn_error_t *
-get_dir_contents(apr_array_header_t **entries,
+get_dir_contents(svn_fs_fs__dir_data_t *dir,
svn_fs_t *fs,
node_revision_t *noderev,
apr_pool_t *result_pool,
@@ -2536,18 +2568,24 @@ get_dir_contents(apr_array_header_t **en
{
svn_stream_t *contents;
- *entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
+ /* Initialize the result. */
+ dir->entries = apr_array_make(result_pool, 16, sizeof(svn_fs_dirent_t *));
+ dir->txn_filesize = SVN_INVALID_FILESIZE;
+
+ /* Read dir contents - unless there is none in which case we are done. */
if (noderev->data_rep && svn_fs_fs__id_txn_used(&noderev->data_rep->txn_id))
{
- const char *filename
- = svn_fs_fs__path_txn_node_children(fs, noderev->id, scratch_pool);
+ /* Get location & current size of the directory representation. */
+ const char *filename;
+ SVN_ERR(get_txn_dir_info(&filename, &dir->txn_filesize, fs, noderev,
+ scratch_pool, scratch_pool));
/* The representation is mutable. Read the old directory
contents from the mutable children file, followed by the
changes we've made in this transaction. */
SVN_ERR(svn_stream_open_readonly(&contents, filename, scratch_pool,
scratch_pool));
- SVN_ERR(read_dir_entries(*entries, contents, TRUE, noderev->id,
+ SVN_ERR(read_dir_entries(dir->entries, contents, TRUE, noderev->id,
result_pool, scratch_pool));
SVN_ERR(svn_stream_close(contents));
}
@@ -2567,7 +2605,7 @@ get_dir_contents(apr_array_header_t **en
/* de-serialize hash */
contents = svn_stream_from_stringbuf(text, scratch_pool);
- SVN_ERR(read_dir_entries(*entries, contents, FALSE, noderev->id,
+ SVN_ERR(read_dir_entries(dir->entries, contents, FALSE, noderev->id,
result_pool, scratch_pool));
}
@@ -2623,6 +2661,7 @@ svn_fs_fs__rep_contents_dir(apr_array_he
{
pair_cache_key_t pair_key = { 0 };
const void *key;
+ svn_fs_fs__dir_data_t *dir;
/* find the cache we may use */
svn_cache__t *cache = locate_dir_cache(fs, &key, &pair_key, noderev,
@@ -2631,19 +2670,34 @@ svn_fs_fs__rep_contents_dir(apr_array_he
{
svn_boolean_t found;
- SVN_ERR(svn_cache__get((void **)entries_p, &found, cache, key,
+ SVN_ERR(svn_cache__get((void **)&dir, &found, cache, key,
result_pool));
if (found)
- return SVN_NO_ERROR;
+ {
+ /* Verify that the cached dir info is not stale
+ * (no-op for committed data). */
+ const char *filename;
+ svn_filesize_t filesize;
+ SVN_ERR(get_txn_dir_info(&filename, &filesize, fs, noderev,
+ scratch_pool, scratch_pool));
+
+ if (filesize == dir->txn_filesize)
+ {
+ /* Still valid. Done. */
+ *entries_p = dir->entries;
+ return SVN_NO_ERROR;
+ }
+ }
}
/* Read in the directory contents. */
- SVN_ERR(get_dir_contents(entries_p, fs, noderev, result_pool,
- scratch_pool));
+ dir = apr_pcalloc(scratch_pool, sizeof(*dir));
+ SVN_ERR(get_dir_contents(dir, fs, noderev, result_pool, scratch_pool));
+ *entries_p = dir->entries;
/* Update the cache, if we are to use one. */
if (cache)
- SVN_ERR(svn_cache__set(cache, key, *entries_p, scratch_pool));
+ SVN_ERR(svn_cache__set(cache, key, dir, scratch_pool));
return SVN_NO_ERROR;
}
@@ -2675,13 +2729,22 @@ svn_fs_fs__rep_contents_dir_entry(svn_fs
scratch_pool);
if (cache)
{
+ extract_dir_entry_baton_t baton;
+
+ const char *filename;
+ svn_filesize_t filesize;
+ SVN_ERR(get_txn_dir_info(&filename, &filesize, fs, noderev,
+ scratch_pool, scratch_pool));
+
/* Cache lookup. */
+ baton.txn_filesize = filesize;
+ baton.name = name;
SVN_ERR(svn_cache__get_partial((void **)dirent,
&found,
cache,
key,
svn_fs_fs__extract_dir_entry,
- (void*)name,
+ &baton,
result_pool));
}
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h
(original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/fs.h
Wed May 27 10:47:54 2015
@@ -623,6 +623,18 @@ typedef struct change_t
svn_fs_path_change2_t info;
} change_t;
+
+/*** Directory (only used at the cache interface) ***/
+typedef struct svn_fs_fs__dir_data_t
+{
+ /* Contents, i.e. all directory entries, sorted by name. */
+ apr_array_header_t *entries;
+
+ /* SVN_INVALID_FILESIZE for committed data, otherwise the length of the
+ * in-txn on-disk representation of that directory. */
+ svn_filesize_t txn_filesize;
+} svn_fs_fs__dir_data_t;
+
#ifdef __cplusplus
}
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.c
Wed May 27 10:47:54 2015
@@ -189,6 +189,19 @@ svn_fs_fs__unparse_revision_trailer(apr_
changes_offset);
}
+/* If ERR is not NULL, wrap it MESSAGE. The latter must have an %ld
+ * format parameter that will be filled with REV. */
+static svn_error_t *
+wrap_footer_error(svn_error_t *err,
+ const char *message,
+ svn_revnum_t rev)
+{
+ if (err)
+ return svn_error_quick_wrapf(err, message, rev);
+
+ return SVN_NO_ERROR;
+}
+
svn_error_t *
svn_fs_fs__parse_footer(apr_off_t *l2p_offset,
svn_checksum_t **l2p_checksum,
@@ -196,6 +209,7 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
svn_checksum_t **p2l_checksum,
svn_stringbuf_t *footer,
svn_revnum_t rev,
+ apr_off_t footer_offset,
apr_pool_t *result_pool)
{
apr_int64_t val;
@@ -204,17 +218,20 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
/* Get the L2P offset. */
const char *str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
- SVN_ERR(svn_cstring_atoi64(&val, str));
+ SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+ footer_offset - 1, 10),
+ "Invalid L2P offset in r%ld footer",
+ rev));
*l2p_offset = (apr_off_t)val;
/* Get the L2P checksum. */
str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
SVN_ERR(svn_checksum_parse_hex(l2p_checksum, svn_checksum_md5, str,
result_pool));
@@ -222,17 +239,33 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
/* Get the P2L offset. */
str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
- SVN_ERR(svn_cstring_atoi64(&val, str));
+ SVN_ERR(wrap_footer_error(svn_cstring_strtoi64(&val, str, 0,
+ footer_offset - 1, 10),
+ "Invalid P2L offset in r%ld footer",
+ rev));
*p2l_offset = (apr_off_t)val;
+ /* The P2L indes follows the L2P index */
+ if (*p2l_offset <= *l2p_offset)
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "P2L offset %s must be larger than L2P offset %s"
+ " in r%ld footer",
+ apr_psprintf(result_pool,
+ "%" APR_UINT64_T_HEX_FMT,
+ (apr_uint64_t)*p2l_offset),
+ apr_psprintf(result_pool,
+ "%" APR_UINT64_T_HEX_FMT,
+ (apr_uint64_t)*l2p_offset),
+ rev);
+
/* Get the P2L checksum. */
str = svn_cstring_tokenize(" ", &last_str);
if (str == NULL)
- return svn_error_create(SVN_ERR_FS_CORRUPT, NULL,
- _("Invalid revision footer"));
+ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL,
+ "Invalid r%ld footer", rev);
SVN_ERR(svn_checksum_parse_hex(p2l_checksum, svn_checksum_md5, str,
result_pool));
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/low_level.h
Wed May 27 10:47:54 2015
@@ -67,6 +67,8 @@ svn_fs_fs__unparse_revision_trailer(apr_
* *P2L_OFFSET, respectively. Also, return the expected checksums in
* in *L2P_CHECKSUM and *P2L_CHECKSUM.
*
+ * FOOTER_OFFSET is used for validation.
+ *
* Note that REV is only used to construct nicer error objects that
* mention this revision. Allocate the checksums in RESULT_POOL.
*/
@@ -77,6 +79,7 @@ svn_fs_fs__parse_footer(apr_off_t *l2p_o
svn_checksum_t **p2l_checksum,
svn_stringbuf_t *footer,
svn_revnum_t rev,
+ apr_off_t footer_offset,
apr_pool_t *result_pool);
/* Given the offset of the L2P index data in L2P_OFFSET, the content
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/rev_file.c
Wed May 27 10:47:54 2015
@@ -259,6 +259,7 @@ svn_fs_fs__auto_read_footer(svn_fs_fs__r
SVN_ERR(svn_fs_fs__parse_footer(&file->l2p_offset, &file->l2p_checksum,
&file->p2l_offset, &file->p2l_checksum,
footer, file->start_revision,
+ filesize - footer_length - 1,
file->pool));
file->footer_offset = filesize - footer_length - 1;
}
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/revprops.c
Wed May 27 10:47:54 2015
@@ -36,11 +36,6 @@
#include "svn_private_config.h"
-/* Give writing processes 10 seconds to replace an existing revprop
- file with a new one. After that time, we assume that the writing
- process got aborted and that we have re-read revprops. */
-#define REVPROP_CHANGE_TIMEOUT (10 * 1000000)
-
svn_error_t *
svn_fs_fs__upgrade_pack_revprops(svn_fs_t *fs,
svn_fs_upgrade_notify_t notify_func,
@@ -657,17 +652,23 @@ write_non_packed_revprop(const char **fi
apr_hash_t *proplist,
apr_pool_t *pool)
{
+ apr_file_t *file;
svn_stream_t *stream;
*final_path = svn_fs_fs__path_revprops(fs, rev, pool);
/* ### do we have a directory sitting around already? we really shouldn't
### have to get the dirname here. */
- SVN_ERR(svn_stream_open_unique(&stream, tmp_path,
- svn_dirent_dirname(*final_path, pool),
- svn_io_file_del_none, pool, pool));
+ SVN_ERR(svn_io_open_unique_file3(&file, tmp_path,
+ svn_dirent_dirname(*final_path, pool),
+ svn_io_file_del_none, pool, pool));
+ stream = svn_stream_from_aprfile2(file, TRUE, pool);
SVN_ERR(svn_hash_write2(proplist, stream, SVN_HASH_TERMINATOR, pool));
SVN_ERR(svn_stream_close(stream));
+ /* Flush temporary file to disk and close it. */
+ SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
+
return SVN_NO_ERROR;
}
@@ -750,7 +751,7 @@ serialize_revprops_header(svn_stream_t *
return SVN_NO_ERROR;
}
-/* Writes the a pack file to FILE_STREAM. It copies the serialized data
+/* Writes the a pack file to FILE. It copies the serialized data
* from REVPROPS for the indexes [START,END) except for index CHANGED_INDEX.
*
* The data for the latter is taken from NEW_SERIALIZED. Note, that
@@ -768,7 +769,7 @@ repack_revprops(svn_fs_t *fs,
int changed_index,
svn_stringbuf_t *new_serialized,
apr_off_t new_total_size,
- svn_stream_t *file_stream,
+ apr_file_t *file,
apr_pool_t *pool)
{
fs_fs_data_t *ffd = fs->fsap_data;
@@ -816,9 +817,11 @@ repack_revprops(svn_fs_t *fs,
? SVN_DELTA_COMPRESSION_LEVEL_DEFAULT
: SVN_DELTA_COMPRESSION_LEVEL_NONE));
- /* finally, write the content to the target stream and close it */
- SVN_ERR(svn_stream_write(file_stream, compressed->data, &compressed->len));
- SVN_ERR(svn_stream_close(file_stream));
+ /* finally, write the content to the target file, flush and close it */
+ SVN_ERR(svn_io_file_write_full(file, compressed->data, compressed->len,
+ NULL, pool));
+ SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
return SVN_NO_ERROR;
}
@@ -826,23 +829,22 @@ repack_revprops(svn_fs_t *fs,
/* Allocate a new pack file name for revisions
* [REVPROPS->START_REVISION + START, REVPROPS->START_REVISION + END - 1]
* of REVPROPS->MANIFEST. Add the name of old file to FILES_TO_DELETE,
- * auto-create that array if necessary. Return an open file stream to
- * the new file in *STREAM allocated in POOL.
+ * auto-create that array if necessary. Return an open file *FILE that is
+ * allocated in POOL.
*/
static svn_error_t *
-repack_stream_open(svn_stream_t **stream,
- svn_fs_t *fs,
- packed_revprops_t *revprops,
- int start,
- int end,
- apr_array_header_t **files_to_delete,
- apr_pool_t *pool)
+repack_file_open(apr_file_t **file,
+ svn_fs_t *fs,
+ packed_revprops_t *revprops,
+ int start,
+ int end,
+ apr_array_header_t **files_to_delete,
+ apr_pool_t *pool)
{
apr_int64_t tag;
const char *tag_string;
svn_string_t *new_filename;
int i;
- apr_file_t *file;
int manifest_offset
= (int)(revprops->start_revision - revprops->manifest_start);
@@ -874,12 +876,11 @@ repack_stream_open(svn_stream_t **stream
APR_ARRAY_IDX(revprops->manifest, i + manifest_offset, const char*)
= new_filename->data;
- /* create a file stream for the new file */
- SVN_ERR(svn_io_file_open(&file, svn_dirent_join(revprops->folder,
- new_filename->data,
- pool),
+ /* open the file */
+ SVN_ERR(svn_io_file_open(file, svn_dirent_join(revprops->folder,
+ new_filename->data,
+ pool),
APR_WRITE | APR_CREATE, APR_OS_DEFAULT, pool));
- *stream = svn_stream_from_aprfile2(file, FALSE, pool);
return SVN_NO_ERROR;
}
@@ -903,6 +904,7 @@ write_packed_revprop(const char **final_
packed_revprops_t *revprops;
apr_int64_t generation = 0;
svn_stream_t *stream;
+ apr_file_t *file;
svn_stringbuf_t *serialized;
apr_off_t new_total_size;
int changed_index;
@@ -933,11 +935,11 @@ write_packed_revprop(const char **final_
*final_path = svn_dirent_join(revprops->folder, revprops->filename,
pool);
- SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
- svn_io_file_del_none, pool, pool));
+ SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder,
+ svn_io_file_del_none, pool, pool));
SVN_ERR(repack_revprops(fs, revprops, 0, revprops->sizes->nelts,
changed_index, serialized, new_total_size,
- stream, pool));
+ file, pool));
}
else
{
@@ -983,50 +985,53 @@ write_packed_revprop(const char **final_
/* write the new, split files */
if (left_count)
{
- SVN_ERR(repack_stream_open(&stream, fs, revprops, 0,
- left_count, files_to_delete, pool));
+ SVN_ERR(repack_file_open(&file, fs, revprops, 0,
+ left_count, files_to_delete, pool));
SVN_ERR(repack_revprops(fs, revprops, 0, left_count,
changed_index, serialized, new_total_size,
- stream, pool));
+ file, pool));
}
if (left_count + right_count < revprops->sizes->nelts)
{
- SVN_ERR(repack_stream_open(&stream, fs, revprops, changed_index,
- changed_index + 1, files_to_delete,
- pool));
+ SVN_ERR(repack_file_open(&file, fs, revprops, changed_index,
+ changed_index + 1, files_to_delete,
+ pool));
SVN_ERR(repack_revprops(fs, revprops, changed_index,
changed_index + 1,
changed_index, serialized, new_total_size,
- stream, pool));
+ file, pool));
}
if (right_count)
{
- SVN_ERR(repack_stream_open(&stream, fs, revprops,
- revprops->sizes->nelts - right_count,
- revprops->sizes->nelts,
- files_to_delete, pool));
+ SVN_ERR(repack_file_open(&file, fs, revprops,
+ revprops->sizes->nelts - right_count,
+ revprops->sizes->nelts,
+ files_to_delete, pool));
SVN_ERR(repack_revprops(fs, revprops,
revprops->sizes->nelts - right_count,
revprops->sizes->nelts, changed_index,
- serialized, new_total_size, stream,
+ serialized, new_total_size, file,
pool));
}
/* write the new manifest */
*final_path = svn_dirent_join(revprops->folder, PATH_MANIFEST, pool);
- SVN_ERR(svn_stream_open_unique(&stream, tmp_path, revprops->folder,
- svn_io_file_del_none, pool, pool));
+ SVN_ERR(svn_io_open_unique_file3(&file, tmp_path, revprops->folder,
+ svn_io_file_del_none, pool, pool));
for (i = 0; i < revprops->manifest->nelts; ++i)
{
const char *filename = APR_ARRAY_IDX(revprops->manifest, i,
const char*);
- SVN_ERR(svn_stream_printf(stream, pool, "%s\n", filename));
+ SVN_ERR(svn_io_file_write_full(file, filename, strlen(filename),
+ NULL, pool));
+ SVN_ERR(svn_io_file_putc('\n', file, pool));
}
- SVN_ERR(svn_stream_close(stream));
+ SVN_ERR(svn_io_file_flush_to_disk(file, pool));
+ SVN_ERR(svn_io_file_close(file, pool));
}
return SVN_NO_ERROR;
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.c
Wed May 27 10:47:54 2015
@@ -153,6 +153,10 @@ typedef struct dir_data_t
* (it's int because the directory is an APR array) */
int count;
+ /** Current length of the in-txn in-disk representation of the directory.
+ * SVN_INVALID_FILESIZE if unknown (i.e. committed data). */
+ svn_filesize_t txn_filesize;
+
/* number of unused dir entry buckets in the index */
apr_size_t over_provision;
@@ -198,15 +202,16 @@ serialize_dir_entry(svn_temp_serializer_
svn_temp_serializer__pop(context);
}
-/* Utility function to serialize the ENTRIES into a new serialization
+/* Utility function to serialize the DIR into a new serialization
* context to be returned. Allocation will be made form POOL.
*/
static svn_temp_serializer__context_t *
-serialize_dir(apr_array_header_t *entries, apr_pool_t *pool)
+serialize_dir(svn_fs_fs__dir_data_t *dir, apr_pool_t *pool)
{
dir_data_t dir_data;
int i = 0;
svn_temp_serializer__context_t *context;
+ apr_array_header_t *entries = dir->entries;
/* calculate sizes */
int count = entries->nelts;
@@ -216,6 +221,7 @@ serialize_dir(apr_array_header_t *entrie
/* copy the hash entries to an auxiliary struct of known layout */
dir_data.count = count;
+ dir_data.txn_filesize = dir->txn_filesize;
dir_data.over_provision = over_provision;
dir_data.operations = 0;
dir_data.entries = apr_palloc(pool, entries_len);
@@ -252,24 +258,29 @@ serialize_dir(apr_array_header_t *entrie
return context;
}
-/* Utility function to reconstruct a dir entries array from serialized data
+/* Utility function to reconstruct a dir entries struct from serialized data
* in BUFFER and DIR_DATA. Allocation will be made form POOL.
*/
-static apr_array_header_t *
+static svn_fs_fs__dir_data_t *
deserialize_dir(void *buffer, dir_data_t *dir_data, apr_pool_t *pool)
{
- apr_array_header_t *result
- = apr_array_make(pool, dir_data->count, sizeof(svn_fs_dirent_t *));
+ svn_fs_fs__dir_data_t *result;
apr_size_t i;
apr_size_t count;
svn_fs_dirent_t *entry;
svn_fs_dirent_t **entries;
+ /* Construct empty directory object. */
+ result = apr_pcalloc(pool, sizeof(*result));
+ result->entries
+ = apr_array_make(pool, dir_data->count, sizeof(svn_fs_dirent_t *));
+ result->txn_filesize = dir_data->txn_filesize;
+
/* resolve the reference to the entries array */
svn_temp_deserializer__resolve(buffer, (void **)&dir_data->entries);
entries = dir_data->entries;
- /* fixup the references within each entry and add it to the hash */
+ /* fixup the references within each entry and add it to the RESULT */
for (i = 0, count = dir_data->count; i < count; ++i)
{
svn_temp_deserializer__resolve(entries, (void **)&entries[i]);
@@ -280,7 +291,7 @@ deserialize_dir(void *buffer, dir_data_t
svn_fs_fs__id_deserialize(entry, (svn_fs_id_t **)&entry->id);
/* add the entry to the hash */
- APR_ARRAY_PUSH(result, svn_fs_dirent_t *) = entry;
+ APR_ARRAY_PUSH(result->entries, svn_fs_dirent_t *) = entry;
}
/* return the now complete hash */
@@ -764,7 +775,7 @@ svn_fs_fs__serialize_dir_entries(void **
void *in,
apr_pool_t *pool)
{
- apr_array_header_t *dir = in;
+ svn_fs_fs__dir_data_t *dir = in;
/* serialize the dir content into a new serialization context
* and return the serialized data */
@@ -803,6 +814,20 @@ svn_fs_fs__get_sharded_offset(void **out
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_fs_fs__extract_dir_filesize(void **out,
+ const void *data,
+ apr_size_t data_len,
+ void *baton,
+ apr_pool_t *pool)
+{
+ const dir_data_t *dir_data = data;
+
+ *(svn_filesize_t *)out = dir_data->txn_filesize;
+
+ return SVN_NO_ERROR;
+}
+
/* Utility function that returns the lowest index of the first entry in
* *ENTRIES that points to a dir entry with a name equal or larger than NAME.
* If an exact match has been found, *FOUND will be set to TRUE. COUNT is
@@ -857,7 +882,7 @@ svn_fs_fs__extract_dir_entry(void **out,
apr_pool_t *pool)
{
const dir_data_t *dir_data = data;
- const char* name = baton;
+ const extract_dir_entry_baton_t *entry_baton = baton;
svn_boolean_t found;
/* resolve the reference to the entries array */
@@ -870,13 +895,14 @@ svn_fs_fs__extract_dir_entry(void **out,
/* binary search for the desired entry by name */
apr_size_t pos = find_entry((svn_fs_dirent_t **)entries,
- name,
+ entry_baton->name,
dir_data->count,
&found);
- /* de-serialize that entry or return NULL, if no match has been found */
+ /* de-serialize that entry or return NULL, if no match has been found.
+ * Be sure to check that the directory contents is still up-to-date. */
*out = NULL;
- if (found)
+ if (found && dir_data->txn_filesize == entry_baton->txn_filesize)
{
const svn_fs_dirent_t *source =
svn_temp_deserializer__ptr(entries, (const void *const
*)&entries[pos]);
@@ -911,31 +937,34 @@ slowly_replace_dir_entry(void **data,
{
replace_baton_t *replace_baton = (replace_baton_t *)baton;
dir_data_t *dir_data = (dir_data_t *)*data;
- apr_array_header_t *dir;
+ svn_fs_fs__dir_data_t *dir;
int idx = -1;
svn_fs_dirent_t *entry;
+ apr_array_header_t *entries;
SVN_ERR(svn_fs_fs__deserialize_dir_entries((void **)&dir,
*data,
dir_data->len,
pool));
- entry = svn_fs_fs__find_dir_entry(dir, replace_baton->name, &idx);
+ entries = dir->entries;
+ entry = svn_fs_fs__find_dir_entry(entries, replace_baton->name, &idx);
/* Replacement or removal? */
if (replace_baton->new_entry)
{
/* Replace ENTRY with / insert the NEW_ENTRY */
if (entry)
- APR_ARRAY_IDX(dir, idx, svn_fs_dirent_t *) = replace_baton->new_entry;
+ APR_ARRAY_IDX(entries, idx, svn_fs_dirent_t *)
+ = replace_baton->new_entry;
else
- svn_sort__array_insert(dir, &replace_baton->new_entry, idx);
+ svn_sort__array_insert(entries, &replace_baton->new_entry, idx);
}
else
{
/* Remove the old ENTRY. */
if (entry)
- svn_sort__array_delete(dir, idx, 1);
+ svn_sort__array_delete(entries, idx, 1);
}
return svn_fs_fs__serialize_dir_entries(data, data_len, dir, pool);
@@ -957,6 +986,12 @@ svn_fs_fs__replace_dir_entry(void **data
svn_temp_serializer__context_t *context;
+ /* update the cached file length info.
+ * Because we are writing to the cache, it is fair to assume that the
+ * caller made sure that the current contents is consistent with the
+ * previous state of the directory file. */
+ dir_data->txn_filesize = replace_baton->txn_filesize;
+
/* after quite a number of operations, let's re-pack everything.
* This is to limit the number of wasted space as we cannot overwrite
* existing data but must always append. */
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/temp_serializer.h
Wed May 27 10:47:54 2015
@@ -192,7 +192,7 @@ svn_fs_fs__deserialize_node_revision(voi
apr_pool_t *pool);
/**
- * Implements #svn_cache__serialize_func_t for a directory contents array
+ * Implements #svn_cache__serialize_func_t for a #svn_fs_fs__dir_data_t
*/
svn_error_t *
svn_fs_fs__serialize_dir_entries(void **data,
@@ -201,7 +201,7 @@ svn_fs_fs__serialize_dir_entries(void **
apr_pool_t *pool);
/**
- * Implements #svn_cache__deserialize_func_t for a directory contents array
+ * Implements #svn_cache__deserialize_func_t for a #svn_fs_fs__dir_data_t
*/
svn_error_t *
svn_fs_fs__deserialize_dir_entries(void **out,
@@ -221,9 +221,38 @@ svn_fs_fs__get_sharded_offset(void **out
apr_pool_t *pool);
/**
+ * Implements #svn_cache__partial_getter_func_t.
+ * Set (svn_filesize_t) @a *out to the filesize info stored with the
+ * serialized directory in @a data of @a data_len. @a baton is unused.
+ */
+svn_error_t *
+svn_fs_fs__extract_dir_filesize(void **out,
+ const void *data,
+ apr_size_t data_len,
+ void *baton,
+ apr_pool_t *pool);
+
+/**
+ * Describes the entry to be found in a directory: Identifies the entry
+ * by @a name and requires the directory file size to be @a filesize.
+ */
+typedef struct extract_dir_entry_baton_t
+{
+ /** name of the directory entry to return */
+ const char *name;
+
+ /** Current length of the in-txn in-disk representation of the directory.
+ * SVN_INVALID_FILESIZE if unknown. */
+ svn_filesize_t txn_filesize;
+} extract_dir_entry_baton_t;
+
+
+/**
* Implements #svn_cache__partial_getter_func_t for a single
* #svn_fs_dirent_t within a serialized directory contents hash,
- * identified by its name (const char @a *baton).
+ * identified by its name (in (extract_dir_entry_baton_t *) @a *baton).
+ * If the filesize specified in the baton does not match the cached
+ * value for this directory, @a *out will be NULL as well.
*/
svn_error_t *
svn_fs_fs__extract_dir_entry(void **out,
@@ -236,7 +265,10 @@ svn_fs_fs__extract_dir_entry(void **out,
* Describes the change to be done to a directory: Set the entry
* identify by @a name to the value @a new_entry. If the latter is
* @c NULL, the entry shall be removed if it exists. Otherwise it
- * will be replaced or automatically added, respectively.
+ * will be replaced or automatically added, respectively. The
+ * @a filesize allows readers to identify stale cache data (e.g.
+ * due to concurrent access to txns); writers use it to update the
+ * cached file size info.
*/
typedef struct replace_baton_t
{
@@ -245,6 +277,10 @@ typedef struct replace_baton_t
/** directory entry to insert instead */
svn_fs_dirent_t *new_entry;
+
+ /** Current length of the in-txn in-disk representation of the directory.
+ * SVN_INVALID_FILESIZE if unknown. */
+ svn_filesize_t txn_filesize;
} replace_baton_t;
/**
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_fs_fs/transaction.c
Wed May 27 10:47:54 2015
@@ -1524,22 +1524,80 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
}
else
{
+ const svn_io_dirent2_t *dirent;
+
/* The directory rep is already mutable, so just open it for append. */
SVN_ERR(svn_io_file_open(&file, filename, APR_WRITE | APR_APPEND,
- APR_OS_DEFAULT, pool));
- out = svn_stream_from_aprfile2(file, TRUE, pool);
+ APR_OS_DEFAULT, subpool));
+ out = svn_stream_from_aprfile2(file, TRUE, subpool);
+
+ /* If the cache contents is stale, drop it.
+ *
+ * Note that the directory file is append-only, i.e. if the size
+ * did not change, the contents didn't either. */
+ if (ffd->txn_dir_cache)
+ {
+ const char *key
+ = svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
+ svn_boolean_t found;
+ svn_filesize_t filesize;
+
+ /* Get the file size that corresponds to the cached contents
+ * (if any). */
+ SVN_ERR(svn_cache__get_partial((void **)&filesize, &found,
+ ffd->txn_dir_cache, key,
+ svn_fs_fs__extract_dir_filesize,
+ NULL, subpool));
+
+ /* File size info still matches?
+ * If not, we need to drop the cache entry. */
+ if (found)
+ {
+ SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+ subpool, subpool));
+
+ if (filesize != dirent->filesize)
+ SVN_ERR(svn_cache__set(ffd->txn_dir_cache, key, NULL,
+ subpool));
+ }
+ }
}
+ /* Append an incremental hash entry for the entry change. */
+ if (id)
+ {
+ svn_fs_dirent_t entry;
+ entry.name = name;
+ entry.id = id;
+ entry.kind = kind;
+
+ SVN_ERR(unparse_dir_entry(&entry, out, subpool));
+ }
+ else
+ {
+ SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
+ strlen(name), name));
+ }
+
+ /* Flush APR buffers. */
+ SVN_ERR(svn_io_file_close(file, subpool));
+ svn_pool_clear(subpool);
+
/* if we have a directory cache for this transaction, update it */
if (ffd->txn_dir_cache)
{
- /* build parameters: (name, new entry) pair */
+ /* build parameters: name, new entry, new file size */
const char *key =
svn_fs_fs__id_unparse(parent_noderev->id, subpool)->data;
replace_baton_t baton;
+ const svn_io_dirent2_t *dirent;
+ SVN_ERR(svn_io_stat_dirent2(&dirent, filename, FALSE, FALSE,
+ subpool, subpool));
+
baton.name = name;
baton.new_entry = NULL;
+ baton.txn_filesize = dirent->filesize;
if (id)
{
@@ -1554,25 +1612,7 @@ svn_fs_fs__set_entry(svn_fs_t *fs,
svn_fs_fs__replace_dir_entry, &baton,
subpool));
}
- svn_pool_clear(subpool);
- /* Append an incremental hash entry for the entry change. */
- if (id)
- {
- svn_fs_dirent_t entry;
- entry.name = name;
- entry.id = id;
- entry.kind = kind;
-
- SVN_ERR(unparse_dir_entry(&entry, out, subpool));
- }
- else
- {
- SVN_ERR(svn_stream_printf(out, subpool, "D %" APR_SIZE_T_FMT "\n%s\n",
- strlen(name), name));
- }
-
- SVN_ERR(svn_io_file_close(file, subpool));
svn_pool_destroy(subpool);
return SVN_NO_ERROR;
}
@@ -2225,7 +2265,7 @@ get_shared_rep(representation_t **old_re
{
/* Make the problem show up in the server log.
- Because not sharing reps is always a save option,
+ Because not sharing reps is always a safe option,
terminating the request would be inappropriate.
*/
svn_checksum_t checksum;
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/cache-membuffer.c
Wed May 27 10:47:54 2015
@@ -2882,8 +2882,15 @@ combine_key(svn_membuffer_cache_t *cache
memcpy(data, key, key_len);
}
- /* scramble key DATA. All of this must be reversible to prevent key
- * collisions. So, we limit ourselves to xor and permutations. */
+ /* Scramble key DATA to spread the key space more evenly across the
+ * cache segments and entry buckets. All of this shall be reversible
+ * to prevent key collisions. So, we limit ourselves to xor and
+ * permutations.
+ *
+ * As long as we compare the full combined key, the additional
+ * fingerprint collisions introduced by a non-reversible scramble
+ * would simply reduce the cache effectiveness.
+ */
data[1] = (data[1] << 27) | (data[1] >> 37);
data[1] ^= data[0] & 0xffff;
data[0] ^= data[1] & APR_UINT64_C(0xffffffffffff0000);
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c
(original)
+++ subversion/branches/1.10-cache-improvements/subversion/libsvn_subr/io.c Wed
May 27 10:47:54 2015
@@ -3582,6 +3582,16 @@ svn_io_file_info_get(apr_finfo_t *finfo,
pool);
}
+svn_error_t *
+svn_io_file_size_get(svn_filesize_t *filesize_p, apr_file_t *file,
+ apr_pool_t *pool)
+{
+ apr_finfo_t finfo;
+ SVN_ERR(svn_io_file_info_get(&finfo, APR_FINFO_SIZE, file, pool));
+
+ *filesize_p = finfo.size;
+ return SVN_NO_ERROR;
+}
svn_error_t *
svn_io_file_read(apr_file_t *file, void *buf,
Modified:
subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/libsvn_wc/externals.c
Wed May 27 10:47:54 2015
@@ -462,9 +462,10 @@ struct edit_baton
const apr_array_header_t *ext_patterns;
const char *diff3cmd;
- const char *url;
const char *repos_root_url;
const char *repos_uuid;
+ const char *old_repos_relpath;
+ const char *new_repos_relpath;
const char *record_ancestor_abspath;
const char *recorded_repos_relpath;
@@ -474,6 +475,8 @@ struct edit_baton
/* Introducing a new file external */
svn_boolean_t added;
+ svn_wc_conflict_resolver_func2_t conflict_func;
+ void *conflict_baton;
svn_cancel_func_t cancel_func;
void *cancel_baton;
svn_wc_notify_func2_t notify_func;
@@ -572,7 +575,8 @@ open_file(const char *path,
*file_baton = eb;
SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, &eb->original_revision,
- NULL, NULL, NULL, &eb->changed_rev,
+ &eb->old_repos_relpath, NULL, NULL,
+ &eb->changed_rev,
&eb->changed_date, &eb->changed_author,
NULL, &eb->original_checksum, NULL, NULL,
&eb->had_props, NULL, NULL,
@@ -733,8 +737,6 @@ close_file(void *file_baton,
const svn_checksum_t *original_checksum = NULL;
svn_boolean_t added = !SVN_IS_VALID_REVNUM(eb->original_revision);
- const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
- eb->url, pool);
if (! added)
{
@@ -908,14 +910,14 @@ close_file(void *file_baton,
svn_wc_conflict_version_create2(
eb->repos_root_url,
eb->repos_uuid,
- repos_relpath,
+ eb->old_repos_relpath,
eb->original_revision,
svn_node_file,
pool),
svn_wc_conflict_version_create2(
eb->repos_root_url,
eb->repos_uuid,
- repos_relpath,
+ eb->new_repos_relpath,
*eb->target_revision,
svn_node_file,
pool),
@@ -933,7 +935,7 @@ close_file(void *file_baton,
eb->db,
eb->local_abspath,
eb->wri_abspath,
- repos_relpath,
+ eb->new_repos_relpath,
eb->repos_root_url,
eb->repos_uuid,
*eb->target_revision,
@@ -963,6 +965,18 @@ close_file(void *file_baton,
/* Run the work queue to complete the installation */
SVN_ERR(svn_wc__wq_run(eb->db, eb->wri_abspath,
eb->cancel_func, eb->cancel_baton, pool));
+
+ if (conflict_skel && eb->conflict_func)
+ SVN_ERR(svn_wc__conflict_invoke_resolver(eb->db,
+ eb->local_abspath,
+ svn_node_file,
+ conflict_skel,
+ NULL /* merge_options */,
+ eb->conflict_func,
+ eb->conflict_baton,
+ eb->cancel_func,
+ eb->cancel_baton,
+ pool));
}
/* Notify */
@@ -1002,6 +1016,7 @@ close_edit(void *edit_baton,
if (!eb->file_closed)
{
+ apr_hash_t *wcroot_iprops = NULL;
/* The file wasn't updated, but its url or revision might have...
e.g. switch between branches for relative externals.
@@ -1009,53 +1024,26 @@ close_edit(void *edit_baton,
investigating when we should and shouldn't update it...
and avoid hard to debug edge cases */
- svn_node_kind_t kind;
- const char *old_repos_relpath;
- svn_revnum_t changed_rev;
- apr_time_t changed_date;
- const char *changed_author;
- const svn_checksum_t *checksum;
- apr_hash_t *pristine_props;
- const char *repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url,
- eb->url, pool);
-
- SVN_ERR(svn_wc__db_base_get_info(NULL, &kind, NULL, &old_repos_relpath,
- NULL, NULL, &changed_rev, &changed_date,
- &changed_author, NULL, &checksum, NULL,
- NULL, NULL, &pristine_props, NULL,
- eb->db, eb->local_abspath,
- pool, pool));
+ if (eb->iprops)
+ {
+ wcroot_iprops = apr_hash_make(pool);
+ svn_hash_sets(wcroot_iprops, eb->local_abspath, eb->iprops);
+ }
- if (kind != svn_node_file)
- return svn_error_createf(SVN_ERR_WC_PATH_UNEXPECTED_STATUS, NULL,
- _("Node '%s' is no existing file external"),
- svn_dirent_local_style(eb->local_abspath,
- pool));
-
- SVN_ERR(svn_wc__db_external_add_file(
- eb->db,
- eb->local_abspath,
- eb->wri_abspath,
- repos_relpath,
- eb->repos_root_url,
- eb->repos_uuid,
- *eb->target_revision,
- pristine_props,
- eb->iprops,
- eb->changed_rev,
- eb->changed_date,
- eb->changed_author,
- checksum,
- NULL /* clear dav props */,
- eb->record_ancestor_abspath,
- eb->recorded_repos_relpath,
- eb->recorded_peg_revision,
- eb->recorded_revision,
- FALSE, NULL,
- TRUE /* keep_recorded_info */,
- NULL /* conflict_skel */,
- NULL /* work_items */,
- pool));
+ SVN_ERR(svn_wc__db_op_bump_revisions_post_update(eb->db,
+ eb->local_abspath,
+ svn_depth_infinity,
+ eb->new_repos_relpath,
+ eb->repos_root_url,
+ eb->repos_uuid,
+ *eb->target_revision,
+ apr_hash_make(pool)
+ /* exclude_relpaths */,
+ wcroot_iprops,
+ TRUE /* empty update */,
+ eb->notify_func,
+ eb->notify_baton,
+ pool));
}
return SVN_NO_ERROR;
@@ -1079,6 +1067,8 @@ svn_wc__get_file_external_editor(const s
const char *recorded_url,
const svn_opt_revision_t *recorded_peg_rev,
const svn_opt_revision_t *recorded_rev,
+ svn_wc_conflict_resolver_func2_t
conflict_func,
+ void *conflict_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_notify_func2_t notify_func,
@@ -1101,9 +1091,12 @@ svn_wc__get_file_external_editor(const s
eb->name = svn_dirent_basename(eb->local_abspath, NULL);
eb->target_revision = target_revision;
- eb->url = apr_pstrdup(edit_pool, url);
eb->repos_root_url = apr_pstrdup(edit_pool, repos_root_url);
eb->repos_uuid = apr_pstrdup(edit_pool, repos_uuid);
+ eb->new_repos_relpath = svn_uri_skip_ancestor(eb->repos_root_url, url,
edit_pool);
+ eb->old_repos_relpath = eb->new_repos_relpath;
+
+ eb->original_revision = SVN_INVALID_REVNUM;
eb->iprops = iprops;
@@ -1127,6 +1120,8 @@ svn_wc__get_file_external_editor(const s
else
eb->recorded_revision = SVN_INVALID_REVNUM; /* Not fixed/HEAD */
+ eb->conflict_func = conflict_func;
+ eb->conflict_baton = conflict_baton;
eb->cancel_func = cancel_func;
eb->cancel_baton = cancel_baton;
eb->notify_func = notify_func;
Modified:
subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/svn/conflict-callbacks.c
Wed May 27 10:47:54 2015
@@ -1130,6 +1130,8 @@ handle_tree_conflict(svn_wc_conflict_res
apr_pool_t *scratch_pool)
{
const char *readable_desc;
+ const char *src_left_version;
+ const char *src_right_version;
apr_pool_t *iterpool;
SVN_ERR(svn_cl__get_human_readable_tree_conflict_description(
@@ -1142,6 +1144,21 @@ handle_tree_conflict(svn_wc_conflict_res
scratch_pool),
readable_desc));
+ src_left_version =
+ svn_cl__node_description(desc->src_left_version,
+ desc->src_left_version->repos_url,
+ scratch_pool);
+ if (src_left_version)
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
+ _("Source left"), src_left_version));
+ src_right_version =
+ svn_cl__node_description(desc->src_right_version,
+ desc->src_right_version->repos_url,
+ scratch_pool);
+ if (src_right_version)
+ SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "%s: %s\n",
+ _("Source right"), src_right_version));
+
iterpool = svn_pool_create(scratch_pool);
while (1)
{
Modified: subversion/branches/1.10-cache-improvements/subversion/svn/svn.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/svn/svn.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/svn/svn.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/svn/svn.c Wed May 27
10:47:54 2015
@@ -398,7 +398,7 @@ const apr_getopt_option_t svn_cl__option
" "
"svn:externals properties")},
{"show-inherited-props", opt_show_inherited_props, 0,
- N_("retrieve target's inherited properties")},
+ N_("retrieve properties set on parents of the target")},
{"search", opt_search, 1,
N_("use ARG as search pattern (glob syntax)")},
{"search-and", opt_search_and, 1,
@@ -1445,8 +1445,13 @@ const svn_opt_subcommand_desc2_t svn_cl_
" directory:\n"
" svn:ignore - A list of file glob patterns to ignore, one per
line.\n"
" svn:global-ignores - Like svn:ignore, but inheritable.\n"
- " svn:auto-props - A list of file glob patterns and properties to
set\n"
- " when adding such files; like [auto-props] in the client
configuration.\n"
+ " svn:auto-props - Automatically set properties on files when they
are\n"
+ " added or imported. Contains key-value pairs, one per line, in the
format:\n"
+ " PATTERN = PROPNAME=VALUE[;PROPNAME=VALUE ...]\n"
+ " Example (where a literal ';' is escaped by adding another ';'):\n"
+ " *.html = svn:eol-style=native;svn:mime-type=text/html;;
charset=UTF8\n"
+ " Applies recursively to all files added or imported under the
directory\n"
+ " it is set on. See also [auto-props] in the client configuration
file.\n"
" svn:externals - A list of module specifiers, one per line, in
the\n"
" following format similar to the syntax of 'svn checkout':\n"
" [-r REV] URL[@PEG] LOCALPATH\n"
Modified:
subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/externals_tests.py
Wed May 27 10:47:54 2015
@@ -4155,6 +4155,153 @@ def file_external_to_normal_file(sbox):
svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
expected_status)
+@Issue(4580)
+def file_external_recorded_info(sbox):
+ "check file external recorded info"
+
+ sbox.build()
+ wc_dir = sbox.wc_dir
+
+ # r2 - Create file external
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', '',
+ 'propset', 'svn:externals',
+ '^/iota i', '')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ '' : Item(status=' U'),
+ 'i' : Item(status='A '),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.add({
+ 'i' : Item(status=' ', wc_rev='2', switched='X')
+ })
+ svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+ expected_status, [], False,
+ '-r', 2, wc_dir)
+
+ expected_infos = [{
+ 'Path': re.escape(sbox.ospath('i')),
+ 'Relative URL': re.escape('^/iota'),
+ 'Revision': '2',
+ 'Last Changed Rev': '1',
+ 'Last Changed Author': 'jrandom'
+ }]
+ svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+ # r3 - No-op change
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', '',
+ 'cp', '1', 'iota', 'iotb')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'iotb' : Item(status='A '),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+ expected_status.add({
+ 'i' : Item(status=' ', wc_rev='3', switched='X'),
+ 'iotb' : Item(status=' ', wc_rev='3')
+ })
+ svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+ expected_status, [], False,
+ '-r', 3, wc_dir)
+
+ expected_infos = [{
+ 'Path': re.escape(sbox.ospath('i')),
+ 'Relative URL': re.escape('^/iota'),
+ 'Revision': '3',
+ 'Last Changed Rev': '1',
+ 'Last Changed Author': 'jrandom'
+ }]
+ svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+ # r4 - Update url
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', '',
+ 'propset', 'svn:externals',
+ '^/iotb i', '')
+
+
+ expected_output = svntest.wc.State(wc_dir, {
+ '' : Item(status=' U'),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 4)
+ expected_status.add({
+ 'i' : Item(status=' ', wc_rev='4', switched='X'),
+ 'iotb' : Item(status=' ', wc_rev='4')
+ })
+ svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+ expected_status, [], False,
+ '-r', 4, wc_dir)
+
+ expected_infos = [{
+ 'Path': re.escape(sbox.ospath('i')),
+ 'Relative URL': re.escape('^/iotb'),
+ 'Revision': '4',
+ 'Last Changed Rev': '3',
+ 'Last Changed Author': 'jrandom'
+ }]
+ svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+ # r5 - Replace file
+ svntest.actions.run_and_verify_svnmucc(None, [],
+ '-U', sbox.repo_url,
+ '-m', '',
+ 'rm', 'iotb',
+ 'cp', '3', 'A/mu', 'iotb')
+
+ expected_output = svntest.wc.State(wc_dir, {
+ 'i' : Item(status='U '),
+ 'iotb' : Item(status='A ', prev_status='D '),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 5)
+ expected_status.add({
+ 'i' : Item(status=' ', wc_rev='5', switched='X'),
+ 'iotb' : Item(status=' ', wc_rev='5')
+ })
+ svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+ expected_status, [], False,
+ '-r', 5, wc_dir)
+
+ expected_infos = [{
+ 'Path': re.escape(sbox.ospath('i')),
+ 'Relative URL': re.escape('^/iotb'),
+ 'Revision': '5',
+ 'Last Changed Rev': '5',
+ 'Last Changed Author': 'jrandom'
+ }]
+ svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
+ # Back to r2. But with a conflict
+ sbox.simple_append('i', 'i')
+ expected_output = svntest.wc.State(wc_dir, {
+ '' : Item(status=' U'),
+ 'iotb' : Item(status='D '),
+ 'i' : Item(status='C '),
+ })
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+ expected_status.add({
+ 'i' : Item(status='C ', wc_rev='5', switched='X'),
+ })
+ svntest.actions.run_and_verify_update(wc_dir, expected_output, None,
+ expected_status, [], False,
+ '-r', 2, wc_dir)
+
+ expected_infos = [{
+ 'Path': re.escape(sbox.ospath('i')),
+ 'Relative URL': re.escape('^/iota'),
+ 'Revision': '5',
+ 'Last Changed Rev': '1',
+ 'Last Changed Author': 'jrandom',
+ 'Conflict Details': re.escape('incoming file edit upon switch'
+ ' Source left: (file) ^/iotb@5'
+ ' Source right: (file) ^/iota@5')
+ }]
+ svntest.actions.run_and_verify_info(expected_infos, sbox.ospath('i'))
+
########################################################################
# Run the tests
@@ -4229,6 +4376,7 @@ test_list = [ None,
copy_pin_externals_whitespace_dir,
nested_notification,
file_external_to_normal_file,
+ file_external_recorded_info,
]
if __name__ == '__main__':
Propchange:
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed May 27 10:47:54 2015
@@ -1,7 +1,7 @@
.libs
test-*
locks-test
-fs-test
+fs-*test
*.o
*.lo
*~
Modified:
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-sequential-test.c
Wed May 27 10:47:54 2015
@@ -251,9 +251,8 @@ static int max_threads = 1; /* Run test
static struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
- SVN_TEST_OPTS_XFAIL_OTOH(reopen_modify,
- "test reopen and modify txn",
- SVN_TEST_PASS_IF_FS_TYPE_IS_NOT("fsfs")),
+ SVN_TEST_OPTS_PASS(reopen_modify,
+ "test reopen and modify txn"),
SVN_TEST_NULL
};
Modified:
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
Wed May 27 10:47:54 2015
@@ -6939,7 +6939,7 @@ freeze_and_commit(const svn_test_opts_t
/* Make some commit using same FS instance. */
SVN_ERR(svn_fs_begin_txn(&txn, fs, new_rev, pool));
SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
- SVN_ERR(svn_fs_change_node_prop(txn_root, "/", "temperature",
+ SVN_ERR(svn_fs_change_node_prop(txn_root, "", "temperature",
svn_string_create("310.05", pool),
pool));
SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));
Modified:
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c?rev=1681963&r1=1681962&r2=1681963&view=diff
==============================================================================
---
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
(original)
+++
subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
Wed May 27 10:47:54 2015
@@ -782,7 +782,47 @@ test_install_stream_to_longpath(apr_pool
return SVN_NO_ERROR;
}
-
+
+static svn_error_t *
+test_file_size_get(apr_pool_t *pool)
+{
+ const char *tmp_dir, *path;
+ apr_file_t *file;
+ svn_filesize_t filesize;
+
+ /* Create an empty directory. */
+ SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "test_file_size_get", pool));
+ SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
+ SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
+ svn_test_add_dir_cleanup(tmp_dir);
+
+ /* Path does not exist. */
+ path = svn_dirent_join(tmp_dir, "file", pool);
+
+ /* Create a file.*/
+ SVN_ERR(svn_io_file_open(&file, path,
+ APR_WRITE | APR_CREATE | APR_BUFFERED,
+ APR_OS_DEFAULT, pool));
+ SVN_ERR(svn_io_file_size_get(&filesize, file, pool));
+ SVN_TEST_ASSERT(filesize == 0);
+
+ /* Write 8 bytes and check new size. */
+ SVN_ERR(svn_io_file_write_full(file, "12345678", 8, NULL, pool));
+
+ SVN_ERR(svn_io_file_size_get(&filesize, file, pool));
+ SVN_TEST_ASSERT(filesize == 8);
+
+ /* Truncate to 2 bytes. */
+ SVN_ERR(svn_io_file_trunc(file, 2, pool));
+
+ SVN_ERR(svn_io_file_size_get(&filesize, file, pool));
+ SVN_TEST_ASSERT(filesize == 2);
+
+ /* Close the file. */
+ SVN_ERR(svn_io_file_close(file, pool));
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
static int max_threads = 3;
@@ -806,6 +846,8 @@ static struct svn_test_descriptor_t test
"test ignore-enoent"),
SVN_TEST_PASS2(test_install_stream_to_longpath,
"test svn_stream__install_stream to long path"),
+ SVN_TEST_PASS2(test_file_size_get,
+ "test svn_io_file_size_get"),
SVN_TEST_NULL
};