Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbfb9dfd

Browse files
committed
Expand the use of get_dirent_type(), shaving a few calls to stat()/lstat()
Several backend-side loops scanning one or more directories withReadDir() (WAL segment recycle/removal in xlog.c, backend-side directorycopy, temporary file removal, configuration file parsing, some logicaldecoding logic and some pgtz stuff) already know the type of the entrybeing scanned thanks to the dirent structure associated to the entry, onplatforms where we know about DT_REG, DT_DIR and DT_LNK to make thedifference between a regular file, a directory and a symbolic link.Relying on the direct structure of an entry saves a few system calls tostat() and lstat() in the loops updated here, shaving some code while onit. The logic of the code remains the same, calling stat() or lstat()depending on if it is necessary to look through symlinks.Authors: Nathan Bossart, Bharath RupireddyReviewed-by: Andres Freund, Thomas Munro, Michael PaquierDiscussion:https://postgr.es/m/CALj2ACV8n-J-f=yiLUOx2=HrQGPSOZM3nWzyQQvLPcccPXxEdg@mail.gmail.com
1 parent11e5f99 commitbfb9dfd

File tree

8 files changed

+53
-75
lines changed

8 files changed

+53
-75
lines changed

‎src/backend/access/heap/rewriteheap.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
#include"access/xact.h"
114114
#include"access/xloginsert.h"
115115
#include"catalog/catalog.h"
116+
#include"common/file_utils.h"
116117
#include"lib/ilist.h"
117118
#include"miscadmin.h"
118119
#include"pgstat.h"
@@ -1213,21 +1214,23 @@ CheckPointLogicalRewriteHeap(void)
12131214
mappings_dir=AllocateDir("pg_logical/mappings");
12141215
while ((mapping_de=ReadDir(mappings_dir,"pg_logical/mappings"))!=NULL)
12151216
{
1216-
structstatstatbuf;
12171217
Oiddboid;
12181218
Oidrelid;
12191219
XLogRecPtrlsn;
12201220
TransactionIdrewrite_xid;
12211221
TransactionIdcreate_xid;
12221222
uint32hi,
12231223
lo;
1224+
PGFileTypede_type;
12241225

12251226
if (strcmp(mapping_de->d_name,".")==0||
12261227
strcmp(mapping_de->d_name,"..")==0)
12271228
continue;
12281229

12291230
snprintf(path,sizeof(path),"pg_logical/mappings/%s",mapping_de->d_name);
1230-
if (lstat(path,&statbuf)==0&& !S_ISREG(statbuf.st_mode))
1231+
de_type=get_dirent_type(path,mapping_de, false,DEBUG1);
1232+
1233+
if (de_type!=PGFILETYPE_ERROR&&de_type!=PGFILETYPE_REG)
12311234
continue;
12321235

12331236
/* Skip over files that cannot be ours. */

‎src/backend/access/transam/xlog.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,9 @@ static void PreallocXlogFiles(XLogRecPtr endptr, TimeLineID tli);
657657
staticvoidRemoveTempXlogFiles(void);
658658
staticvoidRemoveOldXlogFiles(XLogSegNosegno,XLogRecPtrlastredoptr,
659659
XLogRecPtrendptr,TimeLineIDinsertTLI);
660-
staticvoidRemoveXlogFile(constchar*segname,XLogSegNorecycleSegNo,
661-
XLogSegNo*endlogSegNo,TimeLineIDinsertTLI);
660+
staticvoidRemoveXlogFile(conststructdirent*segment_de,
661+
XLogSegNorecycleSegNo,XLogSegNo*endlogSegNo,
662+
TimeLineIDinsertTLI);
662663
staticvoidUpdateLastRemovedPtr(char*filename);
663664
staticvoidValidateXLOGDirectoryStructure(void);
664665
staticvoidCleanupBackupHistory(void);
@@ -3596,8 +3597,7 @@ RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr lastredoptr, XLogRecPtr endptr,
35963597
/* Update the last removed location in shared memory first */
35973598
UpdateLastRemovedPtr(xlde->d_name);
35983599

3599-
RemoveXlogFile(xlde->d_name,recycleSegNo,&endlogSegNo,
3600-
insertTLI);
3600+
RemoveXlogFile(xlde,recycleSegNo,&endlogSegNo,insertTLI);
36013601
}
36023602
}
36033603
}
@@ -3669,8 +3669,7 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
36693669
* - but seems safer to let them be archived and removed later.
36703670
*/
36713671
if (!XLogArchiveIsReady(xlde->d_name))
3672-
RemoveXlogFile(xlde->d_name,recycleSegNo,&endLogSegNo,
3673-
newTLI);
3672+
RemoveXlogFile(xlde,recycleSegNo,&endLogSegNo,newTLI);
36743673
}
36753674
}
36763675

