~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-07 14:25:25 UTC
  • mto: (77.1.25 codestyle)
  • mto: This revision was merged to the branch mainline in revision 82.
  • Revision ID: brian@tangent.org-20080707142525-xzy2nl3ie2ebwfln
LL() cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
/* open a isam-database */
17
17
 
18
18
#include "myisamdef.h"
19
 
#include <mystrings/m_ctype.h>
20
 
#include <drizzled/util/test.h>
 
19
#include <m_ctype.h>
 
20
 
 
21
#if defined(MSDOS) || defined(__WIN__)
 
22
#ifdef __WIN__
 
23
#include <fcntl.h>
 
24
#else
 
25
#include <process.h>                    /* Prototype for getpid */
 
26
#endif
 
27
#endif
 
28
#ifdef VMS
 
29
#include "static.c"
 
30
#endif
21
31
 
22
32
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)
 
33
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
 
34
                                        pos+=size;}
28
35
 
29
36
 
30
37
#define disk_pos_assert(pos, end_pos) \
63
70
  have an open count of 0.
64
71
******************************************************************************/
65
72
 
66
 
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
 
73
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
67
74
{
68
75
  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,
 
76
  uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
70
77
    key_parts,unique_key_parts,fulltext_keys,uniques;
71
78
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
72
79
       data_name[FN_REFLEN];
73
 
  unsigned char *disk_cache= NULL;
74
 
  unsigned char *disk_pos, *end_pos;
 
80
  uchar *disk_cache, *disk_pos, *end_pos;
75
81
  MI_INFO info,*m_info,*old_info;
76
82
  MYISAM_SHARE share_buff,*share;
77
83
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
78
84
  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;
 
85
  ulonglong max_key_file_length, max_data_file_length;
 
86
  DBUG_ENTER("mi_open");
80
87
 
81
88
  kfile= -1;
82
89
  lock_error=1;
83
90
  errpos=0;
84
91
  head_length=sizeof(share_buff.state.header);
85
 
  memset(&info, 0, sizeof(info));
 
92
  bzero((uchar*) &info,sizeof(info));
86
93
 
87
94
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
88
95
                                   MY_UNPACK_FILENAME),MYF(0));
90
97
  if (!(old_info=test_if_reopen(name_buff)))
91
98
  {
92
99
    share= &share_buff;
93
 
    memset(&share_buff, 0, sizeof(share_buff));
 
100
    bzero((uchar*) &share_buff,sizeof(share_buff));
94
101
    share_buff.state.rec_per_key_part=rec_per_key_part;
95
102
    share_buff.state.key_root=key_root;
96
103
    share_buff.state.key_del=key_del;
97
 
    share_buff.key_cache= multi_key_cache_search((unsigned char*) name_buff,
 
104
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
98
105
                                                 strlen(name_buff));
99
106
 
100
 
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
 
107
    DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
 
108
                    if (strstr(name, "/t1"))
 
109
                    {
 
110
                      my_errno= HA_ERR_CRASHED;
 
111
                      goto err;
 
112
                    });
 
113
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
101
114
    {
102
115
      if ((errno != EROFS && errno != EACCES) ||
103
116
          mode != O_RDONLY ||
104
 
          (kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
 
117
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
105
118
        goto err;
106
119
    }
107
120
    share->mode=open_mode;
112
125
      my_errno= HA_ERR_NOT_A_TABLE;
113
126
      goto err;
114
127
    }
115
 
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
 
128
    if (memcmp((uchar*) share->state.header.file_version,
 
129
               (uchar*) myisam_file_magic, 4))
116
130
    {
 
131
      DBUG_PRINT("error",("Wrong header in %s",name_buff));
 
132
      DBUG_DUMP("error_dump",(uchar*) share->state.header.file_version,
 
133
                head_length);
117
134
      my_errno=HA_ERR_NOT_A_TABLE;
118
135
      goto err;
119
136
    }
125
142
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
126
143
          HA_OPTION_RELIES_ON_SQL_LAYER))
127
144
    {
 
145
      DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
128
146
      my_errno=HA_ERR_OLD_FILE;
129
147
      goto err;
130
148
    }
131
149
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
132
150
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
133
151
    {
 
152
      DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
134
153
      my_errno= HA_ERR_UNSUPPORTED;
135
154
      goto err;
136
155
    }
