~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

  • Committer: Brian Aker
  • Date: 2008-11-04 15:39:09 UTC
  • mfrom: (575.1.2 devel)
  • Revision ID: brian@tangent.org-20081104153909-c72hn65udxs1ccal
Merge of Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
#include "myisamdef.h"
19
19
#include <mystrings/m_ctype.h>
 
20
#include <drizzled/util/test.h>
20
21
 
21
22
static void setup_key_functions(MI_KEYDEF *keyinfo);
22
 
#define get_next_element(to,pos,size) \
23
 
  do {                                \
24
 
    memcpy(to, pos, size);            \
25
 
    pos+=size;                        \
26
 
  } while (0)
27
 
 
28
23
 
29
24
#define disk_pos_assert(pos, end_pos) \
30
25
if (pos > end_pos)             \
62
57
  have an open count of 0.
63
58
******************************************************************************/
64
59
 
65
 
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
 
60
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
66
61
{
67
62
  int lock_error,kfile,open_mode,save_errno,have_rtree=0;
68
 
  uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
 
63
  uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
69
64
    key_parts,unique_key_parts,fulltext_keys,uniques;
70
65
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
71
66
       data_name[FN_REFLEN];
72
 
  uchar *disk_cache, *disk_pos, *end_pos;
 
67
  unsigned char *disk_cache= NULL;
 
68
  unsigned char *disk_pos, *end_pos;
73
69
  MI_INFO info,*m_info,*old_info;
74
70
  MYISAM_SHARE share_buff,*share;
75
71
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
92
88
    share_buff.state.rec_per_key_part=rec_per_key_part;
93
89
    share_buff.state.key_root=key_root;
94
90
    share_buff.state.key_del=key_del;
95
 
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
 
91
    share_buff.key_cache= multi_key_cache_search((unsigned char*) name_buff,
96
92
                                                 strlen(name_buff));
97
93
 
98
 
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
 
94
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
99
95
    {
100
96
      if ((errno != EROFS && errno != EACCES) ||
101
97
          mode != O_RDONLY ||
102
 
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
 
98
          (kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
103
99
        goto err;
104
100
    }
105
101
    share->mode=open_mode;
135
131
    /* Don't call realpath() if the name can't be a link */
136
132
    if (!strcmp(name_buff, org_name) ||
137
133
        my_readlink(index_name, org_name, MYF(0)) == -1)
138
 
      (void) stpcpy(index_name, org_name);
 
134
      (void) my_stpcpy(index_name, org_name);
139
135
    *strrchr(org_name, '.')= '\0';
140
136
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
141
137
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
142
138
 
143
139
    info_length=mi_uint2korr(share->state.header.header_length);
144
140
    base_pos=mi_uint2korr(share->state.header.base_pos);
145
 
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
 
141
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
146
142
    {
147
143
      my_errno=ENOMEM;
148
144
      goto err;
150
146
    end_pos=disk_cache+info_length;
151
147
    errpos=2;
152
148
 
153
 
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
 
149
    my_seek(kfile,0L,MY_SEEK_SET,MYF(0));
154
150
    errpos=3;
155
151
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
156
152
    {
240
236
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
241
237
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
242
238
                         &share->mmap_lock,sizeof(rw_lock_t),
243
 
                         NullS))
 
239
                         NULL))
244
240
      goto err;
245
241
    errpos=4;
246
242
    *share=share_buff;
250
246
           sizeof(my_off_t)*keys);
251
247
    memcpy(share->state.key_del, key_del,
252
248
           sizeof(my_off_t) * share->state.header.max_block_size_index);
253
 
    stpcpy(share->unique_file_name, name_buff);
 
249
    my_stpcpy(share->unique_file_name, name_buff);
254
250
    share->unique_name_length= strlen(name_buff);
255
 
    stpcpy(share->index_file_name,  index_name);
256
 
    stpcpy(share->data_file_name,   data_name);
 
251
    my_stpcpy(share->index_file_name,  index_name);
 
