~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

  • Committer: Monty Taylor
  • Date: 2008-07-05 17:07:46 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: monty@inaugust.com-20080705170746-8aq11u9fuwtfwy85
Removed my_alarm. Made my_lock only do the non-alarm version. Moved my_lock to MyISAM where it belongs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* open a isam-database */
17
17
 
18
 
#include "myisamdef.h"
19
 
#include <mystrings/m_ctype.h>
20
 
#include <drizzled/util/test.h>
 
18
#include "fulltext.h"
 
19
#include "sp_defs.h"
 
20
#include "rt_index.h"
 
21
#include <m_ctype.h>
 
22
 
 
23
#if defined(MSDOS) || defined(__WIN__)
 
24
#ifdef __WIN__
 
25
#include <fcntl.h>
 
26
#else
 
27
#include <process.h>                    /* Prototype for getpid */
 
28
#endif
 
29
#endif
 
30
#ifdef VMS
 
31
#include "static.c"
 
32
#endif
21
33
 
22
34
static void setup_key_functions(MI_KEYDEF *keyinfo);
23
 
#define get_next_element(to,pos,size) \
24
 
  do {                                \
25
 
    memcpy(to, pos, size);            \
26
 
    pos+=size;                        \
27
 
  } while (0)
 
35
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
 
36
                                        pos+=size;}
28
37
 
29
38
 
30
39
#define disk_pos_assert(pos, end_pos) \
63
72
  have an open count of 0.
64
73
******************************************************************************/
65
74
 
66
 
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
 
75
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
67
76
{
68
77
  int lock_error,kfile,open_mode,save_errno,have_rtree=0;
69
 
  uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
 
78
  uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
70
79
    key_parts,unique_key_parts,fulltext_keys,uniques;
71
80
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
72
81
       data_name[FN_REFLEN];
73
 
  unsigned char *disk_cache= NULL;
74
 
  unsigned char *disk_pos, *end_pos;
 
82
  uchar *disk_cache, *disk_pos, *end_pos;
75
83
  MI_INFO info,*m_info,*old_info;
76
84
  MYISAM_SHARE share_buff,*share;
77
85
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
78
86
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
79
 
  uint64_t max_key_file_length, max_data_file_length;
 
87
  ulonglong max_key_file_length, max_data_file_length;
 
88
  DBUG_ENTER("mi_open");
80
89
 
81
90
  kfile= -1;
82
91
  lock_error=1;
83
92
  errpos=0;
84
93
  head_length=sizeof(share_buff.state.header);
85
 
  memset(&info, 0, sizeof(info));
 
94
  bzero((uchar*) &info,sizeof(info));
86
95
 
87
96
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
88
97
                                   MY_UNPACK_FILENAME),MYF(0));
90
99
  if (!(old_info=test_if_reopen(name_buff)))
91
100
  {
92
101
    share= &share_buff;
93
 
    memset(&share_buff, 0, sizeof(share_buff));
 
102
    bzero((uchar*) &share_buff,sizeof(share_buff));
94
103
    share_buff.state.rec_per_key_part=rec_per_key_part;
95
104
    share_buff.state.key_root=key_root;
96
105
    share_buff.state.key_del=key_del;
97
 
    share_buff.key_cache= multi_key_cache_search((unsigned char*) name_buff,
 
106
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
98
107
                                                 strlen(name_buff));
99
108
 
100
 
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
 
109
    DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
 
110
                    if (strstr(name, "/t1"))
 
111
                    {
 
112
                      my_errno= HA_ERR_CRASHED;
 
113
                      goto err;
 
114
                    });
 
115
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
101
116
    {
102
117
      if ((errno != EROFS && errno != EACCES) ||
103
118
          mode != O_RDONLY ||
104
 
          (kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
 
119
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
105
120
        goto err;
106
121
    }
107
122
    share->mode=open_mode;
112
127
      my_errno= HA_ERR_NOT_A_TABLE;
113
128
      goto err;
114
129
    }
115
 
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
 
130
    if (memcmp((uchar*) share->state.header.file_version,
 
131
               (uchar*) myisam_file_magic, 4))
116
132
    {
 
133
      DBUG_PRINT("error",("Wrong header in %s",name_buff));
 
134
      DBUG_DUMP("error_dump",(uchar*) share->state.header.file_version,
 
135
                head_length);
117
136
      my_errno=HA_ERR_NOT_A_TABLE;
118
137
      goto err;
119
138
    }
125
144
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
126
145
          HA_OPTION_RELIES_ON_SQL_LAYER))
