(unnamed)
text/plain
#ifdef POWERGRES
static Dllist *rnodes = NULL;
static volatile slock_t mylock = 0;
typedef struct {
RelFileNode rnode;
BlockNumber blkno;
} RelSegInfo;
#undef calloc
#undef malloc
#undef free
#undef realloc
#undef strdup
/*
* Add segment file names to the internal table
*/
static void add_file(RelFileNode rnode, BlockNumber blkno)
{
Dlelem *elm;
RelSegInfo *info;
#ifndef LET_OS_MANAGE_FILESIZE
BlockNumber segno, isegno;
#endif
SpinLockAcquire_NoHoldoff(&mylock);
if (rnodes == NULL)
{
rnodes = DLNewList();
}
elm = DLGetHead(rnodes);
while (elm)
{
RelSegInfo *ip = (RelSegInfo *)DLE_VAL(elm);
#ifndef LET_OS_MANAGE_FILESIZE
segno = blkno / ((BlockNumber) RELSEG_SIZE);
isegno = ip->blkno / ((BlockNumber) RELSEG_SIZE);
#endif
if (((ip->rnode.tblNode == (Oid)0 && rnode.tblNode == (Oid)0 && ip->rnode.relNode == rnode.relNode) ||
(ip->rnode.tblNode == rnode.tblNode && ip->rnode.relNode == rnode.relNode))
#ifndef LET_OS_MANAGE_FILESIZE
&& segno == isegno
#endif
)
{
/* already there */
SpinLockRelease_NoHoldoff(&mylock);
return;
}
elm = DLGetSucc(elm);
}
info = malloc(sizeof(*info));
if (info == NULL)
{
elog(ERROR, "add_file: malloc failed");
}
else
{
info->rnode = rnode;
info->blkno = blkno;
DLAddHead(rnodes, DLNewElem(info));
}
SpinLockRelease_NoHoldoff(&mylock);
}
/*
* fsync all file segments registered in the table
*/
#include <fcntl.h>
static void checkpoint_buffer_sync(void)
{
Dllist *segs;
Dlelem *elm;
File fd;
char segname[MAXPGPATH];
#ifndef LET_OS_MANAGE_FILESIZE
BlockNumber segno;
#endif
if (rnodes == NULL)
return;
SpinLockAcquire_NoHoldoff(&mylock);
segs = DLNewList();
elm = DLGetHead(rnodes);
while (elm)
{
Dlelem *next;
next = DLGetSucc(elm);
DLAddHead(segs, DLNewElem(DLE_VAL(elm)));
DLRemove(elm);
DLFreeElem(elm);
elm = next;
}
SpinLockRelease_NoHoldoff(&mylock);
elm = DLGetHead(segs);
while (elm)
{
RelSegInfo *ip = (RelSegInfo *)DLE_VAL(elm);
if (ip->rnode.tblNode == (Oid) 0) /* "global tablespace" */
{
/* Shared system relations live in {datadir}/global */
snprintf(segname, MAXPGPATH, "%s/global/%u", DataDir, ip->rnode.relNode);
}
else
{
snprintf(segname, MAXPGPATH, "%s/base/%u/%u", DataDir, ip->rnode.tblNode, ip->rnode.relNode);
}
#ifndef LET_OS_MANAGE_FILESIZE
/* append the '.segno', if needed */
segno = ip->blkno / ((BlockNumber) RELSEG_SIZE);
if (segno > 0)
{
snprintf(segname, MAXPGPATH, "%s.%u", segname, segno);
}
#endif
fd = FileNameOpenFile(segname, O_RDWR | PG_BINARY, 0600);
if (fd >= 0)
{
elog(DEBUG1,"flushing %s", segname);
FileSync(fd);
FileClose(fd);
}
elm = DLGetSucc(elm);
}
DLFreeList(segs);
}
#endif /* POWERGRES */