252
    my_stpcpy(share->data_file_name,   data_name);
257
253
 
258
 
    share->blocksize=min(IO_SIZE,myisam_block_size);
 
254
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
259
255
    {
260
256
      HA_KEYSEG *pos=share->keyparts;
261
257
      for (i=0 ; i < keys ; i++)
374
370
    share->base.margin_key_file_length=(share->base.max_key_file_length -
375
371
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
376
372
                                         share->blocksize * keys : 0));
377
 
    share->blocksize=min(IO_SIZE,myisam_block_size);
 
373
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
378
374
    share->data_file_type=STATIC_RECORD;
379
375
    if (share->options & HA_OPTION_PACK_RECORD)
380
376
      share->data_file_type = DYNAMIC_RECORD;
381
 
    my_afree(disk_cache);
 
377
    free(disk_cache);
 
378
    disk_cache= NULL;
382
379
    mi_setup_functions(share);
383
380
    share->is_log_table= false;
384
381
    thr_lock_init(&share->lock);
385
 
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
 
382
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
386
383
    for (i=0; i<keys; i++)
387
 
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
388
 
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
 
384
      my_rwlock_init(&share->key_root_lock[i], NULL);
 
385
    my_rwlock_init(&share->mmap_lock, NULL);
389
386
    if (!thr_lock_inited)
390
387
    {
391
388
      /* Probably a single threaded program; Don't use concurrent inserts */
440
437
                       &info.first_mbr_key, share->base.max_key_length,
441
438
                       &info.filename,strlen(name)+1,
442
439
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
443
 
                       NullS))
 
440
                       NULL))
444
441
    goto err;
445
442
  errpos=6;
446
443
 
447
444
  if (!have_rtree)
448
445
    info.rtree_recursion_state= NULL;
449
446
 
450
 
  stpcpy(info.filename,name);
 
447
  my_stpcpy(info.filename,name);
451
448
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
452
449
  info.lastkey2=info.lastkey+share->base.max_key_length;
453
450
 
510
507
  return(m_info);
511
508
 
512
509
err:
 
510
  if (disk_cache != NULL)
 
511
    free(disk_cache);
513
512
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
514
513
  if ((save_errno == HA_ERR_CRASHED) ||
515
514
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
517
516
    mi_report_error(save_errno, name);
518
517
  switch (errpos) {
519
518
  case 6:
520
 
    my_free((uchar*) m_info,MYF(0));
 
519
    free((unsigned char*) m_info);
521
520
    /* fall through */
522
521
  case 5:
523
 
    VOID(my_close(info.dfile,MYF(0)));
 
522
    my_close(info.dfile,MYF(0));
524
523
    if (old_info)
525
524
      break;                                    /* Don't remove open table */
526
525
    /* fall through */
527
526
  case 4:
528
 
    my_free((uchar*) share,MYF(0));
 
527
    free((unsigned char*) share);
529
528
    /* fall through */
530
529
  case 3:
531
530
    /* fall through */
532
 
  case 2:
533
 
    my_afree(disk_cache);
534
 
    /* fall through */
535
531
  case 1:
536
 
    VOID(my_close(kfile,MYF(0)));
 
532
    my_close(kfile,MYF(0));
537
533
    /* fall through */
538
534
  case 0:
539
535
  default:
545
541
} /* mi_open */
546
542
 
547
543
 
548
 
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
 
544
unsigned char *mi_alloc_rec_buff(MI_INFO *info, ulong length, unsigned char **buf)
549
545
{
550
 
  uint extra;
 
546
  uint32_t extra;
551
547
  uint32_t old_length= 0;
552
548
 
553
549
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
554
550
  {
555
 
    uchar *newptr = *buf;
 
551
    unsigned char *newptr = *buf;
556
552
 
557
553
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
558
554
    if (length == (ulong) -1)
559
555
    {
560
556
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
561
 
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
 
557
        length= cmax(info->s->base.pack_reclength, info->s->max_pack_length);
562
558
      else
563
559
        length= info->s->base.pack_reclength;
564
 
      length= max(length, info->s->base.max_key_length);
 
560
      length= cmax(length, info->s->base.max_key_length);
565
561
      /* Avoid unnecessary realloc */
566
562
      if (newptr && length == old_length)
567
563
        return newptr;
572
568
            MI_REC_BUFF_OFFSET : 0);
573
569
    if (extra && newptr)
574
570
      newptr-= MI_REC_BUFF_OFFSET;
575
 
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
 
571
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*)newptr, length+extra+8,
576
572
                                     MYF(MY_ALLOW_ZERO_PTR))))
