~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

  • Committer: Brian Aker
  • Date: 2008-07-01 20:14:24 UTC
  • Revision ID: brian@tangent.org-20080701201424-rsof5enxl7gkr50p
More cleanup on pread()

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
 
240
300
                         &share->state.key_root,keys*sizeof(my_off_t),
241
301
                         &share->state.key_del,
242
302
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
 
303
#ifdef THREAD
243
304
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
 
305
#endif
244
306
                         &share->mmap_lock,sizeof(rw_lock_t),
245
 
                         NULL))
 
307
                         NullS))
246
308
      goto err;
247
309
    errpos=4;
248
310
    *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);
 
311
    memcpy((char*) share->state.rec_per_key_part,
 
312
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
313
    memcpy((char*) share->state.key_root,
 
314
           (char*) key_root, sizeof(my_off_t)*keys);
 
315
    memcpy((char*) share->state.key_del,
 
316
           (char*) key_del, (sizeof(my_off_t) *
 
317
                             share->state.header.max_block_size_index));
 
318
    strmov(share->unique_file_name, name_buff);
256
319
    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);
 
320
    strmov(share->index_file_name,  index_name);
 
321
    strmov(share->data_file_name,   data_name);
259
322
 
260
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
323
    share->blocksize=min(IO_SIZE,myisam_block_size);
261
324
    {
262
325
      HA_KEYSEG *pos=share->keyparts;
263
326
      for (i=0 ; i < keys ; i++)
266
329
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
267
330
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
268
331
                        end_pos);
 
332
        if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
 
333
          have_rtree=1;
269
334
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
270
335
        share->keyinfo[i].seg=pos;
271
336
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
293
358
          else if (pos->type == HA_KEYTYPE_BINARY)
294
359
            pos->charset= &my_charset_bin;
295
360
        }
 
361
        if (share->keyinfo[i].flag & HA_SPATIAL)
 
362
        {
 
363
#ifdef HAVE_SPATIAL
 
364
          uint sp_segs=SPDIMS*2;
 
365
          share->keyinfo[i].seg=pos-sp_segs;
 
366
          share->keyinfo[i].keysegs--;
 
367
#else
 
368
          my_errno=HA_ERR_UNSUPPORTED;
 
369
          goto err;
 
370
#endif
 
371
        }
 
372
        else if (share->keyinfo[i].flag & HA_FULLTEXT)
 
373
        {
 
374
          if (!fulltext_keys)
 
375
          { /* 4.0 compatibility code, to be removed in 5.0 */
 
376
            share->keyinfo[i].seg=pos-FT_SEGS;
 
377
            share->keyinfo[i].keysegs-=FT_SEGS;
 
378
          }
 
379
          else
 
380
          {
 
381
            uint k;
 
382
            share->keyinfo[i].seg=pos;
 
383
            for (k=0; k < FT_SEGS; k++)
 
384
            {
 
385
              *pos= ft_keysegs[k];
 
386
              pos[0].language= pos[-1].language;
 
387
              if (!(pos[0].charset= pos[-1].charset))
 
388
              {
 
389
                my_errno=HA_ERR_CRASHED;
 
390
                goto err;
 
391
              }
 
392
              pos++;
 
393
            }
 
394
          }
 
395
          if (!share->ft2_keyinfo.seg)
 
396
          {
 
397
            memcpy(& share->ft2_keyinfo, & share->keyinfo[i], sizeof(MI_KEYDEF));
 
398
            share->ft2_keyinfo.keysegs=1;
 
399
            share->ft2_keyinfo.flag=0;
 
400
            share->ft2_keyinfo.keylength=
 
401
            share->ft2_keyinfo.minlength=
 
402
            share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
 
403
            share->ft2_keyinfo.seg=pos-1;
 
404
            share->ft2_keyinfo.end=pos;
 
405
            setup_key_functions(& share->ft2_keyinfo);
 
406
          }
 
407
        }
296
408
        setup_key_functions(share->keyinfo+i);
297
409
        share->keyinfo[i].end=pos;
298
410
        pos->type=HA_KEYTYPE_END;                       /* End */
329
441
        pos->flag=0;
330
442
        pos++;
331
443
      }
 
444
      share->ftparsers= 0;
332
445
    }
333
446
 
334
447
    disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
358
471
 
359
472
    if (! lock_error)
360
473
    {
 
474
      VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
361
475
      lock_error=1;                     /* Database unlocked */
362
476
    }
363
477
 
376
490
    share->base.margin_key_file_length=(share->base.max_key_file_length -
377
491
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
378
492
                                         share->blocksize * keys : 0));
