LTP GCOV extension - code coverage report
Current view: directory - storage/maria - ma_pagecrc.c
Test: mtr_and_unit.info
Date: 2009-03-05 Instrumented lines: 81
Code covered: 86.4 % Executed lines: 70

       1                 : /* Copyright (C) 2007-2008 MySQL AB
       2                 : 
       3                 :    This program is free software; you can redistribute it and/or modify
       4                 :    it under the terms of the GNU General Public License as published by
       5                 :    the Free Software Foundation; version 2 of the License.
       6                 : 
       7                 :    This program is distributed in the hope that it will be useful,
       8                 :    but WITHOUT ANY WARRANTY; without even the implied warranty of
       9                 :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      10                 :    GNU General Public License for more details.
      11                 : 
      12                 :    You should have received a copy of the GNU General Public License
      13                 :    along with this program; if not, write to the Free Software
      14                 :    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
      15                 : 
      16                 : #include "maria_def.h"
      17                 : 
      18                 : 
      19                 : /**
      20                 :   @brief calculate crc of the page avoiding special values
      21                 : 
      22                 :   @param start           The value to start CRC (we use page number here)
      23                 :   @param data            data pointer
      24                 :   @param length          length of the data
      25                 : 
      26                 :   @return crc of the page without special values
      27                 : */
      28                 : 
      29                 : static uint32 maria_page_crc(uint32 start, uchar *data, uint length)
      30          123301 : {
      31          123301 :   uint32 crc= crc32(start, data, length);
      32                 : 
      33                 :   /* we need this assert to get following comparison working */
      34                 :   compile_time_assert(MARIA_NO_CRC_BITMAP_PAGE ==
      35                 :                       MARIA_NO_CRC_NORMAL_PAGE - 1 &&
      36                 :                       MARIA_NO_CRC_NORMAL_PAGE == 0xffffffff);
      37          123301 :   if (crc >= MARIA_NO_CRC_BITMAP_PAGE)
      38               0 :     crc= MARIA_NO_CRC_BITMAP_PAGE - 1;
      39                 : 
      40          123301 :   return(crc);
      41                 : }
      42                 : 
      43                 : /**
      44                 :   @brief Maria pages read callback (checks the page CRC)
      45                 : 
      46                 :   @param page            The page data to check
      47                 :   @param page_no         The page number (<offset>/<page length>)
      48                 :   @param data_ptr        pointer to MARIA_SHARE
      49                 :   @param no_crc_val      Value which means CRC absence
      50                 :                          (MARIA_NO_CRC_NORMAL_PAGE or MARIA_NO_CRC_BITMAP_PAGE)
      51                 :   @param data_length     length of data to calculate CRC
      52                 : 
      53                 :   @retval 0 OK
      54                 :   @retval 1 Error
      55                 : */
      56                 : 
      57                 : static my_bool maria_page_crc_check(uchar *page,
      58                 :                                     pgcache_page_no_t page_no,
      59                 :                                     MARIA_SHARE *share,
      60                 :                                     uint32 no_crc_val,
      61                 :                                     int data_length)
      62          404166 : {
      63          404166 :   uint32 crc= uint4korr(page + share->block_size - CRC_SIZE), new_crc;
      64                 :   my_bool res;
      65          404166 :   DBUG_ENTER("maria_page_crc_check");
      66                 : 
      67          404166 :   DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
      68                 : 
      69                 :   /* we need this assert to get following comparison working */
      70                 :   compile_time_assert(MARIA_NO_CRC_BITMAP_PAGE ==
      71                 :                       MARIA_NO_CRC_NORMAL_PAGE - 1 &&
      72                 :                       MARIA_NO_CRC_NORMAL_PAGE == 0xffffffff);
      73                 :   /*
      74                 :     If crc is no_crc_val then
      75                 :     the page has no crc, so there is nothing to check.
      76                 :   */
      77          404166 :   if (crc >= MARIA_NO_CRC_BITMAP_PAGE)
      78                 :   {
      79          327969 :     DBUG_PRINT("info", ("No crc: %lu  crc: %lu  page: %lu  ",
      80                 :                         (ulong) no_crc_val, (ulong) crc, (ulong) page_no));
      81          327969 :     if (crc != no_crc_val)
      82                 :     {
      83               0 :       my_errno= HA_ERR_WRONG_CRC;
      84               0 :       DBUG_PRINT("error", ("Wrong no CRC value"));
      85               0 :       DBUG_RETURN(1);
      86                 :     }
      87          327969 :     DBUG_RETURN(0);
      88                 :   }
      89           76197 :   new_crc= maria_page_crc((uint32) page_no, page, data_length);
      90           76197 :   DBUG_ASSERT(new_crc != no_crc_val);
      91           76197 :   res= test(new_crc != crc);
      92           76197 :   if (res)
      93                 :   {
      94                 :     /*
      95                 :       Bitmap pages may be totally zero filled in some cases.
      96                 :       This happens when we get a crash after the pagecache has written
      97                 :       out a page that is on a newly created bitmap page and we get
      98                 :       a crash before the bitmap page is written out.
      99                 : 
     100                 :       We handle this case with the following logic:
     101                 :       When reading, approve of bitmap pages where all bytes are zero
     102                 :       (This is after all a bitmap pages where no data is reserved and
     103                 :       the CRC will be corrected at next write)
     104                 :     */
     105             128 :     if (no_crc_val == MARIA_NO_CRC_BITMAP_PAGE &&
     106                 :         crc == 0 && _ma_check_if_zero(page, data_length))
     107                 :     {
     108               0 :       DBUG_PRINT("warning", ("Found bitmap page that was not initialized"));
     109               0 :       DBUG_RETURN(0);
     110                 :     }
     111                 : 
     112             128 :     DBUG_PRINT("error", ("Page: %lu  crc: %lu  calculated crc: %lu",
     113                 :                          (ulong) page_no, (ulong) crc, (ulong) new_crc));
     114             128 :     my_errno= HA_ERR_WRONG_CRC;
     115                 :   }
     116           76197 :   DBUG_RETURN(res);
     117                 : }
     118                 : 
     119                 : 
     120                 : /**
     121                 :   @brief Maria pages write callback (sets the page CRC for data and index
     122                 :   files)
     123                 : 
     124                 :   @param page            The page data to set
     125                 :   @param page_no         The page number (<offset>/<page length>)
     126                 :   @param data_ptr        Write callback data pointer (pointer to MARIA_SHARE)
     127                 : 
     128                 :   @retval 0 OK
     129                 : */
     130                 : 
     131                 : my_bool maria_page_crc_set_normal(uchar *page,
     132                 :                                   pgcache_page_no_t page_no,
     133                 :                                   uchar *data_ptr)
     134           34372 : {
     135           34372 :   MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
     136           34372 :   int data_length= share->block_size - CRC_SIZE;
     137           34372 :   uint32 crc= maria_page_crc((uint32) page_no, page, data_length);
     138           34372 :   DBUG_ENTER("maria_page_crc_set_normal");
     139           34372 :   DBUG_PRINT("info", ("Page %lu  crc: %lu", (ulong) page_no, (ulong)crc));
     140                 : 
     141                 :   /* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
     142           34372 :   int4store_aligned(page + data_length, crc);
     143           34372 :   DBUG_RETURN(0);
     144                 : }
     145                 : 
     146                 : 
     147                 : /**
     148                 :   @brief Maria pages write callback (sets the page CRC for keys)
     149                 : 
     150                 :   @param page            The page data to set
     151                 :   @param page_no         The page number (<offset>/<page length>)
     152                 :   @param data_ptr        Write callback data pointer (pointer to MARIA_SHARE)
     153                 : 
     154                 :   @retval 0 OK
     155                 : */
     156                 : 
     157                 : my_bool maria_page_crc_set_index(uchar *page,
     158                 :                                  pgcache_page_no_t page_no,
     159                 :                                  uchar *data_ptr)
     160           12732 : {
     161           12732 :   MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
     162           12732 :   int data_length= _ma_get_page_used(share, page);
     163           12732 :   uint32 crc= maria_page_crc((uint32) page_no, page, data_length);
     164           12732 :   DBUG_ENTER("maria_page_crc_set_index");
     165           12732 :   DBUG_PRINT("info", ("Page %lu  crc: %lu",
     166                 :                       (ulong) page_no, (ulong) crc));
     167           12732 :   DBUG_ASSERT((uint)data_length <= share->block_size - CRC_SIZE);
     168                 :   /* crc is on the stack so it is aligned, pagecache buffer is aligned, too */
     169           12732 :   int4store_aligned(page + share->block_size - CRC_SIZE, crc);
     170           12732 :   DBUG_RETURN(0);
     171                 : }
     172                 : 
     173                 : 
     174                 : /* interface functions */
     175                 : 
     176                 : 
     177                 : /**
     178                 :   @brief Maria pages read callback (checks the page CRC) for index/data pages
     179                 : 
     180                 :   @param page            The page data to check
     181                 :   @param page_no         The page number (<offset>/<page length>)
     182                 :   @param data_ptr        Read callback data pointer (pointer to MARIA_SHARE)
     183                 : 
     184                 :   @retval 0 OK
     185                 :   @retval 1 Error
     186                 : */
     187                 : 
     188                 : my_bool maria_page_crc_check_data(uchar *page,
     189                 :                                   pgcache_page_no_t page_no,
     190                 :                                   uchar *data_ptr)
     191          120960 : {
     192          120960 :   MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
     193          120960 :   return (maria_page_crc_check(page, (uint32) page_no, share,
     194                 :                                MARIA_NO_CRC_NORMAL_PAGE,
     195                 :                                share->block_size - CRC_SIZE));
     196                 : }
     197                 : 
     198                 : 
     199                 : /**
     200                 :   @brief Maria pages read callback (checks the page CRC) for bitmap pages
     201                 : 
     202                 :   @param page            The page data to check
     203                 :   @param page_no         The page number (<offset>/<page length>)
     204                 :   @param data_ptr        Read callback data pointer (pointer to MARIA_SHARE)
     205                 : 
     206                 :   @retval 0 OK
     207                 :   @retval 1 Error
     208                 : */
     209                 : 
     210                 : my_bool maria_page_crc_check_bitmap(uchar *page,
     211                 :                                     pgcache_page_no_t page_no,
     212                 :                                     uchar *data_ptr)
     213            1729 : {
     214            1729 :   MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
     215            1729 :   return (maria_page_crc_check(page, (uint32) page_no, share,
     216                 :                                MARIA_NO_CRC_BITMAP_PAGE,
     217                 :                                share->block_size - CRC_SIZE));
     218                 : }
     219                 : 
     220                 : 
     221                 : /**
     222                 :   @brief Maria pages read callback (checks the page CRC) for index pages
     223                 : 
     224                 :   @param page            The page data to check
     225                 :   @param page_no         The page number (<offset>/<page length>)
     226                 :   @param data_ptr        Read callback data pointer (pointer to MARIA_SHARE)
     227                 : 
     228                 :   @retval 0 OK
     229                 :   @retval 1 Error
     230                 : */
     231                 : 
     232                 : my_bool maria_page_crc_check_index(uchar *page,
     233                 :                                    pgcache_page_no_t page_no,
     234                 :                                    uchar *data_ptr)
     235          281477 : {
     236          281477 :   MARIA_SHARE *share= (MARIA_SHARE *)data_ptr;
     237          281477 :   uint length= _ma_get_page_used(share, page);
     238          281477 :   if (length > share->block_size - CRC_SIZE)
     239                 :   {
     240               0 :     DBUG_PRINT("error", ("Wrong page length: %u", length));
     241               0 :     return (my_errno= HA_ERR_WRONG_CRC);
     242                 :   }
     243          281477 :   return maria_page_crc_check(page, (uint32) page_no, share,
     244                 :                                MARIA_NO_CRC_NORMAL_PAGE,
     245                 :                               length);
     246                 : }
     247                 : 
     248                 : 
     249                 : /**
     250                 :   @brief Maria pages dumme read callback for temporary tables
     251                 : 
     252                 :   @retval 0 OK
     253                 :   @retval 1 Error
     254                 : */
     255                 : 
     256                 : my_bool maria_page_crc_check_none(uchar *page __attribute__((unused)),
     257                 :                                   pgcache_page_no_t page_no
     258                 :                                   __attribute__((unused)),
     259                 :                                   uchar *data_ptr __attribute__((unused)))
     260          427228 : {
     261          427228 :   return 0;
     262                 : }
     263                 : 
     264                 : 
     265                 : /**
     266                 :   @brief Maria pages write callback (sets the page filler for index/data)
     267                 : 
     268                 :   @param page            The page data to set
     269                 :   @param page_no         The page number (<offset>/<page length>)
     270                 :   @param data_ptr        Write callback data pointer (pointer to MARIA_SHARE)
     271                 : 
     272                 :   @retval 0 OK
     273                 : */
     274                 : 
     275                 : my_bool maria_page_filler_set_normal(uchar *page,
     276                 :                                      pgcache_page_no_t page_no
     277                 :                                      __attribute__((unused)),
     278                 :                                      uchar *data_ptr)
     279          264821 : {
     280          264821 :   DBUG_ENTER("maria_page_filler_set_normal");
     281          264821 :   DBUG_ASSERT(page_no != 0);                    /* Catches some simple bugs */
     282          264821 :   int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
     283                 :                     MARIA_NO_CRC_NORMAL_PAGE);
     284          264821 :   DBUG_RETURN(0);
     285                 : }
     286                 : 
     287                 : 
     288                 : /**
     289                 :   @brief Maria pages write callback (sets the page filler for bitmap)
     290                 : 
     291                 :   @param page            The page data to set
     292                 :   @param page_no         The page number (<offset>/<page length>)
     293                 :   @param data_ptr        Write callback data pointer (pointer to MARIA_SHARE)
     294                 : 
     295                 :   @retval 0 OK
     296                 : */
     297                 : 
     298                 : my_bool maria_page_filler_set_bitmap(uchar *page,
     299                 :                                      pgcache_page_no_t page_no
     300                 :                                      __attribute__((unused)),
     301                 :                                      uchar *data_ptr)
     302             163 : {
     303             163 :   DBUG_ENTER("maria_page_filler_set_bitmap");
     304             163 :   int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
     305                 :                     MARIA_NO_CRC_BITMAP_PAGE);
     306             163 :   DBUG_RETURN(0);
     307                 : }
     308                 : 
     309                 : 
     310                 : /**
     311                 :   @brief Maria pages dummy write callback for temporary tables
     312                 : 
     313                 :   @retval 0 OK
     314                 : */
     315                 : 
     316                 : my_bool maria_page_filler_set_none(uchar *page __attribute__((unused)),
     317                 :                                    pgcache_page_no_t page_no
     318                 :                                    __attribute__((unused)),
     319                 :                                    uchar *data_ptr __attribute__((unused)))
     320          489399 : {
     321                 : #ifdef HAVE_purify
     322                 :   int4store_aligned(page + ((MARIA_SHARE *)data_ptr)->block_size - CRC_SIZE,
     323                 :                     0);
     324                 : #endif
     325          489399 :   return 0;
     326                 : }
     327                 : 
     328                 : 
     329                 : /**
     330                 :   @brief Write failure callback (mark table as corrupted)
     331                 : 
     332                 :   @param data_ptr        Write callback data pointer (pointer to MARIA_SHARE)
     333                 : */
     334                 : 
     335                 : void maria_page_write_failure(uchar* data_ptr)
     336               0 : {
     337               0 :   maria_mark_crashed_share((MARIA_SHARE *)data_ptr);
     338                 : }
     339                 : 
     340                 : 
     341                 : /**
     342                 :   @brief Maria flush log log if needed
     343                 : 
     344                 :   @param page            The page data to set
     345                 :   @param page_no         The page number (<offset>/<page length>)
     346                 :   @param data_ptr        Write callback data pointer (pointer to MARIA_SHARE)
     347                 : 
     348                 :   @retval 0  OK
     349                 :   @retval 1  error
     350                 : */
     351                 : 
     352                 : my_bool maria_flush_log_for_page(uchar *page,
     353                 :                                  pgcache_page_no_t page_no
     354                 :                                  __attribute__((unused)),
     355                 :                                  uchar *data_ptr __attribute__((unused)))
     356          144973 : {
     357                 :   LSN lsn;
     358                 : #ifndef DBUG_OFF
     359          144973 :   const MARIA_SHARE *share= (MARIA_SHARE*) data_ptr;
     360                 : #endif
     361          144973 :   DBUG_ENTER("maria_flush_log_for_page");
     362                 :   /* share is 0 here only in unittest */
     363          144973 :   DBUG_ASSERT(!share || (share->page_type == PAGECACHE_LSN_PAGE &&
     364                 :                          share->now_transactional));
     365          144973 :   lsn= lsn_korr(page);
     366          144973 :   if (translog_flush(lsn))
     367               0 :     DBUG_RETURN(1);
     368          144973 :   DBUG_RETURN(0);
     369                 : }
     370                 : 
     371                 : 
     372                 : my_bool maria_flush_log_for_page_none(uchar *page __attribute__((unused)),
     373                 :                                       pgcache_page_no_t page_no
     374                 :                                       __attribute__((unused)),
     375                 :                                       uchar *data_ptr __attribute__((unused)))
     376          655569 : {
     377          655569 :   return 0;
     378                 : }

Generated by: LTP GCOV extension version 1.4