127
146
    {
 
147
      DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
128
148
      my_errno=HA_ERR_OLD_FILE;
129
149
      goto err;
130
150
    }
131
151
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
132
152
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
133
153
    {
 
154
      DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
134
155
      my_errno= HA_ERR_UNSUPPORTED;
135
156
      goto err;
136
157
    }
137
158
    /* Don't call realpath() if the name can't be a link */
138
159
    if (!strcmp(name_buff, org_name) ||
139
160
        my_readlink(index_name, org_name, MYF(0)) == -1)
140
 
      (void) my_stpcpy(index_name, org_name);
 
161
      (void) strmov(index_name, org_name);
141
162
    *strrchr(org_name, '.')= '\0';
142
163
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
143
164
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
144
165
 
145
166
    info_length=mi_uint2korr(share->state.header.header_length);
146
167
    base_pos=mi_uint2korr(share->state.header.base_pos);
147
 
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
 
168
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
148
169
    {
149
170
      my_errno=ENOMEM;
150
171
      goto err;
152
173
    end_pos=disk_cache+info_length;
153
174
    errpos=2;
154
175
 
155
 
    my_seek(kfile,0L,MY_SEEK_SET,MYF(0));
 
176
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
 
177
    if (!(open_flags & HA_OPEN_TMP_TABLE))
 
178
    {
 
179
      if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
 
180
                              MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
 
181
                                  0 : MY_DONT_WAIT))) &&
 
182
          !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
 
183
        goto err;
 
184
    }
156
185
    errpos=3;
157
186
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
158
187
    {
165
194
    fulltext_keys= (uint) share->state.header.fulltext_keys;
166
195
    key_parts= mi_uint2korr(share->state.header.key_parts);
167
196
    unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
 
197
    if (len != MI_STATE_INFO_SIZE)
 
198
    {
 
199
      DBUG_PRINT("warning",
 
200
                 ("saved_state_info_length: %d  state_info_length: %d",
 
201
                  len,MI_STATE_INFO_SIZE));
 
202
    }
168
203
    share->state_diff_length=len-MI_STATE_INFO_SIZE;
169
204
 
170
205
    mi_state_info_read(disk_cache, &share->state);
171
206
    len= mi_uint2korr(share->state.header.base_info_length);
 
207
    if (len != MI_BASE_INFO_SIZE)
 
208
    {
 
209
      DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
 
210
                            len,MI_BASE_INFO_SIZE));
 
211
    }
172
212
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
173
213
    share->state.state_length=base_pos;
174
214
 
175
215
    if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
176
216
        ((share->state.changed & STATE_CRASHED) ||
177
217
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
178
 
          (share->state.open_count))))
 
218
          (my_disable_locking && share->state.open_count))))
179
219
    {
 
220
      DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u  "
 
221
                          "changed: %u  open_count: %u  !locking: %d",
 
222
                          open_flags, share->state.changed,
 
223
                          share->state.open_count, my_disable_locking));
180
224
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
181
225
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
182
226
      goto err;
189
233
      goto err;
190
234
    }
191
235
 
 
236
    key_parts+=fulltext_keys*FT_SEGS;
192
237
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
193
238
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
194
239
    {
 
240
      DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
195
241
      my_errno=HA_ERR_UNSUPPORTED;
196
242
      goto err;
197
243
    }
199
245
    /* Correct max_file_length based on length of sizeof(off_t) */
200
246
    max_data_file_length=
201
247
      (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
202
 
      (((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
 
248
      (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
203
249
      (mi_safe_mul(share->base.pack_reclength,
204
 
                   (uint64_t) 1 << (share->base.rec_reflength*8))-1);
 
250
                   (ulonglong) 1 << (share->base.rec_reflength*8))-1);
205
251
    max_key_file_length=
206
252
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
207
 
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
 
253
                  ((ulonglong) 1 << (share->base.key_reflength*8))-1);
208
254
#if SIZEOF_OFF_T == 4
209
255
    set_if_smaller(max_data_file_length, INT_MAX32);
210
256
    set_if_smaller(max_key_file_length, INT_MAX32);
211
257
#endif
 
258
#if USE_RAID && SYSTEM_SIZEOF_OFF_T == 4
 
259
    set_if_smaller(max_key_file_length, INT_MAX32);
 
260
    if (!share->base.raid_type)
 
261
    {
 
262
      set_if_smaller(max_data_file_length, INT_MAX32);
 
263
    }
 
264
    else
 
265
    {
 
266
      set_if_smaller(max_data_file_length,
 
267
                     (ulonglong) share->base.raid_chunks << 31);
 
268
    }
 
269
#elif !defined(USE_RAID)
212
270
    if (share->base.raid_type)
213
271
    {
 
272
      DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
214
273
      my_errno=HA_ERR_UNSUPPORTED;
215
274
      goto err;
216
275
    }
 
276
#endif
217
277
    share->base.max_data_file_length=(my_off_t) max_data_file_length;
218
278
    share->base.max_key_file_length=(my_off_t) max_key_file_length;
219
279
 
242
302
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
243
303
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
244
304
                         &share->mmap_lock,sizeof(rw_lock_t),
245
 
                         NULL))
 
305
                         NullS))
246
306
      goto err;
247
307
    errpos=4;
248
308
    *share=share_buff;
249
 
    memcpy(share->state.rec_per_key_part, rec_per_key_part,
250
 
           sizeof(long)*key_parts);
251
 
    memcpy(share->state.key_root, key_root,
252
 
           sizeof(my_off_t)*keys);
253
 
    memcpy(share->state.key_del, key_del,
254
 
           sizeof(my_off_t) * share->state.header.max_block_size_index);
255
 
    my_stpcpy(share->unique_file_name, name_buff);
 
309
    memcpy((char*) share->state.rec_per_key_part,
 
310
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
311
    memcpy((char*) share->state.key_root,
 
312
           (char*) key_root, sizeof(my_off_t)*keys);
 
313
    memcpy((char*) share->state.key_del,
 
314
           (char*) key_del, (sizeof(my_off_t) *
 
315
                             share->state.header.max_block_size_index));
 
316
    strmov(share->unique_file_name, name_buff);
256
317
    share->unique_name_length= strlen(name_buff);
257
 
    my_stpcpy(share->index_file_name,  index_name);
258
 
    my_stpcpy(share->data_file_name,   data_name);
 
318
    strmov(share->index_file_name,  index_name);
 
319
    strmov(share->data_file_name,   data_name);
259
320
 
260
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
321
    share->blocksize=min(IO_SIZE,myisam_block_size);
261
322
    {
262
323
      HA_KEYSEG *pos=share->keyparts;
263
324
      for (i=0 ; i < keys ; i++)
266
327
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
267
328
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
268
329
                        end_pos);
 
330
        if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
 
331
          have_rtree=1;
269
332
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
270
333
        share->keyinfo[i].seg=pos;
271
334
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
293
356
          else if (pos->type == HA_KEYTYPE_BINARY)
294
357
            pos->charset= &my_charset_bin;
295
358
        }
 
359
        if (share->keyinfo[i].flag & HA_SPATIAL)
 
360
        {
 
361
#ifdef HAVE_SPATIAL
 
362
          uint sp_segs=SPDIMS*2;
 
363
          share->keyinfo[i].seg=pos-sp_segs;
 
364
          share->keyinfo[i].keysegs--;
 
365
#else
 
366
          my_errno=HA_ERR_UNSUPPORTED;
 
367
          goto err;
 
368
#endif
 
369
        }
 
370
        else if (share->keyinfo[i].flag & HA_FULLTEXT)
 