379
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
493
    share->blocksize=min(IO_SIZE,myisam_block_size);
380
494
    share->data_file_type=STATIC_RECORD;
381
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
495
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
496
    {
 
497
      share->data_file_type = COMPRESSED_RECORD;
 
498
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
499
      info.s=share;
 
500
      if (_mi_read_pack_info(&info,
 
501
                             (pbool)
 
502
                             test(!(share->options &
 
503
                                    (HA_OPTION_PACK_RECORD |
 
504
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
505
        goto err;
 
506
    }
 
507
    else if (share->options & HA_OPTION_PACK_RECORD)
382
508
      share->data_file_type = DYNAMIC_RECORD;
383
 
    free(disk_cache);
384
 
    disk_cache= NULL;
 
509
    my_afree(disk_cache);
385
510
    mi_setup_functions(share);
386
 
    share->is_log_table= false;
 
511
    share->is_log_table= FALSE;
 
512
#ifdef THREAD
387
513
    thr_lock_init(&share->lock);
388
 
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
 
514
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
389
515
    for (i=0; i<keys; i++)
390
 
      my_rwlock_init(&share->key_root_lock[i], NULL);
391
 
    my_rwlock_init(&share->mmap_lock, NULL);
 
516
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
517
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
392
518
    if (!thr_lock_inited)
393
519
    {
394
520
      /* Probably a single threaded program; Don't use concurrent inserts */
400
526
        ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
401
527
                           HA_OPTION_COMPRESS_RECORD |
402
528
                           HA_OPTION_TEMP_COMPRESS_RECORD)) ||
403
 
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
 
529
         (open_flags & HA_OPEN_TMP_TABLE) ||
 
530
         have_rtree) ? 0 : 1;
404
531
      if (share->concurrent_insert)
405
532
      {
406
 
        share->lock.get_status= mi_get_status;
407
 
        share->lock.copy_status= mi_copy_status;
408
 
        share->lock.update_status= mi_update_status;
 
533
        share->lock.get_status=mi_get_status;
 
534
        share->lock.copy_status=mi_copy_status;
 
535
        share->lock.update_status=mi_update_status;
409
536
        share->lock.restore_status= mi_restore_status;
410
 
        share->lock.check_status= mi_check_status;
 
537
        share->lock.check_status=mi_check_status;
411
538
      }
412
539
    }
 
540
#endif
413
541
    /*
414
542
      Memory mapping can only be requested after initializing intern_lock.
415
543
    */
443
571
                       &info.first_mbr_key, share->base.max_key_length,
444
572
                       &info.filename,strlen(name)+1,
445
573
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
446
 
                       NULL))
 
574
                       NullS))
447
575
    goto err;
448
576
  errpos=6;
449
577
 
450
578
  if (!have_rtree)
451
579
    info.rtree_recursion_state= NULL;
452
580
 
453
 
  my_stpcpy(info.filename,name);
 
581
  strmov(info.filename,name);
454
582
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
455
583
  info.lastkey2=info.lastkey+share->base.max_key_length;
456
584
 
469
597
  info.lock_type=F_UNLCK;
470
598
  info.quick_mode=0;
471
599
  info.bulk_insert=0;
 
600
  info.ft1_to_ft2=0;
472
601
  info.errkey= -1;
473
602
  info.page_changed=1;
474
603
  pthread_mutex_lock(&share->intern_lock);
499
628
 
500
629
  /* Allocate buffer for one record */
501
630
 
502
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
 
631
  /* prerequisites: bzero(info) && info->s=share; are met. */
503
632
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
504
633
    goto err;
505
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
634
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
506
635
 
507
636
  *m_info=info;
 
637
#ifdef THREAD
508
638
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
 
639
#endif
509
640
  m_info->open_list.data=(void*) m_info;
510
641
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
511
642
 
512
643
  pthread_mutex_unlock(&THR_LOCK_myisam);
513
 
  return(m_info);
 
644
  if (myisam_log_file >= 0)
 
645
  {
 
646
    intern_filename(name_buff,share->index_file_name);
 
647
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
648
  }
 
649
  DBUG_RETURN(m_info);
514
650
 
515
651
err:
516
 
  if (disk_cache != NULL)
517
 
    free(disk_cache);
