16
16
*
17
17
**************************************************************************/
18
18
19
- #include < cinttypes>
20
- #include < type_traits>
21
- #include < exception>
22
19
#include < algorithm>
23
- #include < memory>
24
- #include < mutex>
25
- #include < map>
26
20
#include < atomic>
21
+ #include < cinttypes>
27
22
#include < cstring>
23
+ #include < exception>
24
+ #include < memory>
25
+ #include < type_traits>
28
26
29
27
#if REALM_DEBUG
30
28
#include < iostream>
35
33
#include < cstdlib>
36
34
#endif
37
35
38
- #include < realm/util/errno.hpp>
39
36
#include < realm/util/encrypted_file_mapping.hpp>
40
- #include < realm/util/terminate.hpp>
41
- #include < realm/util/thread.hpp>
37
+ #include < realm/util/errno.hpp>
42
38
#include < realm/util/scope_exit.hpp>
39
+ #include < realm/util/terminate.hpp>
43
40
#include < realm/array.hpp>
44
41
#include < realm/alloc_slab.hpp>
42
+ #include < realm/disable_sync_to_disk.hpp>
45
43
#include < realm/group.hpp>
46
44
47
45
using namespace realm ;
@@ -164,9 +162,6 @@ void SlabAlloc::detach(bool keep_file_open) noexcept
164
162
// placed correctly (logically) after the end of the file.
165
163
m_slabs.clear ();
166
164
clear_freelists ();
167
- #if REALM_ENABLE_ENCRYPTION
168
- m_realm_file_info = nullptr ;
169
- #endif
170
165
171
166
m_attach_mode = attach_None;
172
167
}
@@ -805,10 +800,6 @@ ref_type SlabAlloc::attach_file(const std::string& path, Config& cfg, util::Writ
805
800
// the call below to set_encryption_key.
806
801
m_file.set_encryption_key (cfg.encryption_key );
807
802
808
- note_reader_start (this );
809
- util::ScopeExit reader_end_guard ([this ]() noexcept {
810
- note_reader_end (this );
811
- });
812
803
size_t size = 0 ;
813
804
// The size of a database file must not exceed what can be encoded in
814
805
// size_t.
@@ -840,26 +831,17 @@ ref_type SlabAlloc::attach_file(const std::string& path, Config& cfg, util::Writ
840
831
if (size == 0 ) {
841
832
if (REALM_UNLIKELY (cfg.read_only ))
842
833
throw InvalidDatabase (" Read-only access to empty Realm file" , path);
843
-
844
- size_t initial_size = page_size ();
845
- // exFAT does not allocate a unique id for the file until it is non-empty. It must be
846
- // valid at this point because File::get_unique_id() is used to distinguish
847
- // mappings_for_file in the encryption layer. So the prealloc() is required before
848
- // interacting with the encryption layer in File::write().
849
- // Pre-alloc initial space
850
- m_file.prealloc (initial_size); // Throws
851
- // seek() back to the start of the file in preparation for writing the header
852
- // This sequence of File operations is protected from races by
853
- // DB::m_controlmutex, so we know we are the only ones operating on the file
854
- m_file.seek (0 );
834
+ // We want all non-streaming files to be a multiple of the page size
835
+ // to simplify memory mapping, so just pre-reserve the required space now
836
+ m_file.prealloc (page_size ()); // Throws
855
837
const char * data = reinterpret_cast <const char *>(&empty_file_header);
856
- m_file.write (data, sizeof empty_file_header); // Throws
838
+ m_file.write (0 , data, sizeof empty_file_header); // Throws
857
839
858
840
bool disable_sync = get_disable_sync_to_disk () || cfg.disable_sync ;
859
841
if (!disable_sync)
860
842
m_file.sync (); // Throws
861
843
862
- size = initial_size ;
844
+ size = m_file. get_size () ;
863
845
}
864
846
865
847
ref_type top_ref = read_and_validate_header (m_file, path, size, cfg.session_initiator , m_write_observer);
@@ -886,9 +868,6 @@ ref_type SlabAlloc::attach_file(const std::string& path, Config& cfg, util::Writ
886
868
realm::util::encryption_read_barrier (m_mappings[0 ].primary_mapping , 0 , sizeof (Header));
887
869
dg.release (); // Do not detach
888
870
fcg.release (); // Do not close
889
- #if REALM_ENABLE_ENCRYPTION
890
- m_realm_file_info = util::get_file_info_for_file (m_file);
891
- #endif
892
871
return top_ref;
893
872
}
894
873
@@ -905,12 +884,12 @@ void SlabAlloc::convert_from_streaming_form(ref_type top_ref)
905
884
{
906
885
File::Map<Header> writable_map (m_file, File::access_ReadWrite, sizeof (Header)); // Throws
907
886
Header& writable_header = *writable_map.get_addr ();
908
- realm::util::encryption_read_barrier_for_write (writable_map, 0 );
887
+ realm::util::encryption_read_barrier (writable_map, 0 );
909
888
writable_header.m_top_ref [1 ] = top_ref;
910
889
writable_header.m_file_format [1 ] = writable_header.m_file_format [0 ];
911
890
realm::util::encryption_write_barrier (writable_map, 0 );
912
891
writable_map.sync ();
913
- realm::util::encryption_read_barrier_for_write (writable_map, 0 );
892
+ realm::util::encryption_read_barrier (writable_map, 0 );
914
893
writable_header.m_flags |= flags_SelectBit;
915
894
realm::util::encryption_write_barrier (writable_map, 0 );
916
895
writable_map.sync ();
@@ -919,26 +898,6 @@ void SlabAlloc::convert_from_streaming_form(ref_type top_ref)
919
898
}
920
899
}
921
900
922
- void SlabAlloc::note_reader_start (const void * reader_id)
923
- {
924
- #if REALM_ENABLE_ENCRYPTION
925
- if (m_realm_file_info)
926
- util::encryption_note_reader_start (*m_realm_file_info, reader_id);
927
- #else
928
- static_cast <void >(reader_id);
929
- #endif
930
- }
931
-
932
- void SlabAlloc::note_reader_end (const void * reader_id) noexcept
933
- {
934
- #if REALM_ENABLE_ENCRYPTION
935
- if (m_realm_file_info)
936
- util::encryption_note_reader_end (*m_realm_file_info, reader_id);
937
- #else
938
- static_cast <void >(reader_id);
939
- #endif
940
- }
941
-
942
901
ref_type SlabAlloc::attach_buffer (const char * data, size_t size)
943
902
{
944
903
// ExceptionSafety: If this function throws, it must leave the allocator in
@@ -1009,7 +968,7 @@ ref_type SlabAlloc::read_and_validate_header(util::File& file, const std::string
1009
968
{
1010
969
try {
1011
970
// we'll read header and (potentially) footer
1012
- File::Map<char > map_header (file, File::access_ReadOnly, sizeof (Header), 0 , write_observer);
971
+ File::Map<char > map_header (file, File::access_ReadOnly, sizeof (Header), write_observer);
1013
972
realm::util::encryption_read_barrier (map_header, 0 , sizeof (Header));
1014
973
auto header = reinterpret_cast <const Header*>(map_header.get_addr ());
1015
974
@@ -1020,12 +979,12 @@ ref_type SlabAlloc::read_and_validate_header(util::File& file, const std::string
1020
979
size_t footer_page_base = footer_ref & ~(page_size () - 1 );
1021
980
size_t footer_offset = footer_ref - footer_page_base;
1022
981
map_footer = File::Map<char >(file, footer_page_base, File::access_ReadOnly,
1023
- sizeof (StreamingFooter) + footer_offset, 0 , write_observer);
982
+ sizeof (StreamingFooter) + footer_offset, write_observer);
1024
983
realm::util::encryption_read_barrier (map_footer, footer_offset, sizeof (StreamingFooter));
1025
984
footer = reinterpret_cast <const StreamingFooter*>(map_footer.get_addr () + footer_offset);
1026
985
}
1027
986
1028
- auto top_ref = validate_header (header, footer, size, path, file.get_encryption_key () != nullptr ); // Throws
987
+ auto top_ref = validate_header (header, footer, size, path, file.get_encryption () != nullptr ); // Throws
1029
988
1030
989
if (session_initiator && is_file_on_streaming_form (*header)) {
1031
990
// Don't compare file format version fields as they are allowed to differ.
@@ -1278,7 +1237,7 @@ void SlabAlloc::update_reader_view(size_t file_size)
1278
1237
const size_t section_size = std::min<size_t >(1 << section_shift, file_size - section_start_offset);
1279
1238
if (section_size == (1 << section_shift)) {
1280
1239
new_mappings.push_back ({util::File::Map<char >(m_file, section_start_offset, File::access_ReadOnly,
1281
- section_size, 0 , m_write_observer)});
1240
+ section_size, m_write_observer)});
1282
1241
}
1283
1242
else {
1284
1243
new_mappings.push_back ({util::File::Map<char >()});
@@ -1291,7 +1250,7 @@ void SlabAlloc::update_reader_view(size_t file_size)
1291
1250
throw std::bad_alloc ();
1292
1251
}
1293
1252
else {
1294
- new_mappings.back ().primary_mapping .map (m_file, File::access_ReadOnly, section_size, 0 ,
1253
+ new_mappings.back ().primary_mapping .map (m_file, File::access_ReadOnly, section_size,
1295
1254
section_start_offset, m_write_observer);
1296
1255
}
1297
1256
}
@@ -1352,16 +1311,9 @@ void SlabAlloc::update_reader_view(size_t file_size)
1352
1311
void SlabAlloc::schedule_refresh_of_outdated_encrypted_pages ()
1353
1312
{
1354
1313
#if REALM_ENABLE_ENCRYPTION
1355
- // callers must already hold m_mapping_mutex
1356
- for (auto & e : m_mappings) {
1357
- if (auto m = e.primary_mapping .get_encrypted_mapping ()) {
1358
- encryption_mark_pages_for_IV_check (m);
1359
- }
1360
- if (auto m = e.xover_mapping .get_encrypted_mapping ()) {
1361
- encryption_mark_pages_for_IV_check (m);
1362
- }
1314
+ if (auto encryption = m_file.get_encryption ()) {
1315
+ encryption->mark_data_as_possibly_stale ();
1363
1316
}
1364
- // unsafe to do outside writing thread: verify();
1365
1317
#endif // REALM_ENABLE_ENCRYPTION
1366
1318
}
1367
1319
@@ -1457,7 +1409,7 @@ void SlabAlloc::get_or_add_xover_mapping(RefTranslation& txl, size_t index, size
1457
1409
auto end_offset = file_offset + size;
1458
1410
auto mapping_file_offset = file_offset & ~(_page_size - 1 );
1459
1411
auto minimal_mapping_size = end_offset - mapping_file_offset;
1460
- util::File::Map<char > mapping (m_file, mapping_file_offset, File::access_ReadOnly, minimal_mapping_size, 0 ,
1412
+ util::File::Map<char > mapping (m_file, mapping_file_offset, File::access_ReadOnly, minimal_mapping_size,
1461
1413
m_write_observer);
1462
1414
map_entry->xover_mapping = std::move (mapping);
1463
1415
}
0 commit comments