~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/myisam/mi_open.cc

  • Committer: Brian Aker
  • Date: 2010-05-27 01:25:56 UTC
  • mfrom: (1567.1.4 new-staging)
  • Revision ID: brian@gaz-20100527012556-5zgkirkl7swbigd6
Merge of Brian, Paul. PBXT compile issue, and test framework cleanup. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* open a isam-database */
17
17
 
18
 
#include "myisamdef.h"
19
 
#include <mystrings/m_ctype.h>
 
18
#include "myisam_priv.h"
 
19
 
 
20
#include <string.h>
 
21
#include <algorithm>
 
22
 
 
23
#include "drizzled/charset_info.h"
 
24
#include "drizzled/internal/m_string.h"
 
25
#include "drizzled/util/test.h"
 
26
#include "drizzled/global_charset_info.h"
 
27
#include "drizzled/charset.h"
 
28
#include "drizzled/memory/multi_malloc.h"
 
29
 
 
30
 
 
31
using namespace std;
 
32
using namespace drizzled;
20
33
 
21
34
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
 
 
 
35
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
 
36
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg);
 
37
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo);
 
38
static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
 
39
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state);
 
40
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def);
 
41
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base);
28
42
 
29
43
#define disk_pos_assert(pos, end_pos) \
30
44
if (pos > end_pos)             \
31
45
{                              \
32
 
  my_errno=HA_ERR_CRASHED;     \
 
46
  errno=HA_ERR_CRASHED;     \
33
47
  goto err;                    \
34
48
}
35
49
 
41
55
 
42
56
MI_INFO *test_if_reopen(char *filename)
43
57
{
44
 
  LIST *pos;
45
 
 
46
 
  for (pos=myisam_open_list ; pos ; pos=pos->next)
 
58
  list<MI_INFO *>::iterator it= myisam_open_list.begin();
 
59
  while (it != myisam_open_list.end())
47
60
  {
48
 
    MI_INFO *info=(MI_INFO*) pos->data;
 
61
    MI_INFO *info= *it;
49
62
    MYISAM_SHARE *share=info->s;
50
63
    if (!strcmp(share->unique_file_name,filename) && share->last_version)
51
64
      return info;
 
65
    ++it;
52
66
  }
53
67
  return 0;
54
68
}
62
76
  have an open count of 0.
63
77
******************************************************************************/
64
78
 
65
 
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
 
79
MI_INFO *mi_open(const char *name, int mode, uint32_t open_flags)
66
80
{
67
81
  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,
 
82
  uint32_t i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
69
83
    key_parts,unique_key_parts,fulltext_keys,uniques;
70
84
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
71
 
       data_name[FN_REFLEN];
72
 
  uchar *disk_cache, *disk_pos, *end_pos;
 
85
       data_name[FN_REFLEN], rp_buff[PATH_MAX];
 
86
  unsigned char *disk_cache= NULL;
 
87
  unsigned char *disk_pos, *end_pos;
73
88
  MI_INFO info,*m_info,*old_info;
74
89
  MYISAM_SHARE share_buff,*share;
75
90
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
76
 
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
91
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
77
92
  uint64_t max_key_file_length, max_data_file_length;
78
93
 
79
94
  kfile= -1;
82
97
  head_length=sizeof(share_buff.state.header);
83
98
  memset(&info, 0, sizeof(info));
84
99
 
85
 
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
86
 
                                   MY_UNPACK_FILENAME),MYF(0));
 
100
  (void)internal::fn_format(org_name,name,"",MI_NAME_IEXT, MY_UNPACK_FILENAME);
 
101
  if (!realpath(org_name,rp_buff))
 
102
    internal::my_load_path(rp_buff,org_name, NULL);
 
103
  rp_buff[FN_REFLEN-1]= '\0';
 
104
  strcpy(name_buff,rp_buff);
87
105
  pthread_mutex_lock(&THR_LOCK_myisam);
88
106
  if (!(old_info=test_if_reopen(name_buff)))
