~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

Merged.

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>
21
20
 
22
21
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)
 
22
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
 
23
                                        pos+=size;}
28
24
 
29
25
 
30
26
#define disk_pos_assert(pos, end_pos) \
63
59
  have an open count of 0.
64
60
******************************************************************************/
65
61
 
66
 
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
 
62
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
67
63
{
68
64
  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,
 
65
  uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
70
66
    key_parts,unique_key_parts,fulltext_keys,uniques;
71
67
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
72
68
       data_name[FN_REFLEN];
73
 
  unsigned char *disk_cache= NULL;
74
 
  unsigned char *disk_pos, *end_pos;
 
69
  uchar *disk_cache, *disk_pos, *end_pos;
75
70
  MI_INFO info,*m_info,*old_info;
76
71
  MYISAM_SHARE share_buff,*share;
77
72
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
78
73
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
79
74
  uint64_t max_key_file_length, max_data_file_length;
 
75
  DBUG_ENTER("mi_open");
80
76
 
81
77
  kfile= -1;
82
78
  lock_error=1;
83
79
  errpos=0;
84
80
  head_length=sizeof(share_buff.state.header);
85
 
  memset(&info, 0, sizeof(info));
 
81
  bzero((uchar*) &info,sizeof(info));
86
82
 
87
83
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
88
84
                                   MY_UNPACK_FILENAME),MYF(0));
90
86
  if (!(old_info=test_if_reopen(name_buff)))
91
87
  {
92
88
    share= &share_buff;
93
 
    memset(&share_buff, 0, sizeof(share_buff));
 
89
    bzero((uchar*) &share_buff,sizeof(share_buff));
94
90
    share_buff.state.rec_per_key_part=rec_per_key_part;
95
91
    share_buff.state.key_root=key_root;
96
92
    share_buff.state.key_del=key_del;
97
 
    share_buff.key_cache= multi_key_cache_search((unsigned char*) name_buff,
 
93
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
98
94
                                                 strlen(name_buff));
99
95
 
100
 
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
 
96
    DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
 
97
                    if (strstr(name, "/t1"))
 
98
                    {
 
99
                      my_errno= HA_ERR_CRASHED;
 
100
                      goto err;
 
101
                    });
 
102
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
101
103
    {
102
104
      if ((errno != EROFS && errno != EACCES) ||
103
105
          mode != O_RDONLY ||
104
 
          (kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
 
106
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
105
107
        goto err;
106
108
    }
107
109
    share->mode=open_mode;
112
114
      my_errno= HA_ERR_NOT_A_TABLE;
113
115
      goto err;
114
116
    }
115
 
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
 
117
    if (memcmp((uchar*) share->state.header.file_version,
 
118
               (uchar*) myisam_file_magic, 4))
116
119
    {
 
120
      DBUG_PRINT("error",("Wrong header in %s",name_buff));
 
121
      DBUG_DUMP("error_dump",(uchar*) share->state.header.file_version,
 
122
                head_length);
117
123
      my_errno=HA_ERR_NOT_A_TABLE;
118
124
      goto err;
119
125
    }
125
131
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
126
132
          HA_OPTION_RELIES_ON_SQL_LAYER))
127
133
    {
 
134
      DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
128
135
      my_errno=HA_ERR_OLD_FILE;
129
136
      goto err;
130
137
    }
131
138
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
132
139
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
133
140
    {
 
141
      DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
134
142
      my_errno= HA_ERR_UNSUPPORTED;
135
143
      goto err;
136
144
    }
137
145
    /* Don't call realpath() if the name can't be a link */
138
146
    if (!strcmp(name_buff, org_name) ||
139
147
        my_readlink(index_name, org_name, MYF(0)) == -1)
140
 
      (void) my_stpcpy(index_name, org_name);
 
148
      (void) strmov(index_name, org_name);
141
149
    *strrchr(org_name, '.')= '\0';
142
150
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
143
151
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
144
152
 
145
153
    info_length=mi_uint2korr(share->state.header.header_length);
146
154
    base_pos=mi_uint2korr(share->state.header.base_pos);
147
 
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
 
