| 304 | |
| 305 | |
| 306 | void PIO_extend(thread_db* tdbb, jrd_file* main_file, const ULONG extPages, const USHORT pageSize) |
| 307 | { |
| 308 | /************************************** |
| 309 | * |
| 310 | * P I O _ e x t e n d |
| 311 | * |
| 312 | ************************************** |
| 313 | * |
| 314 | * Functional description |
| 315 | * Extend file by extPages pages of pageSize size. |
| 316 | * |
| 317 | **************************************/ |
| 318 | |
| 319 | #if defined(HAVE_LINUX_FALLOC_H) && defined(HAVE_FALLOCATE) |
| 320 | |
| 321 | EngineCheckout cout(tdbb, FB_FUNCTION, EngineCheckout::UNNECESSARY); |
| 322 | |
| 323 | ULONG leftPages = extPages; |
| 324 | for (jrd_file* file = main_file; file && leftPages; file = file->fil_next) |
| 325 | { |
| 326 | const ULONG filePages = PIO_get_number_of_pages(file, pageSize); |
| 327 | const ULONG fileMaxPages = (file->fil_max_page == MAX_ULONG) ? |
| 328 | MAX_ULONG : file->fil_max_page - file->fil_min_page + 1; |
| 329 | if (filePages < fileMaxPages) |
| 330 | { |
| 331 | if (file->fil_flags & FIL_no_fast_extend) |
| 332 | return; |
| 333 | |
| 334 | const ULONG extendBy = MIN(fileMaxPages - filePages + file->fil_fudge, leftPages); |
| 335 | |
| 336 | const off_t offset = static_cast<off_t>(filePages) * pageSize; |
| 337 | const off_t length = static_cast<off_t>(extendBy) * pageSize; |
| 338 | |
| 339 | int r; |
| 340 | for (r = 0; r < IO_RETRY; r++) |
| 341 | { |
| 342 | int err = fallocate(file->fil_desc, 0, offset, length); |
| 343 | if (err == 0) |
| 344 | break; |
| 345 | |
| 346 | err = errno; |
| 347 | if (SYSCALL_INTERRUPTED(err)) |
| 348 | continue; |
| 349 | |
| 350 | if (err != EOPNOTSUPP && err != ENOSYS) |
| 351 | unix_error("fallocate", file, isc_io_write_err); |
| 352 | |
| 353 | file->fil_flags |= FIL_no_fast_extend; |
| 354 | return; |
| 355 | } |
| 356 | |
| 357 | if (r == IO_RETRY) |
| 358 | { |
| 359 | #ifdef DEV_BUILD |
| 360 | fprintf(stderr, "PIO_extend: retry count exceeded\n"); |
| 361 | fflush(stderr); |
| 362 | #endif |
| 363 | unix_error("fallocate_retry", file, isc_io_write_err); |
no test coverage detected