You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by sv...@apache.org on 2015/09/11 06:00:14 UTC

svn commit: r1702370 - in /subversion/branches/1.9.x: ./ STATUS subversion/include/private/svn_io_private.h subversion/libsvn_subr/io.c subversion/libsvn_subr/stream.c

Author: svn-role
Date: Fri Sep 11 04:00:13 2015
New Revision: 1702370

URL: http://svn.apache.org/r1702370
Log:
Merge the r1701064 group from trunk:

 * r1701064, r1701206, r1701298, r1701736
   Fix Access Denied errors on checkout/update with working copies stored on
   SMBv1 network shares [1], [2]. This also should fix potential spurious
   'access denied' errors with local working copies and background
   indexers/antiviruses.
   [1] http://svn.haxx.se/dev/archive-2015-09/0054.shtml
   [2] http://tortoisesvn.tigris.org/ds/viewMessage.do?dsForumId=4061&dsMessageId=3134203
   Justification:
     Regression from Subversion 1.8.x.
   Notes:
     The r1701298, r1701736 patches are the fix (re-introduce a retry loop to
     handle cases where the target of the replacement is still open by another
     application and handle access denied for SMBv1), r1701064 and r1701206
     are just formatting fixes and cleanups.
   Votes:
     +1: rhuijben, ivan, kotkov

Modified:
    subversion/branches/1.9.x/   (props changed)
    subversion/branches/1.9.x/STATUS
    subversion/branches/1.9.x/subversion/include/private/svn_io_private.h
    subversion/branches/1.9.x/subversion/libsvn_subr/io.c
    subversion/branches/1.9.x/subversion/libsvn_subr/stream.c

Propchange: subversion/branches/1.9.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Sep 11 04:00:13 2015
@@ -93,4 +93,4 @@
 /subversion/branches/verify-at-commit:1462039-1462408
 /subversion/branches/verify-keep-going:1439280-1546110
 /subversion/branches/wc-collate-path:1402685-1480384
-/subversion/trunk:1660545-1660547,1660549-1662901,1663003,1663183-1663184,1663338,1663347,1663355,1663374,1663450,1663530,1663671,1663697,1663706,1663738,1663749,1663791,1663991,1664035,1664078,1664080,1664084-1664085,1664187,1664191,1664193,1664200,1664344,1664476,1664480-1664481,1664483,1664489-1664490,1664507,1664520-1664521,1664523,1664526-1664527,1664531-1664532,1664588,1664593-1664594,1664596,1664653,1664664,1664672,1664674,1664684,1664927,1664938-1664940,1664978,1664984,1664997,1665164,1665195,1665213,1665259,1665318,1665437-1665438,1665609,1665611-1665612,1665845,1665850,1665852,1665886,1665894,1665896,1666096,1666258,1666270,1666272,1666379,1666449,1666690,1666832,1666851,1666965,1667101,1667106-1667107,1667120,1667228,1667233-1667235,1667249-1667250,1667258,1667290,1667301,1667471,1667691-1667693,1667699-1667700,1667715,1667941,1667976,1668320,1668598-1668600,1668602-1668603,1668607-1668608,1668618,1669743,1669746,1669749,1669945,1670139,1670149,1670152,1670329,1670337,167
 0347,1670353,1671164,1671388,1672295,1672311,1672372,1672404,1672511-1672512,1672578,1672728,1673044,1673062-1673063,1673065,1673153,1673170,1673172,1673197,1673202,1673204,1673228,1673282,1673445,1673691-1673692,1673746,1673785,1673803,1674015,1674032,1674170,1674301,1674305,1674308,1674339-1674340,1674406,1674415,1674455-1674456,1674475,1674487,1674522,1674580,1674626-1674627,1674785,1674891,1675771,1675774,1676526,1676535,1676538,1676555,1676564,1676570,1676665,1676667,1676769,1677003,1677191,1677267,1677440,1678147,1678149,1678494,1678571,1678734,1678742,1678745-1678746,1678839,1678846,1678894,1678950,1678963,1679166,1679169,1679228,1679230,1679287,1679864,1679866,1679909,1680242,1680264,1680495,1680705,1680819,1681317,1682714,1682854,1683071,1683126,1683135,1683290,1683303,1683311,1683378,1683387,1684034,1684077,1684322,1684325,1684344,1684412,1684940,1685034,1685085,1686175,1686239,1686478,1686541,1686543,1686554,1686557,1686802,1686888,1686984,1687029,1687304,1687389,1687769,
 1687776,1688258,1688273,1688395,1689214,1689216,1689721,1689729,1691712-1691713,1691924,1691928,1692091,1692093,1692098,1692448,1692469-1692470,1692798-1692799,1693135,1693138,1693159,1693886,1694023,1694194,1694481,1694929,1695022,1695600,1695606,1695681,1696222,1696225,1696387,1696695,1697381,1697384,1697387,1697664,1697824,1697835,1697845,1697914,1697967,1698106,1700740,1700951,1701633,1701792,1701797