155
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
148
156
    {
149
157
      my_errno=ENOMEM;
150
158
      goto err;
152
160
    end_pos=disk_cache+info_length;
153
161
    errpos=2;
154
162
 
155
 
    my_seek(kfile,0L,MY_SEEK_SET,MYF(0));
 
163
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
156
164
    errpos=3;
157
165
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
158
166
    {
165
173
    fulltext_keys= (uint) share->state.header.fulltext_keys;
166
174
    key_parts= mi_uint2korr(share->state.header.key_parts);
167
175
    unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
 
176
    if (len != MI_STATE_INFO_SIZE)
 
177
    {
 
178
      DBUG_PRINT("warning",
 
179
                 ("saved_state_info_length: %d  state_info_length: %d",
 
180
                  len,MI_STATE_INFO_SIZE));
 
181
    }
168
182
    share->state_diff_length=len-MI_STATE_INFO_SIZE;
169
183
 
170
184
    mi_state_info_read(disk_cache, &share->state);
171
185
    len= mi_uint2korr(share->state.header.base_info_length);
 
186
    if (len != MI_BASE_INFO_SIZE)
 
187
    {
 
188
      DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
 
189
                            len,MI_BASE_INFO_SIZE));
 
190
    }
172
191
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
173
192
    share->state.state_length=base_pos;
174
193
 
177
196
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
178
197
          (share->state.open_count))))
179
198
    {
 
199
      DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u  "
 
200
                          "changed: %u  open_count: %u",
 
201
                          open_flags, share->state.changed,
 
202
                          share->state.open_count));
180
203
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
181
204
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
182
205
      goto err;
192
215
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
193
216
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
194
217
    {
 
218
      DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
195
219
      my_errno=HA_ERR_UNSUPPORTED;
196
220
      goto err;
197
221
    }
211
235
#endif
212
236
    if (share->base.raid_type)
213
237
    {
 
238
      DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
214
239
      my_errno=HA_ERR_UNSUPPORTED;
215
240
      goto err;
216
241
    }
242
267
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
243
268
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
244
269
                         &share->mmap_lock,sizeof(rw_lock_t),
245
 
                         NULL))
 
270
                         NullS))
246
271
      goto err;
247
272
    errpos=4;
248
273
    *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);
 
274
    memcpy((char*) share->state.rec_per_key_part,
 
275
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
276
    memcpy((char*) share->state.key_root,
 
277
           (char*) key_root, sizeof(my_off_t)*keys);
 
278
    memcpy((char*) share->state.key_del,
 
279
           (char*) key_del, (sizeof(my_off_t) *
 
280
                             share->state.header.max_block_size_index));
 
281
    strmov(share->unique_file_name, name_buff);
256
282
    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);
 
283
    strmov(share->index_file_name,  index_name);
 
284
    strmov(share->data_file_name,   data_name);
259
285
 
260
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
286
    share->blocksize=min(IO_SIZE,myisam_block_size);
261
287
    {
262
288
      HA_KEYSEG *pos=share->keyparts;
263
289
      for (i=0 ; i < keys ; i++)
376
402
    share->base.margin_key_file_length=(share->base.max_key_file_length -
377
403
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
378
404
                                         share->blocksize * keys : 0));
379
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
405
    share->blocksize=min(IO_SIZE,myisam_block_size);
380
406
    share->data_file_type=STATIC_RECORD;
