You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/02/22 23:39:35 UTC

svn commit: r915101 - in /subversion/branches/1.6.x: ./ CHANGES STATUS subversion/libsvn_subr/io.c

Author: hwright
Date: Mon Feb 22 22:39:34 2010
New Revision: 915101

URL: http://svn.apache.org/viewvc?rev=915101&view=rev
Log:
Reintegrate the 1.6.x-r898963 branch:

 * r898963, r899826, r899828
   Fix issue #3501 - Repos & wc issues with some NFS clients, notably NetBSD,
   due to buggy interaction between unlink, rewinddir, and NFS caching.
   Branch resolves two trivial conflicts.
   Justification:
     Bug reporter says, "For me, this problem forces us to stay with
     Subversion 1.4."
   Branch:
     ^/subversion/branches/1.6.x-r898963
   Votes:
     +1: peters, rhuijben, stsp

Modified:
    subversion/branches/1.6.x/   (props changed)
    subversion/branches/1.6.x/CHANGES   (props changed)
    subversion/branches/1.6.x/STATUS
    subversion/branches/1.6.x/subversion/libsvn_subr/io.c

Propchange: subversion/branches/1.6.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 22 22:39:34 2010
@@ -25,6 +25,7 @@
 /subversion/branches/1.6.x-r40452:880530-890996
 /subversion/branches/1.6.x-r889840:889888-890974
 /subversion/branches/1.6.x-r896522:896528-897866
+/subversion/branches/1.6.x-r898963:899874-915098
 /subversion/branches/bdb-reverse-deltas:868395-868874
 /subversion/branches/diff-callbacks3:866404-867106
 /subversion/branches/dont-save-plaintext-passwords-by-default:867073-867463
@@ -54,4 +55,4 @@
 /subversion/branches/tc_url_rev:870696-870828
 /subversion/branches/tree-conflicts:864636-869499
 /subversion/branches/tree-conflicts-notify:870271-870353
-/subversion/trunk:875976,875980-875981,876054-876056,876092,876175,876299,876306,876427,876440,876450,876507,876571,879093,879688,880274-880275,880370,880450,880474,880525-880526,881905,884842,886164,886197,888715,888979,889081,889840,895514,895653,896522,900797
+/subversion/trunk:875976,875980-875981,876054-876056,876092,876175,876299,876306,876427,876440,876450,876507,876571,879093,879688,880274-880275,880370,880450,880474,880525-880526,881905,884842,886164,886197,888715,888979,889081,889840,895514,895653,896522,898963,899826,899828,900797

Propchange: subversion/branches/1.6.x/CHANGES
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Feb 22 22:39:34 2010
@@ -25,6 +25,7 @@
 /subversion/branches/1.6.x-r40452/CHANGES:880530-890996
 /subversion/branches/1.6.x-r889840/CHANGES:889888-890974
 /subversion/branches/1.6.x-r896522/CHANGES:896528-897866
+/subversion/branches/1.6.x-r898963/CHANGES:899874-915098
 /subversion/branches/bdb-reverse-deltas/CHANGES:868395-868874
 /subversion/branches/diff-callbacks3/CHANGES:866404-867106
 /subversion/branches/dont-save-plaintext-passwords-by-default/CHANGES:867073-867463

Modified: subversion/branches/1.6.x/STATUS
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x/STATUS?rev=915101&r1=915100&r2=915101&view=diff
==============================================================================
--- subversion/branches/1.6.x/STATUS (original)
+++ subversion/branches/1.6.x/STATUS Mon Feb 22 22:39:34 2010
@@ -271,16 +271,3 @@
 
 Approved changes:
 =================
-
- * r898963, r899826, r899828
-   Fix issue #3501 - Repos & wc issues with some NFS clients, notably NetBSD,
-   due to buggy interaction between unlink, rewinddir, and NFS caching.
-   Branch resolves two trivial conflicts.
-   Justification:
-     Bug reporter says, "For me, this problem forces us to stay with
-     Subversion 1.4."
-   Branch:
-     ^/subversion/branches/1.6.x-r898963
-   Votes:
-     +1: peters, rhuijben, stsp
-

Modified: subversion/branches/1.6.x/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.6.x/subversion/libsvn_subr/io.c?rev=915101&r1=915100&r2=915101&view=diff
==============================================================================
--- subversion/branches/1.6.x/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/1.6.x/subversion/libsvn_subr/io.c Mon Feb 22 22:39:34 2010
@@ -1862,17 +1862,12 @@
 
  Similar problem has been observed on FreeBSD.
 
- See http://subversion.tigris.org/issues/show_bug.cgi?id=1896 for more
- discussion and an initial solution.
+ The workaround is to delete the files only _after_ the initial
+ directory scan.  A previous workaround involving rewinddir is
+ problematic on Win32 and some NFS clients, notably NetBSD.
 
- To work around the problem, we do a rewinddir after we delete all files
- and see if there's anything left. We repeat the steps untill there's
- nothing left to delete.
-
- This workaround causes issues on Windows where delete's are asynchronous,
- however, so we never rewind if we're on Windows (the delete says it is
- complete, we rewind, we see the same file and try to delete it again,
- we fail.
+ See http://subversion.tigris.org/issues/show_bug.cgi?id=1896 and
+ http://subversion.tigris.org/issues/show_bug.cgi?id=3501.
 */
 
 /* Neither windows nor unix allows us to delete a non-empty
@@ -1884,13 +1879,10 @@
                    svn_cancel_func_t cancel_func, void *cancel_baton,
                    apr_pool_t *pool)
 {
-  apr_status_t status;
-  apr_dir_t *this_dir;
-  apr_finfo_t this_entry;
+  svn_error_t *err;
   apr_pool_t *subpool;
-  apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
-  const char *path_apr;
-  int need_rewind;
+  apr_hash_t *dirents;
+  apr_hash_index_t *ent;
 
   /* Check for pending cancellation request.
      If we need to bail out, do so early. */
