| 1 | /*------------------------------------------------------------------------- | 
|---|
| 2 | * | 
|---|
| 3 | * filemap.h | 
|---|
| 4 | * | 
|---|
| 5 | * Copyright (c) 2013-2019, PostgreSQL Global Development Group | 
|---|
| 6 | *------------------------------------------------------------------------- | 
|---|
| 7 | */ | 
|---|
| 8 | #ifndef FILEMAP_H | 
|---|
| 9 | #define FILEMAP_H | 
|---|
| 10 |  | 
|---|
| 11 | #include "storage/relfilenode.h" | 
|---|
| 12 | #include "storage/block.h" | 
|---|
| 13 |  | 
|---|
| 14 | #include "datapagemap.h" | 
|---|
| 15 |  | 
|---|
| 16 | /* | 
|---|
| 17 | * For every file found in the local or remote system, we have a file entry | 
|---|
| 18 | * which says what we are going to do with the file. For relation files, | 
|---|
| 19 | * there is also a page map, marking pages in the file that were changed | 
|---|
| 20 | * locally. | 
|---|
| 21 | * | 
|---|
| 22 | * The enum values are sorted in the order we want actions to be processed. | 
|---|
| 23 | */ | 
|---|
| 24 | typedef enum | 
|---|
| 25 | { | 
|---|
| 26 | FILE_ACTION_CREATE,			/* create local directory or symbolic link */ | 
|---|
| 27 | FILE_ACTION_COPY,			/* copy whole file, overwriting if exists */ | 
|---|
| 28 | FILE_ACTION_COPY_TAIL,		/* copy tail from 'oldsize' to 'newsize' */ | 
|---|
| 29 | FILE_ACTION_NONE,			/* no action (we might still copy modified | 
|---|
| 30 | * blocks based on the parsed WAL) */ | 
|---|
| 31 | FILE_ACTION_TRUNCATE,		/* truncate local file to 'newsize' bytes */ | 
|---|
| 32 | FILE_ACTION_REMOVE			/* remove local file / directory / symlink */ | 
|---|
| 33 | } file_action_t; | 
|---|
| 34 |  | 
|---|
| 35 | typedef enum | 
|---|
| 36 | { | 
|---|
| 37 | FILE_TYPE_REGULAR, | 
|---|
| 38 | FILE_TYPE_DIRECTORY, | 
|---|
| 39 | FILE_TYPE_SYMLINK | 
|---|
| 40 | } file_type_t; | 
|---|
| 41 |  | 
|---|
| 42 | typedef struct file_entry_t | 
|---|
| 43 | { | 
|---|
| 44 | char	   *path; | 
|---|
| 45 | file_type_t type; | 
|---|
| 46 |  | 
|---|
| 47 | file_action_t action; | 
|---|
| 48 |  | 
|---|
| 49 | /* for a regular file */ | 
|---|
| 50 | size_t		oldsize; | 
|---|
| 51 | size_t		newsize; | 
|---|
| 52 | bool		isrelfile;		/* is it a relation data file? */ | 
|---|
| 53 |  | 
|---|
| 54 | datapagemap_t pagemap; | 
|---|
| 55 |  | 
|---|
| 56 | /* for a symlink */ | 
|---|
| 57 | char	   *link_target; | 
|---|
| 58 |  | 
|---|
| 59 | struct file_entry_t *next; | 
|---|
| 60 | } file_entry_t; | 
|---|
| 61 |  | 
|---|
| 62 | typedef struct filemap_t | 
|---|
| 63 | { | 
|---|
| 64 | /* | 
|---|
| 65 | * New entries are accumulated to a linked list, in process_source_file | 
|---|
| 66 | * and process_target_file. | 
|---|
| 67 | */ | 
|---|
| 68 | file_entry_t *first; | 
|---|
| 69 | file_entry_t *last; | 
|---|
| 70 | int			nlist;			/* number of entries currently in list */ | 
|---|
| 71 |  | 
|---|
| 72 | /* | 
|---|
| 73 | * After processing all the remote files, the entries in the linked list | 
|---|
| 74 | * are moved to this array. After processing local files, too, all the | 
|---|
| 75 | * local entries are added to the array by filemap_finalize, and sorted in | 
|---|
| 76 | * the final order. After filemap_finalize, all the entries are in the | 
|---|
| 77 | * array, and the linked list is empty. | 
|---|
| 78 | */ | 
|---|
| 79 | file_entry_t **array; | 
|---|
| 80 | int			narray;			/* current length of array */ | 
|---|
| 81 |  | 
|---|
| 82 | /* | 
|---|
| 83 | * Summary information. total_size is the total size of the source | 
|---|
| 84 | * cluster, and fetch_size is the number of bytes that needs to be copied. | 
|---|
| 85 | */ | 
|---|
| 86 | uint64		total_size; | 
|---|
| 87 | uint64		fetch_size; | 
|---|
| 88 | } filemap_t; | 
|---|
| 89 |  | 
|---|
| 90 | extern filemap_t *filemap; | 
|---|
| 91 |  | 
|---|
| 92 | extern void filemap_create(void); | 
|---|
| 93 | extern void calculate_totals(void); | 
|---|
| 94 | extern void print_filemap(void); | 
|---|
| 95 |  | 
|---|
| 96 | /* Functions for populating the filemap */ | 
|---|
| 97 | extern void process_source_file(const char *path, file_type_t type, | 
|---|
| 98 | size_t newsize, const char *link_target); | 
|---|
| 99 | extern void process_target_file(const char *path, file_type_t type, | 
|---|
| 100 | size_t newsize, const char *link_target); | 
|---|
| 101 | extern void process_block_change(ForkNumber forknum, RelFileNode rnode, | 
|---|
| 102 | BlockNumber blkno); | 
|---|
| 103 | extern void filemap_finalize(void); | 
|---|
| 104 |  | 
|---|
| 105 | #endif							/* FILEMAP_H */ | 
|---|
| 106 |  | 
|---|