@@ -1168,6 +1168,56 @@ void SharedMemoryBase::unlinkFile(const TEXT* expanded_filename) noexcept
1168
1168
1169
1169
#ifdef UNIX
1170
1170
1171
+ static inline void reportError (const char * func, CheckStatusWrapper* statusVector)
1172
+ {
1173
+ if (!statusVector)
1174
+ system_call_failed::raise (func);
1175
+ else
1176
+ error (statusVector, func, errno);
1177
+ }
1178
+
1179
+ bool allocFileSpace (int fd, off_t offset, FB_SIZE_T length, CheckStatusWrapper* statusVector)
1180
+ {
1181
+ #if defined(HAVE_LINUX_FALLOC_H) && defined(HAVE_FALLOCATE)
1182
+ if (fallocate (fd, 0 , offset, length) == 0 )
1183
+ return true ;
1184
+
1185
+ if (errno != EOPNOTSUPP && errno != ENOSYS)
1186
+ {
1187
+ reportError (" fallocate" , statusVector);
1188
+ return false ;
1189
+ }
1190
+ // fallocate is not supported by this kernel or file system
1191
+ // take the long way around
1192
+ #endif
1193
+ static const FB_SIZE_T buf128KSize = 131072 ;
1194
+ HalfStaticArray<UCHAR, BUFFER_LARGE> buf;
1195
+ const FB_SIZE_T bufSize = length < buf128KSize ? length : buf128KSize;
1196
+
1197
+ memset (buf.getBuffer (bufSize), 0 , bufSize);
1198
+ os_utils::lseek (fd, LSEEK_OFFSET_CAST offset, SEEK_SET);
1199
+
1200
+ while (length)
1201
+ {
1202
+ const FB_SIZE_T cnt = length < bufSize ? length : bufSize;
1203
+ if (write (fd, buf.begin (), cnt) != (ssize_t ) cnt)
1204
+ {
1205
+ reportError (" write" , statusVector);
1206
+ return false ;
1207
+ }
1208
+ length -= cnt;
1209
+ }
1210
+
1211
+ if (fsync (fd))
1212
+ {
1213
+ reportError (" fsync" , statusVector);
1214
+ return false ;
1215
+ }
1216
+
1217
+ return true ;
1218
+ }
1219
+
1220
+
1171
1221
void SharedMemoryBase::internalUnmap ()
1172
1222
{
1173
1223
if (sh_mem_header)
@@ -1303,7 +1353,10 @@ SharedMemoryBase::SharedMemoryBase(const TEXT* filename, ULONG length, IpcObject
1303
1353
if (mainLock->setlock (&statusVector, FileLock::FLM_TRY_EXCLUSIVE))
1304
1354
{
1305
1355
if (trunc_flag)
1356
+ {
1306
1357
FB_UNUSED (os_utils::ftruncate (mainLock->getFd (), length));
1358
+ allocFileSpace (mainLock->getFd (), 0 , length, NULL );
1359
+ }
1307
1360
1308
1361
if (callback->initialize (this , true ))
1309
1362
{
@@ -2436,8 +2489,19 @@ bool SharedMemoryBase::remapFile(CheckStatusWrapper* statusVector, ULONG new_len
2436
2489
}
2437
2490
2438
2491
if (flag)
2492
+ {
2439
2493
FB_UNUSED (os_utils::ftruncate (mainLock->getFd (), new_length));
2440
2494
2495
+ if (new_length > sh_mem_length_mapped)
2496
+ {
2497
+ if (!allocFileSpace (mainLock->getFd (), sh_mem_length_mapped,
2498
+ new_length - sh_mem_length_mapped, statusVector))
2499
+ {
2500
+ return false ;
2501
+ }
2502
+ }
2503
+ }
2504
+
2441
2505
MemoryHeader* const address = (MemoryHeader*) os_utils::mmap (0 , new_length,
2442
2506
PROT_READ | PROT_WRITE, MAP_SHARED, mainLock->getFd (), 0 );
2443
2507
0 commit comments