@@ -363,6 +363,74 @@ pg_tde_delete_principal_key(Oid dbOid)
363363 durable_unlink (path , ERROR );
364364}
365365
366+ static FILE *
367+ pg_tde_open_file_basic_copy (const char * tde_filename , const char * mode , bool ignore_missing )
368+ {
369+ FILE * file ;
370+
371+ file = AllocateFile (tde_filename , mode );
372+ if (file == NULL && !(errno == ENOENT && ignore_missing == true))
373+ {
374+ ereport (ERROR ,
375+ errcode_for_file_access (),
376+ errmsg ("could not open tde file \"%s\": %m" , tde_filename ));
377+ }
378+
379+ return file ;
380+ }
381+
382+ static void
383+ pg_tde_file_header_read_copy (const char * tde_filename , FILE * file , TDEFileHeader * fheader )
384+ {
385+ size_t bytes_read ;
386+
387+ Assert (fheader );
388+
389+ bytes_read = fread (fheader , TDE_FILE_HEADER_SIZE , 1 , file );
390+
391+ if (bytes_read != 1 || fheader -> file_version != PG_TDE_FILEMAGIC )
392+ {
393+ ereport (FATAL ,
394+ errcode_for_file_access (),
395+ errmsg ("TDE map file \"%s\" is corrupted %ld %d: %m" , tde_filename , bytes_read , fheader -> file_version ));
396+ }
397+ }
398+
399+ static FILE *
400+ pg_tde_open_file_write_copy (const char * tde_filename , const TDESignedPrincipalKeyInfo * signed_key_info )
401+ {
402+ FILE * file ;
403+ TDEFileHeader fheader ;
404+
405+ Assert (LWLockHeldByMeInMode (tde_lwlock_enc_keys (), LW_EXCLUSIVE ));
406+
407+ file = pg_tde_open_file_basic_copy (tde_filename , "rb+" , false);
408+
409+ pg_tde_file_header_read_copy (tde_filename , file , & fheader );
410+
411+ ///* In case it's a new file, let's add the header now. */
412+ //if (bytes_read == 0 && signed_key_info)
413+ // pg_tde_file_header_write(tde_filename, fd, signed_key_info, &bytes_written);
414+
415+ return file ;
416+ }
417+
418+ static bool
419+ pg_tde_read_one_map_entry_copy (FILE * map_file , TDEMapEntry * map_entry )
420+ {
421+ size_t entries_read ;
422+
423+ Assert (map_entry );
424+
425+ entries_read = fread (map_entry , MAP_ENTRY_SIZE , 1 , map_file );
426+
427+ /* We've reached the end of the file. */
428+ if (entries_read != 1 )
429+ return false;
430+
431+ return true;
432+ }
433+
366434/*
367435 * The caller must hold an exclusive lock on the key file to avoid
368436 * concurrent in place updates leading to data conflicts.
371439pg_tde_replace_key_map_entry (const RelFileLocator * rlocator , const InternalKey * rel_key_data , TDEPrincipalKey * principal_key )
372440{
373441 char db_map_path [MAXPGPATH ];
374- int map_fd ;
375- off_t curr_pos = 0 ;
442+ FILE * map_file ;
376443 off_t write_pos = 0 ;
377444 TDEMapEntry write_map_entry ;
378445 TDESignedPrincipalKeyInfo signed_key_Info ;
@@ -384,7 +451,7 @@ pg_tde_replace_key_map_entry(const RelFileLocator *rlocator, const InternalKey *
384451 pg_tde_sign_principal_key_info (& signed_key_Info , principal_key );
385452
386453 /* Open and validate file for basic correctness. */
387- map_fd = pg_tde_open_file_write (db_map_path , & signed_key_Info , false, & curr_pos );
454+ map_file = pg_tde_open_file_write_copy (db_map_path , & signed_key_Info );
388455
389456 /*
390457 * Read until we find an empty slot. Otherwise, read until end. This seems
@@ -394,32 +461,31 @@ pg_tde_replace_key_map_entry(const RelFileLocator *rlocator, const InternalKey *
394461 while (1 )
395462 {
396463 TDEMapEntry read_map_entry ;
397- off_t prev_pos = curr_pos ;
398464
399- if (!pg_tde_read_one_map_entry ( map_fd , & read_map_entry , & curr_pos ))
465+ if (!pg_tde_read_one_map_entry_copy ( map_file , & read_map_entry ))
400466 {
401467 if (write_pos == 0 )
402- write_pos = prev_pos ;
468+ write_pos = ftell ( map_file ) ;
403469 break ;
404470 }
405471
406472 if (read_map_entry .spcOid == rlocator -> spcOid && read_map_entry .relNumber == rlocator -> relNumber )
407473 {
408- write_pos = prev_pos ;
474+ write_pos = ftell ( map_file ) - MAP_ENTRY_SIZE ;
409475 break ;
410476 }
411477
412478 if (write_pos == 0 && read_map_entry .type == MAP_ENTRY_EMPTY )
413- write_pos = prev_pos ;
479+ write_pos = ftell ( map_file ) - MAP_ENTRY_SIZE ;
414480 }
415481
416482 /* Initialize map entry and encrypt key */
417483 pg_tde_initialize_map_entry (& write_map_entry , principal_key , rlocator , rel_key_data );
418484
419485 /* Write the given entry at curr_pos; i.e. the free entry. */
420- pg_tde_write_one_map_entry (map_fd , & write_map_entry , & write_pos , db_map_path );
486+ pg_tde_write_one_map_entry (fileno ( map_file ) , & write_map_entry , & write_pos , db_map_path );
421487
422- CloseTransientFile ( map_fd );
488+ FreeFile ( map_file );
423489}
424490
425491#endif /* !FRONTEND */
0 commit comments