PostgreSQL Source Code git master
slru_io.c File Reference
#include "postgres_fe.h"
#include <fcntl.h>
#include "common/fe_memutils.h"
#include "common/file_perm.h"
#include "common/file_utils.h"
#include "pg_upgrade.h"
#include "port/pg_iovec.h"
#include "slru_io.h"
Include dependency graph for slru_io.c:

Go to the source code of this file.

Functions

static SlruSegStateAllocSlruSegState (const char *dir)
 
static char * SlruFileName (SlruSegState *state, int64 segno)
 
static void SlruFlush (SlruSegState *state)
 
SlruSegStateAllocSlruRead (const char *dir, bool long_segment_names)
 
char * SlruReadSwitchPageSlow (SlruSegState *state, uint64 pageno)
 
void FreeSlruRead (SlruSegState *state)
 
SlruSegStateAllocSlruWrite (const char *dir, bool long_segment_names)
 
char * SlruWriteSwitchPageSlow (SlruSegState *state, uint64 pageno)
 
void FreeSlruWrite (SlruSegState *state)
 

Function Documentation

◆ AllocSlruRead()

SlruSegState * AllocSlruRead ( const char *  dir,
bool  long_segment_names 
)

Definition at line 62 of file slru_io.c.

63{
65
66 state->writing = false;
67 state->long_segment_names = long_segment_names;
68
69 return state;
70}
static SlruSegState * AllocSlruSegState(const char *dir)
Definition: slru_io.c:27
Definition: regguts.h:323

References AllocSlruSegState().

Referenced by AllocOldMultiXactRead().

◆ AllocSlruSegState()

static SlruSegState * AllocSlruSegState ( const char *  dir)
static

Definition at line 27 of file slru_io.c.

28{
29 SlruSegState *state = pg_malloc(sizeof(*state));
30
31 state->dir = pstrdup(dir);
32 state->fn = NULL;
33 state->fd = -1;
34 state->segno = -1;
35 state->pageno = 0;
36
37 /* state->writing and state->long_segment_names must be set by caller! */
38
39 return state;
40}
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char * pstrdup(const char *in)
Definition: mcxt.c:1759

References pg_malloc(), and pstrdup().

Referenced by AllocSlruRead(), and AllocSlruWrite().

◆ AllocSlruWrite()

SlruSegState * AllocSlruWrite ( const char *  dir,
bool  long_segment_names 
)

Definition at line 166 of file slru_io.c.

167{
169
170 state->writing = true;
171 state->long_segment_names = long_segment_names;
172
173 return state;
174}

References AllocSlruSegState().

Referenced by rewrite_multixacts().

◆ FreeSlruRead()

void FreeSlruRead ( SlruSegState state)

Definition at line 153 of file slru_io.c.

154{
155 Assert(!state->writing); /* read only mode */
156
157 if (state->fd != -1)
158 close(state->fd);
159 pg_free(state);
160}
void pg_free(void *ptr)
Definition: fe_memutils.c:105
Assert(PointerIsAligned(start, uint64))
#define close(a)
Definition: win32.h:12

References Assert(), close, and pg_free().

Referenced by FreeOldMultiXactReader().

◆ FreeSlruWrite()

void FreeSlruWrite ( SlruSegState state)

Definition at line 260 of file slru_io.c.

261{
262 Assert(state->writing);
263
265
266 if (state->fd != -1)
267 close(state->fd);
268 pg_free(state);
269}
static void SlruFlush(SlruSegState *state)
Definition: slru_io.c:239

References Assert(), close, pg_free(), and SlruFlush().

Referenced by rewrite_multixacts().

◆ SlruFileName()

static char * SlruFileName ( SlruSegState state,
int64  segno 
)
static

Definition at line 44 of file slru_io.c.

45{
46 if (state->long_segment_names)
47 {
48 Assert(segno >= 0 && segno <= INT64CONST(0xFFFFFFFFFFFFFFF));
49 return psprintf("%s/%015" PRIX64, state->dir, segno);
50 }
51 else
52 {
53 Assert(segno >= 0 && segno <= INT64CONST(0xFFFFFF));
54 return psprintf("%s/%04X", state->dir, (unsigned int) segno);
55 }
56}
#define INT64CONST(x)
Definition: c.h:566
char * psprintf(const char *fmt,...)
Definition: psprintf.c:43

References Assert(), INT64CONST, and psprintf().

Referenced by SlruReadSwitchPageSlow(), and SlruWriteSwitchPageSlow().

◆ SlruFlush()

static void SlruFlush ( SlruSegState state)
static

Definition at line 239 of file slru_io.c.

240{
241 struct iovec iovec = {
242 .iov_base = &state->buf,
243 .iov_len = BLCKSZ,
244 };
245 off_t offset;
246
247 if (state->segno == -1)
248 return;
249
250 offset = (state->pageno % SLRU_PAGES_PER_SEGMENT) * BLCKSZ;
251
252 if (pg_pwritev_with_retry(state->fd, &iovec, 1, offset) < 0)
253 pg_fatal("could not write file \"%s\": %m", state->fn);
254}
ssize_t pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
Definition: file_utils.c:659
#define pg_fatal(...)
#define SLRU_PAGES_PER_SEGMENT