577
573
      return newptr;
578
574
    *((uint32_t *) newptr)= (uint32_t) length;
693
689
   Function to save and store the header in the index file (.MYI)
694
690
*/
695
691
 
696
 
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
 
692
uint32_t mi_state_info_write(File file, MI_STATE_INFO *state, uint32_t pWrite)
697
693
{
698
 
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
699
 
  uchar *ptr=buff;
 
694
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
695
  unsigned char *ptr=buff;
700
696
  uint  i, keys= (uint) state->header.keys,
701
697
        key_blocks=state->header.max_block_size_index;
702
698
 
705
701
 
706
702
  /* open_count must be first because of _mi_mark_file_changed ! */
707
703
  mi_int2store(ptr,state->open_count);          ptr +=2;
708
 
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
 
704
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
709
705
  mi_rowstore(ptr,state->state.records);        ptr +=8;
710
706
  mi_rowstore(ptr,state->state.del);            ptr +=8;
711
707
  mi_rowstore(ptr,state->split);                ptr +=8;
733
729
  }
734
730
  if (pWrite & 2)                               /* From isamchk */
735
731
  {
736
 
    uint key_parts= mi_uint2korr(state->header.key_parts);
 
732
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
737
733
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
738
734
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
739
735
    mi_int4store(ptr,state->version);           ptr +=4;
756
752
}
757
753
 
758
754
 
759
 
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
 
755
unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
760
756
{
761
 
  uint i,keys,key_parts,key_blocks;
 
757
  uint32_t i,keys,key_parts,key_blocks;
762
758
  memcpy(&state->header,ptr, sizeof(state->header));
763
759
  ptr +=sizeof(state->header);
764
760
  keys=(uint) state->header.keys;
809
805
}
810
806
 
811
807
 
812
 
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
 
