@@ -110,6 +110,26 @@ static MemoryContext MdCxt; /* context for all MdfdVec objects */
110110#define EXTENSION_DONT_OPEN (1 << 5)
111111
112112
113+ /*
114+ * Fixed-length string to represent paths to files that need to be built by
115+ * md.c.
116+ *
117+ * The maximum number of segments is MaxBlockNumber / RELSEG_SIZE, where
118+ * RELSEG_SIZE can be set to 1 (for testing only).
119+ */
120+ #define SEGMENT_CHARS OIDCHARS
121+ #define MD_PATH_STR_MAXLEN \
122+ (\
123+ REL_PATH_STR_MAXLEN \
124+ + sizeof((char)'.') \
125+ + SEGMENT_CHARS \
126+ )
127+ typedef struct MdPathStr
128+ {
129+ char str [MD_PATH_STR_MAXLEN + 1 ];
130+ } MdPathStr ;
131+
132+
113133/* local routines */
114134static void mdunlinkfork (RelFileLocatorBackend rlocator , ForkNumber forknum ,
115135 bool isRedo );
@@ -123,8 +143,8 @@ static void register_forget_request(RelFileLocatorBackend rlocator, ForkNumber f
123143static void _fdvec_resize (SMgrRelation reln ,
124144 ForkNumber forknum ,
125145 int nseg );
126- static char * _mdfd_segpath (SMgrRelation reln , ForkNumber forknum ,
127- BlockNumber segno );
146+ static MdPathStr _mdfd_segpath (SMgrRelation reln , ForkNumber forknum ,
147+ BlockNumber segno );
128148static MdfdVec * _mdfd_openseg (SMgrRelation reln , ForkNumber forknum ,
129149 BlockNumber segno , int oflags );
130150static MdfdVec * _mdfd_getseg (SMgrRelation reln , ForkNumber forknum ,
@@ -398,20 +418,20 @@ mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
398418 */
399419 if (ret >= 0 || errno != ENOENT )
400420 {
401- char * segpath = ( char * ) palloc ( strlen ( path . str ) + 12 ) ;
421+ MdPathStr segpath ;
402422 BlockNumber segno ;
403423
404424 for (segno = 1 ;; segno ++ )
405425 {
406- sprintf (segpath , "%s.%u" , path .str , segno );
426+ sprintf (segpath . str , "%s.%u" , path .str , segno );
407427
408428 if (!RelFileLocatorBackendIsTemp (rlocator ))
409429 {
410430 /*
411431 * Prevent other backends' fds from holding on to the disk
412432 * space. We're done if we see ENOENT, though.
413433 */
414- if (do_truncate (segpath ) < 0 && errno == ENOENT )
434+ if (do_truncate (segpath . str ) < 0 && errno == ENOENT )
415435 break ;
416436
417437 /*
@@ -421,17 +441,16 @@ mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
421441 register_forget_request (rlocator , forknum , segno );
422442 }
423443
424- if (unlink (segpath ) < 0 )
444+ if (unlink (segpath . str ) < 0 )
425445 {
426446 /* ENOENT is expected after the last segment... */
427447 if (errno != ENOENT )
428448 ereport (WARNING ,
429449 (errcode_for_file_access (),
430- errmsg ("could not remove file \"%s\": %m" , segpath )));
450+ errmsg ("could not remove file \"%s\": %m" , segpath . str )));
431451 break ;
432452 }
433453 }
434- pfree (segpath );
435454 }
436455}
437456
@@ -1528,18 +1547,18 @@ _fdvec_resize(SMgrRelation reln,
15281547 * Return the filename for the specified segment of the relation. The
15291548 * returned string is palloc'd.
15301549 */
1531- static char *
1550+ static MdPathStr
15321551_mdfd_segpath (SMgrRelation reln , ForkNumber forknum , BlockNumber segno )
15331552{
15341553 RelPathStr path ;
1535- char * fullpath ;
1554+ MdPathStr fullpath ;
15361555
15371556 path = relpath (reln -> smgr_rlocator , forknum );
15381557
15391558 if (segno > 0 )
1540- fullpath = psprintf ( "%s.%u" , path .str , segno );
1559+ sprintf ( fullpath . str , "%s.%u" , path .str , segno );
15411560 else
1542- fullpath = pstrdup ( path .str );
1561+ strcpy ( fullpath . str , path .str );
15431562
15441563 return fullpath ;
15451564}
@@ -1554,14 +1573,12 @@ _mdfd_openseg(SMgrRelation reln, ForkNumber forknum, BlockNumber segno,
15541573{
15551574 MdfdVec * v ;
15561575 File fd ;
1557- char * fullpath ;
1576+ MdPathStr fullpath ;
15581577
15591578 fullpath = _mdfd_segpath (reln , forknum , segno );
15601579
15611580 /* open the file */
1562- fd = PathNameOpenFile (fullpath , _mdfd_open_flags () | oflags );
1563-
1564- pfree (fullpath );
1581+ fd = PathNameOpenFile (fullpath .str , _mdfd_open_flags () | oflags );
15651582
15661583 if (fd < 0 )
15671584 return NULL ;
@@ -1697,7 +1714,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
16971714 ereport (ERROR ,
16981715 (errcode_for_file_access (),
16991716 errmsg ("could not open file \"%s\" (target block %u): previous segment is only %u blocks" ,
1700- _mdfd_segpath (reln , forknum , nextsegno ),
1717+ _mdfd_segpath (reln , forknum , nextsegno ). str ,
17011718 blkno , nblocks )));
17021719 }
17031720
@@ -1711,7 +1728,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
17111728 ereport (ERROR ,
17121729 (errcode_for_file_access (),
17131730 errmsg ("could not open file \"%s\" (target block %u): %m" ,
1714- _mdfd_segpath (reln , forknum , nextsegno ),
1731+ _mdfd_segpath (reln , forknum , nextsegno ). str ,
17151732 blkno )));
17161733 }
17171734 }
@@ -1762,11 +1779,10 @@ mdsyncfiletag(const FileTag *ftag, char *path)
17621779 }
17631780 else
17641781 {
1765- char * p ;
1782+ MdPathStr p ;
17661783
17671784 p = _mdfd_segpath (reln , ftag -> forknum , ftag -> segno );
1768- strlcpy (path , p , MAXPGPATH );
1769- pfree (p );
1785+ strlcpy (path , p .str , MD_PATH_STR_MAXLEN );
17701786
17711787 file = PathNameOpenFile (path , _mdfd_open_flags ());
17721788 if (file < 0 )
0 commit comments