From 9c94e9098a4b420f903fdb381335692fb1ed01b3 Mon Sep 17 00:00:00 2001 From: Daniel Shelepanov Date: Wed, 28 Jun 2023 12:03:47 +0300 Subject: [PATCH] [PBCKP-563] lstat optimized in case DT_REG is defined and the PG_VERSION_NUM is less than 13 it is possible to replace lstat call with DT_REG check (readdir call is required) and state that it is either a regular file or a directory. Symlinks to tablespaces assumed to be dirs. --- engine.c | 16 +++++++++++++++- engine.h | 5 +++++ ptrack.c | 28 ++++++++++++++++++++++++++-- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/engine.c b/engine.c index afaae1f..0039961 100644 --- a/engine.c +++ b/engine.c @@ -641,7 +641,10 @@ ptrack_walkdir(const char *path, Oid tablespaceOid, Oid dbOid) { char subpath[MAXPGPATH * 2]; struct stat fst; - int sret; + int sret = 0; +#if SIMPLE_STAT + bool assumeDir = false; +#endif CHECK_FOR_INTERRUPTS(); @@ -651,7 +654,14 @@ ptrack_walkdir(const char *path, Oid tablespaceOid, Oid dbOid) snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name); +#if SIMPLE_STAT + if (de->d_type == DT_REG) + sret = stat(subpath, &fst); + else + assumeDir = true; +#else sret = lstat(subpath, &fst); +#endif if (sret < 0) { @@ -661,7 +671,11 @@ ptrack_walkdir(const char *path, Oid tablespaceOid, Oid dbOid) continue; } +#if SIMPLE_STAT + if (!assumeDir) +#else if (S_ISREG(fst.st_mode)) +#endif #if CFS_SUPPORT ptrack_mark_file(dbOid, tablespaceOid, subpath, de->d_name, is_cfs); #else diff --git a/engine.h b/engine.h index 56777fc..588151c 100644 --- a/engine.h +++ b/engine.h @@ -49,6 +49,11 @@ #define CFS_SUPPORT 1 #endif +/* lstat optimization */ +#if defined(DT_REG) && PG_VERSION_NUM < 130000 +#define SIMPLE_STAT 1 +#endif + /* * Header of ptrack map. */ diff --git a/ptrack.c b/ptrack.c index 22a2acf..5dba6cd 100644 --- a/ptrack.c +++ b/ptrack.c @@ -306,7 +306,10 @@ ptrack_gather_filelist(List **filelist, char *path, Oid spcOid, Oid dbOid) { char subpath[MAXPGPATH * 2]; struct stat fst; - int sret; + int sret = 0; +#if SIMPLE_STAT + bool assumeDir = false; +#endif CHECK_FOR_INTERRUPTS(); @@ -317,8 +320,15 @@ ptrack_gather_filelist(List **filelist, char *path, Oid spcOid, Oid dbOid) continue; snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name); - +#if SIMPLE_STAT + if (de->d_type == DT_REG) + sret = stat(subpath, &fst); + else + assumeDir = true; +#else sret = lstat(subpath, &fst); +#endif + if (sret < 0) { @@ -328,7 +338,11 @@ ptrack_gather_filelist(List **filelist, char *path, Oid spcOid, Oid dbOid) continue; } +#if SIMPLE_STAT + if (!assumeDir) +#else if (S_ISREG(fst.st_mode)) +#endif { if (fst.st_size == 0) { @@ -375,7 +389,12 @@ ptrack_gather_filelist(List **filelist, char *path, Oid spcOid, Oid dbOid) pfl->path, nodeRel(pfl->relnode)); } } +#if SIMPLE_STAT + else + { +#else else if (S_ISDIR(fst.st_mode)) +#endif { if (strspn(de->d_name + 1, "0123456789") == strlen(de->d_name + 1) && dbOid == InvalidOid) @@ -384,10 +403,12 @@ ptrack_gather_filelist(List **filelist, char *path, Oid spcOid, Oid dbOid) ptrack_gather_filelist(filelist, subpath, spcOid, InvalidOid); } /* TODO: is it enough to properly check symlink support? */ +#if !SIMPLE_STAT #if !defined(WIN32) || (PG_VERSION_NUM >= 160000) else if (S_ISLNK(fst.st_mode)) #else else if (pgwin32_is_junction(subpath)) +#endif #endif { /* @@ -397,6 +418,9 @@ ptrack_gather_filelist(List **filelist, char *path, Oid spcOid, Oid dbOid) if (strspn(de->d_name + 1, "0123456789") == strlen(de->d_name + 1)) ptrack_gather_filelist(filelist, subpath, atooid(de->d_name), InvalidOid); } +#if SIMPLE_STAT + } +#endif } FreeDir(dir); /* we ignore any error here */