Fix a race condition that caused pg_database_size() and pg_tablespace_size()
authorAlvaro Herrera <[email protected]>
Sun, 11 Mar 2007 06:44:11 +0000 (06:44 +0000)
committerAlvaro Herrera <[email protected]>
Sun, 11 Mar 2007 06:44:11 +0000 (06:44 +0000)
to fail if an object was removed between calls to ReadDir() and stat().
Per discussion in pgsql-hackers.

http://archives.postgresql.org/pgsql-hackers/2007-03/msg00671.php

Bug report and patch by Michael Fuhr.

src/backend/utils/adt/dbsize.c

index 916385cd43f86e5122ee4bef952e190ed4cef293..643502edadb53eed860311dd4839d17d7ba5aff2 100644 (file)
@@ -52,10 +52,14 @@ db_dir_size(const char *path)
                snprintf(filename, MAXPGPATH, "%s/%s", path, direntry->d_name);
 
                if (stat(filename, &fst) < 0)
-                       ereport(ERROR,
-                                       (errcode_for_file_access(),
-                                        errmsg("could not stat file \"%s\": %m", filename)));
-
+               {
+                       if (errno == ENOENT)
+                               continue;
+                       else
+                               ereport(ERROR,
+                                               (errcode_for_file_access(),
+                                                errmsg("could not stat file \"%s\": %m", filename)));
+               }
                dirsize += fst.st_size;
        }
 
@@ -174,9 +178,14 @@ calculate_tablespace_size(Oid tblspcOid)
                snprintf(pathname, MAXPGPATH, "%s/%s", tblspcPath, direntry->d_name);
 
                if (stat(pathname, &fst) < 0)
-                       ereport(ERROR,
-                                       (errcode_for_file_access(),
-                                        errmsg("could not stat file \"%s\": %m", pathname)));
+               {
+                       if (errno == ENOENT)
+                               continue;
+                       else
+                               ereport(ERROR,
+                                               (errcode_for_file_access(),
+                                                errmsg("could not stat file \"%s\": %m", pathname)));
+               }
 
                if (fst.st_mode & S_IFDIR)
                        totalsize += db_dir_size(pathname);