References pg_fatal, pg_pwritev_with_retry(), and SLRU_PAGES_PER_SEGMENT.

Referenced by FreeSlruWrite(), and SlruWriteSwitchPageSlow().

◆ SlruReadSwitchPageSlow()

char * SlruReadSwitchPageSlow ( SlruSegState state,
uint64  pageno 
)

Definition at line 85 of file slru_io.c.

86{
87 int64 segno;
88 off_t offset;
89 ssize_t bytes_read;
90
91 Assert(!state->writing); /* read only mode */
92
93 if (state->segno != -1 && pageno == state->pageno)
94 return state->buf.data;
95
96 /* If the new page is on a different SLRU segment, open the new segment */
97 segno = pageno / SLRU_PAGES_PER_SEGMENT;
98 if (segno != state->segno)
99 {
100 if (state->segno != -1)
101 {
102 close(state->fd);
103 state->fd = -1;
104
105 pg_free(state->fn);
106 state->fn = NULL;
107
108 state->segno = -1;
109 }
110
111 state->fn = SlruFileName(state, segno);
112 if ((state->fd = open(state->fn, O_RDONLY | PG_BINARY, 0)) < 0)
113 pg_fatal("could not open file \"%s\": %m", state->fn);
114 state->segno = segno;
115 }
116
117 offset = (pageno % SLRU_PAGES_PER_SEGMENT) * BLCKSZ;
118 bytes_read = 0;
119 while (bytes_read < BLCKSZ)
120 {
121 ssize_t rc;
122
123 rc = pg_pread(state->fd,
124 &state->buf.data + bytes_read,
125 BLCKSZ - bytes_read,
126 offset);
127 if (rc < 0)
128 {
129 if (errno == EINTR)
130 continue;
131 pg_fatal("could not read file \"%s\": %m", state->fn);
132 }
133 if (rc == 0)
134 {
135 /* unexpected EOF */
136 pg_log(PG_WARNING, "unexpected EOF reading file \"%s\" at offset %u, reading as zeros",
137 state->fn, (unsigned int) offset);
138 memset(&state->buf.data + bytes_read, 0, BLCKSZ - bytes_read);
139 break;
140 }
141 bytes_read += rc;
142 offset += rc;
143 }
144 state->pageno = pageno;
145
146 return state->buf.data;
147}
int64_t int64
Definition: c.h:549
#define PG_BINARY
Definition: c.h:1271
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
@ PG_WARNING
Definition: pg_upgrade.h:284
#define pg_pread
Definition: port.h:247
static char * SlruFileName(SlruSegState *state, int64 segno)
Definition: slru_io.c:44
#define EINTR
Definition: win32_port.h:361

References Assert(), close, EINTR, PG_BINARY, pg_fatal, pg_free(), pg_log(), pg_pread, PG_WARNING, SLRU_PAGES_PER_SEGMENT, and SlruFileName().

Referenced by SlruReadSwitchPage().

◆ SlruWriteSwitchPageSlow()

char * SlruWriteSwitchPageSlow ( SlruSegState state,
uint64  pageno 
)

Definition at line 187 of file slru_io.c.

188{
189 int64 segno;
190 off_t offset;
191
192 Assert(state->writing);
193
194 if (state->segno != -1 && pageno == state->pageno)
195 return state->buf.data;
196
197 segno = pageno / SLRU_PAGES_PER_SEGMENT;
198 offset = (pageno % SLRU_PAGES_PER_SEGMENT) * BLCKSZ;
199
201 memset(state->buf.data, 0, BLCKSZ);
202
203 if (segno != state->segno)
204 {
205 if (state->segno != -1)
206 {
207 close(state->fd);
208 state->fd = -1;
209
210 pg_free(state->fn);
211 state->fn = NULL;
212
213 state->segno = -1;
214 }
215
216 /* Create the segment */
217 state->fn = SlruFileName(state, segno);
218 if ((state->fd = open(state->fn, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
220 {
221 pg_fatal("could not create file \"%s\": %m", state->fn);
222 }
223
224 state->segno = segno;
225
226 if (offset > 0)
227 {
228 if (pg_pwrite_zeros(state->fd, offset, 0) < 0)
229 pg_fatal("could not write file \"%s\": %m", state->fn);
230 }
231 }
232
233 state->pageno = pageno;
234
235 return state->buf.data;
236}
int pg_file_create_mode
Definition: file_perm.c:19
ssize_t pg_pwrite_zeros(int fd, size_t size, pgoff_t offset)
Definition: file_utils.c:709

References Assert(), close, PG_BINARY, pg_fatal, pg_file_create_mode, pg_free(), pg_pwrite_zeros(), SLRU_PAGES_PER_SEGMENT, SlruFileName(), and SlruFlush().

Referenced by SlruWriteSwitchPage().