1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

misc IO_CACHE cleanups

* remove unused (and not implemented) WRITE_NET type
* remove cast in my_b_write() macro. my_b_* macros are
  function-like, casts are responsibility of the caller
* replace hackish _my_b_write(info,0,0) with the explicit
  my_b_flush_io_cache() in my_b_write_byte()
* remove unused my_b_fill_cache()
* replace pbool -> my_bool
* make internal IO_CACHE functions static
* reformat comments, correct typos, remove obsolete comments (ISAM)
* assert valid cache type in init_functions()
* use IO_ROUND_DN() macro where appropriate
* remove unused DBUG_EXECUTE_IF in _my_b_cache_write()
* remove unnecessary __attribute__((unused))
* fix goto error in parse_file.cc
* remove redundant reinit_io_cache() in uniques.cc
* don't do reinit_io_cache() if the cache was not initialized
  in ma_check.c
* extract duplicate functionality from various _my_b_*_read
  functions into a common wrapper. Same for _my_b_*_write
* create _my_b_cache_write_r instead of having if's in
  _my_b_cache_write (similar to existing _my_b_cache_read and
  _my_b_cache_read_r)
* don't call mysql_file_write() from my_b_flush_io_cache(),
  call info->write_function() instead
This commit is contained in:
Sergei Golubchik
2015-05-18 11:54:55 +02:00
parent 1841557e40
commit 196e852983
11 changed files with 237 additions and 229 deletions

View File

@ -285,7 +285,7 @@ enum cache_type
{ {
TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE, TYPE_NOT_SET= 0, READ_CACHE, WRITE_CACHE,
SEQ_READ_APPEND /* sequential read or append */, SEQ_READ_APPEND /* sequential read or append */,
READ_FIFO, READ_NET,WRITE_NET}; READ_FIFO, READ_NET};
enum flush_type enum flush_type
{ {
@ -517,14 +517,12 @@ extern my_error_reporter my_charset_error_reporter;
#define my_b_read(info,Buffer,Count) \ #define my_b_read(info,Buffer,Count) \
((info)->read_pos + (Count) <= (info)->read_end ?\ ((info)->read_pos + (Count) <= (info)->read_end ?\
(memcpy(Buffer,(info)->read_pos,(size_t) (Count)), \ (memcpy(Buffer,(info)->read_pos,(size_t) (Count)), \
((info)->read_pos+=(Count)),0) :\ ((info)->read_pos+=(Count)), 0) : _my_b_read((info), (Buffer), (Count)))
(*(info)->read_function)((info),Buffer,Count))
#define my_b_write(info,Buffer,Count) \ #define my_b_write(info,Buffer,Count) \
((info)->write_pos + (Count) <=(info)->write_end ?\ ((info)->write_pos + (Count) <=(info)->write_end ?\
(memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\ (memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\
((info)->write_pos+=(Count)),0) : \ ((info)->write_pos+=(Count)), 0) : _my_b_write((info), (Buffer), (Count)))
(*(info)->write_function)((info),(uchar *)(Buffer),(Count)))
#define my_b_get(info) \ #define my_b_get(info) \
((info)->read_pos != (info)->read_end ?\ ((info)->read_pos != (info)->read_end ?\
@ -535,10 +533,7 @@ extern my_error_reporter my_charset_error_reporter;
#define my_b_write_byte(info,chr) \ #define my_b_write_byte(info,chr) \
(((info)->write_pos < (info)->write_end) ?\ (((info)->write_pos < (info)->write_end) ?\
((*(info)->write_pos++)=(chr)) :\ ((*(info)->write_pos++)=(chr)) :\
(_my_b_write(info,0,0) , ((*(info)->write_pos++)=(chr)))) ((my_b_flush_io_cache(info, 1)), ((*(info)->write_pos++)=(chr))))
#define my_b_fill_cache(info) \
(((info)->read_end=(info)->read_pos),(*(info)->read_function)(info,0,0))
#define my_b_tell(info) ((info)->pos_in_file + \ #define my_b_tell(info) ((info)->pos_in_file + \
(size_t) (*(info)->current_pos - (info)->request_pos)) (size_t) (*(info)->current_pos - (info)->request_pos))
@ -741,18 +736,15 @@ void my_store_ptr(uchar *buff, size_t pack_length, my_off_t pos);
my_off_t my_get_ptr(uchar *ptr, size_t pack_length); my_off_t my_get_ptr(uchar *ptr, size_t pack_length);
extern int init_io_cache(IO_CACHE *info,File file,size_t cachesize, extern int init_io_cache(IO_CACHE *info,File file,size_t cachesize,
enum cache_type type,my_off_t seek_offset, enum cache_type type,my_off_t seek_offset,
pbool use_async_io, myf cache_myflags); my_bool use_async_io, myf cache_myflags);
extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type, extern my_bool reinit_io_cache(IO_CACHE *info,enum cache_type type,
my_off_t seek_offset,pbool use_async_io, my_off_t seek_offset, my_bool use_async_io,
pbool clear_cache); my_bool clear_cache);
extern void setup_io_cache(IO_CACHE* info); extern void setup_io_cache(IO_CACHE* info);
extern int _my_b_read(IO_CACHE *info,uchar *Buffer,size_t Count); extern int _my_b_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_read_r(IO_CACHE *info,uchar *Buffer,size_t Count);
extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare, extern void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
IO_CACHE *write_cache, uint num_threads); IO_CACHE *write_cache, uint num_threads);
extern void remove_io_thread(IO_CACHE *info); extern void remove_io_thread(IO_CACHE *info);
extern int _my_b_seq_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_net_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_get(IO_CACHE *info); extern int _my_b_get(IO_CACHE *info);
extern int _my_b_async_read(IO_CACHE *info,uchar *Buffer,size_t Count); extern int _my_b_async_read(IO_CACHE *info,uchar *Buffer,size_t Count);
extern int _my_b_write(IO_CACHE *info,const uchar *Buffer,size_t Count); extern int _my_b_write(IO_CACHE *info,const uchar *Buffer,size_t Count);