89
107
  {
92
110
    share_buff.state.rec_per_key_part=rec_per_key_part;
93
111
    share_buff.state.key_root=key_root;
94
112
    share_buff.state.key_del=key_del;
95
 
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
96
 
                                                 strlen(name_buff));
 
113
    share_buff.key_cache= dflt_key_cache;
97
114
 
98
 
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
 
115
    if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
99
116
    {
100
117
      if ((errno != EROFS && errno != EACCES) ||
101
118
          mode != O_RDONLY ||
102
 
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
 
119
          (kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
103
120
        goto err;
104
121
    }
105
122
    share->mode=open_mode;
106
123
    errpos=1;
107
 
    if (my_read(kfile, share->state.header.file_version, head_length,
 
124
    if (internal::my_read(kfile, share->state.header.file_version, head_length,
108
125
                MYF(MY_NABP)))
109
126
    {
110
 
      my_errno= HA_ERR_NOT_A_TABLE;
 
127
      errno= HA_ERR_NOT_A_TABLE;
111
128
      goto err;
112
129
    }
113
130
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
114
131
    {
115
 
      my_errno=HA_ERR_NOT_A_TABLE;
 
132
      errno=HA_ERR_NOT_A_TABLE;
116
133
      goto err;
117
134
    }
118
135
    share->options= mi_uint2korr(share->state.header.options);
119
136
    if (share->options &
120
137
        ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
121
138
          HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
122
 
          HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
123
 
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
124
 
          HA_OPTION_RELIES_ON_SQL_LAYER))
125
 
    {
126
 
      my_errno=HA_ERR_OLD_FILE;
127
 
      goto err;
128
 
    }
129
 
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
130
 
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
131
 
    {
132
 
      my_errno= HA_ERR_UNSUPPORTED;
133
 
      goto err;
134
 
    }
 
139
          HA_OPTION_TEMP_COMPRESS_RECORD |
 
140
          HA_OPTION_TMP_TABLE
 
141
          ))
 
142
    {
 
143
      errno=HA_ERR_OLD_FILE;
 
144
      goto err;
 
145
    }
 
146
 
135
147
    /* Don't call realpath() if the name can't be a link */
136
 
    if (!strcmp(name_buff, org_name) ||
137
 
        my_readlink(index_name, org_name, MYF(0)) == -1)
138
 
      (void) stpcpy(index_name, org_name);
 
148
    ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
 
149
    if (sym_link_size >= 0 )
 
150
      index_name[sym_link_size]= '\0';
 
151
    if (!strcmp(name_buff, org_name) || sym_link_size == -1)
 
152
      (void) strcpy(index_name, org_name);
139
153
    *strrchr(org_name, '.')= '\0';
140
 
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
 
154
    (void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
141
155
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
142
156
 
143
157
    info_length=mi_uint2korr(share->state.header.header_length);
144
158
    base_pos=mi_uint2korr(share->state.header.base_pos);
145
 
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
 
159
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
146
160
    {
147
 
      my_errno=ENOMEM;
 
161
      errno=ENOMEM;
148
162
      goto err;
149
163
    }
150
164
    end_pos=disk_cache+info_length;
151
165
    errpos=2;
152
166
 
153
 
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
 
167
    lseek(kfile,0,SEEK_SET);
154
168
    errpos=3;
155
 
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
 
169
    if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
156
170
    {
157
 
      my_errno=HA_ERR_CRASHED;
 
171
      errno=HA_ERR_CRASHED;
158
172
      goto err;
159
173
    }
160
174
    len=mi_uint2korr(share->state.header.state_info_length);
170
184
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
171
185
    share->state.state_length=base_pos;
172
186
 
173
 
    if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
174
 
        ((share->state.changed & STATE_CRASHED) ||
175
 
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
176
 
          (share->state.open_count))))
 
187
    if (share->state.changed & STATE_CRASHED)
177
188
    {
178
 
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
 
189
      errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
179
190
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
180
191
      goto err;
181
192
    }
183
194
    /* sanity check */
184
195
    if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
185
196
    {
186
 
      my_errno=HA_ERR_CRASHED;
 
197
      errno=HA_ERR_CRASHED;
187
198
      goto err;
188
199
    }