+/subversion/trunk:1660545-1660547,1660549-1662901,1663003,1663183-1663184,1663338,1663347,1663355,1663374,1663450,1663530,1663671,1663697,1663706,1663738,1663749,1663791,1663991,1664035,1664078,1664080,1664084-1664085,1664187,1664191,1664193,1664200,1664344,1664476,1664480-1664481,1664483,1664489-1664490,1664507,1664520-1664521,1664523,1664526-1664527,1664531-1664532,1664588,1664593-1664594,1664596,1664653,1664664,1664672,1664674,1664684,1664927,1664938-1664940,1664978,1664984,1664997,1665164,1665195,1665213,1665259,1665318,1665437-1665438,1665609,1665611-1665612,1665845,1665850,1665852,1665886,1665894,1665896,1666096,1666258,1666270,1666272,1666379,1666449,1666690,1666832,1666851,1666965,1667101,1667106-1667107,1667120,1667228,1667233-1667235,1667249-1667250,1667258,1667290,1667301,1667471,1667691-1667693,1667699-1667700,1667715,1667941,1667976,1668320,1668598-1668600,1668602-1668603,1668607-1668608,1668618,1669743,1669746,1669749,1669945,1670139,1670149,1670152,1670329,1670337,167
 0347,1670353,1671164,1671388,1672295,1672311,1672372,1672404,1672511-1672512,1672578,1672728,1673044,1673062-1673063,1673065,1673153,1673170,1673172,1673197,1673202,1673204,1673228,1673282,1673445,1673691-1673692,1673746,1673785,1673803,1674015,1674032,1674170,1674301,1674305,1674308,1674339-1674340,1674406,1674415,1674455-1674456,1674475,1674487,1674522,1674580,1674626-1674627,1674785,1674891,1675771,1675774,1676526,1676535,1676538,1676555,1676564,1676570,1676665,1676667,1676769,1677003,1677191,1677267,1677440,1678147,1678149,1678494,1678571,1678734,1678742,1678745-1678746,1678839,1678846,1678894,1678950,1678963,1679166,1679169,1679228,1679230,1679287,1679864,1679866,1679909,1680242,1680264,1680495,1680705,1680819,1681317,1682714,1682854,1683071,1683126,1683135,1683290,1683303,1683311,1683378,1683387,1684034,1684077,1684322,1684325,1684344,1684412,1684940,1685034,1685085,1686175,1686239,1686478,1686541,1686543,1686554,1686557,1686802,1686888,1686984,1687029,1687304,1687389,1687769,
 1687776,1688258,1688273,1688395,1689214,1689216,1689721,1689729,1691712-1691713,1691924,1691928,1692091,1692093,1692098,1692448,1692469-1692470,1692798-1692799,1693135,1693138,1693159,1693886,1694023,1694194,1694481,1694929,1695022,1695600,1695606,1695681,1696222,1696225,1696387,1696695,1697381,1697384,1697387,1697664,1697824,1697835,1697845,1697914,1697967,1698106,1700740,1700951,1701064,1701206,1701298,1701633,1701736,1701792,1701797

Modified: subversion/branches/1.9.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/STATUS?rev=1702370&r1=1702369&r2=1702370&view=diff
==============================================================================
--- subversion/branches/1.9.x/STATUS (original)
+++ subversion/branches/1.9.x/STATUS Fri Sep 11 04:00:13 2015
@@ -136,20 +136,3 @@ Veto-blocked changes:
 
 Approved changes:
 =================
-
- * r1701064, r1701206, r1701298, r1701736
-   Fix Access Denied errors on checkout/update with working copies stored on
-   SMBv1 network shares [1], [2]. This also should fix potential spurious
-   'access denied' errors with local working copies and background
-   indexers/antiviruses.
-   [1] http://svn.haxx.se/dev/archive-2015-09/0054.shtml
-   [2] http://tortoisesvn.tigris.org/ds/viewMessage.do?dsForumId=4061&dsMessageId=3134203
-   Justification:
-     Regression from Subversion 1.8.x.
-   Notes:
-     The r1701298, r1701736 patches are the fix (re-introduce a retry loop to
-     handle cases where the target of the replacement is still open by another
-     application and handle access denied for SMBv1), r1701064 and r1701206
-     are just formatting fixes and cleanups.
-   Votes:
-     +1: rhuijben, ivan, kotkov

