]> granicus.if.org Git - postgresql/commitdiff
Attempt to handle pending-delete files on Windows
authorMagnus Hagander <magnus@hagander.net>
Wed, 4 Jan 2017 09:48:30 +0000 (10:48 +0100)
committerMagnus Hagander <magnus@hagander.net>
Wed, 4 Jan 2017 09:48:30 +0000 (10:48 +0100)
These files are deleted but not yet gone from the filesystem. Operations
on them will return ERROR_DELETE_PENDING.

With this we start treating that as ENOENT, meaning files does not
exist (which is the state it will soon reach). This should be safe in
every case except when we try to recreate a file with exactly the same
name. This is an operation that PostgreSQL does very seldom, so
hopefully that won't happen much -- and even if it does, this treatment
should be no worse than treating it as an unhandled error.

We've been un able to reproduce the bug reliably, so pushing this to
master to get buildfarm coverage and other testing. Once it's proven to
be stable, it should be considered for backpatching.

Discussion: https://postgr.es/m/20160712083220.1426.58667%40wrigleys.postgresql.org

Patch by me and Michael Paquier

src/port/dirmod.c
src/port/win32error.c

index 3db82e32ea942da07163b90858d87737f554e320..08835962be6b22846051fe8b6923a885d05a963f 100644 (file)
@@ -372,7 +372,22 @@ pgwin32_safestat(const char *path, struct stat * buf)
 
        r = stat(path, buf);
        if (r < 0)
+       {
+               if (GetLastError() == ERROR_DELETE_PENDING)
+               {
+                       /*
+                        * File has been deleted, but is not gone from the filesystem
+                        * yet. This can happen when some process with FILE_SHARE_DELETE
+                        * has it open and it will be fully removed once that handle
+                        * is closed. Meanwhile, we can't open it, so indicate that
+                        * the file just doesn't exist.
+                        */
+                       errno = ENOENT;
+                       return -1;
+               }
+
                return r;
+       }
 
        if (!GetFileAttributesEx(path, GetFileExInfoStandard, &attr))
        {
index 91095ee19a707c230e6894250d85cda2d95c7e9a..40655962a87d46fa34436c351db7a295dbd9c9ee 100644 (file)
@@ -161,6 +161,9 @@ static const struct
        },
        {
                ERROR_NOT_ENOUGH_QUOTA, ENOMEM
+       },
+       {
+               ERROR_DELETE_PENDING, ENOENT
        }
 };