189
200
 
190
201
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
191
202
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
192
203
    {
193
 
      my_errno=HA_ERR_UNSUPPORTED;
 
204
      errno=HA_ERR_UNSUPPORTED;
194
205
      goto err;
195
206
    }
196
207
 
204
215
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
205
216
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
206
217
#if SIZEOF_OFF_T == 4
207
 
    set_if_smaller(max_data_file_length, INT_MAX32);
208
 
    set_if_smaller(max_key_file_length, INT_MAX32);
 
218
    set_if_smaller(max_data_file_length, INT32_MAX);
 
219
    set_if_smaller(max_key_file_length, INT32_MAX);
209
220
#endif
210
221
    if (share->base.raid_type)
211
222
    {
212
 
      my_errno=HA_ERR_UNSUPPORTED;
 
223
      errno=HA_ERR_UNSUPPORTED;
213
224
      goto err;
214
225
    }
215
 
    share->base.max_data_file_length=(my_off_t) max_data_file_length;
216
 
    share->base.max_key_file_length=(my_off_t) max_key_file_length;
 
226
    share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
 
227
    share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
217
228
 
218
229
    if (share->options & HA_OPTION_COMPRESS_RECORD)
219
230
      share->base.max_key_length+=2;    /* For safety */
221
232
    /* Add space for node pointer */
222
233
    share->base.max_key_length+= share->base.key_reflength;
223
234
 
224
 
    if (!my_multi_malloc(MY_WME,
225
 
                         &share,sizeof(*share),
226
 
                         &share->state.rec_per_key_part,sizeof(long)*key_parts,
227
 
                         &share->keyinfo,keys*sizeof(MI_KEYDEF),
228
 
                         &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
229
 
                         &share->keyparts,
230
 
                         (key_parts+unique_key_parts+keys+uniques) *
231
 
                         sizeof(HA_KEYSEG),
232
 
                         &share->rec,
233
 
                         (share->base.fields+1)*sizeof(MI_COLUMNDEF),
234
 
                         &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
235
 
                         &share->unique_file_name,strlen(name_buff)+1,
236
 
                         &share->index_file_name,strlen(index_name)+1,
237
 
                         &share->data_file_name,strlen(data_name)+1,
238
 
                         &share->state.key_root,keys*sizeof(my_off_t),
239
 
                         &share->state.key_del,
240
 
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
241
 
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
242
 
                         &share->mmap_lock,sizeof(rw_lock_t),
243
 
                         NullS))
 
235
    if (!drizzled::memory::multi_malloc(false,
 
236
           &share,sizeof(*share),
 
237
           &share->state.rec_per_key_part,sizeof(long)*key_parts,
 
238
           &share->keyinfo,keys*sizeof(MI_KEYDEF),
 
239
           &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
 
240
           &share->keyparts,
 
241
           (key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
 
242
           &share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
 
243
           &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
 
244
           &share->unique_file_name,strlen(name_buff)+1,
 
245
           &share->index_file_name,strlen(index_name)+1,
 
246
           &share->data_file_name,strlen(data_name)+1,
 
247
           &share->state.key_root,keys*sizeof(uint64_t),
 
248
           &share->state.key_del,
 
249
           (share->state.header.max_block_size_index*sizeof(uint64_t)),
 
250
           &share->key_root_lock,sizeof(pthread_rwlock_t)*keys,
 
251
           &share->mmap_lock,sizeof(pthread_rwlock_t),
 
252
           NULL))
244
253
      goto err;
245
254
    errpos=4;
246
255
    *share=share_buff;
247
256
    memcpy(share->state.rec_per_key_part, rec_per_key_part,
248
257
           sizeof(long)*key_parts);
249
258
    memcpy(share->state.key_root, key_root,
250
 
           sizeof(my_off_t)*keys);
 
259
           sizeof(internal::my_off_t)*keys);
251
260
    memcpy(share->state.key_del, key_del,
252
 
           sizeof(my_off_t) * share->state.header.max_block_size_index);
253
 
    stpcpy(share->unique_file_name, name_buff);
 
261
           sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
 
