From 3cae9d6ed02dabb38f9b2a9b952d5138e0a60c42 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Fri, 5 Apr 2019 10:21:54 +1300
Subject: [PATCH] Introduce SegmentNumber typedef for relation segment numbers.

Previously we used BlockNumber for md.c's segment numbers.  Define a
separate typename, but keep the same underlying type.  Also use it for
a couple of tools under src/bin that know about md.c's file layout
scheme.

Discussion: https://postgr.es/m/20190404130258.GA7320%40alvherre.pgsql
---
 src/backend/storage/smgr/md.c       | 28 ++++++++++++++--------------
 src/bin/pg_checksums/pg_checksums.c |  5 +++--
 src/bin/pg_rewind/filemap.c         |  7 ++++---
 src/include/storage/segment.h       | 28 ++++++++++++++++++++++++++++
 src/include/storage/smgr.h          |  3 ++-
 src/include/storage/sync.h          |  3 ++-
 6 files changed, 53 insertions(+), 21 deletions(-)
 create mode 100644 src/include/storage/segment.h

diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index ffb3569698f..84fdc314b31 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -81,7 +81,7 @@
 typedef struct _MdfdVec
 {
 	File		mdfd_vfd;		/* fd number in fd.c's pool */
-	BlockNumber mdfd_segno;		/* segment number, from 0 */
+	SegmentNumber mdfd_segno;	/* segment number, from 0 */
 } MdfdVec;
 
 static MemoryContext MdCxt;		/* context for all MdfdVec objects */
@@ -124,16 +124,16 @@ static MdfdVec *mdopen(SMgrRelation reln, ForkNumber forknum, int behavior);
 static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum,
 					   MdfdVec *seg);
 static void register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum,