Modified: subversion/branches/1.9.x/subversion/include/private/svn_io_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/include/private/svn_io_private.h?rev=1702370&r1=1702369&r2=1702370&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/include/private/svn_io_private.h (original)
+++ subversion/branches/1.9.x/subversion/include/private/svn_io_private.h Fri Sep 11 04:00:13 2015
@@ -171,6 +171,26 @@ svn_error_t*
 svn_io__utf8_to_unicode_longpath(const WCHAR **result,
                                  const char *source,
                                  apr_pool_t *result_pool);
+
+/* This Windows-specific function marks the file to be deleted on close using
+   an existing file handle. It can be used to avoid having to reopen the file
+   as part of the delete handling. Return SVN_ERR_UNSUPPORTED_FEATURE if
+   delete on close operation is not supported by OS. */
+svn_error_t *
+svn_io__win_delete_file_on_close(apr_file_t *file,
+                                 const char *path,
+                                 apr_pool_t *pool);
+
+/* This Windows-specific function renames the file using an existing file
+   handle. It can be used to avoid having to reopen the file as part of the
+   rename operation. Return SVN_ERR_UNSUPPORTED_FEATURE if renaming open
+   file is not supported by OS.*/
+svn_error_t *
+svn_io__win_rename_open_file(apr_file_t *file,
+                             const char *from_path,
+                             const char *to_path,
+                             apr_pool_t *pool);
+
 #endif /* WIN32 */
 
 #ifdef __cplusplus

Modified: subversion/branches/1.9.x/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/libsvn_subr/io.c?rev=1702370&r1=1702369&r2=1702370&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/1.9.x/subversion/libsvn_subr/io.c Fri Sep 11 04:00:13 2015
@@ -142,6 +142,23 @@
 #endif
 
 #ifdef WIN32
+
+#if _WIN32_WINNT < 0x600 /* Does the SDK assume Windows Vista+? */
+typedef struct _FILE_RENAME_INFO {
+  BOOL   ReplaceIfExists;
+  HANDLE RootDirectory;
+  DWORD  FileNameLength;
+  WCHAR  FileName[1];
+} FILE_RENAME_INFO, *PFILE_RENAME_INFO;
+
+typedef struct _FILE_DISPOSITION_INFO {
+  BOOL DeleteFile;
+} FILE_DISPOSITION_INFO, *PFILE_DISPOSITION_INFO;
+
+#define FileRenameInfo 3
+#define FileDispositionInfo 4
+#endif /* WIN32 < Vista */
+
 /* One-time initialization of the late bound Windows API functions. */
 static volatile svn_atomic_t win_dynamic_imports_state = 0;
 
@@ -152,7 +169,13 @@ typedef DWORD (WINAPI *GETFINALPATHNAMEB
                DWORD cchFilePath,
                DWORD dwFlags);
 
+typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile,
+                                                    int FileInformationClass,
+                                                    LPVOID lpFileInformation,
+                                                    DWORD dwBufferSize);
+
 static GETFINALPATHNAMEBYHANDLE get_final_path_name_by_handle_proc = NULL;
