From 84ae0a626d5820f93a3423a518becb6dafc0a2af Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Date: Wed, 4 Sep 2024 16:15:16 +0900
Subject: [PATCH] Split file-related parts from xlog_internal.h

Some modules that require XLOG file manipulation had to include
xlog_internal.h, which contains excessively detailed internal
information. This commit separates the file and file path-related
components into xlogfilepaths.h, thereby avoiding the exposure of
unrelated details of the XLOG module.
---
 src/backend/access/transam/timeline.c         |   1 -
 src/backend/postmaster/pgarch.c               |   1 -
 src/backend/utils/adt/genfile.c               |   1 -
 src/bin/initdb/initdb.c                       |   1 +
 src/bin/pg_archivecleanup/pg_archivecleanup.c |   2 +-
 src/bin/pg_basebackup/pg_basebackup.c         |   4 +-
 src/bin/pg_basebackup/pg_receivewal.c         |   1 +
 src/bin/pg_basebackup/receivelog.c            |   2 +-
 src/bin/pg_basebackup/streamutil.c            |   2 +-
 src/bin/pg_controldata/pg_controldata.c       |   1 -
 src/bin/pg_rewind/pg_rewind.c                 |   2 +-
 src/include/access/xlog.h                     |  13 +-
 src/include/access/xlog_internal.h            | 178 +-------------
 src/include/access/xlogfilepaths.h            | 219 ++++++++++++++++++
 14 files changed, 230 insertions(+), 198 deletions(-)
 create mode 100644 src/include/access/xlogfilepaths.h

diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c
index a27f27cc037..710e92297e3 100644
--- a/src/backend/access/transam/timeline.c
+++ b/src/backend/access/transam/timeline.c
@@ -38,7 +38,6 @@
 #include "access/xlog.h"
 #include "access/xlog_internal.h"
 #include "access/xlogarchive.h"
-#include "access/xlogdefs.h"
 #include "pgstat.h"
 #include "storage/fd.h"
 
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 7e622ae4bd2..4db8a00b849 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -30,7 +30,6 @@
 #include <unistd.h>
 
 #include "access/xlog.h"
-#include "access/xlog_internal.h"
 #include "archive/archive_module.h"
 #include "archive/shell_archive.h"
 #include "lib/binaryheap.h"
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index 80bb807fbe9..af4c148c809 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -21,7 +21,6 @@
 #include <dirent.h>
 
 #include "access/htup_details.h"
-#include "access/xlog_internal.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_tablespace_d.h"
 #include "catalog/pg_type.h"
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 21a0fe3ecd9..f728e0fa802 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -65,6 +65,7 @@
 #endif
 
 #include "access/xlog_internal.h"
+#include "lib/stringinfo.h"
 #include "catalog/pg_authid_d.h"
 #include "catalog/pg_class_d.h"
 #include "catalog/pg_collation_d.h"
diff --git a/src/bin/pg_archivecleanup/pg_archivecleanup.c b/src/bin/pg_archivecleanup/pg_archivecleanup.c
index c25348bcb85..edf1828bc73 100644
--- a/src/bin/pg_archivecleanup/pg_archivecleanup.c
+++ b/src/bin/pg_archivecleanup/pg_archivecleanup.c
@@ -15,7 +15,7 @@
 #include <signal.h>
 #include <sys/time.h>
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "common/logging.h"
 #include "getopt_long.h"
 
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index d4b4e334014..d981bb4c282 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -25,7 +25,7 @@
 #include <zlib.h>
 #endif
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "astreamer_inject.h"
 #include "backup/basebackup.h"
 #include "common/compression.h"
@@ -35,6 +35,8 @@
 #include "fe_utils/option_utils.h"
 #include "fe_utils/recovery_gen.h"
 #include "getopt_long.h"
+#include "pgtime.h"
+#include "port/pg_bswap.h"
 #include "receivelog.h"
 #include "streamutil.h"
 
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
index de3584018b0..4facc35f845 100644
--- a/src/bin/pg_basebackup/pg_receivewal.c
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -27,6 +27,7 @@
 #include <zlib.h>
 #endif
 
+//#include "access/xlogfilepaths.h"
 #include "access/xlog_internal.h"
 #include "common/file_perm.h"
 #include "common/logging.h"
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
index 6b6e32dfbdf..4f72ed42e11 100644
--- a/src/bin/pg_basebackup/receivelog.c
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -18,7 +18,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "common/logging.h"
 #include "libpq-fe.h"
 #include "receivelog.h"
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
index 8e605f43ffe..62eb0586dc4 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -17,7 +17,7 @@
 #include <sys/time.h>
 #include <unistd.h>
 
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "common/connect.h"
 #include "common/file_perm.h"
 #include "common/logging.h"
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index bea779eef94..162f087626d 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -22,7 +22,6 @@
 
 #include "access/transam.h"
 #include "access/xlog.h"