View File

@ -20,11 +20,12 @@
#include "my_static.h" #include "my_static.h"
#include "mysys_err.h" #include "mysys_err.h"
/* /**
Remove an open tempfile so that it doesn't survive Remove an open tempfile so that it doesn't survive if we crash
if we crash; If the operating system doesn't support
this, just remember the file name for later removal If the operating system doesn't support this, just remember
*/ the file name for later removal
*/
static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)), static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
const char *name) const char *name)
@ -49,14 +50,14 @@ static my_bool cache_remove_open_tmp(IO_CACHE *cache __attribute__((unused)),
return 0; return 0;
} }
/* /**
** Open tempfile cached by IO_CACHE Open tempfile cached by IO_CACHE
** Should be used when no seeks are done (only reinit_io_buff)
** Return 0 if cache is inited ok
** The actual file is created when the IO_CACHE buffer gets filled
** If dir is not given, use TMPDIR.
*/
Should be used when no seeks are done (only reinit_io_buff)
Return 0 if cache is inited ok
The actual file is created when the IO_CACHE buffer gets filled
If dir is not given, use TMPDIR.
*/
my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix, my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
size_t cache_size, myf cache_myflags) size_t cache_size, myf cache_myflags)
{ {
@ -71,7 +72,7 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
cache->prefix[0]= 0; cache->prefix[0]= 0;
cache->file_name=0; cache->file_name=0;
cache->buffer=0; /* Mark that not open */ cache->buffer=0; /* Mark that not open */
if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0, if (!init_io_cache(cache, -1, cache_size, WRITE_CACHE, 0L, 0,
MYF(cache_myflags | MY_NABP))) MYF(cache_myflags | MY_NABP)))
{ {
DBUG_RETURN(0); DBUG_RETURN(0);
@ -79,8 +80,9 @@ my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* Create the temporary file */ /**
Create the temporary file
*/
my_bool real_open_cached_file(IO_CACHE *cache) my_bool real_open_cached_file(IO_CACHE *cache)
{ {
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];

View File

@ -23,7 +23,6 @@
Possibly use of asyncronic io. Possibly use of asyncronic io.
macros for read and writes for faster io. macros for read and writes for faster io.
Used instead of FILE when reading or writing whole files. Used instead of FILE when reading or writing whole files.
This code makes mf_rec_cache obsolete (currently only used by ISAM)
One can change info->pos_in_file to a higher value to skip bytes in file if One can change info->pos_in_file to a higher value to skip bytes in file if
also info->read_pos is set to info->read_end. also info->read_pos is set to info->read_end.
If called through open_cached_file(), then the temporary file will If called through open_cached_file(), then the temporary file will
@ -65,6 +64,12 @@ static void my_aiowait(my_aio_result *result);
#define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1)) #define IO_ROUND_UP(X) (((X)+IO_SIZE-1) & ~(IO_SIZE-1))
#define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1)) #define IO_ROUND_DN(X) ( (X) & ~(IO_SIZE-1))
static int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count);
static int _my_b_cache_read_r(IO_CACHE *info, uchar *Buffer, size_t Count);
static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count);
static int _my_b_cache_write(IO_CACHE *info, const uchar *Buffer, size_t Count);
static int _my_b_cache_write_r(IO_CACHE *info, const uchar *Buffer, size_t Count);
/* /*
Setup internal pointers inside IO_CACHE Setup internal pointers inside IO_CACHE
@ -98,6 +103,8 @@ static void
init_functions(IO_CACHE* info) init_functions(IO_CACHE* info)
{ {
enum cache_type type= info->type; enum cache_type type= info->type;
info->read_function = 0; /* Force a core if used */
info->write_function = 0; /* Force a core if used */
switch (type) { switch (type) {
case READ_NET: case READ_NET:
/* /*
@ -110,11 +117,15 @@ init_functions(IO_CACHE* info)
break; break;
case SEQ_READ_APPEND: case SEQ_READ_APPEND:
info->read_function = _my_b_seq_read; info->read_function = _my_b_seq_read;
info->write_function = 0; /* Force a core if used */
break; break;
default: case READ_CACHE:
info->read_function = info->share ? _my_b_read_r : _my_b_read; case WRITE_CACHE:
info->write_function = _my_b_write; case READ_FIFO:
info->read_function = info->share ? _my_b_cache_read_r : _my_b_cache_read;
info->write_function = info->share ? _my_b_cache_write_r : _my_b_cache_write;
break;
case TYPE_NOT_SET:
DBUG_ASSERT(0);
} }
setup_io_cache(info); setup_io_cache(info);
@ -135,7 +146,7 @@ init_functions(IO_CACHE* info)
type Type of cache type Type of cache
seek_offset Where cache should start reading/writing seek_offset Where cache should start reading/writing
use_async_io Set to 1 of we should use async_io (if avaiable) use_async_io Set to 1 of we should use async_io (if avaiable)
cache_myflags Bitmap of differnt flags cache_myflags Bitmap of different flags
MY_WME | MY_FAE | MY_NABP | MY_FNABP | MY_WME | MY_FAE | MY_NABP | MY_FNABP |
MY_DONT_CHECK_FILESIZE MY_DONT_CHECK_FILESIZE
@ -146,7 +157,7 @@ init_functions(IO_CACHE* info)
int init_io_cache(IO_CACHE *info, File file, size_t cachesize, int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
enum cache_type type, my_off_t seek_offset, enum cache_type type, my_off_t seek_offset,
pbool use_async_io, myf cache_myflags) my_bool use_async_io, myf cache_myflags)
{ {
size_t min_cache; size_t min_cache;
my_off_t pos; my_off_t pos;
@ -206,7 +217,7 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
} }
} }
cache_myflags &= ~MY_DONT_CHECK_FILESIZE; cache_myflags &= ~MY_DONT_CHECK_FILESIZE;
if (type != READ_NET && type != WRITE_NET) if (type != READ_NET)
{ {
/* Retry allocating memory in smaller blocks until we get one */ /* Retry allocating memory in smaller blocks until we get one */
cachesize= ((cachesize + min_cache-1) & ~(min_cache-1)); cachesize= ((cachesize + min_cache-1) & ~(min_cache-1));
@ -229,10 +240,11 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
if ((info->buffer= (uchar*) my_malloc(buffer_block, flags)) != 0) if ((info->buffer= (uchar*) my_malloc(buffer_block, flags)) != 0)
{ {
info->write_buffer=info->buffer;
if (type == SEQ_READ_APPEND) if (type == SEQ_READ_APPEND)
info->write_buffer = info->buffer + cachesize; info->write_buffer= info->buffer + cachesize;
info->alloced_buffer=1; else
info->write_buffer= info->buffer;
info->alloced_buffer= 1;
break; /* Enough memory found */ break; /* Enough memory found */
} }
if (cachesize == min_cache) if (cachesize == min_cache)
@ -321,18 +333,16 @@ static void my_aiowait(my_aio_result *result)
my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
my_off_t seek_offset, my_off_t seek_offset,
pbool use_async_io __attribute__((unused)), my_bool use_async_io __attribute__((unused)),
pbool clear_cache) my_bool clear_cache)
{ {
DBUG_ENTER("reinit_io_cache"); DBUG_ENTER("reinit_io_cache");
DBUG_PRINT("enter",("cache: 0x%lx type: %d seek_offset: %lu clear_cache: %d", DBUG_PRINT("enter",("cache: 0x%lx type: %d seek_offset: %lu clear_cache: %d",
(ulong) info, type, (ulong) seek_offset, (ulong) info, type, (ulong) seek_offset,
(int) clear_cache)); (int) clear_cache));
/* One can't do reinit with the following types */ DBUG_ASSERT(type == READ_CACHE || type == WRITE_CACHE);
DBUG_ASSERT(type != READ_NET && info->type != READ_NET && DBUG_ASSERT(info->type == READ_CACHE || info->type == WRITE_CACHE);
type != WRITE_NET && info->type != WRITE_NET &&
type != SEQ_READ_APPEND && info->type != SEQ_READ_APPEND);
/* If the whole file is in memory, avoid flushing to disk */ /* If the whole file is in memory, avoid flushing to disk */
if (! clear_cache && if (! clear_cache &&
@ -413,12 +423,72 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
} /* reinit_io_cache */ } /* reinit_io_cache */
int _my_b_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{
size_t left_length;
int res;
/* If the buffer is not empty yet, copy what is available. */
if ((left_length= (size_t) (info->read_end - info->read_pos)))
{
DBUG_ASSERT(Count > left_length);
memcpy(Buffer, info->read_pos, left_length);
Buffer+=left_length;
Count-=left_length;
}
res= info->read_function(info, Buffer, Count);
if (res && info->error >= 0)
info->error+= left_length; /* update number or read bytes */
return res;
}
int _my_b_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
{
size_t rest_length;
int res;
/* Always use my_b_flush_io_cache() to flush write_buffer! */
DBUG_ASSERT(Buffer != info->write_buffer);
if (info->pos_in_file + info->buffer_length > info->end_of_file)
{
my_errno=errno=EFBIG;
return info->error = -1;
}
rest_length= (size_t) (info->write_end - info->write_pos);
DBUG_ASSERT(Count >= rest_length);
memcpy(info->write_pos, Buffer, (size_t) rest_length);
Buffer+=rest_length;
Count-=rest_length;
info->write_pos+=rest_length;
if (my_b_flush_io_cache(info, 1))
return 1;
if (Count)
{
my_off_t old_pos_in_file= info->pos_in_file;
res= info->write_function(info, Buffer, Count);
Count-= info->pos_in_file - old_pos_in_file;
Buffer+= info->pos_in_file - old_pos_in_file;
}
else
res= 0;
if (!res && Count)
{
memcpy(info->write_pos, Buffer, Count);
info->write_pos+= Count;
}
return res;
}
/* /*
Read buffered. Read buffered.
SYNOPSIS SYNOPSIS
_my_b_read() _my_b_cache_read()
info IO_CACHE pointer info IO_CACHE pointer
Buffer Buffer to retrieve count bytes from file Buffer Buffer to retrieve count bytes from file
Count Number of bytes to read into Buffer Count Number of bytes to read into Buffer
@ -434,7 +504,7 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
types than my_off_t unless you can be sure that their value fits. types than my_off_t unless you can be sure that their value fits.
Same applies to differences of file offsets. Same applies to differences of file offsets.
When changing this function, check _my_b_read_r(). It might need the When changing this function, check _my_b_cache_read_r(). It might need the
same change. same change.
RETURN RETURN
@ -444,20 +514,11 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
Otherwise info->error contains the number of bytes in Buffer. Otherwise info->error contains the number of bytes in Buffer.
*/ */
int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) static int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{ {
size_t length,diff_length,left_length, max_length; size_t length, diff_length, left_length= 0, max_length;
my_off_t pos_in_file; my_off_t pos_in_file;
DBUG_ENTER("_my_b_read"); DBUG_ENTER("_my_b_cache_read");
/* If the buffer is not empty yet, copy what is available. */
if ((left_length= (size_t) (info->read_end-info->read_pos)))
{
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
memcpy(Buffer,info->read_pos, left_length);
Buffer+=left_length;
Count-=left_length;
}
/* pos_in_file always point on where info->buffer was read */ /* pos_in_file always point on where info->buffer was read */
pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer); pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
@ -513,7 +574,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
what we did already read from a block. That way, the read will what we did already read from a block. That way, the read will
end aligned with a block. end aligned with a block.
*/ */
length=(Count & (size_t) ~(IO_SIZE-1))-diff_length; length= IO_ROUND_DN(Count) - diff_length;
if ((read_length= mysql_file_read(info->file,Buffer, length, info->myflags)) if ((read_length= mysql_file_read(info->file,Buffer, length, info->myflags))
!= length) != length)
{ {
@ -681,12 +742,15 @@ void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare,
cshare->source_cache= write_cache; /* Can be NULL. */ cshare->source_cache= write_cache; /* Can be NULL. */
read_cache->share= cshare; read_cache->share= cshare;
read_cache->read_function= _my_b_read_r; read_cache->read_function= _my_b_cache_read_r;
read_cache->current_pos= NULL; read_cache->current_pos= NULL;
read_cache->current_end= NULL; read_cache->current_end= NULL;
if (write_cache) if (write_cache)
{
write_cache->share= cshare; write_cache->share= cshare;
write_cache->write_function= _my_b_cache_write_r;
}
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -954,7 +1018,7 @@ static void unlock_io_cache(IO_CACHE *cache)
Read from IO_CACHE when it is shared between several threads. Read from IO_CACHE when it is shared between several threads.
SYNOPSIS SYNOPSIS
_my_b_read_r() _my_b_cache_read_r()
cache IO_CACHE pointer cache IO_CACHE pointer
Buffer Buffer to retrieve count bytes from file Buffer Buffer to retrieve count bytes from file
Count Number of bytes to read into Buffer Count Number of bytes to read into Buffer
@ -979,7 +1043,7 @@ static void unlock_io_cache(IO_CACHE *cache)
types than my_off_t unless you can be sure that their value fits. types than my_off_t unless you can be sure that their value fits.
Same applies to differences of file offsets. (Bug #11527) Same applies to differences of file offsets. (Bug #11527)
When changing this function, check _my_b_read(). It might need the When changing this function, check _my_b_cache_read(). It might need the
same change. same change.
RETURN RETURN
@ -987,20 +1051,13 @@ static void unlock_io_cache(IO_CACHE *cache)
1 Error: can't read requested characters 1 Error: can't read requested characters
*/ */
int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count) static int _my_b_cache_read_r(IO_CACHE *cache, uchar *Buffer, size_t Count)
{ {
my_off_t pos_in_file; my_off_t pos_in_file;
size_t length, diff_length, left_length; size_t length, diff_length, left_length= 0;
IO_CACHE_SHARE *cshare= cache->share; IO_CACHE_SHARE *cshare= cache->share;
DBUG_ENTER("_my_b_read_r"); DBUG_ENTER("_my_b_cache_read_r");
if ((left_length= (size_t) (cache->read_end - cache->read_pos)))
{
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
memcpy(Buffer, cache->read_pos, left_length);
Buffer+= left_length;
Count-= left_length;
}
while (Count) while (Count)
{ {
size_t cnt, len; size_t cnt, len;
@ -1115,21 +1172,22 @@ int _my_b_read_r(register IO_CACHE *cache, uchar *Buffer, size_t Count)
*/ */
static void copy_to_read_buffer(IO_CACHE *write_cache, static void copy_to_read_buffer(IO_CACHE *write_cache,
const uchar *write_buffer, size_t write_length) const uchar *write_buffer, my_off_t pos_in_file)
{ {
size_t write_length= write_cache->pos_in_file - pos_in_file;
IO_CACHE_SHARE *cshare= write_cache->share; IO_CACHE_SHARE *cshare= write_cache->share;
DBUG_ASSERT(cshare->source_cache == write_cache); DBUG_ASSERT(cshare->source_cache == write_cache);
/* /*
write_length is usually less or equal to buffer_length. write_length is usually less or equal to buffer_length.
It can be bigger if _my_b_write() is called with a big length. It can be bigger if _my_b_cache_write_r() is called with a big length.
*/ */
while (write_length) while (write_length)
{ {
size_t copy_length= MY_MIN(write_length, write_cache->buffer_length); size_t copy_length= MY_MIN(write_length, write_cache->buffer_length);
int __attribute__((unused)) rc; int __attribute__((unused)) rc;
rc= lock_io_cache(write_cache, write_cache->pos_in_file); rc= lock_io_cache(write_cache, pos_in_file);
/* The writing thread does always have the lock when it awakes. */ /* The writing thread does always have the lock when it awakes. */
DBUG_ASSERT(rc); DBUG_ASSERT(rc);
@ -1137,7 +1195,7 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
cshare->error= 0; cshare->error= 0;
cshare->read_end= cshare->buffer + copy_length; cshare->read_end= cshare->buffer + copy_length;
cshare->pos_in_file= write_cache->pos_in_file; cshare->pos_in_file= pos_in_file;
/* Mark all threads as running and wake them. */ /* Mark all threads as running and wake them. */
unlock_io_cache(write_cache); unlock_io_cache(write_cache);
@ -1161,20 +1219,12 @@ static void copy_to_read_buffer(IO_CACHE *write_cache,
1 Failed to read 1 Failed to read
*/ */
int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count) static int _my_b_seq_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{ {
size_t length, diff_length, left_length, save_count, max_length; size_t length, diff_length, left_length= 0, save_count, max_length;
my_off_t pos_in_file; my_off_t pos_in_file;
save_count=Count; save_count=Count;
/* first, read the regular buffer */
if ((left_length=(size_t) (info->read_end-info->read_pos)))
{
DBUG_ASSERT(Count > left_length); /* User is not using my_b_read() */
memcpy(Buffer,info->read_pos, left_length);
Buffer+=left_length;
Count-=left_length;
}
lock_append_buffer(info); lock_append_buffer(info);
/* pos_in_file always point on where info->buffer was read */ /* pos_in_file always point on where info->buffer was read */
@ -1202,7 +1252,7 @@ int _my_b_seq_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
/* Fill first intern buffer */ /* Fill first intern buffer */
size_t read_length; size_t read_length;
length=(Count & (size_t) ~(IO_SIZE-1))-diff_length; length= IO_ROUND_DN(Count) - diff_length;
if ((read_length= mysql_file_read(info->file,Buffer, length, if ((read_length= mysql_file_read(info->file,Buffer, length,
info->myflags)) == (size_t) -1) info->myflags)) == (size_t) -1)
{ {
@ -1319,18 +1369,14 @@ read_append_buffer:
1 An error has occurred; IO_CACHE to error state. 1 An error has occurred; IO_CACHE to error state.
*/ */
int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count) int _my_b_async_read(IO_CACHE *info, uchar *Buffer, size_t Count)
{ {
size_t length,read_length,diff_length,left_length,use_length,org_Count; size_t length, read_length, diff_length, left_length=0, use_length, org_Count;
size_t max_length; size_t max_length;
my_off_t next_pos_in_file; my_off_t next_pos_in_file;
uchar *read_buffer; uchar *read_buffer;
memcpy(Buffer,info->read_pos,
(left_length= (size_t) (info->read_end-info->read_pos)));
Buffer+=left_length;
org_Count=Count; org_Count=Count;
Count-=left_length;
if (info->inited) if (info->inited)
{ /* wait for read block */ { /* wait for read block */
@ -1484,7 +1530,7 @@ int _my_b_async_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
info->read_end-=info->read_length; info->read_end-=info->read_length;
} }
info->read_length=info->buffer_length; /* Use hole buffer */ info->read_length=info->buffer_length; /* Use hole buffer */
info->read_function=_my_b_read; /* Use normal IO_READ next */ info->read_function=_my_b_cache_read; /* Use normal IO_READ next */
} }
else else
info->inited=info->aio_result.pending=1; info->inited=info->aio_result.pending=1;
@ -1514,70 +1560,60 @@ int _my_b_get(IO_CACHE *info)
-1 On error; my_errno contains error code. -1 On error; my_errno contains error code.
*/ */
int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count) static int _my_b_cache_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
{ {
size_t rest_length,length; if (Buffer != info->write_buffer)
my_off_t pos_in_file= info->pos_in_file;
DBUG_EXECUTE_IF("simulate_huge_load_data_file",
{
pos_in_file=(my_off_t)(5000000000ULL);
});
if (pos_in_file+info->buffer_length > info->end_of_file)
{ {
my_errno=errno=EFBIG; Count= IO_ROUND_DN(Count);
return info->error = -1; if (!Count)
return 0;
} }
rest_length= (size_t) (info->write_end - info->write_pos); if (info->seek_not_done)
memcpy(info->write_pos,Buffer,(size_t) rest_length); {
Buffer+=rest_length;
Count-=rest_length;
info->write_pos+=rest_length;
if (my_b_flush_io_cache(info,1))
return 1;
if (Count >= IO_SIZE)
{ /* Fill first intern buffer */
length=Count & (size_t) ~(IO_SIZE-1);
if (info->seek_not_done)
{
/*
Whenever a function which operates on IO_CACHE flushes/writes
some part of the IO_CACHE to disk it will set the property
"seek_not_done" to indicate this to other functions operating
on the IO_CACHE.
*/
if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET, MYF(0)))
{
info->error= -1;
return (1);
}
info->seek_not_done=0;
}
if (mysql_file_write(info->file, Buffer, length, info->myflags | MY_NABP))
return info->error= -1;
/* /*
In case of a shared I/O cache with a writer we normally do direct Whenever a function which operates on IO_CACHE flushes/writes
write cache to read cache copy. Simulate this here by direct some part of the IO_CACHE to disk it will set the property
caller buffer to read cache copy. Do it after the write so that "seek_not_done" to indicate this to other functions operating
the cache readers actions on the flushed part can go in parallel on the IO_CACHE.
with the write of the extra stuff. copy_to_read_buffer()
synchronizes writer and readers so that after this call the
readers can act on the extra stuff while the writer can go ahead
and prepare the next output. copy_to_read_buffer() relies on
info->pos_in_file.
*/ */
if (info->share) if (mysql_file_seek(info->file, info->pos_in_file, MY_SEEK_SET,
copy_to_read_buffer(info, Buffer, length); MYF(info->myflags & MY_WME)) == MY_FILEPOS_ERROR)
{
Count-=length; info->error= -1;
Buffer+=length; return 1;
info->pos_in_file+=length; }
info->seek_not_done=0;
} }
memcpy(info->write_pos,Buffer,(size_t) Count); if (mysql_file_write(info->file, Buffer, Count, info->myflags | MY_NABP))
info->write_pos+=Count; return info->error= -1;
info->pos_in_file+= Count;
return 0;
}
/*
In case of a shared I/O cache with a writer we normally do direct
write cache to read cache copy. Simulate this here by direct
caller buffer to read cache copy. Do it after the write so that
the cache readers actions on the flushed part can go in parallel
with the write of the extra stuff. copy_to_read_buffer()
synchronizes writer and readers so that after this call the
readers can act on the extra stuff while the writer can go ahead
and prepare the next output. copy_to_read_buffer() relies on
info->pos_in_file.
*/
static int _my_b_cache_write_r(IO_CACHE *info, const uchar *Buffer, size_t Count)
{
my_off_t old_pos_in_file= info->pos_in_file;
int res= _my_b_cache_write(info, Buffer, Count);
if (res)
return res;
DBUG_ASSERT(info->share);
copy_to_read_buffer(info, Buffer, old_pos_in_file);
return 0; return 0;
} }
@ -1588,7 +1624,7 @@ int _my_b_write(register IO_CACHE *info, const uchar *Buffer, size_t Count)
the write buffer before we are ready with it. the write buffer before we are ready with it.
*/ */
int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count) int my_b_append(IO_CACHE *info, const uchar *Buffer, size_t Count)
{ {
size_t rest_length,length; size_t rest_length,length;
@ -1613,7 +1649,7 @@ int my_b_append(register IO_CACHE *info, const uchar *Buffer, size_t Count)
} }
if (Count >= IO_SIZE) if (Count >= IO_SIZE)
{ /* Fill first intern buffer */ { /* Fill first intern buffer */
length=Count & (size_t) ~(IO_SIZE-1); length= IO_ROUND_DN(Count);
if (mysql_file_write(info->file,Buffer, length, info->myflags | MY_NABP)) if (mysql_file_write(info->file,Buffer, length, info->myflags | MY_NABP))
{ {
unlock_append_buffer(info); unlock_append_buffer(info);
@ -1652,7 +1688,7 @@ int my_b_safe_write(IO_CACHE *info, const uchar *Buffer, size_t Count)
we will never get a seek over the end of the buffer we will never get a seek over the end of the buffer
*/ */
int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count, int my_block_write(IO_CACHE *info, const uchar *Buffer, size_t Count,
my_off_t pos) my_off_t pos)
{ {
size_t length; size_t length;
@ -1710,11 +1746,9 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
#define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \ #define UNLOCK_APPEND_BUFFER if (need_append_buffer_lock) \
unlock_append_buffer(info); unlock_append_buffer(info);
int my_b_flush_io_cache(IO_CACHE *info, int my_b_flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
int need_append_buffer_lock __attribute__((unused)))
{ {
size_t length; size_t length;
my_off_t pos_in_file;
my_bool append_cache= (info->type == SEQ_READ_APPEND); my_bool append_cache= (info->type == SEQ_READ_APPEND);
DBUG_ENTER("my_b_flush_io_cache"); DBUG_ENTER("my_b_flush_io_cache");
DBUG_PRINT("enter", ("cache: 0x%lx", (long) info)); DBUG_PRINT("enter", ("cache: 0x%lx", (long) info));
@ -1733,52 +1767,30 @@ int my_b_flush_io_cache(IO_CACHE *info,
if ((length=(size_t) (info->write_pos - info->write_buffer))) if ((length=(size_t) (info->write_pos - info->write_buffer)))
{ {
/* info->write_end= (info->write_buffer + info->buffer_length -
In case of a shared I/O cache with a writer we do direct write ((info->pos_in_file + length) & (IO_SIZE - 1)));
cache to read cache copy. Do it before the write here so that if (append_cache)
the readers can work in parallel with the write.
copy_to_read_buffer() relies on info->pos_in_file.
*/
if (info->share)
copy_to_read_buffer(info, info->write_buffer, length);
pos_in_file=info->pos_in_file;
/*
If we have append cache, we always open the file with
O_APPEND which moves the pos to EOF automatically on every write
*/
if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(info->myflags & MY_WME)) ==
MY_FILEPOS_ERROR)
{
UNLOCK_APPEND_BUFFER;
DBUG_RETURN((info->error= -1));
}
if (!append_cache)
info->seek_not_done=0;
}
if (!append_cache)
info->pos_in_file+=length;
info->write_end= (info->write_buffer+info->buffer_length-
((pos_in_file+length) & (IO_SIZE-1)));
if (mysql_file_write(info->file,info->write_buffer,length,
info->myflags | MY_NABP))
info->error= -1;
else
info->error= 0;
if (!append_cache)
{ {
set_if_bigger(info->end_of_file,(pos_in_file+length));
if (mysql_file_write(info->file, info->write_buffer, length,
info->myflags | MY_NABP))
info->error= -1;
else
info->error= 0;
info->end_of_file+= info->write_pos - info->append_read_pos;
info->append_read_pos= info->write_buffer;
DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0)));
} }
else else
{ {
info->end_of_file+=(info->write_pos-info->append_read_pos); int res= info->write_function(info, info->write_buffer, length);
DBUG_ASSERT(info->end_of_file == mysql_file_tell(info->file, MYF(0))); if (res)
} DBUG_RETURN(res);
info->append_read_pos=info->write_pos=info->write_buffer; set_if_bigger(info->end_of_file, info->pos_in_file);
}
info->write_pos= info->write_buffer;
++info->disk_writes; ++info->disk_writes;
UNLOCK_APPEND_BUFFER; UNLOCK_APPEND_BUFFER;
DBUG_RETURN(info->error); DBUG_RETURN(info->error);

View File

@ -51,7 +51,7 @@
#include "rpl_utility.h" #include "rpl_utility.h"
#include "sql_digest.h" #include "sql_digest.h"
#define my_b_write_string(A, B) my_b_write((A), (B), (uint) (sizeof(B) - 1)) #define my_b_write_string(A, B) my_b_write((A), (uchar*)(B), (uint) (sizeof(B) - 1))
using std::max; using std::max;
@ -353,13 +353,13 @@ static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
{ {
char c; char c;
switch ((c=*str++)) { switch ((c=*str++)) {
case '\n': my_b_write(cache, "\\n", 2); break; case '\n': my_b_write(cache, (uchar*)"\\n", 2); break;
case '\r': my_b_write(cache, "\\r", 2); break; case '\r': my_b_write(cache, (uchar*)"\\r", 2); break;
case '\\': my_b_write(cache, "\\\\", 2); break; case '\\': my_b_write(cache, (uchar*)"\\\\", 2); break;
case '\b': my_b_write(cache, "\\b", 2); break; case '\b': my_b_write(cache, (uchar*)"\\b", 2); break;
case '\t': my_b_write(cache, "\\t", 2); break; case '\t': my_b_write(cache, (uchar*)"\\t", 2); break;
case '\'': my_b_write(cache, "\\'", 2); break; case '\'': my_b_write(cache, (uchar*)"\\'", 2); break;
case 0 : my_b_write(cache, "\\0", 2); break; case 0 : my_b_write(cache, (uchar*)"\\0", 2); break;
default: default:
my_b_write_byte(cache, c); my_b_write_byte(cache, c);
break; break;
@ -755,7 +755,7 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed,
if (bits_changed & option) if (bits_changed & option)
{ {
if (*need_comma) if (*need_comma)
my_b_write(file, ", ", 2); my_b_write(file, (uchar*)", ", 2);
my_b_printf(file, "%s=%d", name, MY_TEST(flags & option)); my_b_printf(file, "%s=%d", name, MY_TEST(flags & option));
*need_comma= 1; *need_comma= 1;
} }
@ -1797,7 +1797,7 @@ static void hexdump_minimal_header_to_io_cache(IO_CACHE *file,
DBUG_ASSERT(static_cast<size_t>(emit_buf_written) < sizeof(emit_buf)); DBUG_ASSERT(static_cast<size_t>(emit_buf_written) < sizeof(emit_buf));
my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written); my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written);
my_b_write(file, "#\n", 2); my_b_write(file, (uchar*)"#\n", 2);
} }
@ -1913,7 +1913,7 @@ static void hexdump_data_to_io_cache(IO_CACHE *file,
my_b_write(file, reinterpret_cast<uchar*>(emit_buffer), my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
c - emit_buffer); c - emit_buffer);
} }
my_b_write(file, "#\n", 2); my_b_write(file, (uchar*)"#\n", 2);
} }
/* /*
@ -1970,7 +1970,7 @@ void Log_event::print_header(IO_CACHE* file,
Prefix the next line so that the output from print_helper() Prefix the next line so that the output from print_helper()
will appear as a comment. will appear as a comment.
*/ */
my_b_write(file, "# Event: ", 9); my_b_write(file, (uchar*)"# Event: ", 9);
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -1996,9 +1996,9 @@ my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
if (*s > 0x1F) if (*s > 0x1F)
my_b_write_byte(file, *s); my_b_write_byte(file, *s);
else if (*s == '\'') else if (*s == '\'')
my_b_write(file, "\\'", 2); my_b_write(file, (uchar*)"\\'", 2);
else if (*s == '\\') else if (*s == '\\')
my_b_write(file, "\\\\", 2); my_b_write(file, (uchar*)"\\\\", 2);
else else
{ {
uchar hex[10]; uchar hex[10];
@ -2021,7 +2021,7 @@ static void
my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits) my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
{ {
uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits; uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
my_b_write(file, "b'", 2); my_b_write(file, (uchar*)"b'", 2);
for (bitnum= skip_bits ; bitnum < nbits8; bitnum++) for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
{ {
int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01; int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
@ -2158,7 +2158,7 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
size_t length; size_t length;
longlong si= sint8korr(ptr); longlong si= sint8korr(ptr);
length= (longlong10_to_str(si, tmp, -10) - tmp); length= (longlong10_to_str(si, tmp, -10) - tmp);
my_b_write(file, tmp, length); my_b_write(file, (uchar*)tmp, length);
if (si < 0) if (si < 0)
{ {
ulonglong ui= uint8korr(ptr); ulonglong ui= uint8korr(ptr);
@ -2187,7 +2187,7 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
pos+= sprintf(pos, "%09d.", dec.buf[i]); pos+= sprintf(pos, "%09d.", dec.buf[i]);
pos+= sprintf(pos, "%09d", dec.buf[i]); pos+= sprintf(pos, "%09d", dec.buf[i]);
length= (uint) (pos - buff); length= (uint) (pos - buff);
my_b_write(file, buff, length); my_b_write(file, (uchar*)buff, length);
my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)", my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
precision, decimals); precision, decimals);
return bin_size; return bin_size;
@ -2239,7 +2239,7 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
struct timeval tm; struct timeval tm;
my_timestamp_from_binary(&tm, ptr, meta); my_timestamp_from_binary(&tm, ptr, meta);
int buflen= my_timeval_to_str(&tm, buf, meta); int buflen= my_timeval_to_str(&tm, buf, meta);
my_b_write(file, buf, buflen); my_b_write(file, (uchar*)buf, buflen);
my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta); my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
return my_timestamp_binary_length(meta); return my_timestamp_binary_length(meta);
} }
@ -2477,7 +2477,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
if (print_event_info->verbose > 1) if (print_event_info->verbose > 1)
{ {
my_b_write(file, " /* ", 4); my_b_write(file, (uchar*)" /* ", 4);
if (typestr[0]) if (typestr[0])
my_b_printf(file, "%s ", typestr); my_b_printf(file, "%s ", typestr);
@ -2487,7 +2487,7 @@ Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
my_b_printf(file, "meta=%d nullable=%d is_null=%d ", my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
td->field_metadata(i), td->field_metadata(i),
td->maybe_null(i), is_null); td->maybe_null(i), is_null);
my_b_write(file, "*/", 2); my_b_write(file, (uchar*)"*/", 2);
} }
my_b_write_byte(file, '\n'); my_b_write_byte(file, '\n');

View File

@ -294,7 +294,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
if (my_b_append(&file, (const uchar *)STRING_WITH_LEN("TYPE=")) || if (my_b_append(&file, (const uchar *)STRING_WITH_LEN("TYPE=")) ||
my_b_append(&file, (const uchar *)type->str, type->length) || my_b_append(&file, (const uchar *)type->str, type->length) ||
my_b_append(&file, (const uchar *)STRING_WITH_LEN("\n"))) my_b_append(&file, (const uchar *)STRING_WITH_LEN("\n")))
goto err_w_file; goto err_w_cache;
// write parameters to temporary file // write parameters to temporary file
for (param= parameters; param->name.str; param++) for (param= parameters; param->name.str; param++)

View File

@ -42,6 +42,8 @@
#include "sql_derived.h" #include "sql_derived.h"
#include "sql_show.h" #include "sql_show.h"
extern "C" int _my_b_net_read(IO_CACHE *info, uchar *Buffer, size_t Count);
class XML_TAG { class XML_TAG {
public: public:
int level; int level;

View File

@ -53,7 +53,7 @@ int unique_write_to_file(uchar* key, element_count count, Unique *unique)
int unique_write_to_file_with_count(uchar* key, element_count count, Unique *unique) int unique_write_to_file_with_count(uchar* key, element_count count, Unique *unique)
{ {
return my_b_write(&unique->file, key, unique->size) || return my_b_write(&unique->file, key, unique->size) ||
my_b_write(&unique->file, &count, sizeof(element_count)) ? 1 : 0; my_b_write(&unique->file, (uchar*)&count, sizeof(element_count)) ? 1 : 0;
} }
int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique) int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
@ -694,7 +694,6 @@ bool Unique::merge(TABLE *table, uchar *buff, bool without_last_merge)
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER, open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
MYF(MY_WME)))) MYF(MY_WME))))
return 1; return 1;
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
Sort_param sort_param; Sort_param sort_param;
bzero((char*) &sort_param,sizeof(sort_param)); bzero((char*) &sort_param,sizeof(sort_param));

View File

@ -458,7 +458,7 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf,
goto cleanup2; goto cleanup2;
} }
if (ev->write(&cache) || my_b_write(&cache, rbr_buf, buf_len) || if (ev->write(&cache) || my_b_write(&cache, (uchar*)rbr_buf, buf_len) ||
flush_io_cache(&cache)) flush_io_cache(&cache))
{ {
WSREP_ERROR("Failed to write to '%s'.", filename); WSREP_ERROR("Failed to write to '%s'.", filename);

View File

@ -81,7 +81,7 @@ my_bool _ma_read_cache(MARIA_HA *handler, IO_CACHE *info, uchar *buff,
} }
else else
info->read_pos=info->read_end; /* All block used */ info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length)) if (!_my_b_read(info,buff,length))
DBUG_RETURN(0); DBUG_RETURN(0);
read_length=info->error; read_length=info->error;
} }

View File

@ -4021,8 +4021,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
share->state.state.data_file_length=sort_param.max_pos; share->state.state.data_file_length=sort_param.max_pos;
param->read_cache.file= info->dfile.file; /* re-init read cache */ param->read_cache.file= info->dfile.file; /* re-init read cache */
reinit_io_cache(&param->read_cache,READ_CACHE,share->pack.header_length, if (share->data_file_type != BLOCK_RECORD)
1,1); reinit_io_cache(&param->read_cache, READ_CACHE,
share->pack.header_length, 1, 1);
} }
if (param->testflag & T_WRITE_LOOP) if (param->testflag & T_WRITE_LOOP)

View File

@ -82,7 +82,7 @@ int _mi_read_cache(IO_CACHE *info, uchar *buff, my_off_t pos, uint length,
} }
else else
info->read_pos=info->read_end; /* All block used */ info->read_pos=info->read_end; /* All block used */
if (!(*info->read_function)(info,buff,length)) if (!_my_b_read(info,buff,length))
DBUG_RETURN(0); DBUG_RETURN(0);
read_length=info->error; read_length=info->error;
} }