~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_open.cc

  • Committer: Eric Day
  • Date: 2009-08-27 07:26:22 UTC
  • mto: This revision was merged to the branch mainline in revision 1131.
  • Revision ID: eday@oddments.org-20090827072622-72te13ua0wdlc2ky
Reworked listen interface to not require binding of TCP ports.

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 <mystrings/m_string.h>
 
21
#include <drizzled/util/test.h>
 
22
 
 
23
#include <string.h>
 
24
#include <algorithm>
 
25
 
 
26
using namespace std;
20
27
 
21
28
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
29
 
29
30
#define disk_pos_assert(pos, end_pos) \
30
31
if (pos > end_pos)             \
41
42
 
42
43
MI_INFO *test_if_reopen(char *filename)
43
44
{
44
 
  LIST *pos;
45
 
 
46
 
  for (pos=myisam_open_list ; pos ; pos=pos->next)
 
45
  list<MI_INFO *>::iterator it= myisam_open_list.begin();
 
46
  while (it != myisam_open_list.end())
47
47
  {
48
 
    MI_INFO *info=(MI_INFO*) pos->data;
 
48
    MI_INFO *info= *it;
49
49
    MYISAM_SHARE *share=info->s;
50
50
    if (!strcmp(share->unique_file_name,filename) && share->last_version)
51
51
      return info;
 
52
    ++it;
52
53
  }
53
54
  return 0;
54
55
}
68
69
  uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
69
70
    key_parts,unique_key_parts,fulltext_keys,uniques;
70
71
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
71
 
       data_name[FN_REFLEN];
 
72
       data_name[FN_REFLEN], rp_buff[PATH_MAX];
72
73
  unsigned char *disk_cache= NULL;
73
74
  unsigned char *disk_pos, *end_pos;
74
75
  MI_INFO info,*m_info,*old_info;
83
84
  head_length=sizeof(share_buff.state.header);
84
85
  memset(&info, 0, sizeof(info));
85
86
 
86
 
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
87
 
                                   MY_UNPACK_FILENAME),MYF(0));
 
87
  (void)fn_format(org_name,name,"",MI_NAME_IEXT, MY_UNPACK_FILENAME);
 
88
  if (!realpath(org_name,rp_buff))
 
89
    my_load_path(rp_buff,org_name, NULL);
 
90
  rp_buff[FN_REFLEN-1]= '\0';
 
91
  strcpy(name_buff,rp_buff);
88
92
  pthread_mutex_lock(&THR_LOCK_myisam);
89
93
  if (!(old_info=test_if_reopen(name_buff)))