@@ -3680,9 +3679,9 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
36803679
/*
36813680
* Recycle or remove a log file that's no longer needed.
36823681
*
3683-
*segname is thenameof the segment to recycle or remove. recycleSegNo
3684-
* is the segment number to recycle up to. endlogSegNo is the segment
3685-
* number of the current (or recent) end of WAL.
3682+
*segment_de is thedirent structureof the segment to recycle or remove.
3683+
*recycleSegNois the segment number to recycle up to. endlogSegNo is
3684+
*the segmentnumber of the current (or recent) end of WAL.
36863685
*
36873686
* endlogSegNo gets incremented if the segment is recycled so as it is not
36883687
* checked again with future callers of this function.
@@ -3691,14 +3690,15 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
36913690
* should be used for this timeline.
36923691
*/
36933692
staticvoid
3694-
RemoveXlogFile(constchar*segname,XLogSegNorecycleSegNo,
3695-
XLogSegNo*endlogSegNo,TimeLineIDinsertTLI)
3693+
RemoveXlogFile(conststructdirent*segment_de,
3694+
XLogSegNorecycleSegNo,XLogSegNo*endlogSegNo,
3695+
TimeLineIDinsertTLI)
36963696
{
36973697
charpath[MAXPGPATH];
36983698
#ifdefWIN32
36993699
charnewpath[MAXPGPATH];
37003700
#endif
3701-
structstatstatbuf;
3701+
constchar*segname=segment_de->d_name;
37023702

37033703
snprintf(path,MAXPGPATH,XLOGDIR"/%s",segname);
37043704

@@ -3710,7 +3710,7 @@ RemoveXlogFile(const char *segname, XLogSegNo recycleSegNo,
37103710
if (wal_recycle&&
37113711
*endlogSegNo <=recycleSegNo&&
37123712
XLogCtl->InstallXLogFileSegmentActive&&/* callee rechecks this */
3713-
lstat(path,&statbuf)==0&&S_ISREG(statbuf.st_mode)&&
3713+
get_dirent_type(path,segment_de, false,DEBUG2)==PGFILETYPE_REG&&
37143714
InstallXLogFileSegment(endlogSegNo,path,
37153715
true,recycleSegNo,insertTLI))
37163716
{

‎src/backend/replication/logical/snapbuild.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
#include"access/heapam_xlog.h"
124124
#include"access/transam.h"
125125
#include"access/xact.h"
126+
#include"common/file_utils.h"
126127
#include"miscadmin.h"
127128
#include"pgstat.h"
128129
#include"replication/logical.h"
@@ -2061,15 +2062,16 @@ CheckPointSnapBuild(void)
20612062
uint32hi;
20622063
uint32lo;
20632064
XLogRecPtrlsn;
2064-
structstatstatbuf;
2065+
PGFileTypede_type;
20652066

20662067
if (strcmp(snap_de->d_name,".")==0||
20672068
strcmp(snap_de->d_name,"..")==0)
20682069
continue;
20692070

20702071
snprintf(path,sizeof(path),"pg_logical/snapshots/%s",snap_de->d_name);
2072+
de_type=get_dirent_type(path,snap_de, false,DEBUG1);
20712073

2072-
if (lstat(path,&statbuf)==0&&!S_ISREG(statbuf.st_mode))
2074+
if (de_type!=PGFILETYPE_ERROR&&de_type!=PGFILETYPE_REG)
20732075
{
20742076
elog(DEBUG1,"only regular files expected: %s",path);
20752077
continue;

‎src/backend/replication/slot.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include"access/transam.h"
4343
#include"access/xlog_internal.h"
44+
#include"common/file_utils.h"
4445
#include"common/string.h"
4546
#include"miscadmin.h"
4647
#include"pgstat.h"
@@ -1442,17 +1443,18 @@ StartupReplicationSlots(void)
14421443
replication_dir=AllocateDir("pg_replslot");
14431444
while ((replication_de=ReadDir(replication_dir,"pg_replslot"))!=NULL)
14441445
{
1445-
structstatstatbuf;
14461446
charpath[MAXPGPATH+12];
1447+
PGFileTypede_type;
14471448

14481449
if (strcmp(replication_de->d_name,".")==0||
14491450
strcmp(replication_de->d_name,"..")==0)
14501451
continue;
14511452

14521453
snprintf(path,sizeof(path),"pg_replslot/%s",replication_de->d_name);
1454+
de_type=get_dirent_type(path,replication_de, false,DEBUG1);
14531455

14541456
/* we're only creating directories here, skip if it's not our's */
1455-
if (lstat(path,&statbuf)==0&&!S_ISDIR(statbuf.st_mode))
1457+
if (de_type!=PGFILETYPE_ERROR&&de_type!=PGFILETYPE_DIR)
14561458
continue;
14571459

14581460
/* we crashed while a slot was being setup or deleted, clean up */

‎src/backend/storage/file/copydir.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include<unistd.h>
2323
#include<sys/stat.h>
2424

25+
#include"common/file_utils.h"
2526
#include"miscadmin.h"
2627
#include"pgstat.h"
2728
#include"storage/copydir.h"
@@ -50,7 +51,7 @@ copydir(char *fromdir, char *todir, bool recurse)
5051

5152
while ((xlde=ReadDir(xldir,fromdir))!=NULL)
5253
{
53-
structstatfst;
54+
PGFileTypexlde_type;
5455

5556
/* If we got a cancel signal during the copy of the directory, quit */
5657
CHECK_FOR_INTERRUPTS();
@@ -62,18 +63,15 @@ copydir(char *fromdir, char *todir, bool recurse)
6263
snprintf(fromfile,sizeof(fromfile),"%s/%s",fromdir,xlde->d_name);
6364
snprintf(tofile,sizeof(tofile),"%s/%s",todir,xlde->d_name);
6465

65-
if (lstat(fromfile,&fst)<0)
66-
ereport(ERROR,
67-
(errcode_for_file_access(),
68-
errmsg("could not stat file \"%s\": %m",fromfile)));
66+
xlde_type=get_dirent_type(fromfile,xlde, false,ERROR);
6967

70-
if (S_ISDIR(fst.st_mode))
68+
if (xlde_type==PGFILETYPE_DIR)
7169
{
7270
/* recurse to handle subdirectories */
7371
if (recurse)
7472
copydir(fromfile,tofile, true);
7573
}
76-
elseif (S_ISREG(fst.st_mode))
74+
elseif (xlde_type==PGFILETYPE_REG)
7775
copy_file(fromfile,tofile);
7876
}
7977
FreeDir(xldir);
@@ -89,8 +87,6 @@ copydir(char *fromdir, char *todir, bool recurse)
8987

9088
while ((xlde=ReadDir(xldir,todir))!=NULL)
9189
{
92-
structstatfst;
93-
9490
if (strcmp(xlde->d_name,".")==0||
9591
strcmp(xlde->d_name,"..")==0)
9692
continue;
@@ -101,12 +97,7 @@ copydir(char *fromdir, char *todir, bool recurse)
10197
* We don't need to sync subdirectories here since the recursive
10298
* copydir will do it before it returns
10399
*/
104-
if (lstat(tofile,&fst)<0)
105-
ereport(ERROR,
106-
(errcode_for_file_access(),
107-
errmsg("could not stat file \"%s\": %m",tofile)));
108-
109-
if (S_ISREG(fst.st_mode))
100+
if (get_dirent_type(tofile,xlde, false,ERROR)==PGFILETYPE_REG)
110101
fsync_fname(tofile, false);
111102
}
112103
FreeDir(xldir);

‎src/backend/storage/file/fd.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3156,17 +3156,11 @@ RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all)
31563156
PG_TEMP_FILE_PREFIX,
31573157
strlen(PG_TEMP_FILE_PREFIX))==0)
31583158
{
3159-
structstatstatbuf;
3159+
PGFileTypetype=get_dirent_type(rm_path,temp_de, false,LOG);
31603160

3161-
if (lstat(rm_path,&statbuf)<0)
3162-
{
3163-
ereport(LOG,
3164-
(errcode_for_file_access(),
3165-
errmsg("could not stat file \"%s\": %m",rm_path)));
3161+
if (type==PGFILETYPE_ERROR)
31663162
continue;
3167-
}
3168-
3169-
if (S_ISDIR(statbuf.st_mode))
3163+
elseif (type==PGFILETYPE_DIR)
31703164
{
31713165
/* recursively remove contents, then directory itself */
31723166
RemovePgTempFilesInDir(rm_path, false, true);

‎src/backend/utils/misc/guc-file.l

Lines changed: 16 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include<ctype.h>
1515
#include<unistd.h>
1616

17+
#include"common/file_utils.h"
1718
#include"mb/pg_wchar.h"
1819
#include"miscadmin.h"
1920
#include"storage/fd.h"
@@ -1017,7 +1018,7 @@ ParseConfigDirectory(const char *includedir,
10171018

10181019
while ((de =ReadDir(d, directory)) !=NULL)
10191020
{
1020-
structstat st;
1021+
PGFileTypede_type;
10211022
charfilename[MAXPGPATH];
10221023

10231024
/*
@@ -1034,39 +1035,28 @@ ParseConfigDirectory(const char *includedir,
10341035

10351036
join_path_components(filename, directory, de->d_name);
10361037
canonicalize_path(filename);
1037-
if (stat(filename, &st) ==0)
1038+
de_type =get_dirent_type(filename, de,true, elevel);
1039+
if (de_type == PGFILETYPE_ERROR)
10381040
{
1039-
if (!S_ISDIR(st.st_mode))
1040-
{
1041-
/* Add file to array, increasing its size in blocks of 32 */
1042-
if (num_filenames >= size_filenames)
1043-
{
1044-
size_filenames +=32;
1045-
filenames = (char **)repalloc(filenames,
1046-
size_filenames *sizeof(char *));
1047-
}
1048-
filenames[num_filenames] =pstrdup(filename);
1049-
num_filenames++;
1050-
}
1051-
}
1052-
else
1053-
{
1054-
/*
1055-
* stat does not care about permissions, so the most likely reason
1056-
* a file can't be accessed now is if it was removed between the
1057-
* directory listing and now.
1058-
*/
1059-
ereport(elevel,
1060-
(errcode_for_file_access(),
1061-
errmsg("could not stat file\"%s\": %m",
1062-
filename)));
10631041
record_config_file_error(psprintf("could not stat file\"%s\"",
10641042
filename),
10651043
calling_file, calling_lineno,
10661044
head_p, tail_p);
10671045
status =false;
10681046
goto cleanup;
10691047
}
1048+
elseif (de_type != PGFILETYPE_DIR)
1049+
{
1050+
/* Add file to array, increasing its size in blocks of 32 */
1051+
if (num_filenames >= size_filenames)
1052+
{
1053+
size_filenames +=32;
1054+
filenames = (char **)repalloc(filenames,
1055+
size_filenames *sizeof(char *));
1056+
}
1057+
filenames[num_filenames] =pstrdup(filename);
1058+
num_filenames++;
1059+
}
10701060
}
10711061

10721062
if (num_filenames >0)

‎src/timezone/pgtz.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include<sys/stat.h>
1818
#include<time.h>
1919

20+
#include"common/file_utils.h"
2021
#include"datatype/timestamp.h"
2122
#include"miscadmin.h"
2223
#include"pgtz.h"
@@ -429,7 +430,6 @@ pg_tzenumerate_next(pg_tzenum *dir)
429430
{
430431
structdirent*direntry;
431432
charfullname[MAXPGPATH*2];
432-
structstatstatbuf;
433433

434434
direntry=ReadDir(dir->dirdesc[dir->depth],dir->dirname[dir->depth]);
435435

@@ -447,12 +447,8 @@ pg_tzenumerate_next(pg_tzenum *dir)
447447

448448
snprintf(fullname,sizeof(fullname),"%s/%s",
449449
dir->dirname[dir->depth],direntry->d_name);
450-
if (stat(fullname,&statbuf)!=0)
451-
ereport(ERROR,
452-
(errcode_for_file_access(),
453-
errmsg("could not stat \"%s\": %m",fullname)));
454450

455-
if (S_ISDIR(statbuf.st_mode))
451+
if (get_dirent_type(fullname,direntry, true,ERROR)==PGFILETYPE_DIR)
456452
{
457453
/* Step into the subdirectory */
458454
if (dir->depth >=MAX_TZDIR_DEPTH-1)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp