Skip to content

Commit 0290b40

Browse files
author
acurtis/antony@xiphis.org/ltantony.xiphis.org
committed
Bug#15669
"Test case 'csv' produces incorrect result on OpenBSD" mmapped pages were not being invalidated when writes occurred to the file vi a fd i/o operation. Force explicit invalidation and not rely on implicit invalidation. --BZR-- revision-id: sp1r-acurtis/antony@xiphis.org/ltantony.xiphis.org-20060801163634-53470 property-file-info: ld7:file_id63:sp1f-ha_tina.cc-20040813035429-5pwcme2ehkkuei6gu6ueo4tfldeeyw7l7:message161:Bug#15669 property-file-info: Make sure to invalidate in memory pages when the file has been property-file-info: altered by fd i/o. property-file-info: This is important to some operating systems, such as OpenBSD. property-file-info: 4:path23:sql/examples/ha_tina.ccee property-sp1-file-info: ld9:commit_id90:acurtis/antony@xiphis.org/ltantony.xiphis.org|sql/examples/ha_tina.cc|20060801163630|092367:file_id82:brian@avenger.(none)|sql/examples/ha_tina.cc|20040813035429|30807|9f4ce8b4438c518eee testament3-sha1: 2a2d1e46b02adbd701d90e35f77ad1be36a069f9
1 parent fb235d8 commit 0290b40

File tree

1 file changed

+56
-8
lines changed

1 file changed

+56
-8
lines changed

sql/examples/ha_tina.cc

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,34 @@ static byte* tina_get_key(TINA_SHARE *share,uint *length,
101101
return (byte*) share->table_name;
102102
}
103103

104+
105+
int free_mmap(TINA_SHARE *share)
106+
{
107+
DBUG_ENTER("ha_tina::free_mmap");
108+
if (share->mapped_file)
109+
{
110+
/*
111+
Invalidate the mapped in pages. Some operating systems (eg OpenBSD)
112+
would reuse already cached pages even if the file has been altered
113+
using fd based I/O. This may be optimized by perhaps only invalidating
114+
the last page but optimization of deprecated code is not important.
115+
*/
116+
msync(share->mapped_file, 0, MS_INVALIDATE);
117+
if (munmap(share->mapped_file, share->file_stat.st_size))
118+
DBUG_RETURN(1);
119+
}
120+
share->mapped_file= NULL;
121+
DBUG_RETURN(0);
122+
}
123+
104124
/*
105125
Reloads the mmap file.
106126
*/
107127
int get_mmap(TINA_SHARE *share, int write)
108128
{
109129
DBUG_ENTER("ha_tina::get_mmap");
110-
if (share->mapped_file && munmap(share->mapped_file, share->file_stat.st_size))
130+
131+
if (free_mmap(share))
111132
DBUG_RETURN(1);
112133

113134
if (my_fstat(share->data_file, &share->file_stat, MYF(MY_WME)) == -1)
@@ -230,8 +251,7 @@ static int free_share(TINA_SHARE *share)
230251
int result_code= 0;
231252
if (!--share->use_count){
232253
/* Drop the mapped file */
233-
if (share->mapped_file)
234-
munmap(share->mapped_file, share->file_stat.st_size);
254+
free_mmap(share);
235255
result_code= my_close(share->data_file,MYF(0));
236256
hash_delete(&tina_open_tables, (byte*) share);
237257
thr_lock_delete(&share->lock);
@@ -493,6 +513,13 @@ int ha_tina::write_row(byte * buf)
493513

494514
size= encode_quote(buf);
495515

516+
/*
517+
we are going to alter the file so we must invalidate the in memory pages
518+
otherwise we risk a race between the in memory pages and the disk pages.
519+
*/
520+
if (free_mmap(share))
521+
DBUG_RETURN(-1);
522+
496523
if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP)))
497524
DBUG_RETURN(-1);
498525

@@ -534,8 +561,26 @@ int ha_tina::update_row(const byte * old_data, byte * new_data)
534561
if (chain_append())
535562
DBUG_RETURN(-1);
536563

564+
/*
565+
we are going to alter the file so we must invalidate the in memory pages
566+
otherwise we risk a race between the in memory pages and the disk pages.
567+
*/
568+
if (free_mmap(share))
569+
DBUG_RETURN(-1);
570+
537571
if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP)))
538572
DBUG_RETURN(-1);
573+
574+
/*
575+
Ok, this is means that we will be doing potentially bad things
576+
during a bulk update on some OS'es. Ideally, we should extend the length
577+
of the file, redo the mmap and then write all the updated rows. Upon
578+
finishing the bulk update, truncate the file length to the final length.
579+
Since this code is all being deprecated, not point now to optimize.
580+
*/
581+
if (get_mmap(share, 0) > 0)
582+
DBUG_RETURN(-1);
583+
539584
DBUG_RETURN(0);
540585
}
541586

@@ -812,15 +857,14 @@ int ha_tina::rnd_end()
812857
length= length - (size_t)(ptr->end - ptr->begin);
813858
}
814859

815-
/* Truncate the file to the new size */
816-
if (my_chsize(share->data_file, length, 0, MYF(MY_WME)))
860+
/* Invalidate all cached mmap pages */
861+
if (free_mmap(share))
817862
DBUG_RETURN(-1);
818863

819-
if (munmap(share->mapped_file, length))
864+
/* Truncate the file to the new size */
865+
if (my_chsize(share->data_file, length, 0, MYF(MY_WME)))
820866
DBUG_RETURN(-1);
821867

822-
/* We set it to null so that get_mmap() won't try to unmap it */
823-
share->mapped_file= NULL;
824868
if (get_mmap(share, 0) > 0)
825869
DBUG_RETURN(-1);
826870
}
@@ -838,6 +882,10 @@ int ha_tina::delete_all_rows()
838882
if (!records_is_known)
839883
return (my_errno=HA_ERR_WRONG_COMMAND);
840884

885+
/* Invalidate all cached mmap pages */
886+
if (free_mmap(share))
887+
DBUG_RETURN(-1);
888+
841889
int rc= my_chsize(share->data_file, 0, 0, MYF(MY_WME));
842890

843891
if (get_mmap(share, 0) > 0)

0 commit comments

Comments
 (0)