diff options
author | unknown <svoj@april.(none)> | 2006-04-13 14:37:03 +0500 |
---|---|---|
committer | unknown <svoj@april.(none)> | 2006-04-13 14:37:03 +0500 |
commit | d316b8b10b3b430efef3d429b1588c93e1667e67 (patch) | |
tree | 868ffd855186b712c7ad26b4a94c132c6e4612d0 /myisam/mi_packrec.c | |
parent | 20270e430715194ae0782b71749175328f6c86fb (diff) | |
download | mariadb-git-d316b8b10b3b430efef3d429b1588c93e1667e67.tar.gz |
BUG#17917 - SELECT from compressed MyISAM table crashes MySQL server
Retrieving data from compressed MyISAM table which is bigger than 4G on 32-bit box
with mmap() support results in server crash.
mmap() accepts length of bytes to be mapped in second param, which is 32-bit
size_t. But we pass data_file_length, which is 64-bit my_off_t. As a result only
first data_file_length % 4G were mapped.
This fix adds additional condition for mmap() usage, that is use mmap() for
compressed table which size is no more than 4G on 32-bit platform.
myisam/mi_packrec.c:
Use mmap() for compressed table which size is no more than 4G on 32-bit platform.
Diffstat (limited to 'myisam/mi_packrec.c')
-rw-r--r-- | myisam/mi_packrec.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 322420b71db..bd2d162d100 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -1158,16 +1158,22 @@ my_bool _mi_memmap_file(MI_INFO *info) MYISAM_SHARE *share=info->s; DBUG_ENTER("mi_memmap_file"); - if (!info->s->file_map) + if (!share->file_map) { + my_off_t data_file_length= share->state.state.data_file_length; + if (data_file_length > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN) + { + DBUG_PRINT("warning", ("File is too large for mmap")); + DBUG_RETURN(0); + } if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) < - share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN) + data_file_length + MEMMAP_EXTRA_MARGIN) { DBUG_PRINT("warning",("File isn't extended for memmap")); DBUG_RETURN(0); } file_map=(byte*) - mmap(0,share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN,PROT_READ, + mmap(0, data_file_length + MEMMAP_EXTRA_MARGIN, PROT_READ, MAP_SHARED | MAP_NORESERVE,info->dfile,0L); if (file_map == (byte*) MAP_FAILED) { @@ -1175,7 +1181,7 @@ my_bool _mi_memmap_file(MI_INFO *info) my_errno=errno; DBUG_RETURN(0); } - info->s->file_map=file_map; + share->file_map= file_map; } info->opt_flag|= MEMMAP_USED; info->read_record=share->read_record=_mi_read_mempack_record; |