mirror of
https://github.com/postgres/postgres.git
synced 2025-08-27 07:42:10 +03:00
Skip unnecessary stat() calls in walkdir().
Some kernels can tell us the type of a "dirent", so we can avoid a call to stat() or lstat() in many cases. Define a new function get_dirent_type() to contain that logic, for use by the backend and frontend versions of walkdir(), and perhaps other callers in future. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Juan José Santamaría Flecha <juanjo.santamaria@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKG%2BFzxupGGN4GpUdbzZN%2Btn6FQPHo8w0Q%2BAPH5Wz8RG%2Bww%40mail.gmail.com
This commit is contained in:
@@ -89,6 +89,7 @@
|
||||
#include "access/xlog.h"
|
||||
#include "catalog/pg_tablespace.h"
|
||||
#include "common/file_perm.h"
|
||||
#include "common/file_utils.h"
|
||||
#include "miscadmin.h"
|
||||
#include "pgstat.h"
|
||||
#include "portability/mem.h"
|
||||
@@ -3340,8 +3341,6 @@ walkdir(const char *path,
|
||||
while ((de = ReadDirExtended(dir, path, elevel)) != NULL)
|
||||
{
|
||||
char subpath[MAXPGPATH * 2];
|
||||
struct stat fst;
|
||||
int sret;
|
||||
|
||||
CHECK_FOR_INTERRUPTS();
|
||||
|
||||
@@ -3351,23 +3350,23 @@ walkdir(const char *path,
|
||||
|
||||
snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name);
|
||||
|
||||
if (process_symlinks)
|
||||
sret = stat(subpath, &fst);
|
||||
else
|
||||
sret = lstat(subpath, &fst);
|
||||
|
||||
if (sret < 0)
|
||||
switch (get_dirent_type(subpath, de, process_symlinks, elevel))
|
||||
{
|
||||
ereport(elevel,
|
||||
(errcode_for_file_access(),
|
||||
errmsg("could not stat file \"%s\": %m", subpath)));
|
||||
continue;
|
||||
}
|
||||
case PGFILETYPE_REG:
|
||||
(*action) (subpath, false, elevel);
|
||||
break;
|
||||
case PGFILETYPE_DIR:
|
||||
walkdir(subpath, action, false, elevel);
|
||||
break;
|
||||
default:
|
||||
|
||||
if (S_ISREG(fst.st_mode))
|
||||
(*action) (subpath, false, elevel);
|
||||
else if (S_ISDIR(fst.st_mode))
|
||||
walkdir(subpath, action, false, elevel);
|
||||
/*
|
||||
* Errors are already reported directly by get_dirent_type(),
|
||||
* and any remaining symlinks and unknown file types are
|
||||
* ignored.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreeDir(dir); /* we ignore any error here */
|
||||
|
Reference in New Issue
Block a user