371
        {
 
372
          if (!fulltext_keys)
 
373
          { /* 4.0 compatibility code, to be removed in 5.0 */
 
374
            share->keyinfo[i].seg=pos-FT_SEGS;
 
375
            share->keyinfo[i].keysegs-=FT_SEGS;
 
376
          }
 
377
          else
 
378
          {
 
379
            uint k;
 
380
            share->keyinfo[i].seg=pos;
 
381
            for (k=0; k < FT_SEGS; k++)
 
382
            {
 
383
              *pos= ft_keysegs[k];
 
384
              pos[0].language= pos[-1].language;
 
385
              if (!(pos[0].charset= pos[-1].charset))
 
386
              {
 
387
                my_errno=HA_ERR_CRASHED;
 
388
                goto err;
 
389
              }
 
390
              pos++;
 
391
            }
 
392
          }
 
393
          if (!share->ft2_keyinfo.seg)
 
394
          {
 
395
            memcpy(& share->ft2_keyinfo, & share->keyinfo[i], sizeof(MI_KEYDEF));
 
396
            share->ft2_keyinfo.keysegs=1;
 
397
            share->ft2_keyinfo.flag=0;
 
398
            share->ft2_keyinfo.keylength=
 
399
            share->ft2_keyinfo.minlength=
 
400
            share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
 
401
            share->ft2_keyinfo.seg=pos-1;
 
402
            share->ft2_keyinfo.end=pos;
 
403
            setup_key_functions(& share->ft2_keyinfo);
 
404
          }
 
405
        }
296
406
        setup_key_functions(share->keyinfo+i);
297
407
        share->keyinfo[i].end=pos;
298
408
        pos->type=HA_KEYTYPE_END;                       /* End */
329
439
        pos->flag=0;
330
440
        pos++;
331
441
      }
 
442
      share->ftparsers= 0;
332
443
    }
333
444
 
334
445
    disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
358
469
 
359
470
    if (! lock_error)
360
471
    {
 
472
      VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
361
473
      lock_error=1;                     /* Database unlocked */
362
474
    }
363
475
 
376
488
    share->base.margin_key_file_length=(share->base.max_key_file_length -
377
489
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
378
490
                                         share->blocksize * keys : 0));
379
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
491
    share->blocksize=min(IO_SIZE,myisam_block_size);
380
492
    share->data_file_type=STATIC_RECORD;