518
652
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
519
653
  if ((save_errno == HA_ERR_CRASHED) ||
520
654
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
522
656
    mi_report_error(save_errno, name);
523
657
  switch (errpos) {
524
658
  case 6:
525
 
    free((unsigned char*) m_info);
 
659
    my_free((uchar*) m_info,MYF(0));
526
660
    /* fall through */
527
661
  case 5:
528
 
    my_close(info.dfile,MYF(0));
 
662
    VOID(my_close(info.dfile,MYF(0)));
529
663
    if (old_info)
530
664
      break;                                    /* Don't remove open table */
531
665
    /* fall through */
532
666
  case 4:
533
 
    free((unsigned char*) share);
 
667
    my_free((uchar*) share,MYF(0));
534
668
    /* fall through */
535
669
  case 3:
 
670
    if (! lock_error)
 
671
      VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
 
672
    /* fall through */
 
673
  case 2:
 
674
    my_afree(disk_cache);
536
675
    /* fall through */
537
676
  case 1:
538
 
    my_close(kfile,MYF(0));
 
677
    VOID(my_close(kfile,MYF(0)));
539
678
    /* fall through */
540
679
  case 0:
541
680
  default:
543
682
  }
544
683
  pthread_mutex_unlock(&THR_LOCK_myisam);
545
684
  my_errno=save_errno;
546
 
  return (NULL);
 
685
  DBUG_RETURN (NULL);
547
686
} /* mi_open */
548
687
 
549
688
 
550
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, ulong length, unsigned char **buf)
 
689
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
551
690
{
552
 
  uint32_t extra;
553
 
  uint32_t old_length= 0;
 
691
  uint extra;
 
692
  uint32 old_length= 0;
554
693
 
555
694
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
556
695
  {
557
 
    unsigned char *newptr = *buf;
 
696
    uchar *newptr = *buf;
558
697
 
559
698
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
560
699
    if (length == (ulong) -1)
561
700
    {
562
701
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
563
 
        length= cmax(info->s->base.pack_reclength, info->s->max_pack_length);
 
702
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
564
703
      else
565
704
        length= info->s->base.pack_reclength;
566
 
      length= cmax(length, info->s->base.max_key_length);
 
705
      length= max(length, info->s->base.max_key_length);
567
706
      /* Avoid unnecessary realloc */
568
707
      if (newptr && length == old_length)
569
708
        return newptr;
574
713
            MI_REC_BUFF_OFFSET : 0);
575
714
    if (extra && newptr)
576
715
      newptr-= MI_REC_BUFF_OFFSET;
577
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*)newptr, length+extra+8,
 
716
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
578
717
                                     MYF(MY_ALLOW_ZERO_PTR))))
579
718
      return newptr;
580
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
719
    *((uint32 *) newptr)= (uint32) length;
581
720
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
582
721
  }
583
722
  return *buf;
584
723
}
585
724
 
586
725
 
587
 
uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
726
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
588
727
{
589
 
  uint64_t max_val= ~ (uint64_t) 0;             /* my_off_t is unsigned */
 
728
  ulonglong max_val= ~ (ulonglong) 0;           /* my_off_t is unsigned */
590
729
 
591
730
  if (!a || max_val / a < b)
592
731
    return max_val;
597
736
 
598
737
void mi_setup_functions(register MYISAM_SHARE *share)
599
738
{
600
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
739
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
740
  {
 
741
    share->read_record=_mi_read_pack_record;
 
742
    share->read_rnd=_mi_read_rnd_pack_record;
 
743
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
744
      share->calc_checksum=0;                           /* No checksum */
 
745
    else if (share->options & HA_OPTION_PACK_RECORD)
 
746
      share->calc_checksum= mi_checksum;
 
747
    else
 
748
      share->calc_checksum= mi_static_checksum;
 
749
  }
 
750
  else if (share->options & HA_OPTION_PACK_RECORD)
601
751
  {
602
752
    share->read_record=_mi_read_dynamic_record;
603
753
    share->read_rnd=_mi_read_rnd_dynamic_record;
640
790
 
641
791
static void setup_key_functions(register MI_KEYDEF *keyinfo)
642
792
{
 
793
  if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
 
794
  {
 
795
#ifdef HAVE_RTREE_KEYS
 
796
    keyinfo->ck_insert = rtree_insert;
 
797
    keyinfo->ck_delete = rtree_delete;
 
798
#else
 
799
    DBUG_ASSERT(0); /* mi_open should check it never happens */
 
800
#endif
 
801
  }
 
802
  else
643
803
  {
644
804
    keyinfo->ck_insert = _mi_ck_write;
645
805
    keyinfo->ck_delete = _mi_ck_delete;
695
855
   Function to save and store the header in the index file (.MYI)
696
856
*/
697
857
 
698
 
uint32_t mi_state_info_write(File file, MI_STATE_INFO *state, uint32_t pWrite)
 
858
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
699
859
{
700
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
701
 
  unsigned char *ptr=buff;
 
860
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
861
  uchar *ptr=buff;
702
862
  uint  i, keys= (uint) state->header.keys,
703
863
        key_blocks=state->header.max_block_size_index;
 
864
  DBUG_ENTER("mi_state_info_write");
704
865
 
705
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
866
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
706
867
  ptr+=sizeof(state->header);
707
868
 
708
869
  /* open_count must be first because of _mi_mark_file_changed ! */
709
870
  mi_int2store(ptr,state->open_count);          ptr +=2;
710
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
871
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
711
872
  mi_rowstore(ptr,state->state.records);        ptr +=8;
712
873
  mi_rowstore(ptr,state->state.del);            ptr +=8;
713
874
  mi_rowstore(ptr,state->split);                ptr +=8;
717
878
  mi_sizestore(ptr,state->state.empty);         ptr +=8;
718
879
  mi_sizestore(ptr,state->state.key_empty);     ptr +=8;
719
880
  mi_int8store(ptr,state->auto_increment);      ptr +=8;
720
 
  mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
 
881
  mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
721
882
  mi_int4store(ptr,state->process);             ptr +=4;
722
883
  mi_int4store(ptr,state->unique);              ptr +=4;
723
884
  mi_int4store(ptr,state->status);              ptr +=4;
735
896
  }
736
897
  if (pWrite & 2)                               /* From isamchk */
737
898
  {
738
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
899
    uint key_parts= mi_uint2korr(state->header.key_parts);
739
900
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
740
901
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
741
902
    mi_int4store(ptr,state->version);           ptr +=4;
742
903
    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;
 
904
    mi_int8store(ptr,(ulonglong) state->create_time);   ptr +=8;
 
905
    mi_int8store(ptr,(ulonglong) state->recover_time);  ptr +=8;
 
906
    mi_int8store(ptr,(ulonglong) state->check_time);    ptr +=8;
746
907
    mi_sizestore(ptr,state->rec_per_key_rows);  ptr+=8;
747
908
    for (i=0 ; i < key_parts ; i++)
748
909
    {
751
912
  }
752
913
 
753
914
  if (pWrite & 1)
754
 
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
 
915
    DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
755
916
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
756
 
  return(my_write(file, buff, (size_t) (ptr-buff),
 
917
  DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
757
918
                       MYF(MY_NABP)) != 0);
758
919
}
759
920
 
760
921
 
761
 
unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
922
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
762
923
{
763
 
  uint32_t i,keys,key_parts,key_blocks;
764
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
924
  uint i,keys,key_parts,key_blocks;
 
925
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
765
926
  ptr +=sizeof(state->header);
766
927
  keys=(uint) state->header.keys;
767
928
  key_parts=mi_uint2korr(state->header.key_parts);
811
972
}
812
973
 
813
974
 
814
 
uint32_t mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
 
975
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
815
976
{
816
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
977
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
817
978
 
818
979
  if (!myisam_single_user)
819
980
  {
834
995
**  store and read of MI_BASE_INFO
835
996
****************************************************************************/
836
997
 
837
 
uint32_t mi_base_info_write(File file, MI_BASE_INFO *base)
 
998
uint mi_base_info_write(File file, MI_BASE_INFO *base)
838
999
{
839
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
1000
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
840
1001
 
841
1002
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
842
1003
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
861
1022
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
862
1023
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
863
1024
  *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 */
 
1025
  *ptr++= base->raid_type;
 
1026
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
1027
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
1028
  bzero(ptr,6);                                         ptr +=6; /* extra */
870
1029
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
871
1030
}
872
1031
 
873
1032
 
874
 
unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
1033
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
875
1034
{
876
1035
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
877
1036
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
897
1056
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
898
1057
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
899
1058
  base->extra_alloc_procent = *ptr++;
900
 
 
901
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
902
 
  ptr+= 7; 
 
1059
  base->raid_type= *ptr++;
 
1060
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
1061
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
1062
  /* TO BE REMOVED: Fix for old RAID files */
 
1063
  if (base->raid_type == 0)
 
1064
  {
 
1065
    base->raid_chunks=0;
 
1066
    base->raid_chunksize=0;
 
1067
  }
903
1068
 
904
1069
  ptr+=6;
905
1070
  return ptr;
909
1074
  mi_keydef
910
1075
---------------------------------------------------------------------------*/
911
1076
 
912
 
uint32_t mi_keydef_write(File file, MI_KEYDEF *keydef)
 
1077
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
913
1078
{
914
 
  unsigned char buff[MI_KEYDEF_SIZE];
915
 
  unsigned char *ptr=buff;
 
1079
  uchar buff[MI_KEYDEF_SIZE];
 
1080
  uchar *ptr=buff;
916
1081
 
917
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
1082
  *ptr++ = (uchar) keydef->keysegs;
918
1083
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
919
1084
  mi_int2store(ptr,keydef->flag);               ptr +=2;
920
1085
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
924
1089
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
925
1090
}
926
1091
 
927
 
unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
1092
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
928
1093
{
929
1094
   keydef->keysegs      = (uint) *ptr++;
930
1095
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
937
1102
   keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
938
1103
   keydef->underflow_block_length=keydef->block_length/3;
939
1104
   keydef->version      = 0;                    /* Not saved */
 
1105
   keydef->parser       = &ft_default_parser;
 
1106
   keydef->ftparser_nr  = 0;
940
1107
   return ptr;
941
1108
}
942
1109
 
946
1113
 
947
1114
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
948
1115
{
949
 
  unsigned char buff[HA_KEYSEG_SIZE];
950
 
  unsigned char *ptr=buff;
 
1116
  uchar buff[HA_KEYSEG_SIZE];
 
1117
  uchar *ptr=buff;
951
1118
  ulong pos;
952
1119
 
953
1120
  *ptr++= keyseg->type;
967
1134
}
968
1135
 
969
1136
 
970
 
unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
1137
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
971
1138
{
972
1139
   keyseg->type         = *ptr++;
973
1140
   keyseg->language     = *ptr++;
981
1148
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
982
1149
   keyseg->charset=0;                           /* Will be filled in later */
983
1150
   if (keyseg->null_bit)
984
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1151
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
985
1152
   else
986
1153
   {
987
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1154
     keyseg->bit_pos= (uint16)keyseg->null_pos;
988
1155
     keyseg->null_pos= 0;
989
1156
   }
990
1157
   return ptr;
994
1161
  mi_uniquedef
995
1162
---------------------------------------------------------------------------*/
996
1163
 
997
 
uint32_t mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
 
1164
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
998
1165
{
999
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
1000
 
  unsigned char *ptr=buff;
 
1166
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1167
  uchar *ptr=buff;
1001
1168
 
1002
1169
  mi_int2store(ptr,def->keysegs);               ptr+=2;
1003
 
  *ptr++=  (unsigned char) def->key;
1004
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1170
  *ptr++=  (uchar) def->key;
 
1171
  *ptr++ = (uchar) def->null_are_equal;
1005
1172
 
1006
1173
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1007
1174
}
1008
1175
 
1009
 
unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1176
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1010
1177
{
1011
1178
   def->keysegs = mi_uint2korr(ptr);
1012
1179
   def->key     = ptr[2];
1018
1185
**  MI_COLUMNDEF
1019
1186
***************************************************************************/
1020
1187
 
1021
 
uint32_t mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
 
1188
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1022
1189
{
1023
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1024
 
  unsigned char *ptr=buff;
 
1190
  uchar buff[MI_COLUMNDEF_SIZE];
 
1191
  uchar *ptr=buff;
1025
1192
 
1026
1193
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1027
1194
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1030
1197
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1031
1198
}
1032
1199
 
1033
 
unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1200
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1034
1201
{
1035
1202
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1036
1203
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1037
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1204
   recinfo->null_bit= (uint8) *ptr++;
1038
1205
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1039
1206
   return ptr;
1040
1207
}
1041
1208
 
1042
1209
/**************************************************************************
1043
 
Open data file
 
1210
Open data file with or without RAID
1044
1211
We can't use dup() here as the data file descriptors need to have different
1045
1212
active seek-positions.
1046
1213
 
1051
1218
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1052
1219
                     File file_to_dup __attribute__((unused)))
1053
1220
{
1054
 
    info->dfile=my_open(share->data_file_name, share->mode,
 
1221
#ifdef USE_RAID
 
1222
  if (share->base.raid_type)
 
1223
  {
 
1224
    info->dfile=my_raid_open(share->data_file_name,
 
1225
                             share->mode | O_SHARE,
 
1226
                             share->base.raid_type,
 
1227
                             share->base.raid_chunks,
 
1228
                             share->base.raid_chunksize,
 
1229
                             MYF(MY_WME | MY_RAID));
 
1230
  }
 
1231
  else
 
1232
#endif
 
1233
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1055
1234
                        MYF(MY_WME));
1056
1235
  return info->dfile >= 0 ? 0 : 1;
1057
1236
}
1059
1238
 
1060
1239
int mi_open_keyfile(MYISAM_SHARE *share)
1061
1240
{
1062
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
 
1241
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1063
1242
                            MYF(MY_WME))) < 0)
1064
1243
    return 1;
1065
1244
  return 0;