381
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
407
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
408
    {
 
409
      share->data_file_type = COMPRESSED_RECORD;
 
410
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
411
      info.s=share;
 
412
      if (_mi_read_pack_info(&info,
 
413
                             (bool)
 
414
                             test(!(share->options &
 
415
                                    (HA_OPTION_PACK_RECORD |
 
416
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
417
        goto err;
 
418
    }
 
419
    else if (share->options & HA_OPTION_PACK_RECORD)
382
420
      share->data_file_type = DYNAMIC_RECORD;
383
 
    free(disk_cache);
384
 
    disk_cache= NULL;
 
421
    my_afree(disk_cache);
385
422
    mi_setup_functions(share);
386
423
    share->is_log_table= false;
387
424
    thr_lock_init(&share->lock);
388
 
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
 
425
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
389
426
    for (i=0; i<keys; i++)
390
 
      my_rwlock_init(&share->key_root_lock[i], NULL);
391
 
    my_rwlock_init(&share->mmap_lock, NULL);
 
427
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
428
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
392
429
    if (!thr_lock_inited)
393
430
    {
394
431
      /* Probably a single threaded program; Don't use concurrent inserts */
443
480
                       &info.first_mbr_key, share->base.max_key_length,
444
481
                       &info.filename,strlen(name)+1,
445
482
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
446
 
                       NULL))
 
483
                       NullS))
447
484
    goto err;
448
485
  errpos=6;
449
486
 
450
487
  if (!have_rtree)
451
488
    info.rtree_recursion_state= NULL;
452
489
 
453
 
  my_stpcpy(info.filename,name);
 
490
  strmov(info.filename,name);
454
491
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
455
492
  info.lastkey2=info.lastkey+share->base.max_key_length;
456
493
 
499
536
 
500
537
  /* Allocate buffer for one record */
501
538
 
502
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
 
539
  /* prerequisites: bzero(info) && info->s=share; are met. */
503
540
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
504
541
    goto err;
505
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
542
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
506
543
 
507
544
  *m_info=info;
508
545
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
510
547
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
511
548
 
512
549
  pthread_mutex_unlock(&THR_LOCK_myisam);
513
 
  return(m_info);
 
550
  if (myisam_log_file >= 0)
 
551
  {
 
552
    intern_filename(name_buff,share->index_file_name);
 
553
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
554
  }
 
555
  DBUG_RETURN(m_info);
514
556
 
515
557
err:
516
 
  if (disk_cache != NULL)
517
 
    free(disk_cache);
518
558
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
519
559
  if ((save_errno == HA_ERR_CRASHED) ||
520
560
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
522
562
    mi_report_error(save_errno, name);
523
563
  switch (errpos) {
524
564
  case 6:
525
 
    free((unsigned char*) m_info);
 
565
    my_free((uchar*) m_info,MYF(0));
526
566
    /* fall through */
527
567
  case 5:
528
 
    my_close(info.dfile,MYF(0));
 
568
    VOID(my_close(info.dfile,MYF(0)));
529
569
    if (old_info)
530
570
      break;                                    /* Don't remove open table */
531
571
    /* fall through */
532
572
  case 4:
533
 
    free((unsigned char*) share);
 
573
    my_free((uchar*) share,MYF(0));
534
574
    /* fall through */
535
575
  case 3:
536
576
    /* fall through */
 
577
  case 2:
 
578
    my_afree(disk_cache);
 
579
    /* fall through */
537
580
  case 1:
538
 
    my_close(kfile,MYF(0));
 
581
    VOID(my_close(kfile,MYF(0)));
539
582
    /* fall through */
540
583
  case 0:
541
584
  default:
543
586
  }
544
587
  pthread_mutex_unlock(&THR_LOCK_myisam);
545
588
  my_errno=save_errno;
546
 
  return (NULL);
 
589
  DBUG_RETURN (NULL);
547
590
} /* mi_open */
548
591
 
549
592
 
550
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, ulong length, unsigned char **buf)
 
593
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
551
594
{
552
 
  uint32_t extra;
553
 
  uint32_t old_length= 0;
 
595
  uint extra;
 
596
  uint32 old_length= 0;
554
597
 
555
598
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
556
599
  {
557
 
    unsigned char *newptr = *buf;
 
600
    uchar *newptr = *buf;
558
601
 
559
602
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
560
603
    if (length == (ulong) -1)
561
604
    {
562
605
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
563
 
        length= cmax(info->s->base.pack_reclength, info->s->max_pack_length);
 
606
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
564
607
      else
565
608
        length= info->s->base.pack_reclength;
566
 
      length= cmax(length, info->s->base.max_key_length);
 
609
      length= max(length, info->s->base.max_key_length);
567
610
      /* Avoid unnecessary realloc */
568
611
      if (newptr && length == old_length)
569
612
        return newptr;
574
617
            MI_REC_BUFF_OFFSET : 0);
575
618
    if (extra && newptr)
576
619
      newptr-= MI_REC_BUFF_OFFSET;
577
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*)newptr, length+extra+8,
 
620
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
578
621
                                     MYF(MY_ALLOW_ZERO_PTR))))
579
622
      return newptr;
580
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
623
    *((uint32 *) newptr)= (uint32) length;
