1 /*------------------------------------------------------------------------- 2 * 3 * filemap.h 4 * 5 * Copyright (c) 2013-2021, PostgreSQL Global Development Group 6 *------------------------------------------------------------------------- 7 */ 8 #ifndef FILEMAP_H 9 #define FILEMAP_H 10 11 #include "datapagemap.h" 12 #include "storage/block.h" 13 #include "storage/relfilenode.h" 14 15 /* these enum values are sorted in the order we want actions to be processed */ 16 typedef enum 17 { 18 FILE_ACTION_UNDECIDED = 0, /* not decided yet */ 19 20 FILE_ACTION_CREATE, /* create local directory or symbolic link */ 21 FILE_ACTION_COPY, /* copy whole file, overwriting if exists */ 22 FILE_ACTION_COPY_TAIL, /* copy tail from 'source_size' to 23 * 'target_size' */ 24 FILE_ACTION_NONE, /* no action (we might still copy modified 25 * blocks based on the parsed WAL) */ 26 FILE_ACTION_TRUNCATE, /* truncate local file to 'newsize' bytes */ 27 FILE_ACTION_REMOVE /* remove local file / directory / symlink */ 28 } file_action_t; 29 30 typedef enum 31 { 32 FILE_TYPE_UNDEFINED = 0, 33 34 FILE_TYPE_REGULAR, 35 FILE_TYPE_DIRECTORY, 36 FILE_TYPE_SYMLINK 37 } file_type_t; 38 39 /* 40 * For every file found in the local or remote system, we have a file entry 41 * that contains information about the file on both systems. For relation 42 * files, there is also a page map that marks pages in the file that were 43 * changed in the target after the last common checkpoint. 44 * 45 * When gathering information, these are kept in a hash table, private to 46 * filemap.c. decide_file_actions() fills in the 'action' field, sorts all 47 * the entries, and returns them in an array, ready for executing the actions. 48 */ 49 typedef struct file_entry_t 50 { 51 uint32 status; /* hash status */ 52 53 const char *path; 54 bool isrelfile; /* is it a relation data file? */ 55 56 /* 57 * Status of the file in the target. 58 */ 59 bool target_exists; 60 file_type_t target_type; 61 size_t target_size; /* for a regular file */ 62 char *target_link_target; /* for a symlink */ 63 64 /* 65 * Pages that were modified in the target and need to be replaced from the 66 * source. 67 */ 68 datapagemap_t target_pages_to_overwrite; 69 70 /* 71 * Status of the file in the source. 72 */ 73 bool source_exists; 74 file_type_t source_type; 75 size_t source_size; 76 char *source_link_target; /* for a symlink */ 77 78 /* 79 * What will we do to the file? 80 */ 81 file_action_t action; 82 } file_entry_t; 83 84 /* 85 * This contains the final decisions on what to do with each file. 86 * 'entries' array contains an entry for each file, sorted in the order 87 * that their actions should executed. 88 */ 89 typedef struct filemap_t 90 { 91 /* Summary information, filled by calculate_totals() */ 92 uint64 total_size; /* total size of the source cluster */ 93 uint64 fetch_size; /* number of bytes that needs to be copied */ 94 95 int nentries; /* size of 'entries' array */ 96 file_entry_t *entries[FLEXIBLE_ARRAY_MEMBER]; 97 } filemap_t; 98 99 /* Functions for populating the filemap */ 100 extern void filehash_init(void); 101 extern void process_source_file(const char *path, file_type_t type, 102 size_t size, const char *link_target); 103 extern void process_target_file(const char *path, file_type_t type, 104 size_t size, const char *link_target); 105 extern void process_target_wal_block_change(ForkNumber forknum, 106 RelFileNode rnode, 107 BlockNumber blkno); 108 109 extern filemap_t *decide_file_actions(void); 110 extern void calculate_totals(filemap_t *filemap); 111 extern void print_filemap(filemap_t *filemap); 112 113 #endif /* FILEMAP_H */ 114