134{
135 char *buffer;
136 int srcfd;
138 int nbytes;
139 off_t offset;
140 off_t flush_offset;
141
142 /* Size of copy buffer (read and write requests) */
143#define COPY_BUF_SIZE (8 * BLCKSZ)
144
145 /*
146 * Size of data flush requests. It seems beneficial on most platforms to
147 * do this every 1MB or so. But macOS, at least with early releases of
148 * APFS, is really unfriendly to small mmap/msync requests, so there do it
149 * only every 32MB.
150 */
151#if defined(__darwin__)
152#define FLUSH_DISTANCE (32 * 1024 * 1024)
153#else
154#define FLUSH_DISTANCE (1024 * 1024)
155#endif
156
157 /* Use palloc to ensure we get a maxaligned buffer */
159
160 /*
161 * Open the files
162 */
164 if (srcfd < 0)
167 errmsg(
"could not open file \"%s\": %m", fromfile)));
168
173 errmsg(
"could not create file \"%s\": %m", tofile)));
174
175 /*
176 * Do the data copying.
177 */
178 flush_offset = 0;
179 for (offset = 0;; offset += nbytes)
180 {
181 /* If we got a cancel signal during the copy of the file, quit */
183
184 /*
185 * We fsync the files later, but during the copy, flush them every so
186 * often to avoid spamming the cache and hopefully get the kernel to
187 * start writing them out before the fsync comes.
188 */
190 {
192 flush_offset = offset;
193 }
194
198 if (nbytes < 0)
201 errmsg(
"could not read file \"%s\": %m", fromfile)));
202 if (nbytes == 0)
203 break;
204 errno = 0;
206 if ((
int)
write(
dstfd, buffer, nbytes) != nbytes)
207 {
208 /* if write didn't set errno, assume problem is no disk space */
209 if (errno == 0)
210 errno = ENOSPC;
213 errmsg(
"could not write to file \"%s\": %m", tofile)));
214 }
216 }
217
218 if (offset > flush_offset)
220
224 errmsg(
"could not close file \"%s\": %m", tofile)));
225
229 errmsg(
"could not close file \"%s\": %m", fromfile)));
230
232}
int errcode_for_file_access(void)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void pg_flush_data(int fd, off_t offset, off_t nbytes)
int CloseTransientFile(int fd)
int OpenTransientFile(const char *fileName, int fileFlags)
void pfree(void *pointer)
#define CHECK_FOR_INTERRUPTS()
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)