-#include "access/xlog_internal.h"
 #include "catalog/pg_control.h"
 #include "common/controldata_utils.h"
 #include "common/logging.h"
diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c
index 2c8b1a07007..a625105fbcc 100644
--- a/src/bin/pg_rewind/pg_rewind.c
+++ b/src/bin/pg_rewind/pg_rewind.c
@@ -15,7 +15,7 @@
 #include <unistd.h>
 
 #include "access/timeline.h"
-#include "access/xlog_internal.h"
+#include "access/xlogfilepaths.h"
 #include "catalog/catversion.h"
 #include "catalog/pg_control.h"
 #include "common/controldata_utils.h"
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d313099c027..7ef9264fabc 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -16,6 +16,7 @@
 #include "datatype/timestamp.h"
 #include "lib/stringinfo.h"
 #include "nodes/pg_list.h"
+#include "access/xlogfilepaths.h"
 
 
 /* Sync methods */
@@ -299,16 +300,4 @@ extern void do_pg_abort_backup(int code, Datum arg);
 extern void register_persistent_abort_backup_handler(void);
 extern SessionBackupState get_backup_status(void);
 
-/* File path names (all relative to $PGDATA) */
-#define RECOVERY_SIGNAL_FILE	"recovery.signal"
-#define STANDBY_SIGNAL_FILE		"standby.signal"
-#define BACKUP_LABEL_FILE		"backup_label"
-#define BACKUP_LABEL_OLD		"backup_label.old"
-
-#define TABLESPACE_MAP			"tablespace_map"
-#define TABLESPACE_MAP_OLD		"tablespace_map.old"
-
-/* files to signal promotion to primary */
-#define PROMOTE_SIGNAL_FILE		"promote"
-
 #endif							/* XLOG_H */
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 2cf8d55d706..5e846e48073 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -21,6 +21,7 @@
 
 #include "access/xlogdefs.h"
 #include "access/xlogreader.h"
+#include "access/xlogfilepaths.h"
 #include "datatype/timestamp.h"
 #include "lib/stringinfo.h"
 #include "pgtime.h"