137
156
    /* Don't call realpath() if the name can't be a link */
138
157
    if (!strcmp(name_buff, org_name) ||
139
158
        my_readlink(index_name, org_name, MYF(0)) == -1)
140
 
      (void) my_stpcpy(index_name, org_name);
 
159
      (void) strmov(index_name, org_name);
141
160
    *strrchr(org_name, '.')= '\0';
142
161
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
143
162
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
144
163
 
145
164
    info_length=mi_uint2korr(share->state.header.header_length);
146
165
    base_pos=mi_uint2korr(share->state.header.base_pos);
147
 
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
 
166
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
148
167
    {
149
168
      my_errno=ENOMEM;
150
169
      goto err;
152
171
    end_pos=disk_cache+info_length;
153
172
    errpos=2;
154
173
 
155
 
    my_seek(kfile,0L,MY_SEEK_SET,MYF(0));
 
174
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
 
175
    if (!(open_flags & HA_OPEN_TMP_TABLE))
 
176
    {
 
177
      if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
 
178
                              MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
 
179
                                  0 : MY_DONT_WAIT))) &&
 
180
          !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
 
181
        goto err;
 
182
    }
156
183
    errpos=3;
157
184
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
158
185
    {
165
192
    fulltext_keys= (uint) share->state.header.fulltext_keys;
166
193
    key_parts= mi_uint2korr(share->state.header.key_parts);
167
194
    unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
 
195
    if (len != MI_STATE_INFO_SIZE)
 
196
    {
 
197
      DBUG_PRINT("warning",
 
198
                 ("saved_state_info_length: %d  state_info_length: %d",
 
199
                  len,MI_STATE_INFO_SIZE));
 
200
    }
168
201
    share->state_diff_length=len-MI_STATE_INFO_SIZE;
169
202
 
170
203
    mi_state_info_read(disk_cache, &share->state);
171
204
    len= mi_uint2korr(share->state.header.base_info_length);
 
205
    if (len != MI_BASE_INFO_SIZE)
 
206
    {
 
207
      DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
 
208
                            len,MI_BASE_INFO_SIZE));
 
209
    }
172
210
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
173
211
    share->state.state_length=base_pos;
174
212
 
175
213
    if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
176
214
        ((share->state.changed & STATE_CRASHED) ||
177
215
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
178
 
          (share->state.open_count))))
 
216
          (my_disable_locking && share->state.open_count))))
179
217
    {
 
218
      DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u  "
 
219
                          "changed: %u  open_count: %u  !locking: %d",
 
220
                          open_flags, share->state.changed,
 
221
                          share->state.open_count, my_disable_locking));
180
222
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
181
223
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
182
224
      goto err;
192
234
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
193
235
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
194
236
    {
 
237
      DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
195
238
      my_errno=HA_ERR_UNSUPPORTED;
196
239
      goto err;
197
240
    }
199
242
    /* Correct max_file_length based on length of sizeof(off_t) */
200
243
    max_data_file_length=
201
244
      (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
202
 
      (((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
 
245
      (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
203
246
      (mi_safe_mul(share->base.pack_reclength,
204
 
                   (uint64_t) 1 << (share->base.rec_reflength*8))-1);
 
247
                   (ulonglong) 1 << (share->base.rec_reflength*8))-1);
205
248
    max_key_file_length=
206
249
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
207
 
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
 
250
                  ((ulonglong) 1 << (share->base.key_reflength*8))-1);
208
251
#if SIZEOF_OFF_T == 4
209
252
    set_if_smaller(max_data_file_length, INT_MAX32);
210
253
    set_if_smaller(max_key_file_length, INT_MAX32);
211
254
#endif
212
255
    if (share->base.raid_type)
213
256
    {
 
257
      DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
214
258
      my_errno=HA_ERR_UNSUPPORTED;
215
259
      goto err;
216
260
    }
242
286
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
243
287
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
244
288
                         &share->mmap_lock,sizeof(rw_lock_t),
245
 
                         NULL))
 
289
                         NullS))
246
290
      goto err;
247
291
    errpos=4;
248
292
    *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);
 