262
    strcpy(share->unique_file_name, name_buff);
254
263
    share->unique_name_length= strlen(name_buff);
255
 
    stpcpy(share->index_file_name,  index_name);
256
 
    stpcpy(share->data_file_name,   data_name);
 
264
    strcpy(share->index_file_name,  index_name);
 
265
    strcpy(share->data_file_name,   data_name);
257
266
 
258
 
    share->blocksize=min(IO_SIZE,myisam_block_size);
 
267
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
259
268
    {
260
269
      HA_KEYSEG *pos=share->keyparts;
261
270
      for (i=0 ; i < keys ; i++)
264
273
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
265
274
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
266
275
                        end_pos);
267
 
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
 
276
        set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
268
277
        share->keyinfo[i].seg=pos;
269
278
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
270
279
        {
273
282
              ! (share->options & (HA_OPTION_COMPRESS_RECORD |
274
283
                                   HA_OPTION_PACK_RECORD)))
275
284
          {
276
 
            my_errno= HA_ERR_CRASHED;
 
285
            errno= HA_ERR_CRASHED;
277
286
            goto err;
278
287
          }
279
288
          if (pos->type == HA_KEYTYPE_TEXT ||
282
291
          {
283
292
            if (!pos->language)
284
293
              pos->charset=default_charset_info;
285
 
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
 
294
            else if (!(pos->charset= get_charset(pos->language)))
286
295
            {
287
 
              my_errno=HA_ERR_UNKNOWN_CHARSET;
 
296
              errno=HA_ERR_UNKNOWN_CHARSET;
288
297
              goto err;
289
298
            }
290
299
          }
314
323
          {
315
324
            if (!pos->language)
316
325
              pos->charset=default_charset_info;
317
 
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
 
326
            else if (!(pos->charset= get_charset(pos->language)))
318
327
            {
319
 
              my_errno=HA_ERR_UNKNOWN_CHARSET;
 
328
              errno=HA_ERR_UNKNOWN_CHARSET;
320
329
              goto err;
321
330
            }
322
331
          }
348
357
    share->rec[i].type=(int) FIELD_LAST;        /* End marker */
349
358
    if (offset > share->base.reclength)
350
359
    {
351
 
      /* purecov: begin inspected */
352
 
      my_errno= HA_ERR_CRASHED;
 
360
      errno= HA_ERR_CRASHED;
353
361
      goto err;
354
 
      /* purecov: end */
355
362
    }
356
363
 
357
364
    if (! lock_error)
374
381
    share->base.margin_key_file_length=(share->base.max_key_file_length -
375
382
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
376
383
                                         share->blocksize * keys : 0));
377
 
    share->blocksize=min(IO_SIZE,myisam_block_size);
 
384
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
378
385
    share->data_file_type=STATIC_RECORD;
379
386
    if (share->options & HA_OPTION_PACK_RECORD)
380
387
      share->data_file_type = DYNAMIC_RECORD;
381
 
    my_afree(disk_cache);
 
388
    free(disk_cache);
 
389
    disk_cache= NULL;
382
390
    mi_setup_functions(share);
383
391
    share->is_log_table= false;
384
392
    thr_lock_init(&share->lock);
385
 
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
 
393
    pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST);
386
394
    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));
 
395
      pthread_rwlock_init(&share->key_root_lock[i], NULL);
 
396
    pthread_rwlock_init(&share->mmap_lock, NULL);
389
397
    if (!thr_lock_inited)
390
398
    {
391
399
      /* Probably a single threaded program; Don't use concurrent inserts */
407
415
        share->lock.check_status= mi_check_status;
408
416
      }
409
417
    }
410
 
    /*
411
 
      Memory mapping can only be requested after initializing intern_lock.
412
 
    */
413
 
    if (open_flags & HA_OPEN_MMAP)
414
 
    {
415
 
      info.s= share;
416
 
      mi_extra(&info, HA_EXTRA_MMAP, 0);
417
 
    }
418
418
  }
419
419
  else
