/**********************************************************************//**
Tries to extend a data file so that it would accommodate the number of pages
given. The tablespace must be cached in the memory cache. If the space is big
enough already, does nothing.
@return TRUE if success */
UNIV_INTERN
ibool
fil_extend_space_to_desired_size(
/*=============================*/
ulint* actual_size, /*!< out: size of the space after extension;
if we ran out of disk space this may be lower
than the desired size */
ulint space_id, /*!< in: space id */
ulint size_after_extend)/*!< in: desired size in pages after the
extension; if the current space size is bigger
than this already, the function does nothing */
{
fil_node_t* node;
fil_space_t* space;
byte* buf2;
byte* buf;
ulint buf_size;
ulint start_page_no;
ulint file_start_page_no;
ulint offset_high;
ulint offset_low;
ulint page_size;
ibool success = TRUE;
fil_mutex_enter_and_prepare_for_io(space_id);
space = fil_space_get_by_id(space_id);
ut_a(space);
if (space->size >= size_after_extend) {
/* Space already big enough */
*actual_size = space->size;
mutex_exit(&fil_system->mutex);
return(TRUE);
}
page_size = dict_table_flags_to_zip_size(space->flags);
if (!page_size) {
page_size = UNIV_PAGE_SIZE;
}
node = UT_LIST_GET_LAST(space->chain);
fil_node_prepare_for_io(node, fil_system, space);
start_page_no = space->size;
file_start_page_no = space->size - node->size;
/* Extend at most 64 pages at a time */
buf_size = ut_min(, size_after_extend - start_page_no) * page_size;
buf2 = mem_alloc(buf_size + page_size);
buf = ut_align(buf2, page_size);
memset(buf, , buf_size);
while (start_page_no < size_after_extend) {
ulint n_pages = ut_min(buf_size / page_size,
size_after_extend - start_page_no);
offset_high = (start_page_no - file_start_page_no)
/ ( * (( * ) / page_size));
offset_low = ((start_page_no - file_start_page_no)
% ( * (( * ) / page_size)))
* page_size;
#ifdef UNIV_HOTBACKUP
success = os_file_write(node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages);
#else
success = os_aio(OS_FILE_WRITE, OS_AIO_SYNC,
node->name, node->handle, buf,
offset_low, offset_high,
page_size * n_pages,
NULL, NULL);
#endif
if (success) {
node->size += n_pages;
space->size += n_pages;
os_has_said_disk_full = FALSE;
} else {
/* Let us measure the size of the file to determine
how much we were able to extend it */
n_pages = ((ulint)
(os_file_get_size_as_iblonglong(
node->handle)
/ page_size)) - node->size;
node->size += n_pages;
space->size += n_pages;
break;
}
start_page_no += n_pages;
}
mem_free(buf2);
fil_node_complete_io(node, fil_system, OS_FILE_WRITE);
*actual_size = space->size;
#ifndef UNIV_HOTBACKUP
) {
ulint pages_per_mb = ( * ) / page_size;
/* Keep the last data file size info up to date, rounded to
full megabytes */
srv_data_file_sizes[srv_n_data_files - ]
= (node->size / pages_per_mb) * pages_per_mb;
}
#endif /* !UNIV_HOTBACKUP */
/*
printf("Extended %s to %lu, actual size %lu pages\n", space->name,
size_after_extend, *actual_size); */
mutex_exit(&fil_system->mutex);
fil_flush(space_id);
return(success);
}