293
    memcpy((char*) share->state.rec_per_key_part,
 
294
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
295
    memcpy((char*) share->state.key_root,
 
296
           (char*) key_root, sizeof(my_off_t)*keys);
 
297
    memcpy((char*) share->state.key_del,
 
298
           (char*) key_del, (sizeof(my_off_t) *
 
299
                             share->state.header.max_block_size_index));
 
300
    strmov(share->unique_file_name, name_buff);
256
301
    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);
 
302
    strmov(share->index_file_name,  index_name);
 
303
    strmov(share->data_file_name,   data_name);
259
304
 
260
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
305
    share->blocksize=min(IO_SIZE,myisam_block_size);
261
306
    {
262
307
      HA_KEYSEG *pos=share->keyparts;
263
308
      for (i=0 ; i < keys ; i++)
358
403
 
359
404
    if (! lock_error)
360
405
    {
 
406
      VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
361
407
      lock_error=1;                     /* Database unlocked */
362
408
    }
363
409
 
376
422
    share->base.margin_key_file_length=(share->base.max_key_file_length -
377
423
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
378
424
                                         share->blocksize * keys : 0));
379
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
425
    share->blocksize=min(IO_SIZE,myisam_block_size);
380
426
    share->data_file_type=STATIC_RECORD;
381
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
427
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
428
    {
 
429
      share->data_file_type = COMPRESSED_RECORD;
 
430
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
431
      info.s=share;
 
432
      if (_mi_read_pack_info(&info,
 
433
                             (pbool)
 
434
                             test(!(share->options &
 
435
                                    (HA_OPTION_PACK_RECORD |
 
436
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
437
        goto err;
 
438
    }
 
439
    else if (share->options & HA_OPTION_PACK_RECORD)
382
440
      share->data_file_type = DYNAMIC_RECORD;
383
 
    free(disk_cache);
384
 
    disk_cache= NULL;
 
441
    my_afree(disk_cache);
385
442
    mi_setup_functions(share);
386
 
    share->is_log_table= false;
 
443
    share->is_log_table= FALSE;
387
444
    thr_lock_init(&share->lock);
388
 
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
 
445
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
389
446
    for (i=0; i<keys; i++)
390
 
      my_rwlock_init(&share->key_root_lock[i], NULL);
391
 
    my_rwlock_init(&share->mmap_lock, NULL);
 
447
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
448
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
392
449
    if (!thr_lock_inited)
393
450
    {
394
451
      /* Probably a single threaded program; Don't use concurrent inserts */
403
460
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
404
461
      if (share->concurrent_insert)
405
462
      {
406
 
        share->lock.get_status= mi_get_status;
407
 
        share->lock.copy_status= mi_copy_status;
408
 
        share->lock.update_status= mi_update_status;
 
463
        share->lock.get_status=mi_get_status;
 
464
        share->lock.copy_status=mi_copy_status;
 
465
        share->lock.update_status=mi_update_status;
409
466
        share->lock.restore_status= mi_restore_status;
410
 
        share->lock.check_status= mi_check_status;
 
467
        share->lock.check_status=mi_check_status;
411
468
      }
412
469
    }
413
470
    /*
443
500
                       &info.first_mbr_key, share->base.max_key_length,
444
501
                       &info.filename,strlen(name)+1,
445
502
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
446
 
                       NULL))
 
503
                       NullS))
447
504
    goto err;
448
505
  errpos=6;
449
506
 
450
507
  if (!have_rtree)
451
508
    info.rtree_recursion_state= NULL;
452
509
 
453
 
  my_stpcpy(info.filename,name);
 
510
  strmov(info.filename,name);
454
511
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
455
512
  info.lastkey2=info.lastkey+share->base.max_key_length;
456
513
 
499
556
 
500
557
  /* Allocate buffer for one record */
501
558
 
502
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
 
559
  /* prerequisites: bzero(info) && info->s=share; are met. */
503
560
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
504
561
    goto err;
505
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
562
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
506
563
 
507
564
  *m_info=info;
508
565
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
510
567
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
511
568
 
512
569
  pthread_mutex_unlock(&THR_LOCK_myisam);
513
 
  return(m_info);
 
570
  if (myisam_log_file >= 0)
 
571
  {
 
572
    intern_filename(name_buff,share->index_file_name);
 
573
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
574
  }
 
575
  DBUG_RETURN(m_info);
514
576
 
515
577
err:
516
 
  if (disk_cache != NULL)
517
 
    free(disk_cache);
518
578
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
519
579
  if ((save_errno == HA_ERR_CRASHED) ||
520
580
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
522
582
    mi_report_error(save_errno, name);
523
583
  switch (errpos) {
524
584
  case 6:
525
 
    free((unsigned char*) m_info);
 
585
    my_free((uchar*) m_info,MYF(0));
526
586
    /* fall through */
527
587
  case 5:
528
 
    my_close(info.dfile,MYF(0));
 
588
    VOID(my_close(info.dfile,MYF(0)));
529
589
    if (old_info)
530
590
      break;                                    /* Don't remove open table */
531
591
    /* fall through */
532
592
  case 4:
533
 
    free((unsigned char*) share);
 
593
    my_free((uchar*) share,MYF(0));
534
594
    /* fall through */
535
595
  case 3:
 
596
    if (! lock_error)
 
597
      VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
 
598
    /* fall through */
 
599
  case 2:
 
600
    my_afree(disk_cache);
536
601
    /* fall through */
537
602
  case 1:
538
 
    my_close(kfile,MYF(0));
 
603
    VOID(my_close(kfile,MYF(0)));
539
604
    /* fall through */
540
605
  case 0:
541
606
  default:
543
608
  }
544
609
  pthread_mutex_unlock(&THR_LOCK_myisam);
545
610
  my_errno=save_errno;
546
 
  return (NULL);
 
611
  DBUG_RETURN (NULL);
547
612
} /* mi_open */
548
613
 
549
614
 
550
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, ulong length, unsigned char **buf)
 
615
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
551
616
{
552
 
  uint32_t extra;
553
 
  uint32_t old_length= 0;
 
617
  uint extra;
 
618
  uint32 old_length= 0;
554
619
 
555
620
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
556
621
  {
557
 
    unsigned char *newptr = *buf;
 
622
    uchar *newptr = *buf;
558
623
 
559
624
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
560
625
    if (length == (ulong) -1)
561
626
    {
562
627
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
563
 
        length= cmax(info->s->base.pack_reclength, info->s->max_pack_length);
 
628
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
564
629
      else
565
630
        length= info->s->base.pack_reclength;
566
 
      length= cmax(length, info->s->base.max_key_length);
 
631
      length= max(length, info->s->base.max_key_length);
567
632
      /* Avoid unnecessary realloc */
568
633
      if (newptr && length == old_length)
569
634
        return newptr;
574
639
            MI_REC_BUFF_OFFSET : 0);
575
640
    if (extra && newptr)
576
641
      newptr-= MI_REC_BUFF_OFFSET;
577
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*)newptr, length+extra+8,
 
642
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
578
643
                                     MYF(MY_ALLOW_ZERO_PTR))))
579
644
      return newptr;
580
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
645
    *((uint32 *) newptr)= (uint32) length;
581
646
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
582
647
  }
583
648
  return *buf;
584
649
}
585
650
 