420
420
  {
421
421
    share= old_info->s;
422
422
    if (mode == O_RDWR && share->mode == O_RDONLY)
423
423
    {
424
 
      my_errno=EACCES;                          /* Can't open in write mode */
 
424
      errno=EACCES;                             /* Can't open in write mode */
425
425
      goto err;
426
426
    }
427
427
    if (mi_open_datafile(&info, share, old_info->dfile))
431
431
  }
432
432
 
433
433
  /* alloc and set up private structure parts */
434
 
  if (!my_multi_malloc(MY_WME,
435
 
                       &m_info,sizeof(MI_INFO),
436
 
                       &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
437
 
                       &info.buff,(share->base.max_key_block_length*2+
438
 
                                   share->base.max_key_length),
439
 
                       &info.lastkey,share->base.max_key_length*3+1,
440
 
                       &info.first_mbr_key, share->base.max_key_length,
441
 
                       &info.filename,strlen(name)+1,
442
 
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
443
 
                       NullS))
 
434
  if (!drizzled::memory::multi_malloc(MY_WME,
 
435
         &m_info,sizeof(MI_INFO),
 
436
         &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
 
437
         &info.buff,(share->base.max_key_block_length*2+
 
438
                     share->base.max_key_length),
 
439
         &info.lastkey,share->base.max_key_length*3+1,
 
440
         &info.first_mbr_key, share->base.max_key_length,
 
441
         &info.filename,strlen(name)+1,
 
442
         &info.rtree_recursion_state,have_rtree ? 1024 : 0,
 
443
         NULL))
444
444
    goto err;
445
445
  errpos=6;
446
446
 
447
447
  if (!have_rtree)
448
448
    info.rtree_recursion_state= NULL;
449
449
 
450
 
  stpcpy(info.filename,name);
 
450
  strcpy(info.filename,name);
451
451
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
452
452
  info.lastkey2=info.lastkey+share->base.max_key_length;
453
453
 
483
483
  {
484
484
    share->temporary=share->delay_key_write=1;
485
485
    share->write_flag=MYF(MY_NABP);
486
 
    share->w_locks++;                   /* We don't have to update status */
487
 
    share->tot_locks++;
 
486
    /*
 
487
     * The following two statements are commented out as a fix of
 
488
     * bug https://bugs.launchpad.net/drizzle/+bug/387627
 
489
     *
 
490
     * UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
 
491
     * The root cause of why this makes a difference hasn't
 
492
     * been found, but this fixes things for now.
 
493
     */
 
494
//    share->w_locks++;                 // We don't have to update status
 
495
//    share->tot_locks++;
488
496
    info.lock_type=F_WRLCK;
489
497
  }
490
 
  if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
491
 
      (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
492
 
      myisam_delay_key_write)
493
 
    share->delay_key_write=1;
 
498
 
 
499
  share->delay_key_write= 1;
494
500
  info.state= &share->state.state;      /* Change global values by default */
495
501
  pthread_mutex_unlock(&share->intern_lock);
496
502
 
503
509
 
504
510
  *m_info=info;
505
511
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
506
 
  m_info->open_list.data=(void*) m_info;
507
 
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
 
512
  myisam_open_list.push_front(m_info);
508
513
 
509
514
  pthread_mutex_unlock(&THR_LOCK_myisam);
510
515
  return(m_info);
511
516
 
512
517
err:
513
 
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
 
518
  if (disk_cache != NULL)
 
519
    free(disk_cache);
 
520
  save_errno=errno ? errno : HA_ERR_END_OF_FILE;
514
521
  if ((save_errno == HA_ERR_CRASHED) ||
515
522
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
516
523
      (save_errno == HA_ERR_CRASHED_ON_REPAIR))
517
524
    mi_report_error(save_errno, name);
