]> granicus.if.org Git - apache/commitdiff
When moving a file over device boundaries and unlinking the source file fails
authorStefan Fritsch <sf@apache.org>
Tue, 10 Nov 2009 22:13:50 +0000 (22:13 +0000)
committerStefan Fritsch <sf@apache.org>
Tue, 10 Nov 2009 22:13:50 +0000 (22:13 +0000)
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

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@834697 13f79535-47bb-0310-9956-ffa450edef68

modules/dav/fs/repos.c

index fde1d4cd223b54cd349e1be38abdee2708c1f88a..c3e66bc70be06d00b69ba4124ce0a3245668cba2 100644 (file)
@@ -428,11 +428,24 @@ static dav_error * dav_fs_copymove_file(
     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? */