~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

Removed/replaced DBUG symbols and TRUE/FALSE

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* open a isam-database */
17
17
 
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;
 
18
#include "myisamdef.h"
 
19
#include <m_ctype.h>
33
20
 
34
21
static void setup_key_functions(MI_KEYDEF *keyinfo);
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);
 
22
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
 
23
                                        pos+=size;}
 
24
 
42
25
 
43
26
#define disk_pos_assert(pos, end_pos) \
44
27
if (pos > end_pos)             \
45
28
{                              \
46
 
  errno=HA_ERR_CRASHED;     \
 
29
  my_errno=HA_ERR_CRASHED;     \
47
30
  goto err;                    \
48
31
}
49
32
 
55
38
 
56
39
MI_INFO *test_if_reopen(char *filename)
57
40
{
58
 
  list<MI_INFO *>::iterator it= myisam_open_list.begin();
59
 
  while (it != myisam_open_list.end())
 
41
  LIST *pos;
 
42
 
 
43
  for (pos=myisam_open_list ; pos ; pos=pos->next)
60
44
  {
61
 
    MI_INFO *info= *it;
 
45
    MI_INFO *info=(MI_INFO*) pos->data;
62
46
    MYISAM_SHARE *share=info->s;
63
47
    if (!strcmp(share->unique_file_name,filename) && share->last_version)
64
48
      return info;
65
 
    ++it;
66
49
  }
67
50
  return 0;
68
51
}
76
59
  have an open count of 0.
77
60
******************************************************************************/
78
61
 
79
 
MI_INFO *mi_open(const drizzled::TableIdentifier &identifier, int mode, uint32_t open_flags)
 
62
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
80
63
{
81
64
  int lock_error,kfile,open_mode,save_errno,have_rtree=0;
82
 
  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,
83
66
    key_parts,unique_key_parts,fulltext_keys,uniques;
84
67
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
85
 
       data_name[FN_REFLEN], rp_buff[PATH_MAX];
86
 
  unsigned char *disk_cache= NULL;
87
 
  unsigned char *disk_pos, *end_pos;
 
68
       data_name[FN_REFLEN];
 
69
  uchar *disk_cache, *disk_pos, *end_pos;
88
70
  MI_INFO info,*m_info,*old_info;
89
71
  MYISAM_SHARE share_buff,*share;
90
72
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
91
 
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
92
 
  uint64_t max_key_file_length, max_data_file_length;
 
73
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
74
  ulonglong max_key_file_length, max_data_file_length;
 
75
  DBUG_ENTER("mi_open");
93
76
 
94
77
  kfile= -1;
95
78
  lock_error=1;
96
79
  errpos=0;
97
80
  head_length=sizeof(share_buff.state.header);
98
 
  memset(&info, 0, sizeof(info));
 
81
  bzero((uchar*) &info,sizeof(info));
99
82
 
100
 
  (void)internal::fn_format(org_name,
101
 
                            identifier.getPath().c_str(), 
102
 
                            "",
103
 
                            MI_NAME_IEXT,
104
 
                            MY_UNPACK_FILENAME);
105
 
  if (!realpath(org_name,rp_buff))
106
 
    internal::my_load_path(rp_buff,org_name, NULL);
107
 
  rp_buff[FN_REFLEN-1]= '\0';
108
 
  strcpy(name_buff,rp_buff);
109
 
  THR_LOCK_myisam.lock();
 
83
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
 
84
                                   MY_UNPACK_FILENAME),MYF(0));
 
85
  pthread_mutex_lock(&THR_LOCK_myisam);
110
86
  if (!(old_info=test_if_reopen(name_buff)))
111
87
  {
112
88
    share= &share_buff;
113
 
    memset(&share_buff, 0, sizeof(share_buff));
 
89
    bzero((uchar*) &share_buff,sizeof(share_buff));
114
90
    share_buff.state.rec_per_key_part=rec_per_key_part;
115
91
    share_buff.state.key_root=key_root;
116
92
    share_buff.state.key_del=key_del;
117
 
    share_buff.setKeyCache();
 
93
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
 
94
                                                 strlen(name_buff));
118
95
 