518
525
  switch (errpos) {
519
526
  case 6:
520
 
    my_free((uchar*) m_info,MYF(0));
 
527
    free((unsigned char*) m_info);
521
528
    /* fall through */
522
529
  case 5:
523
 
    VOID(my_close(info.dfile,MYF(0)));
 
530
    internal::my_close(info.dfile,MYF(0));
524
531
    if (old_info)
525
532
      break;                                    /* Don't remove open table */
526
533
    /* fall through */
527
534
  case 4:
528
 
    my_free((uchar*) share,MYF(0));
 
535
    free((unsigned char*) share);
529
536
    /* fall through */
530
537
  case 3:
531
538
    /* fall through */
532
 
  case 2:
533
 
    my_afree(disk_cache);
534
 
    /* fall through */
535
539
  case 1:
536
 
    VOID(my_close(kfile,MYF(0)));
 
540
    internal::my_close(kfile,MYF(0));
537
541
    /* fall through */
538
542
  case 0:
539
543
  default:
540
544
    break;
541
545
  }
542
546
  pthread_mutex_unlock(&THR_LOCK_myisam);
543
 
  my_errno=save_errno;
 
547
  errno=save_errno;
544
548
  return (NULL);
545
549
} /* mi_open */
546
550
 
547
551
 
548
 
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
 
552
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
549
553
{
550
 
  uint extra;
 
554
  uint32_t extra;
551
555
  uint32_t old_length= 0;
552
556
 
553
557
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
554
558
  {
555
 
    uchar *newptr = *buf;
 
559
    unsigned char *newptr = *buf;
556
560
 
557
561
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
558
562
    if (length == (ulong) -1)
561
565
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
562
566
      else
563
567
        length= info->s->base.pack_reclength;
564
 
      length= max(length, info->s->base.max_key_length);
 
568
      length= max((uint32_t)length, info->s->base.max_key_length);
565
569
      /* Avoid unnecessary realloc */
566
570
      if (newptr && length == old_length)
567
571
        return newptr;
572
576
            MI_REC_BUFF_OFFSET : 0);
573
577
    if (extra && newptr)
574
578
      newptr-= MI_REC_BUFF_OFFSET;
575
 
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
576
 
                                     MYF(MY_ALLOW_ZERO_PTR))))
 
579
    void *tmpnewptr= NULL;
 
580
    if (!(tmpnewptr= realloc(newptr, length+extra+8))) 
577
581
      return newptr;
 
582
    newptr= (unsigned char *)tmpnewptr;
578
583
    *((uint32_t *) newptr)= (uint32_t) length;
579
584
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
580
585
  }
582
587
}
583
588
 
584
589
 
585
 
uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
590
static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
586
591
{
587
 
  uint64_t max_val= ~ (uint64_t) 0;             /* my_off_t is unsigned */
 
592
  uint64_t max_val= ~ (uint64_t) 0;             /* internal::my_off_t is unsigned */
588
593
 
589
594
  if (!a || max_val / a < b)
590
595
    return max_val;
630
635
  }
631
636
  share->file_read= mi_nommap_pread;
632
637
  share->file_write= mi_nommap_pwrite;
633
 
  if (!(share->options & HA_OPTION_CHECKSUM))
634
 
    share->calc_checksum=0;
635
 
  return;
 
638
  share->calc_checksum=0;
636
639
}
637
640
 
638
641
 
693
696
   Function to save and store the header in the index file (.MYI)
694
697
*/
695
698
 
696
 
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
 
699
uint32_t mi_state_info_write(int file, MI_STATE_INFO *state, uint32_t pWrite)
697
700
{
698
 
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
699
 
  uchar *ptr=buff;
 
701
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
702
  unsigned char *ptr=buff;
700
703
  uint  i, keys= (uint) state->header.keys,
701
704
        key_blocks=state->header.max_block_size_index;
702
705
 
705
708
 
706
709
  /* open_count must be first because of _mi_mark_file_changed ! */
707
710
  mi_int2store(ptr,state->open_count);          ptr +=2;
708
 
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
 
711
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
709
712
  mi_rowstore(ptr,state->state.records);        ptr +=8;
710
713
  mi_rowstore(ptr,state->state.del);            ptr +=8;
711
714
  mi_rowstore(ptr,state->split);                ptr +=8;
733
736
  }
734
737
  if (pWrite & 2)                               /* From isamchk */
