Index: subversion/libsvn_fs_fs/fs_fs.c =================================================================== --- subversion/libsvn_fs_fs/fs_fs.c (revision 29335) +++ subversion/libsvn_fs_fs/fs_fs.c (working copy) @@ -1090,14 +1090,15 @@ * after the close, at the end of your loop. Immediately after your * loop, return err if err. * - * You must initialize err to SVN_NO_ERROR, as these macros do not. + * You must initialize err to SVN_NO_ERROR and filehandle to NULL, as + * these macros do not. */ #define SVN_ESTALE_RETRY_COUNT 10 #ifdef ESTALE -#define SVN_RETRY_ESTALE(err, expr) \ - { \ +#define SVN_RETRY_ESTALE(err, filehandle, expr) \ + { \ /* Clear err here (svn_error_clear can safely be passed * SVN_NO_ERROR) rather than after finding ESTALE so we can return * the ESTALE error on the last iteration of the loop. */ \ @@ -1105,8 +1106,13 @@ err = (expr); \ if (err) \ { \ - if (APR_TO_OS_ERROR(err->apr_err) == ESTALE) \ - continue; \ + apr_status_t _e = APR_TO_OS_ERROR(err->apr_err); \ + /* ENOENT can only happen for open calls */ \ + if ((_e == ESTALE) || (_e == EIO) || (_e == ENOENT)) { \ + if (NULL != filehandle) \ + (void)apr_file_close(filehandle); \ + continue; \ + } \ return err; \ } \ } @@ -1116,12 +1122,13 @@ err = (expr); \ if (err) \ { \ - if (APR_TO_OS_ERROR(err->apr_err) != ESTALE) \ + apr_status_t _e = APR_TO_OS_ERROR(err->apr_err); \ + if ((_e != ESTALE) && (_e != EIO)) \ return err; \ } \ } #else -#define SVN_RETRY_ESTALE(err, expr) SVN_ERR(expr) +#define SVN_RETRY_ESTALE(err, filehandle, expr) SVN_ERR(expr) #define SVN_IGNORE_ESTALE(err, expr) SVN_ERR(expr) #endif @@ -1139,7 +1146,7 @@ static svn_error_t * read_current(const char *fname, char **buf, apr_pool_t *pool) { - apr_file_t *revision_file; + apr_file_t *revision_file = NULL; apr_size_t len; int i; svn_error_t *err = SVN_NO_ERROR; @@ -1151,13 +1158,15 @@ { svn_pool_clear(iterpool); - SVN_RETRY_ESTALE(err, svn_io_file_open(&revision_file, fname, - APR_READ | APR_BUFFERED, - APR_OS_DEFAULT, iterpool)); + SVN_RETRY_ESTALE(err, revision_file, + svn_io_file_open(&revision_file, fname, + APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, iterpool)); len = CURRENT_BUF_LEN; - SVN_RETRY_ESTALE(err, svn_io_read_length_line(revision_file, - *buf, &len, iterpool)); + SVN_RETRY_ESTALE(err, revision_file, + svn_io_read_length_line(revision_file, + *buf, &len, iterpool)); SVN_IGNORE_ESTALE(err, svn_io_file_close(revision_file, iterpool)); break; @@ -2148,7 +2157,7 @@ svn_revnum_t rev, apr_pool_t *pool) { - apr_file_t *revprop_file; + apr_file_t *revprop_file = NULL; apr_hash_t *proplist; svn_error_t *err = SVN_NO_ERROR; int i; @@ -2185,7 +2194,7 @@ } SVN_ERR(svn_hash__clear(proplist)); - SVN_RETRY_ESTALE(err, + SVN_RETRY_ESTALE(err, revprop_file, svn_hash_read2(proplist, svn_stream_from_aprfile(revprop_file, iterpool), @@ -3519,7 +3528,7 @@ { struct get_and_increment_txn_key_baton *cb = baton; const char *txn_current_filename = path_txn_current(cb->fs, pool); - apr_file_t *txn_current_file; + apr_file_t *txn_current_file = NULL; const char *tmp_filename; char next_txn_id[MAX_KEY_SIZE+3]; svn_error_t *err = SVN_NO_ERROR; @@ -3534,15 +3543,17 @@ { svn_pool_clear(iterpool); - SVN_RETRY_ESTALE(err, svn_io_file_open(&txn_current_file, - txn_current_filename, - APR_READ | APR_BUFFERED, - APR_OS_DEFAULT, iterpool)); + SVN_RETRY_ESTALE(err, txn_current_file, + svn_io_file_open(&txn_current_file, + txn_current_filename, + APR_READ | APR_BUFFERED, + APR_OS_DEFAULT, iterpool)); len = MAX_KEY_SIZE; - SVN_RETRY_ESTALE(err, svn_io_read_length_line(txn_current_file, - cb->txn_id, - &len, - iterpool)); + SVN_RETRY_ESTALE(err, txn_current_file, + svn_io_read_length_line(txn_current_file, + cb->txn_id, + &len, + iterpool)); SVN_IGNORE_ESTALE(err, svn_io_file_close(txn_current_file, iterpool)); break;