381
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
493
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
494
    {
 
495
      share->data_file_type = COMPRESSED_RECORD;
 
496
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
497
      info.s=share;
 
498
      if (_mi_read_pack_info(&info,
 
499
                             (pbool)
 
500
                             test(!(share->options &
 
501
                                    (HA_OPTION_PACK_RECORD |
 
502
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
503
        goto err;
 
504
    }
 
505
    else if (share->options & HA_OPTION_PACK_RECORD)
382
506
      share->data_file_type = DYNAMIC_RECORD;
383
 
    free(disk_cache);
384
 
    disk_cache= NULL;
 
507
    my_afree(disk_cache);
385
508
    mi_setup_functions(share);
386
 
    share->is_log_table= false;
 
509
    share->is_log_table= FALSE;
387
510
    thr_lock_init(&share->lock);
388
 
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
 
511
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
389
512
    for (i=0; i<keys; i++)
390
 
      my_rwlock_init(&share->key_root_lock[i], NULL);
391
 
    my_rwlock_init(&share->mmap_lock, NULL);
 
513
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
514
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
392
515
    if (!thr_lock_inited)
393
516
    {
394
517
      /* Probably a single threaded program; Don't use concurrent inserts */
400
523
        ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
401
524
                           HA_OPTION_COMPRESS_RECORD |
402
525
                           HA_OPTION_TEMP_COMPRESS_RECORD)) ||
403
 
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
 
526
         (open_flags & HA_OPEN_TMP_TABLE) ||
 
527
         have_rtree) ? 0 : 1;
404
528
      if (share->concurrent_insert)
405
529
      {
406
 
        share->lock.get_status= mi_get_status;
407
 
        share->lock.copy_status= mi_copy_status;
408
 
        share->lock.update_status= mi_update_status;
 
530
        share->lock.get_status=mi_get_status;
 
531
        share->lock.copy_status=mi_copy_status;
 
532
        share->lock.update_status=mi_update_status;
409
533
        share->lock.restore_status= mi_restore_status;
410
 
        share->lock.check_status= mi_check_status;
 
534
        share->lock.check_status=mi_check_status;
411
535
      }
412
536
    }
413
537
    /*
443
567
                       &info.first_mbr_key, share->base.max_key_length,
444
568
                       &info.filename,strlen(name)+1,
445
569
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
446
 
                       NULL))
 
570
                       NullS))
447
571
    goto err;
448
572
  errpos=6;
449
573
 
450
574
  if (!have_rtree)
451
575
    info.rtree_recursion_state= NULL;
452
576
 
453
 
  my_stpcpy(info.filename,name);
 
577
  strmov(info.filename,name);
454
578
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
455
579
  info.lastkey2=info.lastkey+share->base.max_key_length;
456
580
 
469
593
  info.lock_type=F_UNLCK;
470
594
  info.quick_mode=0;
471
595
  info.bulk_insert=0;
 
596
  info.ft1_to_ft2=0;
472
597
  info.errkey= -1;
473
598
  info.page_changed=1;
474
599
  pthread_mutex_lock(&share->intern_lock);
499
624
 
500
625
  /* Allocate buffer for one record */
501
626
 
502
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
 
627
  /* prerequisites: bzero(info) && info->s=share; are met. */
503
628
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
504
629
    goto err;
505
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
630
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
506
631
 
507
632
  *m_info=info;
508
633
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
510
635
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
511
636
 
512
637
  pthread_mutex_unlock(&THR_LOCK_myisam);
513
 
  return(m_info);
 
638
  if (myisam_log_file >= 0)
 
639
  {
 
640
    intern_filename(name_buff,share->index_file_name);
 
641
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
642
  }
 
643
  DBUG_RETURN(m_info);
514
644
 
515
645
err:
516
 
  if (disk_cache != NULL)
517
 
    free(disk_cache);
518
646
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
519
647
  if ((save_errno == HA_ERR_CRASHED) ||
520
648
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
522
650
    mi_report_error(save_errno, name);
523
651
  switch (errpos) {
524
652
  case 6:
525
 
    free((unsigned char*) m_info);
 
653
    my_free((uchar*) m_info,MYF(0));
526
654
    /* fall through */
527
655
  case 5:
528
 
    my_close(info.dfile,MYF(0));
 
656
    VOID(my_close(info.dfile,MYF(0)));
529
657
    if (old_info)
530
658
      break;                                    /* Don't remove open table */
531
659
    /* fall through */
532
660
  case 4:
533
 
    free((unsigned char*) share);
 
661
    my_free((uchar*) share,MYF(0));
534
662
    /* fall through */
535
663
  case 3:
 
664
    if (! lock_error)
 
665
      VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
 
666
    /* fall through */
 
667
  case 2:
 
668
    my_afree(disk_cache);
536
669
    /* fall through */
537
670
  case 1:
538
 
    my_close(kfile,MYF(0));
 
671
    VOID(my_close(kfile,MYF(0)));
539
672
    /* fall through */
540
673
  case 0:
541
674
  default:
543
676
  }
544
677
  pthread_mutex_unlock(&THR_LOCK_myisam);
545
678
  my_errno=save_errno;
546
 
  return (NULL);
 
679
  DBUG_RETURN (NULL);
547
680
} /* mi_open */
548
681
 
549
682
 
550
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, ulong length, unsigned char **buf)
 
683
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
551
684
{
552
 
  uint32_t extra;
553
 
  uint32_t old_length= 0;
 
685
  uint extra;
 
686
  uint32 old_length= 0;
554
687
 
555
688
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
556
689
  {
557
 
    unsigned char *newptr = *buf;
 
690
    uchar *newptr = *buf;
558
691
 
559
692
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
560
693
    if (length == (ulong) -1)
561
694
    {
562
695
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
563
 
        length= cmax(info->s->base.pack_reclength, info->s->max_pack_length);
 
696
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
564
697
      else
565
698
        length= info->s->base.pack_reclength;
566
 
      length= cmax(length, info->s->base.max_key_length);
 
699
      length= max(length, info->s->base.max_key_length);
567
700
      /* Avoid unnecessary realloc */
568
701
      if (newptr && length == old_length)
569
702
        return newptr;
574
707
            MI_REC_BUFF_OFFSET : 0);
575
708
    if (extra && newptr)
576
709
      newptr-= MI_REC_BUFF_OFFSET;
577
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*)newptr, length+extra+8,
 
710
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
578
711
                                     MYF(MY_ALLOW_ZERO_PTR))))