808
uint32_t mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
813
809
{
814
 
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
810
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
815
811
 
816
812
  if (!myisam_single_user)
817
813
  {
832
828
**  store and read of MI_BASE_INFO
833
829
****************************************************************************/
834
830
 
835
 
uint mi_base_info_write(File file, MI_BASE_INFO *base)
 
831
uint32_t mi_base_info_write(File file, MI_BASE_INFO *base)
836
832
{
837
 
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
833
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
838
834
 
839
835
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
840
836
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
859
855
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
860
856
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
861
857
  *ptr++= base->extra_alloc_procent;
862
 
  *ptr++= base->raid_type;
863
 
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
864
 
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
858
  /* old raid info  slots */
 
859
  *ptr++= 0;
 
860
  mi_int2store(ptr,UINT16_C(0));                        ptr +=2;
 
861
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
 
862
 
865
863
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
866
864
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
867
865
}
868
866
 
869
867
 
870
 
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
 
868
unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
871
869
{
872
870
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
873
871
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
893
891
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
894
892
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
895
893
  base->extra_alloc_procent = *ptr++;
896
 
  base->raid_type= *ptr++;
897
 
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
898
 
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
899
 
  /* TO BE REMOVED: Fix for old RAID files */
900
 
  if (base->raid_type == 0)
901
 
  {
902
 
    base->raid_chunks=0;
903
 
    base->raid_chunksize=0;
904
 
  }
 
894
 
 
895
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
 
896
  ptr+= 7; 
905
897
 
906
898
  ptr+=6;
907
899
  return ptr;
911
903
  mi_keydef
912
904
---------------------------------------------------------------------------*/
913
905
 
914
 
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
 
906
uint32_t mi_keydef_write(File file, MI_KEYDEF *keydef)
915
907
{
916
 
  uchar buff[MI_KEYDEF_SIZE];
917
 
  uchar *ptr=buff;
 
908
  unsigned char buff[MI_KEYDEF_SIZE];
 
909
  unsigned char *ptr=buff;
918
910
 
919
 
  *ptr++ = (uchar) keydef->keysegs;
 
911
  *ptr++ = (unsigned char) keydef->keysegs;
920
912
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
921
913
  mi_int2store(ptr,keydef->flag);               ptr +=2;
922
914
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
926
918
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
927
919
}
928
920
 
929
 
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
 
921
unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
930
922
{
931
923
   keydef->keysegs      = (uint) *ptr++;
932
924
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
948
940
 
949
941
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
950
942
{
951
 
  uchar buff[HA_KEYSEG_SIZE];
952
 
  uchar *ptr=buff;
 
943
  unsigned char buff[HA_KEYSEG_SIZE];
 
944
  unsigned char *ptr=buff;
953
945
  ulong pos;
954
946
 
955
947
  *ptr++= keyseg->type;
969
961
}
970
962
 
971
963
 
972
 
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
 
964
unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
973
965
{
974
966
   keyseg->type         = *ptr++;
975
967
   keyseg->language     = *ptr++;
996
988
  mi_uniquedef
997
989
---------------------------------------------------------------------------*/
998
990
 
999
 
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
 
991
uint32_t mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
1000
992
{
1001
 
  uchar buff[MI_UNIQUEDEF_SIZE];
1002
 
  uchar *ptr=buff;
 
993
  unsigned char buff[MI_UNIQUEDEF_SIZE];
 
994
  unsigned char *ptr=buff;
1003
995
 
1004
996
  mi_int2store(ptr,def->keysegs);               ptr+=2;
1005
 
  *ptr++=  (uchar) def->key;
1006
 
  *ptr++ = (uchar) def->null_are_equal;
 
997
  *ptr++=  (unsigned char) def->key;
 
998
  *ptr++ = (unsigned char) def->null_are_equal;
1007
999
 
1008
1000
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1009
1001
}
1010
1002
 
1011
 
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
 
1003
unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1012
1004
{
1013
1005
   def->keysegs = mi_uint2korr(ptr);
1014
1006
   def->key     = ptr[2];
1020
1012
**  MI_COLUMNDEF
1021
1013
***************************************************************************/
1022
1014
 
1023
 
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
 
1015
uint32_t mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1024
1016
{
1025
 
  uchar buff[MI_COLUMNDEF_SIZE];
1026
 
  uchar *ptr=buff;
 
1017
  unsigned char buff[MI_COLUMNDEF_SIZE];
 
1018
  unsigned char *ptr=buff;
1027
1019
 
1028
1020
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1029
1021
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1032
1024
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1033
1025
}
1034
1026
 
1035
 
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
 
1027
unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1036
1028
{
1037
1029
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1038
1030
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1042
1034
}
1043
1035
 
1044
1036
/**************************************************************************
1045
 
Open data file with or without RAID
 
1037
Open data file
1046
1038
We can't use dup() here as the data file descriptors need to have different
1047
1039
active seek-positions.
1048
1040
 
1053
1045
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1054
1046
                     File file_to_dup __attribute__((unused)))
1055
1047
{
1056
 
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
 
1048
    info->dfile=my_open(share->data_file_name, share->mode,
1057
1049
                        MYF(MY_WME));
1058
1050
  return info->dfile >= 0 ? 0 : 1;
1059
1051
}
1061
1053
 
1062
1054
int mi_open_keyfile(MYISAM_SHARE *share)
1063
1055
{
1064
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
 
1056
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
1065
1057
                            MYF(MY_WME))) < 0)
1066
1058
    return 1;
1067
1059
  return 0;