735
738
  {
736
 
    uint key_parts= mi_uint2korr(state->header.key_parts);
 
739
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
737
740
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
738
741
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
739
742
    mi_int4store(ptr,state->version);           ptr +=4;
751
754
  if (pWrite & 1)
752
755
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
753
756
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
754
 
  return(my_write(file, buff, (size_t) (ptr-buff),
 
757
  return(internal::my_write(file, buff, (size_t) (ptr-buff),
755
758
                       MYF(MY_NABP)) != 0);
756
759
}
757
760
 
758
761
 
759
 
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
 
762
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
760
763
{
761
 
  uint i,keys,key_parts,key_blocks;
 
764
  uint32_t i,keys,key_parts,key_blocks;
762
765
  memcpy(&state->header,ptr, sizeof(state->header));
763
766
  ptr +=sizeof(state->header);
764
767
  keys=(uint) state->header.keys;
777
780
  state->state.empty    = mi_sizekorr(ptr);     ptr +=8;
778
781
  state->state.key_empty= mi_sizekorr(ptr);     ptr +=8;
779
782
  state->auto_increment=mi_uint8korr(ptr);      ptr +=8;
780
 
  state->state.checksum=(ha_checksum) mi_uint8korr(ptr);        ptr +=8;
 
783
  state->state.checksum=(internal::ha_checksum) mi_uint8korr(ptr);      ptr +=8;
781
784
  state->process= mi_uint4korr(ptr);            ptr +=4;
782
785
  state->unique = mi_uint4korr(ptr);            ptr +=4;
783
786
  state->status = mi_uint4korr(ptr);            ptr +=4;
809
812
}
810
813
 
811
814
 
812
 
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, bool pRead)
 
815
uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead)
813
816
{
814
 
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
817
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
815
818
 
816
 
  if (!myisam_single_user)
 
819
  if (pRead)
817
820
  {
818
 
    if (pRead)
819
 
    {
820
 
      if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
821
 
        return 1;
822
 
    }
823
 
    else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
 
821
    if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
824
822
      return 1;
825
 
    mi_state_info_read(buff, state);
826
823
  }
 
824
  else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
 
825
    return 1;
 
826
  mi_state_info_read(buff, state);
 
827
 
827
828
  return 0;
828
829
}
829
830
 
832
833
**  store and read of MI_BASE_INFO
833
834
****************************************************************************/
834
835
 
835
 
uint mi_base_info_write(File file, MI_BASE_INFO *base)
 
836
uint32_t mi_base_info_write(int file, MI_BASE_INFO *base)
836
837
{
837
 
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
838
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
838
839
 
839
840
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
840
841
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
859
860
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
860
861
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
861
862
  *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;
 
863
  /* old raid info  slots */
 
864
  *ptr++= 0;
 
865
  mi_int2store(ptr,UINT16_C(0));                        ptr +=2;
 
866
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
 
867
 
865
868
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
866
 
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
869
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
867
870
}
868
871
 
869
872
 
870
 
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
 
873
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
871
874
{
872
875
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
873
876
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
893
896
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
894
897
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
895
898
  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
 
  }
 
899
 
 
900
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
 
901
  ptr+= 7;
905
902
 
906
903
  ptr+=6;
907
904
  return ptr;
911
908
  mi_keydef
912
909
---------------------------------------------------------------------------*/
913
910
 
914
 
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
 
911
uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef)
915
912
{
916
 
  uchar buff[MI_KEYDEF_SIZE];
917
 
  uchar *ptr=buff;
 
913
  unsigned char buff[MI_KEYDEF_SIZE];
 
914
  unsigned char *ptr=buff;
918
915
 
919
 
  *ptr++ = (uchar) keydef->keysegs;
 
916
  *ptr++ = (unsigned char) keydef->keysegs;
920
917
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
921
918
  mi_int2store(ptr,keydef->flag);               ptr +=2;
922
919
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
923
920
  mi_int2store(ptr,keydef->keylength);          ptr +=2;
924
921
  mi_int2store(ptr,keydef->minlength);          ptr +=2;
925
922
  mi_int2store(ptr,keydef->maxlength);          ptr +=2;
926
 
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
923
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
927
924
}
928
925
 