@@ -84,187 +85,10 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader;
 #define XLogPageHeaderSize(hdr)		\
 	(((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD)
 
-/* wal_segment_size can range from 1MB to 1GB */
-#define WalSegMinSize 1024 * 1024
-#define WalSegMaxSize 1024 * 1024 * 1024
-/* default number of min and max wal segments */
-#define DEFAULT_MIN_WAL_SEGS 5
-#define DEFAULT_MAX_WAL_SEGS 64
-
-/* check that the given size is a valid wal_segment_size */
-#define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0)
-#define IsValidWalSegSize(size) \
-	 (IsPowerOf2(size) && \
-	 ((size) >= WalSegMinSize && (size) <= WalSegMaxSize))
-
-#define XLogSegmentsPerXLogId(wal_segsz_bytes)	\
-	(UINT64CONST(0x100000000) / (wal_segsz_bytes))
-
-#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \
-		(dest) = (segno) * (wal_segsz_bytes) + (offset)
-
-#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)	\
-	((xlogptr) & ((wal_segsz_bytes) - 1))
-
-/*
- * Compute a segment number from an XLogRecPtr.
- *
- * For XLByteToSeg, do the computation at face value.  For XLByteToPrevSeg,
- * a boundary byte is taken to be in the previous segment.  This is suitable
- * for deciding which segment to write given a pointer to a record end,
- * for example.
- */
-#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	logSegNo = (xlrp) / (wal_segsz_bytes)
-
-#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	logSegNo = ((xlrp) - 1) / (wal_segsz_bytes)
-
-/*
- * Convert values of GUCs measured in megabytes to equiv. segment count.
- * Rounds down.
- */
-#define XLogMBVarToSegs(mbvar, wal_segsz_bytes) \
-	((mbvar) / ((wal_segsz_bytes) / (1024 * 1024)))
-
-/*
- * Is an XLogRecPtr within a particular XLOG segment?
- *
- * For XLByteInSeg, do the computation at face value.  For XLByteInPrevSeg,
- * a boundary byte is taken to be in the previous segment.
- */
-#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	(((xlrp) / (wal_segsz_bytes)) == (logSegNo))
-
-#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
-	((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo))
-
 /* Check if an XLogRecPtr value is in a plausible range */
 #define XRecOffIsValid(xlrp) \
 		((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD)
 
-/*
- * The XLog directory and control file (relative to $PGDATA)
- */
-#define XLOGDIR				"pg_wal"
-#define XLOG_CONTROL_FILE	"global/pg_control"
-
-/*
- * These macros encapsulate knowledge about the exact layout of XLog file
- * names, timeline history file names, and archive-status file names.
- */
-#define MAXFNAMELEN		64
-
-/* Length of XLog file name */
-#define XLOG_FNAME_LEN	   24
-
-/*
- * Generate a WAL segment file name.  Do not use this function in a helper
- * function allocating the result generated.
- */
-static inline void
-XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
-}
-
-static inline void
-XLogFileNameById(char *fname, TimeLineID tli, uint32 log, uint32 seg)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg);
-}
-
-static inline bool
-IsXLogFileName(const char *fname)
-{
-	return (strlen(fname) == XLOG_FNAME_LEN && \
-			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN);
-}
-
-/*
- * XLOG segment with .partial suffix.  Used by pg_receivewal and at end of
- * archive recovery, when we want to archive a WAL segment but it might not
- * be complete yet.
- */
-static inline bool
-IsPartialXLogFileName(const char *fname)
-{
-	return (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") &&
-			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
-			strcmp(fname + XLOG_FNAME_LEN, ".partial") == 0);
-}
-
-static inline void
-XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
-{
-	uint32		log;
-	uint32		seg;
-
-	sscanf(fname, "%08X%08X%08X", tli, &log, &seg);
-	*logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg;
-}
-
-static inline void
-XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
-}
-
-static inline void
-TLHistoryFileName(char *fname, TimeLineID tli)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X.history", tli);
-}
-
-static inline bool
-IsTLHistoryFileName(const char *fname)
-{
-	return (strlen(fname) == 8 + strlen(".history") &&
-			strspn(fname, "0123456789ABCDEF") == 8 &&
-			strcmp(fname + 8, ".history") == 0);
-}
-
-static inline void
-TLHistoryFilePath(char *path, TimeLineID tli)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli);
-}
-
-static inline void
-StatusFilePath(char *path, const char *xlog, const char *suffix)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix);
-}
-
-static inline void
-BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
-{
-	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes)));
-}
-
-static inline bool
-IsBackupHistoryFileName(const char *fname)
-{
-	return (strlen(fname) > XLOG_FNAME_LEN &&
-			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
-			strcmp(fname + strlen(fname) - strlen(".backup"), ".backup") == 0);
-}
-
-static inline void
-BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
-{
-	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli,
-			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
-			 (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes)));
-}
 
 /*
  * Information logged when we detect a change in one of the parameters
diff --git a/src/include/access/xlogfilepaths.h b/src/include/access/xlogfilepaths.h
new file mode 100644
index 00000000000..cdde2ccae4f
--- /dev/null
+++ b/src/include/access/xlogfilepaths.h
@@ -0,0 +1,219 @@
+/*
+ * xlogfilepaths.h
+ *
+ * File name definitions and handling macros for PostgreSQL write-ahead logs.
+ *
+ * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/access/xlogfilepaths.h
+ */
+#ifndef XLOG_FILEPATHS_H
+#define XLOG_FILEPATHS_H
+
+#include "access/xlogdefs.h"
+
+/*
+ * The XLog directory and files (relative to $PGDATA)
+ */
+#define XLOGDIR					"pg_wal"
+
+/* control files */
+#define XLOG_CONTROL_FILE		"global/pg_control"
+#define BACKUP_LABEL_FILE		"backup_label"
+#define BACKUP_LABEL_OLD		"backup_label.old"
+
+/* tablespace map */
+#define TABLESPACE_MAP			"tablespace_map"
+#define TABLESPACE_MAP_OLD		"tablespace_map.old"
+
+/* files to signal run mode to standby */
+#define RECOVERY_SIGNAL_FILE	"recovery.signal"
+#define STANDBY_SIGNAL_FILE		"standby.signal"
+
+/* files to signal promotion to primary */
+#define PROMOTE_SIGNAL_FILE		"promote"
+
+/* wal_segment_size can range from 1MB to 1GB */
+#define WalSegMinSize 1024 * 1024
+#define WalSegMaxSize 1024 * 1024 * 1024
+
+/* default number of min and max wal segments */
+#define DEFAULT_MIN_WAL_SEGS 5
+#define DEFAULT_MAX_WAL_SEGS 64
+
+
+/*
+ * These macros encapsulate knowledge about the exact layout of XLog file
+ * names, timeline history file names, and archive-status file names.
+ */
+#define MAXFNAMELEN		64
+
+/* Length of XLog file name */
+#define XLOG_FNAME_LEN	   24
+
+/* check that the given size is a valid wal_segment_size */
+#define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0)
+#define IsValidWalSegSize(size) \
+	 (IsPowerOf2(size) && \
+	 ((size) >= WalSegMinSize && (size) <= WalSegMaxSize))
+
+/* Number of segments in a logical XLOG file */
+#define XLogSegmentsPerXLogId(wal_segsz_bytes)	\
+	(UINT64CONST(0x100000000) / (wal_segsz_bytes))
+
+/*
+ * Compute an XLogRecPtr from a segment number and offset.
+ */
+#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \
+		(dest) = (segno) * (wal_segsz_bytes) + (offset)
+/*
+ * Compute a segment number from an XLogRecPtr.
+ *
+ * For XLByteToSeg, do the computation at face value.  For XLByteToPrevSeg,
+ * a boundary byte is taken to be in the previous segment.  This is suitable
+ * for deciding which segment to write given a pointer to a record end,
+ * for example.
+ */
+#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	logSegNo = (xlrp) / (wal_segsz_bytes)
+
+#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	logSegNo = ((xlrp) - 1) / (wal_segsz_bytes)
+
+/* Compute the in-segment offset from an XLogRecPtr. */
+#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)	\
+	((xlogptr) & ((wal_segsz_bytes) - 1))
+
+/*
+ * Convert values of GUCs measured in megabytes to equiv. segment count.
+ * Rounds down.
+ */
+#define XLogMBVarToSegs(mbvar, wal_segsz_bytes) \
+	((mbvar) / ((wal_segsz_bytes) / (1024 * 1024)))
+
+/*
+ * Is an XLogRecPtr within a particular XLOG segment?
+ *
+ * For XLByteInSeg, do the computation at face value.  For XLByteInPrevSeg,
+ * a boundary byte is taken to be in the previous segment.
+ */
+#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	(((xlrp) / (wal_segsz_bytes)) == (logSegNo))
+
+#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \
+	((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo))
+
+/*
+ * XLOG file name handling functions
+ */
+static inline void
+StatusFilePath(char *path, const char *xlog, const char *suffix)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix);
+}
+
+static inline bool
+IsTLHistoryFileName(const char *fname)
+{
+	return (strlen(fname) == 8 + strlen(".history") &&
+			strspn(fname, "0123456789ABCDEF") == 8 &&
+			strcmp(fname + 8, ".history") == 0);
+}
+
+static inline void
+XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
+{
+	uint32		log;
+	uint32		seg;
+
+	sscanf(fname, "%08X%08X%08X", tli, &log, &seg);
+	*logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg;
+}
+
+static inline void
+XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
+}
+
+/*
+ * Generate a WAL segment file name.  Do not use this function in a helper
+ * function allocating the result generated.
+ */
+static inline void
+XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)));
+}
+
+static inline void
+XLogFileNameById(char *fname, TimeLineID tli, uint32 log, uint32 seg)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg);
+}
+
+static inline bool
+IsXLogFileName(const char *fname)
+{
+	return (strlen(fname) == XLOG_FNAME_LEN && \
+			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN);
+}
+
+/*
+ * XLOG segment with .partial suffix.  Used by pg_receivewal and at end of
+ * archive recovery, when we want to archive a WAL segment but it might not
+ * be complete yet.
+ */
+static inline bool
+IsPartialXLogFileName(const char *fname)
+{
+	return (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") &&
+			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
+			strcmp(fname + XLOG_FNAME_LEN, ".partial") == 0);
+}
+
+static inline void
+TLHistoryFileName(char *fname, TimeLineID tli)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X.history", tli);
+}
+
+static inline void
+TLHistoryFilePath(char *path, TimeLineID tli)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli);
+}
+
+static inline void
+BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
+{
+	snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes)));
+}
+
+static inline bool
+IsBackupHistoryFileName(const char *fname)
+{
+	return (strlen(fname) > XLOG_FNAME_LEN &&
+			strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
+			strcmp(fname + strlen(fname) - strlen(".backup"), ".backup") == 0);
+}
+
+static inline void
+BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes)
+{
+	snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli,
+			 (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)),
+			 (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes)));
+}
+
+
+#endif							/* XLOG_FILEPATHS_H */
-- 
2.48.1