586
651
 
587
 
uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
652
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
588
653
{
589
 
  uint64_t max_val= ~ (uint64_t) 0;             /* my_off_t is unsigned */
 
654
  ulonglong max_val= ~ (ulonglong) 0;           /* my_off_t is unsigned */
590
655
 
591
656
  if (!a || max_val / a < b)
592
657
    return max_val;
597
662
 
598
663
void mi_setup_functions(register MYISAM_SHARE *share)
599
664
{
600
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
665
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
666
  {
 
667
    share->read_record=_mi_read_pack_record;
 
668
    share->read_rnd=_mi_read_rnd_pack_record;
 
669
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
670
      share->calc_checksum=0;                           /* No checksum */
 
671
    else if (share->options & HA_OPTION_PACK_RECORD)
 
672
      share->calc_checksum= mi_checksum;
 
673
    else
 
674
      share->calc_checksum= mi_static_checksum;
 
675
  }
 
676
  else if (share->options & HA_OPTION_PACK_RECORD)
601
677
  {
602
678
    share->read_record=_mi_read_dynamic_record;
603
679
    share->read_rnd=_mi_read_rnd_dynamic_record;
695
771
   Function to save and store the header in the index file (.MYI)
696
772
*/
697
773
 
698
 
uint32_t mi_state_info_write(File file, MI_STATE_INFO *state, uint32_t pWrite)
 
774
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
699
775
{
700
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
701
 
  unsigned char *ptr=buff;
 
776
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
777
  uchar *ptr=buff;
702
778
  uint  i, keys= (uint) state->header.keys,
703
779
        key_blocks=state->header.max_block_size_index;
 
780
  DBUG_ENTER("mi_state_info_write");
704
781
 
705
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
782
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
706
783
  ptr+=sizeof(state->header);
707
784
 
708
785
  /* open_count must be first because of _mi_mark_file_changed ! */
709
786
  mi_int2store(ptr,state->open_count);          ptr +=2;
710
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
787
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
711
788
  mi_rowstore(ptr,state->state.records);        ptr +=8;
712
789
  mi_rowstore(ptr,state->state.del);            ptr +=8;
713
790
  mi_rowstore(ptr,state->split);                ptr +=8;
717
794
  mi_sizestore(ptr,state->state.empty);         ptr +=8;
718
795
  mi_sizestore(ptr,state->state.key_empty);     ptr +=8;
719
796
  mi_int8store(ptr,state->auto_increment);      ptr +=8;
720
 
  mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
 
797
  mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
721
798
  mi_int4store(ptr,state->process);             ptr +=4;
722
799
  mi_int4store(ptr,state->unique);              ptr +=4;
723
800
  mi_int4store(ptr,state->status);              ptr +=4;
735
812
  }
736
813
  if (pWrite & 2)                               /* From isamchk */
737
814
  {
738
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
815
    uint key_parts= mi_uint2korr(state->header.key_parts);
739
816
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
740
817
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
741
818
    mi_int4store(ptr,state->version);           ptr +=4;
742
819
    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;
 
820
    mi_int8store(ptr,(ulonglong) state->create_time);   ptr +=8;
 
821
    mi_int8store(ptr,(ulonglong) state->recover_time);  ptr +=8;
 
822
    mi_int8store(ptr,(ulonglong) state->check_time);    ptr +=8;
746
823
    mi_sizestore(ptr,state->rec_per_key_rows);  ptr+=8;
747
824
    for (i=0 ; i < key_parts ; i++)
748
825
    {
751
828
  }
752
829
 
753
830
  if (pWrite & 1)
754
 
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
 
831
    DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
755
832
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
756
 
  return(my_write(file, buff, (size_t) (ptr-buff),
 
833
  DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
757
834
                       MYF(MY_NABP)) != 0);
758
835
}
759
836
 
760
837
 
761
 
unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
838
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
762
839
{
763
 
  uint32_t i,keys,key_parts,key_blocks;
764
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
840
  uint i,keys,key_parts,key_blocks;
 
841
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
765
842
  ptr +=sizeof(state->header);
766
843
  keys=(uint) state->header.keys;
767
844
  key_parts=mi_uint2korr(state->header.key_parts);
811
888
}
812
889
 
813
890
 
814
 
uint32_t mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
 
891
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
815
892
{
816
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
893
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
817
894
 
818
895
  if (!myisam_single_user)
819
896
  {
834
911
**  store and read of MI_BASE_INFO
835
912
****************************************************************************/
836
913
 
837
 
uint32_t mi_base_info_write(File file, MI_BASE_INFO *base)
 
914
uint mi_base_info_write(File file, MI_BASE_INFO *base)
838
915
{
839
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
916
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
840
917
 
841
918
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
842
919
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
861
938
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
862
939
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
863
940
  *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 */
 
941
  *ptr++= base->raid_type;
 
942
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
943
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
944
  bzero(ptr,6);                                         ptr +=6; /* extra */
870
945
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
871
946
}
872
947
 
873
948
 
874
 
unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
949
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
875
950
{
876
951
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
877
952
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
897
972
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
898
973
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
899
974
  base->extra_alloc_procent = *ptr++;
900
 
 
901
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
902
 
  ptr+= 7; 
 
975
  base->raid_type= *ptr++;
 
976
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
977
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
978
  /* TO BE REMOVED: Fix for old RAID files */
 
979
  if (base->raid_type == 0)
 
980
  {
 
981
    base->raid_chunks=0;
 
982
    base->raid_chunksize=0;
 
983
  }
903
984
 
904
985
  ptr+=6;
905
986
  return ptr;
909
990
  mi_keydef
910
991
---------------------------------------------------------------------------*/
911
992
 
912
 
uint32_t mi_keydef_write(File file, MI_KEYDEF *keydef)
 
993
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
913
994
{
914
 
  unsigned char buff[MI_KEYDEF_SIZE];
915
 
  unsigned char *ptr=buff;
 
995
  uchar buff[MI_KEYDEF_SIZE];
 
996
  uchar *ptr=buff;
916
997
 
917
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
998
  *ptr++ = (uchar) keydef->keysegs;
918
999
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
919
1000
  mi_int2store(ptr,keydef->flag);               ptr +=2;
920
1001
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
924
1005
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
925
1006
}
926
1007
 
927
 
unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
1008
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
928
1009
{
929
1010
   keydef->keysegs      = (uint) *ptr++;
930
1011
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
946
1027
 
947
1028
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
948
1029
{
949
 
  unsigned char buff[HA_KEYSEG_SIZE];
950
 
  unsigned char *ptr=buff;
 
1030
  uchar buff[HA_KEYSEG_SIZE];
 
1031
  uchar *ptr=buff;
951
1032
  ulong pos;
952
1033
 
953
1034
  *ptr++= keyseg->type;
967
1048
}
968
1049
 
969
1050
 
970
 
unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
1051
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
971
1052
{
972
1053
   keyseg->type         = *ptr++;
973
1054
   keyseg->language     = *ptr++;
981
1062
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
982
1063
   keyseg->charset=0;                           /* Will be filled in later */
983
1064
   if (keyseg->null_bit)
984
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1065
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
985
1066
   else
986
1067
   {
987
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1068
     keyseg->bit_pos= (uint16)keyseg->null_pos;
988
1069
     keyseg->null_pos= 0;
989
1070
   }
990
1071
   return ptr;
994
1075
  mi_uniquedef
995
1076
---------------------------------------------------------------------------*/
996
1077
 
997
 
uint32_t mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
 
1078
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
998
1079
{
999
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
1000
 
  unsigned char *ptr=buff;
 
1080
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1081
  uchar *ptr=buff;
1001
1082
 
1002
1083
  mi_int2store(ptr,def->keysegs);               ptr+=2;
1003
 
  *ptr++=  (unsigned char) def->key;
1004
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1084
  *ptr++=  (uchar) def->key;
 
1085
  *ptr++ = (uchar) def->null_are_equal;
1005
1086
 
1006
1087
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1007
1088
}
1008
1089
 
1009
 
unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1090
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1010
1091
{
1011
1092
   def->keysegs = mi_uint2korr(ptr);
1012
1093
   def->key     = ptr[2];
1018
1099
**  MI_COLUMNDEF
1019
1100
***************************************************************************/
1020
1101
 
1021
 
uint32_t mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
 
1102
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1022
1103
{
1023
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1024
 
  unsigned char *ptr=buff;
 
1104
  uchar buff[MI_COLUMNDEF_SIZE];
 
1105
  uchar *ptr=buff;
1025
1106
 
1026
1107
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1027
1108
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1030
1111
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1031
1112
}
1032
1113
 
1033
 
unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1114
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1034
1115
{
1035
1116
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1036
1117
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1037
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1118
   recinfo->null_bit= (uint8) *ptr++;
1038
1119
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1039
1120
   return ptr;
1040
1121
}
1041
1122
 
1042
1123
/**************************************************************************
1043
 
Open data file
 
1124
Open data file with or without RAID
1044
1125
We can't use dup() here as the data file descriptors need to have different
1045
1126
active seek-positions.
1046
1127
 
1051
1132
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1052
1133
                     File file_to_dup __attribute__((unused)))
1053
1134
{
1054
 
    info->dfile=my_open(share->data_file_name, share->mode,
 
1135
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1055
1136
                        MYF(MY_WME));
1056
1137
  return info->dfile >= 0 ? 0 : 1;
1057
1138
}
1059
1140
 
1060
1141
int mi_open_keyfile(MYISAM_SHARE *share)
1061
1142
{
1062
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
 
1143
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1063
1144
                            MYF(MY_WME))) < 0)
1064
1145
    return 1;
1065
1146
  return 0;