diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2007-03-11 06:43:23 +0000 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2007-03-11 06:43:23 +0000 |
commit | 3cda014bf435c616bb78de45b46b199add79c409 (patch) | |
tree | 0361d404062b617578fdd79bddb0c0cb254c0ed8 | |
parent | 15c31ce09ecc691d949763437f3f975200e73224 (diff) | |
download | postgresql-3cda014bf435c616bb78de45b46b199add79c409.tar.gz postgresql-3cda014bf435c616bb78de45b46b199add79c409.zip |
Fix a race condition that caused pg_database_size() and pg_tablespace_size()
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.
-rw-r--r-- | src/backend/utils/adt/dbsize.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 11ae30ab9c6..757b97dc334 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -5,7 +5,7 @@ * Copyright (c) 2002-2005, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.7 2005/10/29 00:31:51 petere Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.7.2.1 2007/03/11 06:43:23 alvherre Exp $ * */ @@ -51,10 +51,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; } @@ -173,9 +177,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); |