581
624
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
582
625
  }
583
626
  return *buf;
597
640
 
598
641
void mi_setup_functions(register MYISAM_SHARE *share)
599
642
{
600
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
643
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
644
  {
 
645
    share->read_record=_mi_read_pack_record;
 
646
    share->read_rnd=_mi_read_rnd_pack_record;
 
647
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
648
      share->calc_checksum=0;                           /* No checksum */
 
649
    else if (share->options & HA_OPTION_PACK_RECORD)
 
650
      share->calc_checksum= mi_checksum;
 
651
    else
 
652
      share->calc_checksum= mi_static_checksum;
 
653
  }
 
654
  else if (share->options & HA_OPTION_PACK_RECORD)
601
655
  {
602
656
    share->read_record=_mi_read_dynamic_record;
603
657
    share->read_rnd=_mi_read_rnd_dynamic_record;
695
749
   Function to save and store the header in the index file (.MYI)
696
750
*/
697
751
 
698
 
uint32_t mi_state_info_write(File file, MI_STATE_INFO *state, uint32_t pWrite)
 
752
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
699
753
{
700
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
701
 
  unsigned char *ptr=buff;
 
754
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
755
  uchar *ptr=buff;
702
756
  uint  i, keys= (uint) state->header.keys,
703
757
        key_blocks=state->header.max_block_size_index;
 
758
  DBUG_ENTER("mi_state_info_write");
704
759
 
705
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
760
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
706
761
  ptr+=sizeof(state->header);
707
762
 
708
763
  /* open_count must be first because of _mi_mark_file_changed ! */
709
764
  mi_int2store(ptr,state->open_count);          ptr +=2;
710
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
765
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
711
766
  mi_rowstore(ptr,state->state.records);        ptr +=8;
712
767
  mi_rowstore(ptr,state->state.del);            ptr +=8;
713
768
  mi_rowstore(ptr,state->split);                ptr +=8;
735
790
  }
736
791
  if (pWrite & 2)                               /* From isamchk */
737
792
  {
738
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
793
    uint key_parts= mi_uint2korr(state->header.key_parts);
739
794
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
740
795
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
741
796
    mi_int4store(ptr,state->version);           ptr +=4;
751
806
  }
752
807
 
753
808
  if (pWrite & 1)
754
 
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
 
809
    DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
755
810
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
756
 
  return(my_write(file, buff, (size_t) (ptr-buff),
 
811
  DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
757
812
                       MYF(MY_NABP)) != 0);
758
813
}
759
814
 
760
815
 
761
 
unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
816
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
762
817
{
763
 
  uint32_t i,keys,key_parts,key_blocks;
764
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
818
  uint i,keys,key_parts,key_blocks;
 
819
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
765
820
  ptr +=sizeof(state->header);
766
821
  keys=(uint) state->header.keys;
767
822
  key_parts=mi_uint2korr(state->header.key_parts);
811
866
}
812
867
 
813
868
 
814
 
uint32_t mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
 
869
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
815
870
{
816
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
871
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
817
872
 
818
873
  if (!myisam_single_user)
819
874
  {
834
889
**  store and read of MI_BASE_INFO
835
890
****************************************************************************/
836
891
 
837
 
uint32_t mi_base_info_write(File file, MI_BASE_INFO *base)
 
892
uint mi_base_info_write(File file, MI_BASE_INFO *base)
838
893
{
839
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
894
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
840
895
 
841
896
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
842
897
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
861
916
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
862
917
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
863
918
  *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 */
 
919
  *ptr++= base->raid_type;
 
920
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
921
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
922
  bzero(ptr,6);                                         ptr +=6; /* extra */
870
923
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
871
924
}
872
925
 
873
926
 
874
 
unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
927
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
875
928
{
876
929
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
877
930
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
897
950
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
898
951
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
899
952
  base->extra_alloc_procent = *ptr++;
900
 
 
901
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
902
 
  ptr+= 7; 
 
953
  base->raid_type= *ptr++;
 
954
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
955
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
956
  /* TO BE REMOVED: Fix for old RAID files */
 
957
  if (base->raid_type == 0)
 
958
  {
 
959
    base->raid_chunks=0;
 
960
    base->raid_chunksize=0;
 
961
  }
903
962
 
904
963
  ptr+=6;
905
964
  return ptr;
909
968
  mi_keydef
910
969
---------------------------------------------------------------------------*/
911
970
 
912
 
uint32_t mi_keydef_write(File file, MI_KEYDEF *keydef)
 
971
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
913
972
{
914
 
  unsigned char buff[MI_KEYDEF_SIZE];
915
 
  unsigned char *ptr=buff;
 
973
  uchar buff[MI_KEYDEF_SIZE];
 
974
  uchar *ptr=buff;
916
975
 
917
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
976
  *ptr++ = (uchar) keydef->keysegs;
918
977
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
919
978
  mi_int2store(ptr,keydef->flag);               ptr +=2;
920
979
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
924
983
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
925
984
}
926
985
 
927
 
unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
986
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
928
987
{
929
988
   keydef->keysegs      = (uint) *ptr++;
930
989
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
946
1005
 
947
1006
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
948
1007
{
949
 
  unsigned char buff[HA_KEYSEG_SIZE];
950
 
  unsigned char *ptr=buff;
 
1008
  uchar buff[HA_KEYSEG_SIZE];
 
1009
  uchar *ptr=buff;
951
1010
  ulong pos;
952
1011
 
953
1012
  *ptr++= keyseg->type;
967
1026
}
968
1027
 
969
1028
 
970
 
unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
1029
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
971
1030
{
972
1031
   keyseg->type         = *ptr++;
973
1032
   keyseg->language     = *ptr++;
981
1040
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
982
1041
   keyseg->charset=0;                           /* Will be filled in later */
983
1042
   if (keyseg->null_bit)
984
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1043
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
985
1044
   else
986
1045
   {
987
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1046
     keyseg->bit_pos= (uint16)keyseg->null_pos;
988
1047
     keyseg->null_pos= 0;
989
1048
   }
990
1049
   return ptr;
994
1053
  mi_uniquedef
995
1054
---------------------------------------------------------------------------*/
996
1055
 
997
 
uint32_t mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
 
1056
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
998
1057
{
999
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
1000
 
  unsigned char *ptr=buff;
 
1058
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1059
  uchar *ptr=buff;
1001
1060
 
1002
1061
  mi_int2store(ptr,def->keysegs);               ptr+=2;
1003
 
  *ptr++=  (unsigned char) def->key;
1004
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1062
  *ptr++=  (uchar) def->key;
 
1063
  *ptr++ = (uchar) def->null_are_equal;
1005
1064
 
1006
1065
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1007
1066
}
1008
1067
 
1009
 
unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1068
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1010
1069
{
1011
1070
   def->keysegs = mi_uint2korr(ptr);
1012
1071
   def->key     = ptr[2];
1018
1077
**  MI_COLUMNDEF
1019
1078
***************************************************************************/
1020
1079
 
1021
 
uint32_t mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
 
1080
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1022
1081
{
1023
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1024
 
  unsigned char *ptr=buff;
 
1082
  uchar buff[MI_COLUMNDEF_SIZE];
 
1083
  uchar *ptr=buff;
1025
1084
 
1026
1085
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1027
1086
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1030
1089
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1031
1090
}
1032
1091
 
1033
 
unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1092
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1034
1093
{
1035
1094
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1036
1095
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1037
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1096
   recinfo->null_bit= (uint8) *ptr++;
1038
1097
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1039
1098
   return ptr;
1040
1099
}
1041
1100
 
1042
1101
/**************************************************************************
1043
 
Open data file
 
1102
Open data file with or without RAID
1044
1103
We can't use dup() here as the data file descriptors need to have different
1045
1104
active seek-positions.
1046
1105
 
1051
1110
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1052
1111
                     File file_to_dup __attribute__((unused)))
1053
1112
{
1054
 
    info->dfile=my_open(share->data_file_name, share->mode,
 
1113
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1055
1114
                        MYF(MY_WME));
1056
1115
  return info->dfile >= 0 ? 0 : 1;
1057
1116
}
1059
1118
 
1060
1119
int mi_open_keyfile(MYISAM_SHARE *share)
1061
1120
{
1062
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
 
1121
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1063
1122
                            MYF(MY_WME))) < 0)
1064
1123
    return 1;
1065
1124
  return 0;