119
 
    if ((kfile=internal::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)
120
103
    {
121
104
      if ((errno != EROFS && errno != EACCES) ||
122
105
          mode != O_RDONLY ||
123
 
          (kfile=internal::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)
124
107
        goto err;
125
108
    }
126
109
    share->mode=open_mode;
127
110
    errpos=1;
128
 
    if (internal::my_read(kfile, share->state.header.file_version, head_length,
 
111
    if (my_read(kfile, share->state.header.file_version, head_length,
129
112
                MYF(MY_NABP)))
130
113
    {
131
 
      errno= HA_ERR_NOT_A_TABLE;
 
114
      my_errno= HA_ERR_NOT_A_TABLE;
132
115
      goto err;
133
116
    }
134
 
    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))
135
119
    {
136
 
      errno=HA_ERR_NOT_A_TABLE;
 
120
      DBUG_PRINT("error",("Wrong header in %s",name_buff));
 
121
      DBUG_DUMP("error_dump",(uchar*) share->state.header.file_version,
 
122
                head_length);
 
123
      my_errno=HA_ERR_NOT_A_TABLE;
137
124
      goto err;
138
125
    }
139
126
    share->options= mi_uint2korr(share->state.header.options);
140
127
    if (share->options &
141
128
        ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
142
129
          HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
143
 
          HA_OPTION_TEMP_COMPRESS_RECORD |
144
 
          HA_OPTION_TMP_TABLE
145
 
          ))
146
 
    {
147
 
      errno=HA_ERR_OLD_FILE;
148
 
      goto err;
149
 
    }
150
 
 
 
130
          HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
 
131
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
 
132
          HA_OPTION_RELIES_ON_SQL_LAYER))
 
133
    {
 
134
      DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
 
135
      my_errno=HA_ERR_OLD_FILE;
 
136
      goto err;
 
137
    }
 
138
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
 
139
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
 
140
    {
 
141
      DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
 
142
      my_errno= HA_ERR_UNSUPPORTED;
 
143
      goto err;
 
144
    }
151
145
    /* Don't call realpath() if the name can't be a link */
152
 
    ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
153
 
    if (sym_link_size >= 0 )
154
 
      index_name[sym_link_size]= '\0';
155
 
    if (!strcmp(name_buff, org_name) || sym_link_size == -1)
156
 
      (void) strcpy(index_name, org_name);
 
146
    if (!strcmp(name_buff, org_name) ||
 
147
        my_readlink(index_name, org_name, MYF(0)) == -1)
 
148
      (void) strmov(index_name, org_name);
157
149
    *strrchr(org_name, '.')= '\0';
158
 
    (void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
 
150
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
159
151
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
160
152
 
161
153
    info_length=mi_uint2korr(share->state.header.header_length);
162
154
    base_pos=mi_uint2korr(share->state.header.base_pos);
163
 
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
 
155
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
164
156
    {
165
 
      errno=ENOMEM;
 
157
      my_errno=ENOMEM;
166
158
      goto err;
167
159
    }
168
160
    end_pos=disk_cache+info_length;
169
161
    errpos=2;
170
162
 
171
 
    lseek(kfile,0,SEEK_SET);
 
163
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
 
164
    if (!(open_flags & HA_OPEN_TMP_TABLE))
 
165
    {
 
166
      if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
 
167
                              MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
 
168
                                  0 : MY_DONT_WAIT))) &&
 
169
          !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
 
170
        goto err;
 
171
    }
172
172
    errpos=3;
173
 
    if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
 
173
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
174
174
    {
175
 
      errno=HA_ERR_CRASHED;
 
175
      my_errno=HA_ERR_CRASHED;
176
176
      goto err;
177
177
    }
178
178
    len=mi_uint2korr(share->state.header.state_info_length);
181
181
    fulltext_keys= (uint) share->state.header.fulltext_keys;
182
182
    key_parts= mi_uint2korr(share->state.header.key_parts);
183
183
    unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
 
184
    if (len != MI_STATE_INFO_SIZE)
 
185
    {
 
186
      DBUG_PRINT("warning",
 
187
                 ("saved_state_info_length: %d  state_info_length: %d",
 
188
                  len,MI_STATE_INFO_SIZE));
 
189
    }
184
190
    share->state_diff_length=len-MI_STATE_INFO_SIZE;
185
191
 
186
192
    mi_state_info_read(disk_cache, &share->state);
187
193
    len= mi_uint2korr(share->state.header.base_info_length);
 
194
    if (len != MI_BASE_INFO_SIZE)
 
195
    {
 
196
      DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
 
197
                            len,MI_BASE_INFO_SIZE));
 
198
    }
188
199
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
189
200
    share->state.state_length=base_pos;
190
201
 
191
 
    if (share->state.changed & STATE_CRASHED)
 
202
    if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
 
203
        ((share->state.changed & STATE_CRASHED) ||
 
204
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
 
205
          (my_disable_locking && share->state.open_count))))
192
206
    {
193
 
      errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
 
207
      DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u  "
 
208
                          "changed: %u  open_count: %u  !locking: %d",
 
209
                          open_flags, share->state.changed,
 
210
                          share->state.open_count, my_disable_locking));
 
211
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
194
212
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
195
213
      goto err;
196
214
    }
198
216
    /* sanity check */
199
217
    if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
200
218
    {
201
 
      errno=HA_ERR_CRASHED;
 
219
      my_errno=HA_ERR_CRASHED;
202
220
      goto err;
203
221
    }
204
222
 
205
223
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
206
224
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
207
225
    {
208
 
      errno=HA_ERR_UNSUPPORTED;
 
226
      DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
 
227
      my_errno=HA_ERR_UNSUPPORTED;
209
228
      goto err;
210
229
    }
211
230
 
