You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2009/11/10 23:13:50 UTC

svn commit: r834697 - /httpd/httpd/trunk/modules/dav/fs/repos.c

Author: sf
Date: Tue Nov 10 22:13:50 2009
New Revision: 834697

URL: http://svn.apache.org/viewvc?rev=834697&view=rev
Log:
When moving a file over device boundaries and unlinking the source file fails
because it does not exist anymore, don't unlink the destination file.

While it is unclear to me how/when this can happen, at least one user
encountered the problem:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=273476

Modified:
    httpd/httpd/trunk/modules/dav/fs/repos.c

Modified: httpd/httpd/trunk/modules/dav/fs/repos.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/dav/fs/repos.c?rev=834697&r1=834696&r2=834697&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/dav/fs/repos.c (original)
+++ httpd/httpd/trunk/modules/dav/fs/repos.c Tue Nov 10 22:13:50 2009
@@ -428,11 +428,24 @@
     apr_file_close(inf);
     apr_file_close(outf);
 
-    if (is_move && apr_file_remove(src, p) != APR_SUCCESS) {
+    if (is_move && (status = apr_file_remove(src, p)) != APR_SUCCESS) {
         dav_error *err;
         int save_errno = errno;   /* save the errno that got us here */
 
-        if (apr_file_remove(dst, p) != APR_SUCCESS) {
+        if (APR_STATUS_IS_ENOENT(status)) {
+            /*
+             * Something is wrong here but the result is what we wanted.
+             * We definitely should not remove the destination file.
+             */
+             err = dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0,
+                                 apr_psprintf(p, "Could not remove source "
+                                              "file %s after move to %s. The "
+                                              "server may be in an "
+                                              "inconsistent state.", src, dst));
+            err->save_errno = save_errno;
+            return err;
+        } 
+        else if (apr_file_remove(dst, p) != APR_SUCCESS) {
             /* ### ACK. this creates an inconsistency. do more!? */
 
             /* ### use something besides 500? */