+static SetFileInformationByHandle_t set_file_information_by_handle_proc = NULL;
 
 /* Forward declaration. */
 static svn_error_t * io_win_read_link(svn_string_t **dest,
@@ -1861,11 +1884,18 @@ io_win_file_attrs_set(const char *fname,
 
 static svn_error_t *win_init_dynamic_imports(void *baton, apr_pool_t *pool)
 {
-    get_final_path_name_by_handle_proc = (GETFINALPATHNAMEBYHANDLE)
-      GetProcAddress(GetModuleHandleA("kernel32.dll"),
-                     "GetFinalPathNameByHandleW");
+  HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
 
-    return SVN_NO_ERROR;
+  if (kernel32)
+    {
+      get_final_path_name_by_handle_proc = (GETFINALPATHNAMEBYHANDLE)
+        GetProcAddress(kernel32, "GetFinalPathNameByHandleW");
+
+      set_file_information_by_handle_proc = (SetFileInformationByHandle_t)
+        GetProcAddress(kernel32, "SetFileInformationByHandle");
+    }
+
+  return SVN_NO_ERROR;
 }
 
 static svn_error_t * io_win_read_link(svn_string_t **dest,
@@ -1937,6 +1967,130 @@ static svn_error_t * io_win_read_link(sv
       }
 }
 
+/* Wrapper around Windows API function SetFileInformationByHandle() that
+ * returns APR status instead of boolean flag. */
+static apr_status_t
+win32_set_file_information_by_handle(HANDLE hFile,
+                                     int FileInformationClass,
+                                     LPVOID lpFileInformation,
+                                     DWORD dwBufferSize)
+{
+  svn_error_clear(svn_atomic__init_once(&win_dynamic_imports_state,
+                                        win_init_dynamic_imports,
+                                        NULL, NULL));
+
+  if (!set_file_information_by_handle_proc)
+    {
+      return SVN_ERR_UNSUPPORTED_FEATURE;
+    }
+
+  if (!set_file_information_by_handle_proc(hFile, FileInformationClass,
+                                           lpFileInformation,
+                                           dwBufferSize))
+    {
+      return apr_get_os_error();
+    }
+
+  return APR_SUCCESS;
+}
+
+svn_error_t *
+svn_io__win_delete_file_on_close(apr_file_t *file,
+                                 const char *path,
+                                 apr_pool_t *pool)
+{
+  FILE_DISPOSITION_INFO disposition_info;
+  HANDLE hFile;
+  apr_status_t status;
+
+  apr_os_file_get(&hFile, file);
+
+  disposition_info.DeleteFile = TRUE;
+
+  status = win32_set_file_information_by_handle(hFile, FileDispositionInfo,
+                                                &disposition_info,
+                                                sizeof(disposition_info));
+
+  if (status)
+    {
+      return svn_error_wrap_apr(status, _("Can't remove file '%s'"),
+                                svn_dirent_local_style(path, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io__win_rename_open_file(apr_file_t *file,
+                             const char *from_path,
+                             const char *to_path,
+                             apr_pool_t *pool)
+{
+  WCHAR *w_final_abspath;
+  size_t path_len;
+  size_t rename_size;
+  FILE_RENAME_INFO *rename_info;
+  HANDLE hFile;
+  apr_status_t status;
+
+  apr_os_file_get(&hFile, file);
+
+  SVN_ERR(svn_io__utf8_to_unicode_longpath(
+            &w_final_abspath, svn_dirent_local_style(to_path,pool),
+            pool));
+
+  path_len = wcslen(w_final_abspath);
+  rename_size = sizeof(*rename_info) + sizeof(WCHAR) * path_len;
+
+  /* The rename info struct doesn't need hacks for long paths,
+     so no ugly escaping calls here */
+  rename_info = apr_pcalloc(pool, rename_size);
+  rename_info->ReplaceIfExists = TRUE;
+  rename_info->FileNameLength = path_len;
+  memcpy(rename_info->FileName, w_final_abspath, path_len * sizeof(WCHAR));
+
+  status = win32_set_file_information_by_handle(hFile, FileRenameInfo,
+                                                rename_info,
+                                                rename_size);
+
+  if (APR_STATUS_IS_EACCES(status) || APR_STATUS_IS_EEXIST(status))
+    {
+      /* Set the destination file writable because Windows will not allow
+         us to rename when final_abspath is read-only. */
+      SVN_ERR(svn_io_set_file_read_write(to_path, TRUE, pool));
+
+      status = win32_set_file_information_by_handle(hFile,
+                                                    FileRenameInfo,
+                                                    rename_info,
+                                                    rename_size);
+   }
+
+  /* Windows returns Vista+ client accessing network share stored on Windows
+     Server 2003 returns ERROR_ACCESS_DENIED. The same happens when Vista+
+     client access Windows Server 2008 with disabled SMBv2 protocol.
+
+     So return SVN_ERR_UNSUPPORTED_FEATURE in this case like we do when
+     SetFileInformationByHandle() is not available and let caller to
+     handle it.
+
+     See "Access denied error on checkout-commit after updating to 1.9.X"
+     discussion on dev@s.a.o:
+     http://svn.haxx.se/dev/archive-2015-09/0054.shtml */
+  if (status == APR_FROM_OS_ERROR(ERROR_ACCESS_DENIED))
+    {
+      status = SVN_ERR_UNSUPPORTED_FEATURE;
+    }
+
+  if (status)
+    {
+      return svn_error_wrap_apr(status, _("Can't move '%s' to '%s'"),
+                                svn_dirent_local_style(from_path, pool),
+                                svn_dirent_local_style(to_path, pool));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 #endif /* WIN32 */
 
 svn_error_t *

Modified: subversion/branches/1.9.x/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.9.x/subversion/libsvn_subr/stream.c?rev=1702370&r1=1702369&r2=1702370&view=diff
==============================================================================
--- subversion/branches/1.9.x/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/1.9.x/subversion/libsvn_subr/stream.c Fri Sep 11 04:00:13 2015
@@ -2028,48 +2028,6 @@ struct install_baton_t
 
 #ifdef WIN32
 
-#if _WIN32_WINNT < 0x600 /* Does the SDK assume Windows Vista+? */
-typedef struct _FILE_RENAME_INFO {
-  BOOL   ReplaceIfExists;
-  HANDLE RootDirectory;
-  DWORD  FileNameLength;
-  WCHAR  FileName[1];
-} FILE_RENAME_INFO, *PFILE_RENAME_INFO;
-
-typedef struct _FILE_DISPOSITION_INFO {
-  BOOL DeleteFile;
-} FILE_DISPOSITION_INFO, *PFILE_DISPOSITION_INFO;
-
-#define FileRenameInfo 3
-#define FileDispositionInfo 4
-
-typedef BOOL (WINAPI *SetFileInformationByHandle_t)(HANDLE hFile,
-                                                    int FileInformationClass,
-                                                    LPVOID lpFileInformation,
-                                                    DWORD dwBufferSize);
-
-static volatile SetFileInformationByHandle_t SetFileInformationByHandle_p = 0;
-#define SetFileInformationByHandle (*SetFileInformationByHandle_p)
-
-static volatile svn_atomic_t SetFileInformationByHandle_a = 0;
-
-
-static svn_error_t *
-find_SetFileInformationByHandle(void *baton, apr_pool_t *scratch_pool)
-{
-  HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
-
-  if (kernel32)
-    {
-      SetFileInformationByHandle_p =
-                    (SetFileInformationByHandle_t)
-                      GetProcAddress(kernel32, "SetFileInformationByHandle");
-    }
-
-  return SVN_NO_ERROR;
-}
-#endif /* WIN32 < Vista */
-
 /* Create and open a tempfile in DIRECTORY. Return its handle and path */
 static svn_error_t *
 create_tempfile(HANDLE *hFile,
@@ -2227,98 +2185,40 @@ svn_stream__install_stream(svn_stream_t
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(final_abspath));
 #ifdef WIN32
-
-#if _WIN32_WINNT < 0x600
-  SVN_ERR(svn_atomic__init_once(&SetFileInformationByHandle_a,
-                                find_SetFileInformationByHandle,
-                                NULL, scratch_pool));
-
-  if (!SetFileInformationByHandle_p)
-    SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
-  else
-#endif /* WIN32 < Windows Vista */
+  err = svn_io__win_rename_open_file(ib->baton_apr.file,  ib->tmp_path,
+                                     final_abspath, scratch_pool);
+  if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
     {
-      WCHAR *w_final_abspath;
-      size_t path_len;
-      size_t rename_size;
-      FILE_RENAME_INFO *rename_info;
-      HANDLE hFile;
-
-      apr_os_file_get(&hFile, ib->baton_apr.file);
-
-      SVN_ERR(svn_io__utf8_to_unicode_longpath(&w_final_abspath,
-                                               svn_dirent_local_style(
-                                                          final_abspath,
-                                                          scratch_pool),
-                                               scratch_pool));
-      path_len = wcslen(w_final_abspath);
-      rename_size = sizeof(*rename_info) + sizeof(WCHAR) * path_len;
-
-      /* The rename info struct doesn't need hacks for long paths,
-         so no ugly escaping calls here */
-      rename_info = apr_pcalloc(scratch_pool, rename_size);
-      rename_info->ReplaceIfExists = TRUE;
-      rename_info->FileNameLength = path_len;
-      memcpy(rename_info->FileName, w_final_abspath, path_len * sizeof(WCHAR));
+      svn_error_t *err2;
 
-      if (!SetFileInformationByHandle(hFile, FileRenameInfo, rename_info,
-                                      rename_size))
-        {
-          svn_boolean_t retry = FALSE;
-          err = svn_error_wrap_apr(apr_get_os_error(), NULL);
+      err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
+                                                    scratch_pool),
+                                         scratch_pool);
 
-          /* ### rhuijben: I wouldn't be surprised if we later find out that we
-                           have to fall back to close+rename on some specific
-                           error values here, to support some non standard NAS
-                           and filesystem scenarios. */
-
-          if (make_parents && err && APR_STATUS_IS_ENOENT(err->apr_err))
-            {
-              svn_error_t *err2;
+      if (err2)
+        return svn_error_trace(svn_error_compose_create(err, err2));
+      else
+        svn_error_clear(err);
 
-              err2 = svn_io_make_dir_recursively(svn_dirent_dirname(final_abspath,
-                                                            scratch_pool),
-                                                 scratch_pool);
+      err = svn_io__win_rename_open_file(ib->baton_apr.file, ib->tmp_path,
+                                         final_abspath, scratch_pool);
+    }
 
-              if (err2)
-                return svn_error_trace(svn_error_compose_create(err, err2));
-              else
-                svn_error_clear(err);
-
-              retry = TRUE;
-              err = NULL;
-            }
-          else if (err && (APR_STATUS_IS_EACCES(err->apr_err)
-                           || APR_STATUS_IS_EEXIST(err->apr_err)))
-            {
-              svn_error_clear(err);
-              retry = TRUE;
-              err = NULL;
-
-              /* Set the destination file writable because Windows will not allow
-                 us to rename when final_abspath is read-only. */
-              SVN_ERR(svn_io_set_file_read_write(final_abspath, TRUE,
-                                                 scratch_pool));
-            }
-
-          if (retry)
-            {
-              if (!SetFileInformationByHandle(hFile, FileRenameInfo,
-                                              rename_info, rename_size))
-                {
-                  err = svn_error_wrap_apr(
-                                apr_get_os_error(),
-                                _("Can't move '%s' to '%s'"),
-                                svn_dirent_local_style(ib->tmp_path,
-                                                       scratch_pool),
-                                svn_dirent_local_style(final_abspath,
-                                                       scratch_pool));
-                }
-            }
-        }
-      else
-        err = NULL;
+  /* ### rhuijben: I wouldn't be surprised if we later find out that we
+                   have to fall back to close+rename on some specific
+                   error values here, to support some non standard NAS
+                   and filesystem scenarios. */
+  if (err && err->apr_err == SVN_ERR_UNSUPPORTED_FEATURE)
+    {
+      /* Rename open files is not supported on this platform: fallback to
+         svn_io_file_rename2(). */
+      svn_error_clear(err);
+      err = SVN_NO_ERROR;
 
+      SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
+    }
+  else
+    {
       return svn_error_compose_create(err,
                                       svn_io_file_close(ib->baton_apr.file,
                                                         scratch_pool));
@@ -2382,37 +2282,22 @@ svn_stream__install_delete(svn_stream_t
   struct install_baton_t *ib = install_stream->baton;
 
 #ifdef WIN32
-  BOOL done;
-
-#if _WIN32_WINNT < 0x600
-
-  SVN_ERR(svn_atomic__init_once(&SetFileInformationByHandle_a,
-                                find_SetFileInformationByHandle,
-                                NULL, scratch_pool));
+  svn_error_t *err;
 
-  if (!SetFileInformationByHandle_p)
-    done = FALSE;
-  else
-#endif /* WIN32 < Windows Vista */
+  /* Mark the file as delete on close to avoid having to reopen
+     the file as part of the delete handling. */
+  err = svn_io__win_delete_file_on_close(ib->baton_apr.file,  ib->tmp_path,
+                                         scratch_pool);
+  if (err == SVN_NO_ERROR)
     {
-      FILE_DISPOSITION_INFO disposition_info;
-      HANDLE hFile;
-
-      apr_os_file_get(&hFile, ib->baton_apr.file);
-
-      disposition_info.DeleteFile = TRUE;
-
-      /* Mark the file as delete on close to avoid having to reopen
-         the file as part of the delete handling. */
-      done = SetFileInformationByHandle(hFile, FileDispositionInfo,
-                                        &disposition_info,
-                                        sizeof(disposition_info));
+      SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
+      return SVN_NO_ERROR; /* File is already gone */
     }
 
-   SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
-
-   if (done)
-     return SVN_NO_ERROR; /* File is already gone */
+  /* Deleting file on close may be unsupported, so ignore errors and
+     fallback to svn_io_remove_file2(). */
+  svn_error_clear(err);
+  SVN_ERR(svn_io_file_close(ib->baton_apr.file, scratch_pool));
 #endif
 
   return svn_error_trace(svn_io_remove_file2(ib->tmp_path, FALSE,