Author: stefan2
Date: Wed Dec 1 00:15:11 2010
New Revision: 1040832
URL: http://svn.apache.org/viewvc?rev=1040832&view=rev
Log:
Port (not merge) a fix for a FSFS packing race condition from the
performance branch to /trunk: There is a slight time window
between finding the name of a rev file and actually open it. If
the revision in question gets packed just within this window,
we will find the new (and final) file name with just one retry.
* subversion/libsvn_fs_fs/fs_fs.c
(open_pack_or_rev_file): retry once upon "missing file" error
Modified:
subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1040832&r1=1040831&r2=1040832&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Wed Dec 1 00:15:11 2010
@@ -1903,21 +1903,42 @@ open_pack_or_rev_file(apr_file_t **file,
{
svn_error_t *err;
const char *path;
+ svn_boolean_t retry = FALSE;
- err = svn_fs_fs__path_rev_absolute(&path, fs, rev, pool);
+ do
+ {
+ err = svn_fs_fs__path_rev_absolute(&path, fs, rev, pool);
- if (! err)
- err = svn_io_file_open(file, path,
- APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
+ /* open the revision file in buffered r/o mode */
+ if (! err)
+ err = svn_io_file_open(file, path,
+ APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool);
- if (err && APR_STATUS_IS_ENOENT(err->apr_err))
- {
- svn_error_clear(err);
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), rev);
+ if (err && APR_STATUS_IS_ENOENT(err->apr_err))
+ {
+ /* Could not open the file. This may happen if the
+ * file once existed but got packed later. */
+ svn_error_clear(err);
+
+ /* if that was our 2nd attempt, leave it at that. */
+ if (retry)
+ return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+ _("No such revision %ld"), rev);
+
+ /* we failed for the first time. Refresh cache & retry. */
+ SVN_ERR(update_min_unpacked_rev(fs, pool));
+
+ retry = TRUE;
+ }
+ else
+ {
+ /* the file exists but something prevented us from opnening it */
+ return svn_error_return(err);
+ }
}
+ while (err);
- return svn_error_return(err);
+ return SVN_NO_ERROR;
}
/* Given REV in FS, set *REV_OFFSET to REV's offset in the packed file.