#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 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 */