@@ -1898,112 +1890,50 @@
   if (cancel_func)
     SVN_ERR((*cancel_func)(cancel_baton));
 
-  /* Convert path to native here and call apr_dir_open directly,
-     instead of just using svn_io_dir_open, because we're going to
-     need path_apr later anyway when we remove the dir itself. */
-
-  if (path[0] == '\0')
-    /* APR doesn't like "" directories; use "." instead. */
-    SVN_ERR(cstring_from_utf8(&path_apr, ".", pool));
-  else
-    SVN_ERR(cstring_from_utf8(&path_apr, path, pool));
+  subpool = svn_pool_create(pool);
 
-  status = apr_dir_open(&this_dir, path_apr, pool);
-  if (status)
+  err = svn_io_get_dirents2(&dirents, path, subpool);
+  if (err)
     {
       /* if the directory doesn't exist, our mission is accomplished */
-      if (ignore_enoent && APR_STATUS_IS_ENOENT(status))
-        return SVN_NO_ERROR;
-      else
-        return svn_error_wrap_apr(status,
-                                  _("Can't open directory '%s'"),
-                                  svn_path_local_style(path, pool));
+      if (ignore_enoent && APR_STATUS_IS_ENOENT(err->apr_err))
+	{
+	  svn_error_clear(err);
+	  return SVN_NO_ERROR;
+	}
+      return err;
     }
 
-  subpool = svn_pool_create(pool);
-
-  do
+  for (ent = apr_hash_first(subpool, dirents); ent; ent = apr_hash_next(ent))
     {
-      need_rewind = FALSE;
-
-      for (status = apr_dir_read(&this_entry, flags, this_dir);
-           status == APR_SUCCESS;
-           status = apr_dir_read(&this_entry, flags, this_dir))
+      const void *key;
+      void *val;
+      char *fullpath;
+
+      apr_hash_this(ent, &key, NULL, &val);
+      fullpath = svn_path_join(path, key, subpool);
+      if (((svn_io_dirent_t *)val)->kind == svn_node_dir)
         {
-          svn_pool_clear(subpool);
-          if ((this_entry.filetype == APR_DIR)
-              && ((this_entry.name[0] == '.')
-                  && ((this_entry.name[1] == '\0')
-                      || ((this_entry.name[1] == '.')
-                          && (this_entry.name[2] == '\0')))))
-            {
-              continue;
-            }
-          else  /* something other than "." or "..", so proceed */
-            {
-              const char *fullpath, *entry_utf8;
-
-#ifndef WIN32
-              need_rewind = TRUE;
-#endif
-
-              SVN_ERR(entry_name_to_utf8(&entry_utf8, this_entry.name,
-                                         path_apr, subpool));
-
-              fullpath = svn_path_join(path, entry_utf8, subpool);
-
-              if (this_entry.filetype == APR_DIR)
-                {
-                  /* Don't check for cancellation, the callee
-                     will immediately do so */
-                  SVN_ERR(svn_io_remove_dir2(fullpath, FALSE,
-                                             cancel_func, cancel_baton,
-                                             subpool));
-                }
-              else
-                {
-                  svn_error_t *err;
-
-                  if (cancel_func)
-                    SVN_ERR((*cancel_func)(cancel_baton));
-
-                  err = svn_io_remove_file(fullpath, subpool);
-                  if (err)
-                    return svn_error_createf
-                      (err->apr_err, err, _("Can't remove '%s'"),
-                       svn_path_local_style(fullpath, subpool));
-                }
-            }
+          /* Don't check for cancellation, the callee will immediately do so */
+          SVN_ERR(svn_io_remove_dir2(fullpath, FALSE, cancel_func,
+                                     cancel_baton, subpool));
         }
-
-      if (need_rewind)
+      else
         {
-          status = apr_dir_rewind(this_dir);
-          if (status)
-            return svn_error_wrap_apr(status, _("Can't rewind directory '%s'"),
-                                      svn_path_local_style (path, pool));
+          if (cancel_func)
+            SVN_ERR((*cancel_func)(cancel_baton));
+
+          err = svn_io_remove_file(fullpath, subpool);
+          if (err)
+            return svn_error_createf
+              (err->apr_err, err, _("Can't remove '%s'"),
+               svn_path_local_style(fullpath, subpool));
         }
     }
-  while (need_rewind);
 
   svn_pool_destroy(subpool);
 
-  if (!APR_STATUS_IS_ENOENT(status))
-    return svn_error_wrap_apr(status, _("Can't read directory '%s'"),
-                              svn_path_local_style(path, pool));
-
-  status = apr_dir_close(this_dir);
-  if (status)
-    return svn_error_wrap_apr(status, _("Error closing directory '%s'"),
-                              svn_path_local_style(path, pool));
-
-  status = apr_dir_remove(path_apr, pool);
-  WIN32_RETRY_LOOP(status, apr_dir_remove(path_apr, pool));
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't remove '%s'"),
-                              svn_path_local_style(path, pool));
-
-  return APR_SUCCESS;
+  return svn_io_dir_remove_nonrecursive(path, pool);
 }
 
 svn_error_t *