-						BlockNumber segno);
+						SegmentNumber segno);
 static void register_forget_request(RelFileNodeBackend rnode, ForkNumber forknum,
-						BlockNumber segno);
+						SegmentNumber segno);
 static void _fdvec_resize(SMgrRelation reln,
 			  ForkNumber forknum,
 			  int nseg);
 static char *_mdfd_segpath(SMgrRelation reln, ForkNumber forknum,
-			  BlockNumber segno);
+			  SegmentNumber segno);
 static MdfdVec *_mdfd_openseg(SMgrRelation reln, ForkNumber forkno,
-			  BlockNumber segno, int oflags);
+			  SegmentNumber segno, int oflags);
 static MdfdVec *_mdfd_getseg(SMgrRelation reln, ForkNumber forkno,
 			 BlockNumber blkno, bool skipFsync, int behavior);
 static BlockNumber _mdnblocks(SMgrRelation reln, ForkNumber forknum,
@@ -329,7 +329,7 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo)
 	if (ret >= 0)
 	{
 		char	   *segpath = (char *) palloc(strlen(path) + 12);
-		BlockNumber segno;
+		SegmentNumber segno;
 
 		/*
 		 * Note that because we loop until getting ENOENT, we will correctly
@@ -715,7 +715,7 @@ mdnblocks(SMgrRelation reln, ForkNumber forknum)
 {
 	MdfdVec    *v = mdopen(reln, forknum, EXTENSION_FAIL);
 	BlockNumber nblocks;
-	BlockNumber segno = 0;
+	SegmentNumber segno = 0;
 
 	/* mdopen has opened the first segment */
 	Assert(reln->md_num_open_segs[forknum] > 0);
@@ -865,7 +865,7 @@ mdtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks)
 void
 mdimmedsync(SMgrRelation reln, ForkNumber forknum)
 {
-	int			segno;
+	SegmentNumber segno;
 
 	/*
 	 * NOTE: mdnblocks makes sure we have opened all active segments, so that
@@ -925,7 +925,7 @@ register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
  */
 static void
 register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum,
-						BlockNumber segno)
+						SegmentNumber segno)
 {
 	FileTag		tag;
 
@@ -942,7 +942,7 @@ register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum,
  */
 static void
 register_forget_request(RelFileNodeBackend rnode, ForkNumber forknum,
-						BlockNumber segno)
+						SegmentNumber segno)
 {
 	FileTag		tag;
 
@@ -1043,7 +1043,7 @@ _fdvec_resize(SMgrRelation reln,
  * returned string is palloc'd.
  */
 static char *
-_mdfd_segpath(SMgrRelation reln, ForkNumber forknum, BlockNumber segno)
+_mdfd_segpath(SMgrRelation reln, ForkNumber forknum, SegmentNumber segno)
 {
 	char	   *path,
 			   *fullpath;
@@ -1066,7 +1066,7 @@ _mdfd_segpath(SMgrRelation reln, ForkNumber forknum, BlockNumber segno)
  * and make a MdfdVec object for it.  Returns NULL on failure.
  */
 static MdfdVec *
-_mdfd_openseg(SMgrRelation reln, ForkNumber forknum, BlockNumber segno,
+_mdfd_openseg(SMgrRelation reln, ForkNumber forknum, SegmentNumber segno,
 			  int oflags)
 {
 	MdfdVec    *v;
@@ -1110,8 +1110,8 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
 			 bool skipFsync, int behavior)
 {
 	MdfdVec    *v;
-	BlockNumber targetseg;
-	BlockNumber nextsegno;
+	SegmentNumber targetseg;
+	SegmentNumber nextsegno;
 
 	/* some way to handle non-existent segments needs to be specified */
 	Assert(behavior &
diff --git a/src/bin/pg_checksums/pg_checksums.c b/src/bin/pg_checksums/pg_checksums.c
index bc899826580..26a7988035a 100644
--- a/src/bin/pg_checksums/pg_checksums.c
+++ b/src/bin/pg_checksums/pg_checksums.c
@@ -29,6 +29,7 @@
 #include "storage/bufpage.h"
 #include "storage/checksum.h"
 #include "storage/checksum_impl.h"
+#include "storage/segment.h"
 
 
 static int64 files = 0;
@@ -167,7 +168,7 @@ skipfile(const char *fn)
 }
 
 static void
-scan_file(const char *fn, BlockNumber segmentno)
+scan_file(const char *fn, SegmentNumber segmentno)
 {
 	PGAlignedBlock buf;
 	PageHeader	header = (PageHeader) buf.data;
@@ -310,7 +311,7 @@ scan_directory(const char *basedir, const char *subdir, bool sizeonly)
 			char		fnonly[MAXPGPATH];
 			char	   *forkpath,
 					   *segmentpath;
-			BlockNumber segmentno = 0;
+			SegmentNumber segmentno = 0;
 
 			if (skipfile(de->d_name))
 				continue;
diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c
index 63d0baee745..f76eee65dd3 100644
--- a/src/bin/pg_rewind/filemap.c
+++ b/src/bin/pg_rewind/filemap.c
@@ -22,12 +22,13 @@
 #include "catalog/pg_tablespace_d.h"
 #include "fe_utils/logging.h"
 #include "storage/fd.h"
+#include "storage/segment.h"
 
 filemap_t  *filemap = NULL;
 
 static bool isRelDataFile(const char *path);
 static char *datasegpath(RelFileNode rnode, ForkNumber forknum,
-			BlockNumber segno);
+			SegmentNumber segno);
 static int	path_cmp(const void *a, const void *b);
 static int	final_filemap_cmp(const void *a, const void *b);
 static void filemap_list_to_array(filemap_t *map);
@@ -424,7 +425,7 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
 	file_entry_t *key_ptr;
 	file_entry_t *entry;
 	BlockNumber blkno_inseg;
-	int			segno;
+	SegmentNumber segno;
 	filemap_t  *map = filemap;
 	file_entry_t **e;
 
@@ -762,7 +763,7 @@ isRelDataFile(const char *path)
  * The returned path is palloc'd
  */
 static char *
-datasegpath(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
+datasegpath(RelFileNode rnode, ForkNumber forknum, SegmentNumber segno)
 {
 	char	   *path;
 	char	   *segpath;
diff --git a/src/include/storage/segment.h b/src/include/storage/segment.h
new file mode 100644
index 00000000000..7aa86d4d964
--- /dev/null
+++ b/src/include/storage/segment.h
@@ -0,0 +1,28 @@
+/*-------------------------------------------------------------------------
+ *
+ * segment.h
+ *   POSTGRES disk segment definitions.
+ *
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/storage/segment.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef SEGMENT_H
+#define SEGMENT_H
+
+#include "storage/block.h"
+
+/*
+ * We avoid creating very large disk files by cutting relations up into
+ * smaller segment files.  Since there are values of RELSEG_SIZE and BLCKSZ
+ * that would require md.c to create more than 2^16 segments for a relation
+ * with MaxBlockNumber blocks, we can't use anything smaller than the size
+ * we use for BlockNumber, so just define one in terms of the other.
+ */
+typedef BlockNumber SegmentNumber;
+
+#endif							/* SEGMENT_H */
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 770193e285e..20d91213b99 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -17,6 +17,7 @@
 #include "lib/ilist.h"
 #include "storage/block.h"
 #include "storage/relfilenode.h"
+#include "storage/segment.h"
 
 /*
  * smgr.c maintains a table of SMgrRelation objects, which are essentially
@@ -67,7 +68,7 @@ typedef struct SMgrRelationData
 	 * for md.c; per-fork arrays of the number of open segments
 	 * (md_num_open_segs) and the segments themselves (md_seg_fds).
 	 */
-	int			md_num_open_segs[MAX_FORKNUM + 1];
+	SegmentNumber md_num_open_segs[MAX_FORKNUM + 1];
 	struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1];
 
 	/* if unowned, list link in list of all unowned SMgrRelations */
diff --git a/src/include/storage/sync.h b/src/include/storage/sync.h
index 124a49ea984..6759321e645 100644
--- a/src/include/storage/sync.h
+++ b/src/include/storage/sync.h
@@ -14,6 +14,7 @@
 #define SYNC_H
 
 #include "storage/relfilenode.h"
+#include "storage/segment.h"
 
 /*
  * Type of sync request.  These are used to manage the set of pending
@@ -47,7 +48,7 @@ typedef struct FileTag
 	int16		handler;		/* SyncRequstHandler value, saving space */
 	int16		forknum;		/* ForkNumber, saving space */
 	RelFileNode rnode;
-	uint32		segno;
+	SegmentNumber segno;
 } FileTag;
 
 extern void InitSync(void);
-- 
2.21.0