212
231
    /* Correct max_file_length based on length of sizeof(off_t) */
213
232
    max_data_file_length=
214
233
      (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
215
 
      (((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
 
234
      (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
216
235
      (mi_safe_mul(share->base.pack_reclength,
217
 
                   (uint64_t) 1 << (share->base.rec_reflength*8))-1);
 
236
                   (ulonglong) 1 << (share->base.rec_reflength*8))-1);
218
237
    max_key_file_length=
219
238
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
220
 
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
 
239
                  ((ulonglong) 1 << (share->base.key_reflength*8))-1);
221
240
#if SIZEOF_OFF_T == 4
222
 
    set_if_smaller(max_data_file_length, INT32_MAX);
223
 
    set_if_smaller(max_key_file_length, INT32_MAX);
 
241
    set_if_smaller(max_data_file_length, INT_MAX32);
 
242
    set_if_smaller(max_key_file_length, INT_MAX32);
224
243
#endif
225
244
    if (share->base.raid_type)
226
245
    {
227
 
      errno=HA_ERR_UNSUPPORTED;
 
246
      DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
 
247
      my_errno=HA_ERR_UNSUPPORTED;
228
248
      goto err;
229
249
    }
230
 
    share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
231
 
    share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
 
250
    share->base.max_data_file_length=(my_off_t) max_data_file_length;
 
251
    share->base.max_key_file_length=(my_off_t) max_key_file_length;
232
252
 
233
253
    if (share->options & HA_OPTION_COMPRESS_RECORD)
234
254
      share->base.max_key_length+=2;    /* For safety */
236
256
    /* Add space for node pointer */
237
257
    share->base.max_key_length+= share->base.key_reflength;
238
258
 
239
 
    if (!drizzled::memory::multi_malloc(false,
240
 
           &share,sizeof(*share),
241
 
           &share->state.rec_per_key_part,sizeof(long)*key_parts,
242
 
           &share->keyinfo,keys*sizeof(MI_KEYDEF),
243
 
           &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
244
 
           &share->keyparts,
245
 
           (key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
246
 
           &share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
247
 
           &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
248
 
           &share->unique_file_name,strlen(name_buff)+1,
249
 
           &share->index_file_name,strlen(index_name)+1,
250
 
           &share->data_file_name,strlen(data_name)+1,
251
 
           &share->state.key_root,keys*sizeof(uint64_t),
252
 
           &share->state.key_del,
253
 
           (share->state.header.max_block_size_index*sizeof(uint64_t)),
254
 
           NULL))
 
259
    if (!my_multi_malloc(MY_WME,
 
260
                         &share,sizeof(*share),
 
261
                         &share->state.rec_per_key_part,sizeof(long)*key_parts,
 
262
                         &share->keyinfo,keys*sizeof(MI_KEYDEF),
 
263
                         &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
 
264
                         &share->keyparts,
 
265
                         (key_parts+unique_key_parts+keys+uniques) *
 
266
                         sizeof(HA_KEYSEG),
 
267
                         &share->rec,
 
268
                         (share->base.fields+1)*sizeof(MI_COLUMNDEF),
 
269
                         &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
 
270
                         &share->unique_file_name,strlen(name_buff)+1,
 
271
                         &share->index_file_name,strlen(index_name)+1,
 
272
                         &share->data_file_name,strlen(data_name)+1,
 
273
                         &share->state.key_root,keys*sizeof(my_off_t),
 
274
                         &share->state.key_del,
 
275
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
 
276
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
 
277
                         &share->mmap_lock,sizeof(rw_lock_t),
 
278
                         NullS))
255
279
      goto err;
256
280
    errpos=4;
257
281
    *share=share_buff;
258
 
    memcpy(share->state.rec_per_key_part, rec_per_key_part,
259
 
           sizeof(long)*key_parts);
260
 
    memcpy(share->state.key_root, key_root,
261
 
           sizeof(internal::my_off_t)*keys);
262
 
    memcpy(share->state.key_del, key_del,
263
 
           sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
264
 
    strcpy(share->unique_file_name, name_buff);
 
282
    memcpy((char*) share->state.rec_per_key_part,
 
283
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
284
    memcpy((char*) share->state.key_root,
 
285
           (char*) key_root, sizeof(my_off_t)*keys);
 
286
    memcpy((char*) share->state.key_del,
 
287
           (char*) key_del, (sizeof(my_off_t) *
 
288
                             share->state.header.max_block_size_index));
 
289
    strmov(share->unique_file_name, name_buff);
265
290
    share->unique_name_length= strlen(name_buff);
266
 
    strcpy(share->index_file_name,  index_name);
267
 
    strcpy(share->data_file_name,   data_name);
 
291
    strmov(share->index_file_name,  index_name);
 
292
    strmov(share->data_file_name,   data_name);
268
293
 
269
 
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
 
294
    share->blocksize=min(IO_SIZE,myisam_block_size);
270
295
    {
271
296
      HA_KEYSEG *pos=share->keyparts;
272
297
      for (i=0 ; i < keys ; i++)
275
300
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
276
301
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
277
302
                        end_pos);
278
 
        set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
 
303
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
279
304
        share->keyinfo[i].seg=pos;
280
305
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
281
306
        {
284
309
              ! (share->options & (HA_OPTION_COMPRESS_RECORD |
285
310
                                   HA_OPTION_PACK_RECORD)))
286
311
          {
287
 
            errno= HA_ERR_CRASHED;
 
312
            my_errno= HA_ERR_CRASHED;
288
313
            goto err;
289
314
          }
290
315
          if (pos->type == HA_KEYTYPE_TEXT ||
293
318
          {
294
319
            if (!pos->language)
295
320
              pos->charset=default_charset_info;
296
 
            else if (!(pos->charset= get_charset(pos->language)))
 
321
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
297
322
            {
298
 
              errno=HA_ERR_UNKNOWN_CHARSET;
 
323
              my_errno=HA_ERR_UNKNOWN_CHARSET;
299
324
              goto err;
300
325
            }
301
326
          }
325
350
          {
326
351
            if (!pos->language)
327
352
              pos->charset=default_charset_info;
328
 
            else if (!(pos->charset= get_charset(pos->language)))
 
353
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
329
354
            {
330
 
              errno=HA_ERR_UNKNOWN_CHARSET;
 
355
              my_errno=HA_ERR_UNKNOWN_CHARSET;
331
356
              goto err;
332
357
            }
333
358
          }
359
384
    share->rec[i].type=(int) FIELD_LAST;        /* End marker */
360
385
    if (offset > share->base.reclength)
361
386
    {
362
 
      errno= HA_ERR_CRASHED;
 
387
      /* purecov: begin inspected */
 
388
      my_errno= HA_ERR_CRASHED;
363
389
      goto err;
 
390
      /* purecov: end */
364
391
    }
365
392
 
366
393
    if (! lock_error)
367
394
    {
 
395
      VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
368
396
      lock_error=1;                     /* Database unlocked */
369
397
    }
370
398
 
383
411
    share->base.margin_key_file_length=(share->base.max_key_file_length -
384
412
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
385
413
                                         share->blocksize * keys : 0));
386
 
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
 
414
    share->blocksize=min(IO_SIZE,myisam_block_size);
387
415
    share->data_file_type=STATIC_RECORD;
388
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
416
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
417
    {
 
418
      share->data_file_type = COMPRESSED_RECORD;
 
419
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
420
      info.s=share;
 
421
      if (_mi_read_pack_info(&info,
 
422
                             (pbool)
 
423
                             test(!(share->options &
 
424
                                    (HA_OPTION_PACK_RECORD |
 
425
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
426
        goto err;
 
427
    }
 
428
    else if (share->options & HA_OPTION_PACK_RECORD)
389
429
      share->data_file_type = DYNAMIC_RECORD;
390
 
    free(disk_cache);
391
 
    disk_cache= NULL;
 
430
    my_afree(disk_cache);
392
431
    mi_setup_functions(share);
393
 
    share->is_log_table= false;
394
 
    if (myisam_concurrent_insert)
 
432
    share->is_log_table= FALSE;
 
433
    thr_lock_init(&share->lock);
 
434
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
 
435
    for (i=0; i<keys; i++)
 
436
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
437
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
 
438
    if (!thr_lock_inited)
 
439
    {
 
440
      /* Probably a single threaded program; Don't use concurrent inserts */
 
441
      myisam_concurrent_insert=0;
 
442
    }
 
443
    else if (myisam_concurrent_insert)
395
444
    {
396
445
      share->concurrent_insert=
397
446
        ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
400
449
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
401
450
      if (share->concurrent_insert)
402
451
      {
403
 
        assert(0);
 
452
        share->lock.get_status=mi_get_status;
 
453
        share->lock.copy_status=mi_copy_status;
 
454
        share->lock.update_status=mi_update_status;
 
455
        share->lock.restore_status= mi_restore_status;
 
456
        share->lock.check_status=mi_check_status;
404
457
      }
405
458
    }
 
459
    /*
 
460
      Memory mapping can only be requested after initializing intern_lock.
 
461
    */
 
462
    if (open_flags & HA_OPEN_MMAP)
 
463
    {
 
464
      info.s= share;
 
465
      mi_extra(&info, HA_EXTRA_MMAP, 0);
 
466
    }
406
467
  }
407
468
  else
408
469
  {
409
470
    share= old_info->s;
410
471
    if (mode == O_RDWR && share->mode == O_RDONLY)
411
472
    {
412
 
      errno=EACCES;                             /* Can't open in write mode */
 
473
      my_errno=EACCES;                          /* Can't open in write mode */
413
474
      goto err;
414
475
    }
415
476
    if (mi_open_datafile(&info, share, old_info->dfile))
419
480
  }
420
481
 
421
482
  /* alloc and set up private structure parts */
422
 
  if (!drizzled::memory::multi_malloc(MY_WME,
423
 
         &m_info,sizeof(MI_INFO),
424
 
         &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
425
 
         &info.buff,(share->base.max_key_block_length*2+
426
 
                     share->base.max_key_length),
427
 
         &info.lastkey,share->base.max_key_length*3+1,
428
 
         &info.first_mbr_key, share->base.max_key_length,
429
 
         &info.filename, identifier.getPath().length()+1,
430
 
         &info.rtree_recursion_state,have_rtree ? 1024 : 0,
431
 
         NULL))
 
483
  if (!my_multi_malloc(MY_WME,
 
484
                       &m_info,sizeof(MI_INFO),
 
485
                       &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
 
486
                       &info.buff,(share->base.max_key_block_length*2+
 
487
                                   share->base.max_key_length),
 
488
                       &info.lastkey,share->base.max_key_length*3+1,
 
489
                       &info.first_mbr_key, share->base.max_key_length,
 
490
                       &info.filename,strlen(name)+1,
 
491
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
 
492
                       NullS))
432
493
    goto err;
433
494
  errpos=6;
434
495
 
435
496
  if (!have_rtree)
436
497
    info.rtree_recursion_state= NULL;
437
498
 
438
 
  strcpy(info.filename, identifier.getPath().c_str());
 
499
  strmov(info.filename,name);
439
500
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
440
501
  info.lastkey2=info.lastkey+share->base.max_key_length;
441
502
 
456
517
  info.bulk_insert=0;
457
518
  info.errkey= -1;
458
519
  info.page_changed=1;
 
520
  pthread_mutex_lock(&share->intern_lock);
459
521
  info.read_record=share->read_record;
460
522
  share->reopen++;
461
523
  share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
470
532
  {
471
533
    share->temporary=share->delay_key_write=1;
472
534
    share->write_flag=MYF(MY_NABP);
473
 
    /*
474
 
     * The following two statements are commented out as a fix of
475
 
     * bug https://bugs.launchpad.net/drizzle/+bug/387627
476
 
     *
477
 
     * UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
478
 
     * The root cause of why this makes a difference hasn't
479
 
     * been found, but this fixes things for now.
480
 
     */
481
 
//    share->w_locks++;                 // We don't have to update status
482
 
//    share->tot_locks++;
 
535
    share->w_locks++;                   /* We don't have to update status */
 
536
    share->tot_locks++;
483
537
    info.lock_type=F_WRLCK;
484
538
  }
485
 
 
486
 
  share->delay_key_write= 1;
 
539
  if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
 
540
      (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
 
541
      myisam_delay_key_write)
 
542
    share->delay_key_write=1;
487
543
  info.state= &share->state.state;      /* Change global values by default */
 
544
  pthread_mutex_unlock(&share->intern_lock);
488
545
 
489
546
  /* Allocate buffer for one record */
490
547
 
491
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
 
548
  /* prerequisites: bzero(info) && info->s=share; are met. */
492
549
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
493
550
    goto err;
494
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
551
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
495
552
 
496
553
  *m_info=info;
497
 
  myisam_open_list.push_front(m_info);
 
554
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
 
555
  m_info->open_list.data=(void*) m_info;
 
556
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
498
557
 
499
 
  THR_LOCK_myisam.unlock();
500
 
  return(m_info);
 
558
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
559
  if (myisam_log_file >= 0)
 
560
  {
 
561
    intern_filename(name_buff,share->index_file_name);
 
562
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
563
  }
 
564
  DBUG_RETURN(m_info);
501
565
 
502
566
err:
503
 
  if (disk_cache != NULL)
504
 
    free(disk_cache);
505
 
  save_errno=errno ? errno : HA_ERR_END_OF_FILE;
 
567
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
506
568
  if ((save_errno == HA_ERR_CRASHED) ||
507
569
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
508
570
      (save_errno == HA_ERR_CRASHED_ON_REPAIR))
509
 
    mi_report_error(save_errno, identifier.getPath().c_str());
 
571
    mi_report_error(save_errno, name);
510
572
  switch (errpos) {
511
573
  case 6:
512
 
    free((unsigned char*) m_info);
 
574
    my_free((uchar*) m_info,MYF(0));
513
575
    /* fall through */
514
576
  case 5:
515
 
    internal::my_close(info.dfile,MYF(0));
 
577
    VOID(my_close(info.dfile,MYF(0)));
516
578
    if (old_info)
517
579
      break;                                    /* Don't remove open table */
518
580
    /* fall through */
519
581
  case 4:
520
 
    free((unsigned char*) share);
 
582
    my_free((uchar*) share,MYF(0));
521
583
    /* fall through */
522
584
  case 3:
 
585
    if (! lock_error)
 
586
      VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
 
587
    /* fall through */
 
588
  case 2:
 
589
    my_afree(disk_cache);
523
590
    /* fall through */
524
591
  case 1:
525
 
    internal::my_close(kfile,MYF(0));
 
592
    VOID(my_close(kfile,MYF(0)));
526
593
    /* fall through */
527
594
  case 0:
528
595
  default:
529
596
    break;
530
597
  }
531
 
  THR_LOCK_myisam.unlock();
532
 
  errno=save_errno;
533
 
  return (NULL);
 
598
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
599
  my_errno=save_errno;
 
600
  DBUG_RETURN (NULL);
534
601
} /* mi_open */
535
602
 
536
603
 
537
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
 
604
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
538
605
{
539
 
  uint32_t extra;
540
 
  uint32_t old_length= 0;
 
606
  uint extra;
 
607
  uint32 old_length= 0;
541
608
 
542
609
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
543
610
  {
544
 
    unsigned char *newptr = *buf;
 
611
    uchar *newptr = *buf;
545
612
 
546
613
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
547
614
    if (length == (ulong) -1)
550
617
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
551
618
      else
552
619
        length= info->s->base.pack_reclength;
553
 
      length= max((uint32_t)length, info->s->base.max_key_length);
 
620
      length= max(length, info->s->base.max_key_length);
554
621
      /* Avoid unnecessary realloc */
555
622
      if (newptr && length == old_length)
556
623
        return newptr;
561
628
            MI_REC_BUFF_OFFSET : 0);
562
629
    if (extra && newptr)
563
630
      newptr-= MI_REC_BUFF_OFFSET;
564
 
    void *tmpnewptr= NULL;
565
 
    if (!(tmpnewptr= realloc(newptr, length+extra+8))) 
 
631
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
 
632
                                     MYF(MY_ALLOW_ZERO_PTR))))
566
633
      return newptr;
567
 
    newptr= (unsigned char *)tmpnewptr;
568
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
634
    *((uint32 *) newptr)= (uint32) length;
569
635
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
570
636
  }
571
637
  return *buf;
572
638
}
573
639
 
574
640
 
575
 
static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
641
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
576
642
{
577
 
  uint64_t max_val= ~ (uint64_t) 0;             /* internal::my_off_t is unsigned */
 
643
  ulonglong max_val= ~ (ulonglong) 0;           /* my_off_t is unsigned */
578
644
 
579
645
  if (!a || max_val / a < b)
580
646
    return max_val;
585
651
 
586
652
void mi_setup_functions(register MYISAM_SHARE *share)
587
653
{
588
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
654
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
655
  {
 
656
    share->read_record=_mi_read_pack_record;
 
657
    share->read_rnd=_mi_read_rnd_pack_record;
 
658
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
659
      share->calc_checksum=0;                           /* No checksum */
 
660
    else if (share->options & HA_OPTION_PACK_RECORD)
 
661
      share->calc_checksum= mi_checksum;
 
662
    else
 
663
      share->calc_checksum= mi_static_checksum;
 
664
  }
 
665
  else if (share->options & HA_OPTION_PACK_RECORD)
589
666
  {
590
667
    share->read_record=_mi_read_dynamic_record;
591
668
    share->read_rnd=_mi_read_rnd_dynamic_record;
620
697
  }
621
698
  share->file_read= mi_nommap_pread;
622
699
  share->file_write= mi_nommap_pwrite;
623
 
  share->calc_checksum=0;
 
700
  if (!(share->options & HA_OPTION_CHECKSUM))
 
701
    share->calc_checksum=0;
 
702
  return;
624
703
}
625
704
 
626
705
 
681
760
   Function to save and store the header in the index file (.MYI)
682
761
*/
683
762
 
684
 
uint32_t mi_state_info_write(int file, MI_STATE_INFO *state, uint32_t pWrite)
 
763
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
685
764
{
686
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
687
 
  unsigned char *ptr=buff;
 
765
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
766
  uchar *ptr=buff;
688
767
  uint  i, keys= (uint) state->header.keys,
689
768
        key_blocks=state->header.max_block_size_index;
 
769
  DBUG_ENTER("mi_state_info_write");
690
770
 
691
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
771
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
692
772
  ptr+=sizeof(state->header);
693
773
 
694
774
  /* open_count must be first because of _mi_mark_file_changed ! */
695
775
  mi_int2store(ptr,state->open_count);          ptr +=2;
696
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
776
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
697
777
  mi_rowstore(ptr,state->state.records);        ptr +=8;
698
778
  mi_rowstore(ptr,state->state.del);            ptr +=8;
699
779
  mi_rowstore(ptr,state->split);                ptr +=8;
703
783
  mi_sizestore(ptr,state->state.empty);         ptr +=8;
704
784
  mi_sizestore(ptr,state->state.key_empty);     ptr +=8;
705
785
  mi_int8store(ptr,state->auto_increment);      ptr +=8;
706
 
  mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
 
786
  mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
707
787
  mi_int4store(ptr,state->process);             ptr +=4;
708
788
  mi_int4store(ptr,state->unique);              ptr +=4;
709
789
  mi_int4store(ptr,state->status);              ptr +=4;
721
801
  }
722
802
  if (pWrite & 2)                               /* From isamchk */
723
803
  {
724
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
804
    uint key_parts= mi_uint2korr(state->header.key_parts);
725
805
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
726
806
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
727
807
    mi_int4store(ptr,state->version);           ptr +=4;
728
808
    mi_int8store(ptr,state->key_map);           ptr +=8;
729
 
    mi_int8store(ptr,(uint64_t) state->create_time);    ptr +=8;
730
 
    mi_int8store(ptr,(uint64_t) state->recover_time);   ptr +=8;
731
 
    mi_int8store(ptr,(uint64_t) state->check_time);     ptr +=8;
 
809
    mi_int8store(ptr,(ulonglong) state->create_time);   ptr +=8;
 
810
    mi_int8store(ptr,(ulonglong) state->recover_time);  ptr +=8;
 
811
    mi_int8store(ptr,(ulonglong) state->check_time);    ptr +=8;
732
812
    mi_sizestore(ptr,state->rec_per_key_rows);  ptr+=8;
733
813
    for (i=0 ; i < key_parts ; i++)
734
814
    {
737
817
  }
738
818
 
739
819
  if (pWrite & 1)
740
 
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
 
820
    DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
741
821
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
742
 
  return(internal::my_write(file, buff, (size_t) (ptr-buff),
 
822
  DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
743
823
                       MYF(MY_NABP)) != 0);
744
824
}
745
825
 
746
826
 
747
 
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
827
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
748
828
{
749
 
  uint32_t i,keys,key_parts,key_blocks;
750
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
829
  uint i,keys,key_parts,key_blocks;
 
830
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
751
831
  ptr +=sizeof(state->header);
752
832
  keys=(uint) state->header.keys;
753
833
  key_parts=mi_uint2korr(state->header.key_parts);
765
845
  state->state.empty    = mi_sizekorr(ptr);     ptr +=8;
766
846
  state->state.key_empty= mi_sizekorr(ptr);     ptr +=8;
767
847
  state->auto_increment=mi_uint8korr(ptr);      ptr +=8;
768
 
  state->state.checksum=(internal::ha_checksum) mi_uint8korr(ptr);      ptr +=8;
 
848
  state->state.checksum=(ha_checksum) mi_uint8korr(ptr);        ptr +=8;
769
849
  state->process= mi_uint4korr(ptr);            ptr +=4;
770
850
  state->unique = mi_uint4korr(ptr);            ptr +=4;
771
851
  state->status = mi_uint4korr(ptr);            ptr +=4;
797
877
}
798
878
 
799
879
 
800
 
uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead)
 
880
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
801
881
{
802
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
882
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
803
883
 
804
 
  if (pRead)
 
884
  if (!myisam_single_user)
805
885
  {
806
 
    if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
 
886
    if (pRead)
 
887
    {
 
888
      if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
 
889
        return 1;
 
890
    }
 
891
    else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
807
892
      return 1;
 
893
    mi_state_info_read(buff, state);
808
894
  }
809
 
  else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
810
 
    return 1;
811
 
  mi_state_info_read(buff, state);
812
 
 
813
895
  return 0;
814
896
}
815
897
 
818
900
**  store and read of MI_BASE_INFO
819
901
****************************************************************************/
820
902
 
821
 
uint32_t mi_base_info_write(int file, MI_BASE_INFO *base)
 
903
uint mi_base_info_write(File file, MI_BASE_INFO *base)
822
904
{
823
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
905
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
824
906
 
825
907
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
826
908
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
845
927
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
846
928
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
847
929
  *ptr++= base->extra_alloc_procent;
848
 
  /* old raid info  slots */
849
 
  *ptr++= 0;
850
 
  mi_int2store(ptr,UINT16_C(0));                        ptr +=2;
851
 
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
852
 
 
853
 
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
854
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
930
  *ptr++= base->raid_type;
 
931
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
932
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
933
  bzero(ptr,6);                                         ptr +=6; /* extra */
 
934
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
855
935
}
856
936
 
857
937
 
858
 
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
938
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
859
939
{
860
940
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
861
941
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
881
961
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
882
962
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
883
963
  base->extra_alloc_procent = *ptr++;
884
 
 
885
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
886
 
  ptr+= 7;
 
964
  base->raid_type= *ptr++;
 
965
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
966
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
967
  /* TO BE REMOVED: Fix for old RAID files */
 
968
  if (base->raid_type == 0)
 
969
  {
 
970
    base->raid_chunks=0;
 
971
    base->raid_chunksize=0;
 
972
  }
887
973
 
888
974
  ptr+=6;
889
975
  return ptr;
893
979
  mi_keydef
894
980
---------------------------------------------------------------------------*/
895
981
 
896
 
uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef)
 
982
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
897
983
{
898
 
  unsigned char buff[MI_KEYDEF_SIZE];
899
 
  unsigned char *ptr=buff;
 
984
  uchar buff[MI_KEYDEF_SIZE];
 
985
  uchar *ptr=buff;
900
986
 
901
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
987
  *ptr++ = (uchar) keydef->keysegs;
902
988
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
903
989
  mi_int2store(ptr,keydef->flag);               ptr +=2;
904
990
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
905
991
  mi_int2store(ptr,keydef->keylength);          ptr +=2;
906
992
  mi_int2store(ptr,keydef->minlength);          ptr +=2;
907
993
  mi_int2store(ptr,keydef->maxlength);          ptr +=2;
908
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
994
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
909
995
}
910
996
 
911
 
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
997
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
912
998
{
913
999
   keydef->keysegs      = (uint) *ptr++;
914
1000
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
928
1014
**  mi_keyseg
929
1015
***************************************************************************/
930
1016
 
931
 
int mi_keyseg_write(int file, const HA_KEYSEG *keyseg)
 
1017
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
932
1018
{
933
 
  unsigned char buff[HA_KEYSEG_SIZE];
934
 
  unsigned char *ptr=buff;
 
1019
  uchar buff[HA_KEYSEG_SIZE];
 
1020
  uchar *ptr=buff;
935
1021
  ulong pos;
936
1022
 
937
1023
  *ptr++= keyseg->type;
946
1032
  pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
947
1033
  mi_int4store(ptr, pos);
948
1034
  ptr+=4;
949
 
 
950
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1035
  
 
1036
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
951
1037
}
952
1038
 
953
1039
 
954
 
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
1040
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
955
1041
{
956
1042
   keyseg->type         = *ptr++;
957
1043
   keyseg->language     = *ptr++;
965
1051
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
966
1052
   keyseg->charset=0;                           /* Will be filled in later */
967
1053
   if (keyseg->null_bit)
968
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1054
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
969
1055
   else
970
1056
   {
971
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1057
     keyseg->bit_pos= (uint16)keyseg->null_pos;
972
1058
     keyseg->null_pos= 0;
973
1059
   }
974
1060
   return ptr;
978
1064
  mi_uniquedef
979
1065
---------------------------------------------------------------------------*/
980
1066
 
981
 
uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *def)
 
1067
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
982
1068
{
983
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
984
 
  unsigned char *ptr=buff;
 
1069
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1070
  uchar *ptr=buff;
985
1071
 
986
1072
  mi_int2store(ptr,def->keysegs);               ptr+=2;
987
 
  *ptr++=  (unsigned char) def->key;
988
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1073
  *ptr++=  (uchar) def->key;
 
1074
  *ptr++ = (uchar) def->null_are_equal;
989
1075
 
990
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1076
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
991
1077
}
992
1078
 
993
 
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1079
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
994
1080
{
995
1081
   def->keysegs = mi_uint2korr(ptr);
996
1082
   def->key     = ptr[2];
1002
1088
**  MI_COLUMNDEF
1003
1089
***************************************************************************/
1004
1090
 
1005
 
uint32_t mi_recinfo_write(int file, MI_COLUMNDEF *recinfo)
 
1091
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1006
1092
{
1007
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1008
 
  unsigned char *ptr=buff;
 
1093
  uchar buff[MI_COLUMNDEF_SIZE];
 
1094
  uchar *ptr=buff;
1009
1095
 
1010
1096
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1011
1097
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1012
1098
  *ptr++ = recinfo->null_bit;
1013
1099
  mi_int2store(ptr,recinfo->null_pos);  ptr+= 2;
1014
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1100
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1015
1101
}
1016
1102
 
1017
 
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1103
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1018
1104
{
1019
1105
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1020
1106
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1021
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1107
   recinfo->null_bit= (uint8) *ptr++;
1022
1108
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1023
1109
   return ptr;
1024
1110
}
1025
1111
 
1026
1112
/**************************************************************************
1027
 
Open data file
 
1113
Open data file with or without RAID
1028
1114
We can't use dup() here as the data file descriptors need to have different
1029
1115
active seek-positions.
1030
1116
 
1032
1118
exist a dup()-like call that would give us two different file descriptors.
1033
1119
*************************************************************************/
1034
1120
 
1035
 
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
 
1121
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
 
1122
                     File file_to_dup __attribute__((unused)))
1036
1123
{
1037
 
  (void)file_to_dup; 
1038
 
  info->dfile=internal::my_open(share->data_file_name, share->mode,
1039
 
                      MYF(MY_WME));
 
1124
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
 
1125
                        MYF(MY_WME));
1040
1126
  return info->dfile >= 0 ? 0 : 1;
1041
1127
}
1042
1128
 
1043
1129
 
1044
1130
int mi_open_keyfile(MYISAM_SHARE *share)
1045
1131
{
1046
 
  if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
 
1132
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1047
1133
                            MYF(MY_WME))) < 0)
1048
1134
    return 1;
1049
1135
  return 0;