summaryrefslogtreecommitdiff
path: root/mysys/mulalloc.c
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2015-08-13 01:27:23 +0300
committerMonty <monty@mariadb.org>2015-08-13 01:27:23 +0300
commitafa9cb7519fcb73d546bba45d3baa7b157926084 (patch)
treee207ab7924f79ce56c822cf2f6b76f2ff9fe925a /mysys/mulalloc.c
parent0403790722e3941779ccea26e85fcd818e2320b5 (diff)
downloadmariadb-git-afa9cb7519fcb73d546bba45d3baa7b157926084.tar.gz
Fixed overrun in key cache if one tried to allocate a key cache
of more than 45G with a key_cache_block_size of 1024 or less. The problem was that some of the arguments to my_multi_malloc() got to be more than 4G. Fix: - Inntroduced my_multi_malloc_large() that can handle big regions. - Changed MyISAM and Aria key caches to use my_multi_malloc_large(). I didn't change the default my_multi_malloc() as this would be a too big patch and we don't allocate 4G blocks anywhere else.
Diffstat (limited to 'mysys/mulalloc.c')
-rw-r--r--mysys/mulalloc.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/mysys/mulalloc.c b/mysys/mulalloc.c
index 9384ed744ad..fceecdc1dc7 100644
--- a/mysys/mulalloc.c
+++ b/mysys/mulalloc.c
@@ -62,3 +62,47 @@ void* my_multi_malloc(myf myFlags, ...)
va_end(args);
DBUG_RETURN((void*) start);
}
+
+
+/*
+ Same as my_multi_malloc, but each entry can be over 4G
+
+ SYNOPSIS
+ my_multi_malloc()
+ myFlags Flags
+ ptr1, length1 Multiple arguments terminated by null ptr
+ ptr2, length2 ...
+ ...
+ NULL
+*/
+
+void *my_multi_malloc_large(myf myFlags, ...)
+{
+ va_list args;
+ char **ptr,*start,*res;
+ size_t tot_length,length;
+ DBUG_ENTER("my_multi_malloc");
+
+ va_start(args,myFlags);
+ tot_length=0;
+ while ((ptr=va_arg(args, char **)))
+ {
+ length=va_arg(args,ulonglong);
+ tot_length+=ALIGN_SIZE(length);
+ }
+ va_end(args);
+
+ if (!(start=(char *) my_malloc(tot_length, myFlags)))
+ DBUG_RETURN(0); /* purecov: inspected */
+
+ va_start(args,myFlags);
+ res=start;
+ while ((ptr=va_arg(args, char **)))
+ {
+ *ptr=res;
+ length=va_arg(args,ulonglong);
+ res+=ALIGN_SIZE(length);
+ }
+ va_end(args);
+ DBUG_RETURN((void*) start);
+}