@@ -110,6 +110,26 @@ static MemoryContext MdCxt; /* context for all MdfdVec objects */
110
110
#define EXTENSION_DONT_OPEN (1 << 5)
111
111
112
112
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
+
113
133
/* local routines */
114
134
static void mdunlinkfork (RelFileLocatorBackend rlocator , ForkNumber forknum ,
115
135
bool isRedo );
@@ -123,8 +143,8 @@ static void register_forget_request(RelFileLocatorBackend rlocator, ForkNumber f
123
143
static void _fdvec_resize (SMgrRelation reln ,
124
144
ForkNumber forknum ,
125
145
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 );
128
148
static MdfdVec * _mdfd_openseg (SMgrRelation reln , ForkNumber forknum ,
129
149
BlockNumber segno , int oflags );
130
150
static MdfdVec * _mdfd_getseg (SMgrRelation reln , ForkNumber forknum ,
@@ -398,20 +418,20 @@ mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
398
418
*/
399
419
if (ret >= 0 || errno != ENOENT )
400
420
{
401
- char * segpath = ( char * ) palloc ( strlen ( path . str ) + 12 ) ;
421
+ MdPathStr segpath ;
402
422
BlockNumber segno ;
403
423
404
424
for (segno = 1 ;; segno ++ )
405
425
{
406
- sprintf (segpath , "%s.%u" , path .str , segno );
426
+ sprintf (segpath . str , "%s.%u" , path .str , segno );
407
427
408
428
if (!RelFileLocatorBackendIsTemp (rlocator ))
409
429
{
410
430
/*
411
431
* Prevent other backends' fds from holding on to the disk
412
432
* space. We're done if we see ENOENT, though.
413
433
*/
414
- if (do_truncate (segpath ) < 0 && errno == ENOENT )
434
+ if (do_truncate (segpath . str ) < 0 && errno == ENOENT )
415
435
break ;
416
436
417
437
/*
@@ -421,17 +441,16 @@ mdunlinkfork(RelFileLocatorBackend rlocator, ForkNumber forknum, bool isRedo)
421
441
register_forget_request (rlocator , forknum , segno );
422
442
}
423
443
424
- if (unlink (segpath ) < 0 )
444
+ if (unlink (segpath . str ) < 0 )
425
445
{
426
446
/* ENOENT is expected after the last segment... */
427
447
if (errno != ENOENT )
428
448
ereport (WARNING ,
429
449
(errcode_for_file_access (),
430
- errmsg ("could not remove file \"%s\": %m" , segpath )));
450
+ errmsg ("could not remove file \"%s\": %m" , segpath . str )));
431
451
break ;
432
452
}
433
453
}
434
- pfree (segpath );
435
454
}
436
455
}
437
456
@@ -1528,18 +1547,18 @@ _fdvec_resize(SMgrRelation reln,
1528
1547
* Return the filename for the specified segment of the relation. The
1529
1548
* returned string is palloc'd.
1530
1549
*/
1531
- static char *
1550
+ static MdPathStr
1532
1551
_mdfd_segpath (SMgrRelation reln , ForkNumber forknum , BlockNumber segno )
1533
1552
{
1534
1553
RelPathStr path ;
1535
- char * fullpath ;
1554
+ MdPathStr fullpath ;
1536
1555
1537
1556
path = relpath (reln -> smgr_rlocator , forknum );
1538
1557
1539
1558
if (segno > 0 )
1540
- fullpath = psprintf ( "%s.%u" , path .str , segno );
1559
+ sprintf ( fullpath . str , "%s.%u" , path .str , segno );
1541
1560
else
1542
- fullpath = pstrdup ( path .str );
1561
+ strcpy ( fullpath . str , path .str );
1543
1562
1544
1563
return fullpath ;
1545
1564
}
@@ -1554,14 +1573,12 @@ _mdfd_openseg(SMgrRelation reln, ForkNumber forknum, BlockNumber segno,
1554
1573
{
1555
1574
MdfdVec * v ;
1556
1575
File fd ;
1557
- char * fullpath ;
1576
+ MdPathStr fullpath ;
1558
1577
1559
1578
fullpath = _mdfd_segpath (reln , forknum , segno );
1560
1579
1561
1580
/* open the file */
1562
- fd = PathNameOpenFile (fullpath , _mdfd_open_flags () | oflags );
1563
-
1564
- pfree (fullpath );
1581
+ fd = PathNameOpenFile (fullpath .str , _mdfd_open_flags () | oflags );
1565
1582
1566
1583
if (fd < 0 )
1567
1584
return NULL ;
@@ -1697,7 +1714,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
1697
1714
ereport (ERROR ,
1698
1715
(errcode_for_file_access (),
1699
1716
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 ,
1701
1718
blkno , nblocks )));
1702
1719
}
1703
1720
@@ -1711,7 +1728,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
1711
1728
ereport (ERROR ,
1712
1729
(errcode_for_file_access (),
1713
1730
errmsg ("could not open file \"%s\" (target block %u): %m" ,
1714
- _mdfd_segpath (reln , forknum , nextsegno ),
1731
+ _mdfd_segpath (reln , forknum , nextsegno ). str ,
1715
1732
blkno )));
1716
1733
}
1717
1734
}
@@ -1762,11 +1779,10 @@ mdsyncfiletag(const FileTag *ftag, char *path)
1762
1779
}
1763
1780
else
1764
1781
{
1765
- char * p ;
1782
+ MdPathStr p ;
1766
1783
1767
1784
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 );
1770
1786
1771
1787
file = PathNameOpenFile (path , _mdfd_open_flags ());
1772
1788
if (file < 0 )
0 commit comments