90
94
  {
93
97
    share_buff.state.rec_per_key_part=rec_per_key_part;
94
98
    share_buff.state.key_root=key_root;
95
99
    share_buff.state.key_del=key_del;
96
 
    share_buff.key_cache= multi_key_cache_search((unsigned char*) name_buff,
97
 
                                                 strlen(name_buff));
 
100
    share_buff.key_cache= dflt_key_cache;
98
101
 
99
 
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
 
102
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
100
103
    {
101
104
      if ((errno != EROFS && errno != EACCES) ||
102
105
          mode != O_RDONLY ||
103
 
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
 
106
          (kfile=my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
104
107
        goto err;
105
108
    }
106
109
    share->mode=open_mode;
134
137
      goto err;
135
138
    }
136
139
    /* Don't call realpath() if the name can't be a link */
137
 
    if (!strcmp(name_buff, org_name) ||
138
 
        my_readlink(index_name, org_name, MYF(0)) == -1)
139
 
      (void) my_stpcpy(index_name, org_name);
 
140
    ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
 
141
    if (sym_link_size >= 0 )
 
142
      index_name[sym_link_size]= '\0';
 
143
    if (!strcmp(name_buff, org_name) || sym_link_size == -1)
 
144
      (void) strcpy(index_name, org_name);
140
145
    *strrchr(org_name, '.')= '\0';
141
146
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
142
147
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
151
156
    end_pos=disk_cache+info_length;
152
157
    errpos=2;
153
158
 
154
 
    my_seek(kfile,0L,MY_SEEK_SET,MYF(0));
 
159
    lseek(kfile,0,SEEK_SET);
155
160
    errpos=3;
156
161
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
157
162
    {
205
210
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
206
211
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
207
212
#if SIZEOF_OFF_T == 4
208
 
    set_if_smaller(max_data_file_length, INT_MAX32);
209
 
    set_if_smaller(max_key_file_length, INT_MAX32);
 
213
    set_if_smaller(max_data_file_length, INT32_MAX);
 
214
    set_if_smaller(max_key_file_length, INT32_MAX);
210
215
#endif
211
216
    if (share->base.raid_type)
212
217
    {
239
244
                         &share->state.key_root,keys*sizeof(my_off_t),
240
245
                         &share->state.key_del,
241
246
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
242
 
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
243
 
                         &share->mmap_lock,sizeof(rw_lock_t),
 
247
                         &share->key_root_lock,sizeof(pthread_rwlock_t)*keys,
 
248
                         &share->mmap_lock,sizeof(pthread_rwlock_t),
244
249
                         NULL))
245
250
      goto err;
246
251
    errpos=4;
251
256
           sizeof(my_off_t)*keys);
252
257
    memcpy(share->state.key_del, key_del,
253
258
           sizeof(my_off_t) * share->state.header.max_block_size_index);
254
 
    my_stpcpy(share->unique_file_name, name_buff);
 
259
    strcpy(share->unique_file_name, name_buff);
255
260
    share->unique_name_length= strlen(name_buff);
256
 
    my_stpcpy(share->index_file_name,  index_name);
257
 
    my_stpcpy(share->data_file_name,   data_name);
 
261
    strcpy(share->index_file_name,  index_name);
 
262
    strcpy(share->data_file_name,   data_name);
258
263
 
259
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
264
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
260
265
    {
261
266
      HA_KEYSEG *pos=share->keyparts;
262
267
      for (i=0 ; i < keys ; i++)
265
270
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
266
271
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
267
272
                        end_pos);
268
 
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
 
273
        set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
269
274
        share->keyinfo[i].seg=pos;
270
275
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
271
276
        {
283
288
          {
284
289
            if (!pos->language)
285
290
              pos->charset=default_charset_info;
286
 
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
 
291
            else if (!(pos->charset= get_charset(pos->language)))
287
292
            {
288
293
              my_errno=HA_ERR_UNKNOWN_CHARSET;
289
294
              goto err;
315
320
          {
316
321
            if (!pos->language)
317
322
              pos->charset=default_charset_info;
318
 
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
 
323
            else if (!(pos->charset= get_charset(pos->language)))
319
324
            {
320
325
              my_errno=HA_ERR_UNKNOWN_CHARSET;
321
326
              goto err;
375
380
    share->base.margin_key_file_length=(share->base.max_key_file_length -
376
381
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
377
382
                                         share->blocksize * keys : 0));
378
 
    share->blocksize=cmin(IO_SIZE,myisam_block_size);
 
383
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
379
384
    share->data_file_type=STATIC_RECORD;
380
385
    if (share->options & HA_OPTION_PACK_RECORD)
381
386
      share->data_file_type = DYNAMIC_RECORD;
386
391
    thr_lock_init(&share->lock);
387
392
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
388
393
    for (i=0; i<keys; i++)
389
 
      my_rwlock_init(&share->key_root_lock[i], NULL);
390
 
    my_rwlock_init(&share->mmap_lock, NULL);
 
394
      pthread_rwlock_init(&share->key_root_lock[i], NULL);
 
395
    pthread_rwlock_init(&share->mmap_lock, NULL);
391
396
    if (!thr_lock_inited)
392
397
    {
393
398
      /* Probably a single threaded program; Don't use concurrent inserts */
409
414
        share->lock.check_status= mi_check_status;
410
415
      }
411
416
    }
412
 
    /*
413
 
      Memory mapping can only be requested after initializing intern_lock.
414
 
    */
415
 
    if (open_flags & HA_OPEN_MMAP)
416
 
    {
417
 
      info.s= share;
418
 
      mi_extra(&info, HA_EXTRA_MMAP, 0);
419
 
    }
420
417
  }
421
418
  else
422
419
  {
449
446
  if (!have_rtree)
450
447
    info.rtree_recursion_state= NULL;
451
448
 
452
 
  my_stpcpy(info.filename,name);
 
449
  strcpy(info.filename,name);
453
450
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
454
451
  info.lastkey2=info.lastkey+share->base.max_key_length;
455
452
 
485
482
  {
486
483
    share->temporary=share->delay_key_write=1;
487
484
    share->write_flag=MYF(MY_NABP);
488
 
    share->w_locks++;                   /* We don't have to update status */
489
 
    share->tot_locks++;
 
485
    /*
 
486
     * The following two statements are commented out as a fix of
 
487
     * bug https://bugs.launchpad.net/drizzle/+bug/387627
 
488
     *
 
489
     * UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
 
490
     * The root cause of why this makes a difference hasn't
 
491
     * been found, but this fixes things for now.
 
492
     */
 
493
//    share->w_locks++;                 // We don't have to update status
 
494
//    share->tot_locks++;
490
495
    info.lock_type=F_WRLCK;
491
496
  }
492
497
  if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
505
510
 
506
511
  *m_info=info;
507
512
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
508
 
  m_info->open_list.data=(void*) m_info;
509
 
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
 
513
  myisam_open_list.push_front(m_info);
510
514
 
511
515
  pthread_mutex_unlock(&THR_LOCK_myisam);
512
516
  return(m_info);
546
550
} /* mi_open */
547
551
 
548
552
 
549
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, ulong length, unsigned char **buf)
 
553
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
550
554
{
551
555
  uint32_t extra;
552
556
  uint32_t old_length= 0;
559
563
    if (length == (ulong) -1)
560
564
    {
561
565
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
562
 
        length= cmax(info->s->base.pack_reclength, info->s->max_pack_length);
 
566
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
563
567
      else
564
568
        length= info->s->base.pack_reclength;
565
 
      length= cmax(length, info->s->base.max_key_length);
 
569
      length= max((uint32_t)length, info->s->base.max_key_length);
566
570
      /* Avoid unnecessary realloc */
567
571
      if (newptr && length == old_length)
568
572
        return newptr;
573
577
            MI_REC_BUFF_OFFSET : 0);
574
578
    if (extra && newptr)
575
579
      newptr-= MI_REC_BUFF_OFFSET;
576
 
    if (!(newptr=(unsigned char*) my_realloc((unsigned char*)newptr, length+extra+8,
577
 
                                     MYF(MY_ALLOW_ZERO_PTR))))
 
580
    void *tmpnewptr= NULL;
 
581
    if (!(tmpnewptr= realloc(newptr, length+extra+8))) 
578
582
      return newptr;
 
583
    newptr= (unsigned char *)tmpnewptr;
579
584
    *((uint32_t *) newptr)= (uint32_t) length;
580
585
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
581
586
  }
860
865
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
861
866
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
862
867
  *ptr++= base->extra_alloc_procent;
863
 
  *ptr++= base->raid_type;
864
 
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
865
 
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
868
  /* old raid info  slots */
 
869
  *ptr++= 0;
 
870
  mi_int2store(ptr,UINT16_C(0));                        ptr +=2;
 
871
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
 
872
 
866
873
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
867
874
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
868
875
}
894
901
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
895
902
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
896
903
  base->extra_alloc_procent = *ptr++;
897
 
  base->raid_type= *ptr++;
898
 
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
899
 
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
900
 
  /* TO BE REMOVED: Fix for old RAID files */
901
 
  if (base->raid_type == 0)
902
 
  {
903
 
    base->raid_chunks=0;
904
 
    base->raid_chunksize=0;
905
 
  }
 
904
 
 
905
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
 
906
  ptr+= 7;
906
907
 
907
908
  ptr+=6;
908
909
  return ptr;
965
966
  pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
966
967
  mi_int4store(ptr, pos);
967
968
  ptr+=4;
968
 
  
 
969
 
969
970
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
970
971
}
971
972
 
1043
1044
}
1044
1045
 
1045
1046
/**************************************************************************
1046
 
Open data file with or without RAID
 
1047
Open data file
1047
1048
We can't use dup() here as the data file descriptors need to have different
1048
1049
active seek-positions.
1049
1050
 
1051
1052
exist a dup()-like call that would give us two different file descriptors.
1052
1053
*************************************************************************/
1053
1054
 
1054
 
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1055
 
                     File file_to_dup __attribute__((unused)))
 
1055
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, File file_to_dup)
1056
1056
{
1057
 
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1058
 
                        MYF(MY_WME));
 
1057
  (void)file_to_dup; 
 
1058
  info->dfile=my_open(share->data_file_name, share->mode,
 
1059
                      MYF(MY_WME));
1059
1060
  return info->dfile >= 0 ? 0 : 1;
1060
1061
}
1061
1062
 
1062
1063
 
1063
1064
int mi_open_keyfile(MYISAM_SHARE *share)
1064
1065
{
1065
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
 
1066
  if ((share->kfile=my_open(share->unique_file_name, share->mode,
1066
1067
                            MYF(MY_WME))) < 0)
1067
1068
    return 1;
1068
1069
  return 0;