PostgreSQL Source Code: src/common/file_utils.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#ifndef FRONTEND
18#else
20#endif
21
23#include <fcntl.h>
24#include <sys/stat.h>
26
28#ifdef FRONTEND
30#endif
33
34#ifdef FRONTEND
35
36
37#if defined(HAVE_SYNC_FILE_RANGE)
38#define PG_FLUSH_DATA_WORKS 1
39#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
40#define PG_FLUSH_DATA_WORKS 1
41#endif
42
43
44
45
46#define MINIMUM_VERSION_FOR_PG_WAL 100000
47
48static void walkdir(const char *path,
49 int (*action) (const char *fname, bool isdir),
52
53#ifdef HAVE_SYNCFS
54
55
56
57
58
59
60static void
62{
63 int fd;
64
66
67 if (fd < 0)
68 {
69 pg_log_error("could not open file \"%s\": %m", path);
70 return;
71 }
72
74 {
75 pg_log_error("could not synchronize file system for file \"%s\": %m", path);
78 }
79
81}
82
83#endif
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98void
103{
107
108
112
113
114
115
116
118
119 {
120 struct stat st;
121
124 else if (S_ISLNK(st.st_mode))
126 }
127
129 {
131 {
132#ifndef HAVE_SYNCFS
133 pg_log_error("this build does not support sync method \"%s\"",
134 "syncfs");
136#else
137 DIR *dir;
139
140
141
142
143
144
145
146
147
148
150
151
153 {
155 if (dir == NULL)
156 pg_log_error("could not open directory \"%s\": %m",
158 else
159 {
161 {
163
164 if (strcmp(de->d_name, ".") == 0 ||
165 strcmp(de->d_name, "..") == 0)
166 continue;
167
171 }
172
174 pg_log_error("could not read directory \"%s\": %m",
176
178 }
179 }
180
181
184#endif
185 }
186 break;
187
189 {
191
194
195
196
197
198
199#ifdef PG_FLUSH_DATA_WORKS
205#endif
206
207
208
209
210
211
212
213
214
215
216
222
225 }
226 break;
227 }
228}
229
230
231
232
233
234
235void
237{
239 {
241 {
242#ifndef HAVE_SYNCFS
243 pg_log_error("this build does not support sync method \"%s\"",
244 "syncfs");
246#else
247
248
249
250
252#endif
253 }
254 break;
255
257 {
258
259
260
261
262#ifdef PG_FLUSH_DATA_WORKS
264#endif
265
267 }
268 break;
269 }
270}
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289static void
291 int (*action) (const char *fname, bool isdir),
294{
295 DIR *dir;
297
299 return;
300
302 if (dir == NULL)
303 {
304 pg_log_error("could not open directory \"%s\": %m", path);
305 return;
306 }
307
309 {
311
312 if (strcmp(de->d_name, ".") == 0 ||
313 strcmp(de->d_name, "..") == 0)
314 continue;
315
317
319 {
321 (*action) (subpath, false);
322 break;
325 break;
326 default:
327
328
329
330
331
332
333 break;
334 }
335 }
336
338 pg_log_error("could not read directory \"%s\": %m", path);
339
341
342
343
344
345
346
347
348 (*action) (path, true);
349}
350
351
352
353
354
355
356
357
358int
360{
361#ifdef PG_FLUSH_DATA_WORKS
362 int fd;
363
365
366 if (fd < 0)
367 {
369 return 0;
370 pg_log_error("could not open file \"%s\": %m", fname);
371 return -1;
372 }
373
374
375
376
377
378
379#if defined(HAVE_SYNC_FILE_RANGE)
381#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
383#else
384#error PG_FLUSH_DATA_WORKS should not have been defined
385#endif
386
388#endif
389 return 0;
390}
391
392
393
394
395
396
397
398
399int
401{
402 int fd;
403 int flags;
405
406
407
408
409
410
411
415 else
417
418
419
420
421
422
423 fd = open(fname, flags, 0);
424 if (fd < 0)
425 {
427 return 0;
428 pg_log_error("could not open file \"%s\": %m", fname);
429 return -1;
430 }
431
433
434
435
436
437
439 {
440 pg_log_error("could not fsync file \"%s\": %m", fname);
443 }
444
446 return 0;
447}
448
449
450
451
452
453
454
455int
457{
459
462
463
464
465
466
467
470
472 return -1;
473
474 return 0;
475}
476
477
478
479
480
481
482int
484{
485 int fd;
486
487
488
489
490
491
492
493
495 return -1;
496
498 if (fd < 0)
499 {
501 {
503 return -1;
504 }
505 }
506 else
507 {
509 {
513 }
515 }
516
517
519 {
520 pg_log_error("could not rename file \"%s\" to \"%s\": %m",
522 return -1;
523 }
524
525
526
527
528
530 return -1;
531
533 return -1;
534
535 return 0;
536}
537
538#endif
539
540
541
542
543
544
545
550 int elevel)
551{
553
554
555
556
557
558
559
560#if defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK)
563 else if (de->d_type == DT_DIR)
567 else
569#else
571#endif
572
574 {
577
578
581 else
583
584 if (sret < 0)
585 {
587#ifdef FRONTEND
589#else
592 errmsg("could not stat file \"%s\": %m", path)));
593#endif
594 }
601 }
602
603 return result;
604}
605
606
607
608
609
610
611
612
613int
618{
620
621
623 {
627
628
630 {
631
632
633
634
636 return 0;
637 }
638 }
639
640
643
644
648
650}
651
652
653
654
655
656
657
660{
664
665
667 {
669 return -1;
670 }
671
672 do
673 {
674
676 if (part < 0)
677 return -1;
678
679#ifdef SIMULATE_SHORT_WRITE
681#endif
682
683
685 offset += part;
686
687
688
689
690
691
694 } while (iovcnt > 0);
695
696 return sum;
697}
698
699
700
701
702
703
704
705
706
707
710{
716
717
719 {
722
724 {
726
728
731 else
733
736 }
737
739
742
745 }
746
748
750}
#define unconstify(underlying_type, expr)
#define Assert(condition)
struct dirent * readdir(DIR *)
DIR * opendir(const char *)
int errcode_for_file_access(void)
#define ereport(elevel,...)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
void fsync_fname(const char *fname, bool isdir)
static int fsync_parent_path(const char *fname, int elevel)
static void walkdir(const char *path, void(*action)(const char *fname, bool isdir, int elevel), bool process_symlinks, int elevel)
int compute_remaining_iovec(struct iovec *destination, const struct iovec *source, int iovcnt, size_t transferred)
ssize_t pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
ssize_t pg_pwrite_zeros(int fd, size_t size, pgoff_t offset)
PGFileType get_dirent_type(const char *path, const struct dirent *de, bool look_through_symlinks, int elevel)
@ DATA_DIR_SYNC_METHOD_SYNCFS
@ DATA_DIR_SYNC_METHOD_FSYNC
static bool sync_data_files
static DataDirSyncMethod sync_method
void pg_log_generic(enum pg_log_level level, enum pg_log_part part, const char *pg_restrict fmt,...)
#define pg_log_error(...)
Datum subpath(PG_FUNCTION_ARGS)
void pfree(void *pointer)
#define MINIMUM_VERSION_FOR_PG_WAL
static ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, pgoff_t offset)
static rewind_source * source
void get_parent_directory(char *path)
size_t strlcpy(char *dst, const char *src, size_t siz)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)