929
 
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
 
926
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
930
927
{
931
928
   keydef->keysegs      = (uint) *ptr++;
932
929
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
946
943
**  mi_keyseg
947
944
***************************************************************************/
948
945
 
949
 
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
 
946
int mi_keyseg_write(int file, const HA_KEYSEG *keyseg)
950
947
{
951
 
  uchar buff[HA_KEYSEG_SIZE];
952
 
  uchar *ptr=buff;
 
948
  unsigned char buff[HA_KEYSEG_SIZE];
 
949
  unsigned char *ptr=buff;
953
950
  ulong pos;
954
951
 
955
952
  *ptr++= keyseg->type;
964
961
  pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
965
962
  mi_int4store(ptr, pos);
966
963
  ptr+=4;
967
 
  
968
 
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
964
 
 
965
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
969
966
}
970
967
 
971
968
 
972
 
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
 
969
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
973
970
{
974
971
   keyseg->type         = *ptr++;
975
972
   keyseg->language     = *ptr++;
996
993
  mi_uniquedef
997
994
---------------------------------------------------------------------------*/
998
995
 
999
 
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
 
996
uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *def)
1000
997
{
1001
 
  uchar buff[MI_UNIQUEDEF_SIZE];
1002
 
  uchar *ptr=buff;
 
998
  unsigned char buff[MI_UNIQUEDEF_SIZE];
 
999
  unsigned char *ptr=buff;
1003
1000
 
1004
1001
  mi_int2store(ptr,def->keysegs);               ptr+=2;
1005
 
  *ptr++=  (uchar) def->key;
1006
 
  *ptr++ = (uchar) def->null_are_equal;
 
1002
  *ptr++=  (unsigned char) def->key;
 
1003
  *ptr++ = (unsigned char) def->null_are_equal;
1007
1004
 
1008
 
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1005
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1009
1006
}
1010
1007
 
1011
 
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
 
1008
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
1012
1009
{
1013
1010
   def->keysegs = mi_uint2korr(ptr);
1014
1011
   def->key     = ptr[2];
1020
1017
**  MI_COLUMNDEF
1021
1018
***************************************************************************/
1022
1019
 
1023
 
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
 
1020
uint32_t mi_recinfo_write(int file, MI_COLUMNDEF *recinfo)
1024
1021
{
1025
 
  uchar buff[MI_COLUMNDEF_SIZE];
1026
 
  uchar *ptr=buff;
 
1022
  unsigned char buff[MI_COLUMNDEF_SIZE];
 
1023
  unsigned char *ptr=buff;
1027
1024
 
1028
1025
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1029
1026
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1030
1027
  *ptr++ = recinfo->null_bit;
1031
1028
  mi_int2store(ptr,recinfo->null_pos);  ptr+= 2;
1032
 
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1029
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1033
1030
}
1034
1031
 
1035
 
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
 
1032
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
1036
1033
{
1037
1034
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1038
1035
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1042
1039
}
1043
1040
 
1044
1041
/**************************************************************************
1045
 
Open data file with or without RAID
 
1042
Open data file
1046
1043
We can't use dup() here as the data file descriptors need to have different
1047
1044
active seek-positions.
1048
1045
 
1050
1047
exist a dup()-like call that would give us two different file descriptors.
1051
1048
*************************************************************************/
1052
1049
 
1053
 
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
1054
 
                     File file_to_dup __attribute__((unused)))
 
1050
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
1055
1051
{
1056
 
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
1057
 
                        MYF(MY_WME));
 
1052
  (void)file_to_dup; 
 
1053
  info->dfile=internal::my_open(share->data_file_name, share->mode,
 
1054
                      MYF(MY_WME));
1058
1055
  return info->dfile >= 0 ? 0 : 1;
1059
1056
}
1060
1057
 
1061
1058
 
1062
1059
int mi_open_keyfile(MYISAM_SHARE *share)
1063
1060
{
1064
 
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
 
1061
  if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
1065
1062
                            MYF(MY_WME))) < 0)
1066
1063
    return 1;
1067
1064
  return 0;