@@ -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 ,
115135bool isRedo );
@@ -123,8 +143,8 @@ static void register_forget_request(RelFileLocatorBackend rlocator, ForkNumber f
123143static void _fdvec_resize (SMgrRelation reln ,
124144ForkNumber forknum ,
125145int 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 ,
129149BlockNumber segno ,int oflags );
130150static MdfdVec * _mdfd_getseg (SMgrRelation reln ,ForkNumber forknum ,
@@ -398,20 +418,20 @@ mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
398418 */
399419if (ret >=0 || errno != ENOENT )
400420{
401- char * segpath = ( char * ) palloc ( strlen ( path . str ) + 12 ) ;
421+ MdPathStr segpath ;
402422BlockNumber segno ;
403423
404424for (segno = 1 ;;segno ++ )
405425{
406- sprintf (segpath ,"%s.%u" ,path .str ,segno );
426+ sprintf (segpath . str ,"%s.%u" ,path .str ,segno );
407427
408428if (!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 )
415435break ;
416436
417437/*
@@ -421,17 +441,16 @@ mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
421441register_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... */
427447if (errno != ENOENT )
428448ereport (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 )));
431451break ;
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{
15341553RelPathStr path ;
1535- char * fullpath ;
1554+ MdPathStr fullpath ;
15361555
15371556path = relpath (reln -> smgr_rlocator ,forknum );
15381557
15391558if (segno > 0 )
1540- fullpath = psprintf ( "%s.%u" ,path .str ,segno );
1559+ sprintf ( fullpath . str , "%s.%u" ,path .str ,segno );
15411560else
1542- fullpath = pstrdup ( path .str );
1561+ strcpy ( fullpath . str , path .str );
15431562
15441563return fullpath ;
15451564}
@@ -1554,14 +1573,12 @@ _mdfd_openseg(SMgrRelation reln, ForkNumber forknum, BlockNumber segno,
15541573{
15551574MdfdVec * v ;
15561575File fd ;
1557- char * fullpath ;
1576+ MdPathStr fullpath ;
15581577
15591578fullpath = _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
15661583if (fd < 0 )
15671584return NULL ;
@@ -1697,7 +1714,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
16971714ereport (ERROR ,
16981715(errcode_for_file_access (),
16991716errmsg ("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 ,
17011718blkno ,nblocks )));
17021719}
17031720
@@ -1711,7 +1728,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
17111728ereport (ERROR ,
17121729(errcode_for_file_access (),
17131730errmsg ("could not open file \"%s\" (target block %u): %m" ,
1714- _mdfd_segpath (reln ,forknum ,nextsegno ),
1731+ _mdfd_segpath (reln ,forknum ,nextsegno ). str ,
17151732blkno )));
17161733}
17171734}
@@ -1762,11 +1779,10 @@ mdsyncfiletag(const FileTag *ftag, char *path)
17621779}
17631780else
17641781{
1765- char * p ;
1782+ MdPathStr p ;
17661783
17671784p = _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
17711787file = PathNameOpenFile (path ,_mdfd_open_flags ());
17721788if (file < 0 )