579
712
      return newptr;
580
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
713
    *((uint32 *) newptr)= (uint32) length;
581
714
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
582
715
  }
583
716
  return *buf;
584
717
}
585
718
 
586
719
 
587
 
uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
720
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
588
721
{
589
 
  uint64_t max_val= ~ (uint64_t) 0;             /* my_off_t is unsigned */
 
722
  ulonglong max_val= ~ (ulonglong) 0;           /* my_off_t is unsigned */
590
723
 
591
724
  if (!a || max_val / a < b)
592
725
    return max_val;
597
730
 
598
731
void mi_setup_functions(register MYISAM_SHARE *share)
599
732
{
600
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
733
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
734
  {
 
735
    share->read_record=_mi_read_pack_record;
 
736
    share->read_rnd=_mi_read_rnd_pack_record;
 
737
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
738
      share->calc_checksum=0;                           /* No checksum */
 
739
    else if (share->options & HA_OPTION_PACK_RECORD)
 
740
      share->calc_checksum= mi_checksum;
 
741
    else
 
742
      share->calc_checksum= mi_static_checksum;
 
743
  }
 
744
  else if (share->options & HA_OPTION_PACK_RECORD)
601
745
  {
602
746
    share->read_record=_mi_read_dynamic_record;
603
747
    share->read_rnd=_mi_read_rnd_dynamic_record;
640
784
 
641
785
static void setup_key_functions(register MI_KEYDEF *keyinfo)
642
786
{
 
787
  if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
 
788
  {
 
789
#ifdef HAVE_RTREE_KEYS
 
790
    keyinfo->ck_insert = rtree_insert;
 
791
    keyinfo->ck_delete = rtree_delete;
 
792
#else
 
793
    DBUG_ASSERT(0); /* mi_open should check it never happens */
 
794
#endif
 
795
  }
 
796
  else
643
797
  {
644
798
    keyinfo->ck_insert = _mi_ck_write;
645
799
    keyinfo->ck_delete = _mi_ck_delete;
695
849
   Function to save and store the header in the index file (.MYI)
696
850
*/
697
851
 
698
 
uint32_t mi_state_info_write(File file, MI_STATE_INFO *state, uint32_t pWrite)
 
852
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
699
853
{
700
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
701
 
  unsigned char *ptr=buff;
 
854
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
855
  uchar *ptr=buff;
702
856
  uint  i, keys= (uint) state->header.keys,
703
857
        key_blocks=state->header.max_block_size_index;
 
858
  DBUG_ENTER("mi_state_info_write");
704
859
 
705
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
860
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
706
861
  ptr+=sizeof(state->header);
707
862
 
708
863
  /* open_count must be first because of _mi_mark_file_changed ! */
709
864
  mi_int2store(ptr,state->open_count);          ptr +=2;
710
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
865
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
711
866
  mi_rowstore(ptr,state->state.records);        ptr +=8;
712
867
  mi_rowstore(ptr,state->state.del);            ptr +=8;
713
868
  mi_rowstore(ptr,state->split);                ptr +=8;
717
872
  mi_sizestore(ptr,state->state.empty);         ptr +=8;
718
873
  mi_sizestore(ptr,state->state.key_empty);     ptr +=8;
719
874
  mi_int8store(ptr,state->auto_increment);      ptr +=8;
720
 
  mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
 
875
  mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
721
876
  mi_int4store(ptr,state->process);             ptr +=4;
722
877
  mi_int4store(ptr,state->unique);              ptr +=4;
723
878
  mi_int4store(ptr,state->status);              ptr +=4;
735
890
  }
736
891
  if (pWrite & 2)                               /* From isamchk */
737
892
  {
738
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
893
    uint key_parts= mi_uint2korr(state->header.key_parts);
739
894
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
740
895
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
741
896
    mi_int4store(ptr,state->version);           ptr +=4;
742
897
    mi_int8store(ptr,state->key_map);           ptr +=8;
743
 
    mi_int8store(ptr,(uint64_t) state->create_time);    ptr +=8;
744
 
    mi_int8store(ptr,(uint64_t) state->recover_time);   ptr +=8;
745
 
    mi_int8store(ptr,(uint64_t) state->check_time);     ptr +=8;
 
898
    mi_int8store(ptr,(ulonglong) state->create_time);   ptr +=8;
 
899
    mi_int8store(ptr,(ulonglong) state->recover_time);  ptr +=8;
 
900
    mi_int8store(ptr,(ulonglong) state->check_time);    ptr +=8;
746
901
    mi_sizestore(ptr,state->rec_per_key_rows);  ptr+=8;
747
902
    for (i=0 ; i < key_parts ; i++)
748
903
    {
751
906
  }
752
907
 
753
908
  if (pWrite & 1)
754
 
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
 
909
    DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
755
910
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
756
 
  return(my_write(file, buff, (size_t) (ptr-buff),
 
911
  DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
757
912
                       MYF(MY_NABP)) != 0);
758
913
}
759
914
 
760
915
 
761
 
unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
916
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
762
917
{
763
 
  uint32_t i,keys,key_parts,key_blocks;
764
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
918
  uint i,keys,key_parts,key_blocks;
 
919
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
765
920
  ptr +=sizeof(state->header);
766
921
  keys=(uint) state->header.keys;
767
922
  key_parts=mi_uint2korr(state->header.key_parts);
811
966
}
812
967
 
813
968
 
814
 
uint32_t mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
 
969
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
815
970
{
816
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
971
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
817
972
 
818
973
  if (!myisam_single_user)
819
974
  {
834
989
**  store and read of MI_BASE_INFO
835
990
****************************************************************************/
836
991
 
837
 
uint32_t mi_base_info_write(File file, MI_BASE_INFO *base)
 
992
uint mi_base_info_write(File file, MI_BASE_INFO *base)
838
993
{
839
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
994
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
840
995
 
841
996
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
842
997
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
861
1016
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
862
1017
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
863
1018
  *ptr++= base->extra_alloc_procent;
864
 
  /* old raid info  slots */
865
 
  *ptr++= 0;
866
 
  mi_int2store(ptr,UINT16_C(0));                        ptr +=2;
867
 
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
868
 
 
869
 
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
 
1019
  *ptr++= base->raid_type;
 
1020
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
1021
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
1022
  bzero(ptr,6);                                         ptr +=6; /* extra */
870
1023
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
871
1024
}
872
1025
 
873
1026
 
874
 
unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
1027
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
875
1028
{
876
1029
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
877
1030
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
897
1050
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
898
1051
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
899
1052
  base->extra_alloc_procent = *ptr++;
900
 
 
901
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
902
 
  ptr+= 7; 
 
1053
  base->raid_type= *ptr++;
 
1054
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
1055
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
1056
  /* TO BE REMOVED: Fix for old RAID files */
 
1057
  if (base->raid_type == 0)
 
1058
  {
 
1059
    base->raid_chunks=0;
 
1060
    base->raid_chunksize=0;
 
1061
  }
903
1062
 
904
1063
  ptr+=6;
905
1064
  return ptr;
909
1068
  mi_keydef
910
1069
---------------------------------------------------------------------------*/
911
1070
 
912
 
uint32_t mi_keydef_write(File file, MI_KEYDEF *keydef)
 
1071
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
913
1072
{
914
 
  unsigned char buff[MI_KEYDEF_SIZE];
915
 
  unsigned char *ptr=buff;
 
1073
  uchar buff[MI_KEYDEF_SIZE];
 
1074
  uchar *ptr=buff;
916
1075
 
917
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
1076
  *ptr++ = (uchar) keydef->keysegs;
918
1077
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
919
1078
  mi_int2store(ptr,keydef->flag);               ptr +=2;
920
1079
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
924
1083
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
925
1084
}
926
1085
 
927
 
unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
1086
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
928
1087
{
929
1088
   keydef->keysegs      = (uint) *ptr++;
930
1089
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
937
1096
   keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
938
1097
   keydef->underflow_block_length=keydef->block_length/3;
939
1098
   keydef->version      = 0;                    /* Not saved */
 
1099
   keydef->parser       = &ft_default_parser;
 
1100
   keydef->ftparser_nr  = 0;
940
1101
   return ptr;
941
1102
}
942
1103
 
946
1107
 
947
1108
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
948
1109
{
949
 
  unsigned char buff[HA_KEYSEG_SIZE];
950
 
  unsigned char *ptr=buff;
 
1110
  uchar buff[HA_KEYSEG_SIZE];
 
1111
  uchar *ptr=buff;
951
1112
  ulong pos;
952
1113
 
953
1114
  *ptr++= keyseg->type;
967
1128
}
968
1129
 
969
1130
 
970
 
unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
1131
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
971
1132
{
972
1133
   keyseg->type         = *ptr++;
973
1134
   keyseg->language     = *ptr++;
981
1142
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
982
1143
   keyseg->charset=0;                           /* Will be filled in later */
983
1144
   if (keyseg->null_bit)
984
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1145
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
985
1146
   else
986
1147
   {
987
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1148
     keyseg->bit_pos= (uint16)keyseg->null_pos;
988
1149
     keyseg->null_pos= 0;
989
1150
   }
990
1151
   return ptr;
994
1155
  mi_uniquedef
995
1156
---------------------------------------------------------------------------*/
996
1157
 
997
 
uint32_t mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
 
1158
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
998
1159
{
999
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
1000
 
  unsigned char *ptr=buff;
 
1160
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1161
  uchar *ptr=buff;
1001
1162
 
1002
1163
  mi_int2store(ptr,def->keysegs);               ptr+=2;
1003
 
  *ptr++=  (unsigned char) def->key;
1004
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1164
  *ptr++=  (uchar) def->key;
 
1165
  *ptr++ = (uchar) def->null_are_equal;
1005
1166
 
1006
1167
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1007
1168
}
1008
1169
 
1009
 
unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1170
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1010
1171
{
1011
1172
   def->keysegs = mi_uint2korr(ptr);
1012
1173
   def->key     = ptr[2];
1018
1179
**  MI_COLUMNDEF
1019
1180
***************************************************************************/
1020
1181
 
1021
 
uint32_t mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
 
1182
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1022
1183
{
1023
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1024
 
  unsigned char *ptr=buff;
 
1184
  uchar buff[MI_COLUMNDEF_SIZE];
 
1185
  uchar *ptr=buff;
1025
1186
 
1026
1187
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1027
1188
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1030
1191
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1031
1192
}
1032
1193
 
1033
 
unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1194
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1034
1195
{
1035
1196
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1036
1197
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1037
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1198
   recinfo->null_bit= (uint8) *ptr++;
1038
1199
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1039
1200
   return ptr;
1040
1201
}
1041
1202
 
1042
1203
/**************************************************************************
1043
 
Open data file
 
1204
Open data file with or without RAID
1044
1205
We can't use dup() here as the data file descriptors need to have different
1045
1206
active seek-positions.
1046
1207
 
1051
1212
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1052
1213
                     File file_to_dup __attribute__((unused)))
1053
1214
{
1054
 
    info->dfile=my_open(share->data_file_name, share->mode,
 
1215
#ifdef USE_RAID
 
1216
  if (share->base.raid_type)
 
1217
  {
 
1218
    info->dfile=my_raid_open(share->data_file_name,
 
1219
                             share->mode | O_SHARE,
 
1220
                             share->base.raid_type,
 
1221
                             share->base.raid_chunks,
 
1222
                             share->base.raid_chunksize,
 
1223
                             MYF(MY_WME | MY_RAID));
 
1224
  }
 
1225
  else
 
1226
#endif
 
1227
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1055
1228
                        MYF(MY_WME));
1056
1229
  return info->dfile >= 0 ? 0 : 1;
1057
1230
}
1059
1232
 
1060
1233
int mi_open_keyfile(MYISAM_SHARE *share)
1061
1234
{
1062
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
 
1235
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1063
1236
                            MYF(MY_WME))) < 0)
1064
1237
    return 1;
1065
1238
  return 0;