~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

  • Committer: Jim Winstead
  • Date: 2008-07-19 02:56:45 UTC
  • mto: (202.1.8 codestyle)
  • mto: This revision was merged to the branch mainline in revision 207.
  • Revision ID: jimw@mysql.com-20080719025645-w2pwytebgzusjzjb
Various fixes to enable compilation on Mac OS X, and remove the glib dependency.
Temporarily disables tab-completion in the drizzle client until an appropriate
autoconf check can be added/enabled.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/* open a isam-database */
17
17
 
18
 
#include "myisam_priv.h"
19
 
 
20
 
#include <string.h>
21
 
#include <algorithm>
22
 
#include <memory>
23
 
#include <boost/scoped_ptr.hpp>
24
 
#include <boost/scoped_array.hpp>
25
 
 
26
 
#include "drizzled/charset_info.h"
27
 
#include "drizzled/internal/m_string.h"
28
 
#include "drizzled/util/test.h"
29
 
#include "drizzled/global_charset_info.h"
30
 
#include "drizzled/charset.h"
31
 
#include "drizzled/memory/multi_malloc.h"
32
 
 
33
 
 
34
 
using namespace std;
35
 
using namespace drizzled;
 
18
#include "myisamdef.h"
 
19
#include <m_ctype.h>
36
20
 
37
21
static void setup_key_functions(MI_KEYDEF *keyinfo);
38
 
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef);
39
 
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg);
40
 
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo);
41
 
static uint64_t mi_safe_mul(uint64_t a, uint64_t b);
42
 
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state);
43
 
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def);
44
 
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
 
45
25
 
46
26
#define disk_pos_assert(pos, end_pos) \
47
27
if (pos > end_pos)             \
48
28
{                              \
49
 
  errno=HA_ERR_CRASHED;     \
 
29
  my_errno=HA_ERR_CRASHED;     \
50
30
  goto err;                    \
51
31
}
52
32
 
58
38
 
59
39
MI_INFO *test_if_reopen(char *filename)
60
40
{
61
 
  list<MI_INFO *>::iterator it= myisam_open_list.begin();
62
 
  while (it != myisam_open_list.end())
 
41
  LIST *pos;
 
42
 
 
43
  for (pos=myisam_open_list ; pos ; pos=pos->next)
63
44
  {
64
 
    MI_INFO *info= *it;
 
45
    MI_INFO *info=(MI_INFO*) pos->data;
65
46
    MYISAM_SHARE *share=info->s;
66
47
    if (!strcmp(share->unique_file_name,filename) && share->last_version)
67
48
      return info;
68
 
    ++it;
69
49
  }
70
50
  return 0;
71
51
}
79
59
  have an open count of 0.
80
60
******************************************************************************/
81
61
 
82
 
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)
83
63
{
84
64
  int lock_error,kfile,open_mode,save_errno,have_rtree=0;
85
 
  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,
86
66
    key_parts,unique_key_parts,fulltext_keys,uniques;
87
67
  char name_buff[FN_REFLEN], org_name[FN_REFLEN], index_name[FN_REFLEN],
88
 
       data_name[FN_REFLEN], rp_buff[PATH_MAX];
89
 
  unsigned char *disk_cache= NULL;
90
 
  unsigned char *disk_pos, *end_pos;
 
68
       data_name[FN_REFLEN];
 
69
  uchar *disk_cache, *disk_pos, *end_pos;
91
70
  MI_INFO info,*m_info,*old_info;
92
 
  boost::scoped_ptr<MYISAM_SHARE> share_buff_ap(new MYISAM_SHARE);
93
 
  MYISAM_SHARE &share_buff= *share_buff_ap.get();
94
 
  MYISAM_SHARE *share;
95
 
  boost::scoped_array<ulong> rec_per_key_part_ap(new ulong[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG]);
96
 
  ulong *rec_per_key_part= rec_per_key_part_ap.get();
97
 
  internal::my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
71
  MYISAM_SHARE share_buff,*share;
 
72
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
 
73
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
98
74
  uint64_t max_key_file_length, max_data_file_length;
99
75
 
100
76
  kfile= -1;
101
77
  lock_error=1;
102
78
  errpos=0;
103
79
  head_length=sizeof(share_buff.state.header);
104
 
  memset(&info, 0, sizeof(info));
 
80
  bzero((uchar*) &info,sizeof(info));
105
81
 
106
 
  (void)internal::fn_format(org_name,
107
 
                            identifier.getPath().c_str(), 
108
 
                            "",
109
 
                            MI_NAME_IEXT,
110
 
                            MY_UNPACK_FILENAME);
111
 
  if (!realpath(org_name,rp_buff))
112
 
    internal::my_load_path(rp_buff,org_name, NULL);
113
 
  rp_buff[FN_REFLEN-1]= '\0';
114
 
  strcpy(name_buff,rp_buff);
115
 
  THR_LOCK_myisam.lock();
 
82
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
 
83
                                   MY_UNPACK_FILENAME),MYF(0));
 
84
  pthread_mutex_lock(&THR_LOCK_myisam);
116
85
  if (!(old_info=test_if_reopen(name_buff)))
117
86
  {
118
87
    share= &share_buff;
119
 
    memset(&share_buff, 0, sizeof(share_buff));
 
88
    bzero((uchar*) &share_buff,sizeof(share_buff));
120
89
    share_buff.state.rec_per_key_part=rec_per_key_part;
121
90
    share_buff.state.key_root=key_root;
122
91
    share_buff.state.key_del=key_del;
123
 
    share_buff.setKeyCache();
 
92
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
 
93
                                                 strlen(name_buff));
124
94
 
125
 
    if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
 
95
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
126
96
    {
127
97
      if ((errno != EROFS && errno != EACCES) ||
128
98
          mode != O_RDONLY ||
129
 
          (kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
 
99
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
130
100
        goto err;
131
101
    }
132
102
    share->mode=open_mode;
133
103
    errpos=1;
134
 
    if (internal::my_read(kfile, share->state.header.file_version, head_length,
 
104
    if (my_read(kfile, share->state.header.file_version, head_length,
135
105
                MYF(MY_NABP)))
136
106
    {
137
 
      errno= HA_ERR_NOT_A_TABLE;
 
107
      my_errno= HA_ERR_NOT_A_TABLE;
138
108
      goto err;
139
109
    }
140
 
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
 
110
    if (memcmp((uchar*) share->state.header.file_version,
 
111
               (uchar*) myisam_file_magic, 4))
141
112
    {
142
 
      errno=HA_ERR_NOT_A_TABLE;
 
113
      my_errno=HA_ERR_NOT_A_TABLE;
143
114
      goto err;
144
115
    }
145
116
    share->options= mi_uint2korr(share->state.header.options);
146
 
    static const uint64_t OLD_FILE_OPTIONS= HA_OPTION_PACK_RECORD |
147
 
            HA_OPTION_PACK_KEYS |
148
 
            HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
149
 
            HA_OPTION_TEMP_COMPRESS_RECORD |
150
 
            HA_OPTION_TMP_TABLE;
151
 
    if (share->options & ~OLD_FILE_OPTIONS)
152
 
    {
153
 
      errno=HA_ERR_OLD_FILE;
154
 
      goto err;
155
 
    }
156
 
 
 
117
    if (share->options &
 
118
        ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
 
119
          HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
 
120
          HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
 
121
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
 
122
          HA_OPTION_RELIES_ON_SQL_LAYER))
 
123
    {
 
124
      my_errno=HA_ERR_OLD_FILE;
 
125
      goto err;
 
126
    }
 
127
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
 
128
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
 
129
    {
 
130
      my_errno= HA_ERR_UNSUPPORTED;
 
131
      goto err;
 
132
    }
157
133
    /* Don't call realpath() if the name can't be a link */
158
 
    ssize_t sym_link_size= readlink(org_name,index_name,FN_REFLEN-1);
159
 
    if (sym_link_size >= 0 )
160
 
      index_name[sym_link_size]= '\0';
161
 
    if (!strcmp(name_buff, org_name) || sym_link_size == -1)
162
 
      (void) strcpy(index_name, org_name);
 
134
    if (!strcmp(name_buff, org_name) ||
 
135
        my_readlink(index_name, org_name, MYF(0)) == -1)
 
136
      (void) strmov(index_name, org_name);
163
137
    *strrchr(org_name, '.')= '\0';
164
 
    (void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
 
138
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
165
139
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
166
140
 
167
141
    info_length=mi_uint2korr(share->state.header.header_length);
168
142
    base_pos=mi_uint2korr(share->state.header.base_pos);
169
 
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
 
143
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
170
144
    {
171
 
      errno=ENOMEM;
 
145
      my_errno=ENOMEM;
172
146
      goto err;
173
147
    }
174
148
    end_pos=disk_cache+info_length;
175
149
    errpos=2;
176
150
 
177
 
    lseek(kfile,0,SEEK_SET);
 
151
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
178
152
    errpos=3;
179
 
    if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
 
153
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
180
154
    {
181
 
      errno=HA_ERR_CRASHED;
 
155
      my_errno=HA_ERR_CRASHED;
182
156
      goto err;
183
157
    }
184
158
    len=mi_uint2korr(share->state.header.state_info_length);
194
168
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
195
169
    share->state.state_length=base_pos;
196
170
 
197
 
    if (share->state.changed & STATE_CRASHED)
 
171
    if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
 
172
        ((share->state.changed & STATE_CRASHED) ||
 
173
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
 
174
          (share->state.open_count))))
198
175
    {
199
 
      errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
 
176
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
200
177
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
201
178
      goto err;
202
179
    }
204
181
    /* sanity check */
205
182
    if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
206
183
    {
207
 
      errno=HA_ERR_CRASHED;
 
184
      my_errno=HA_ERR_CRASHED;
208
185
      goto err;
209
186
    }
210
187
 
211
188
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
212
189
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
213
190
    {
214
 
      errno=HA_ERR_UNSUPPORTED;
 
191
      my_errno=HA_ERR_UNSUPPORTED;
215
192
      goto err;
216
193
    }
217
194
 
225
202
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
226
203
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
227
204
#if SIZEOF_OFF_T == 4
228
 
    set_if_smaller(max_data_file_length, INT32_MAX);
229
 
    set_if_smaller(max_key_file_length, INT32_MAX);
 
205
    set_if_smaller(max_data_file_length, INT_MAX32);
 
206
    set_if_smaller(max_key_file_length, INT_MAX32);
230
207
#endif
231
208
    if (share->base.raid_type)
232
209
    {
233
 
      errno=HA_ERR_UNSUPPORTED;
 
210
      my_errno=HA_ERR_UNSUPPORTED;
234
211
      goto err;
235
212
    }
236
 
    share->base.max_data_file_length=(internal::my_off_t) max_data_file_length;
237
 
    share->base.max_key_file_length=(internal::my_off_t) max_key_file_length;
 
213
    share->base.max_data_file_length=(my_off_t) max_data_file_length;
 
214
    share->base.max_key_file_length=(my_off_t) max_key_file_length;
238
215
 
239
216
    if (share->options & HA_OPTION_COMPRESS_RECORD)
240
217
      share->base.max_key_length+=2;    /* For safety */
242
219
    /* Add space for node pointer */
243
220
    share->base.max_key_length+= share->base.key_reflength;
244
221
 
245
 
    if (!drizzled::memory::multi_malloc(false,
246
 
           &share,sizeof(*share),
247
 
           &share->state.rec_per_key_part,sizeof(long)*key_parts,
248
 
           &share->keyinfo,keys*sizeof(MI_KEYDEF),
249
 
           &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
250
 
           &share->keyparts,
251
 
           (key_parts+unique_key_parts+keys+uniques) * sizeof(HA_KEYSEG),
252
 
           &share->rec, (share->base.fields+1)*sizeof(MI_COLUMNDEF),
253
 
           &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
254
 
           &share->unique_file_name,strlen(name_buff)+1,
255
 
           &share->index_file_name,strlen(index_name)+1,
256
 
           &share->data_file_name,strlen(data_name)+1,
257
 
           &share->state.key_root,keys*sizeof(uint64_t),
258
 
           &share->state.key_del,
259
 
           (share->state.header.max_block_size_index*sizeof(uint64_t)),
260
 
           NULL))
 
222
    if (!my_multi_malloc(MY_WME,
 
223
                         &share,sizeof(*share),
 
224
                         &share->state.rec_per_key_part,sizeof(long)*key_parts,
 
225
                         &share->keyinfo,keys*sizeof(MI_KEYDEF),
 
226
                         &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
 
227
                         &share->keyparts,
 
228
                         (key_parts+unique_key_parts+keys+uniques) *
 
229
                         sizeof(HA_KEYSEG),
 
230
                         &share->rec,
 
231
                         (share->base.fields+1)*sizeof(MI_COLUMNDEF),
 
232
                         &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
 
233
                         &share->unique_file_name,strlen(name_buff)+1,
 
234
                         &share->index_file_name,strlen(index_name)+1,
 
235
                         &share->data_file_name,strlen(data_name)+1,
 
236
                         &share->state.key_root,keys*sizeof(my_off_t),
 
237
                         &share->state.key_del,
 
238
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
 
239
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
 
240
                         &share->mmap_lock,sizeof(rw_lock_t),
 
241
                         NullS))
261
242
      goto err;
262
243
    errpos=4;
263
244
    *share=share_buff;
264
 
    memcpy(share->state.rec_per_key_part, rec_per_key_part,
265
 
           sizeof(long)*key_parts);
266
 
    memcpy(share->state.key_root, key_root,
267
 
           sizeof(internal::my_off_t)*keys);
268
 
    memcpy(share->state.key_del, key_del,
269
 
           sizeof(internal::my_off_t) * share->state.header.max_block_size_index);
270
 
    strcpy(share->unique_file_name, name_buff);
 
245
    memcpy((char*) share->state.rec_per_key_part,
 
246
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
247
    memcpy((char*) share->state.key_root,
 
248
           (char*) key_root, sizeof(my_off_t)*keys);
 
249
    memcpy((char*) share->state.key_del,
 
250
           (char*) key_del, (sizeof(my_off_t) *
 
251
                             share->state.header.max_block_size_index));
 
252
    strmov(share->unique_file_name, name_buff);
271
253
    share->unique_name_length= strlen(name_buff);
272
 
    strcpy(share->index_file_name,  index_name);
273
 
    strcpy(share->data_file_name,   data_name);
 
254
    strmov(share->index_file_name,  index_name);
 
255
    strmov(share->data_file_name,   data_name);
274
256
 
275
 
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
 
257
    share->blocksize=min(IO_SIZE,myisam_block_size);
276
258
    {
277
259
      HA_KEYSEG *pos=share->keyparts;
278
260
      for (i=0 ; i < keys ; i++)
281
263
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
282
264
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
283
265
                        end_pos);
284
 
        set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
 
266
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
285
267
        share->keyinfo[i].seg=pos;
286
268
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
287
269
        {
290
272
              ! (share->options & (HA_OPTION_COMPRESS_RECORD |
291
273
                                   HA_OPTION_PACK_RECORD)))
292
274
          {
293
 
            errno= HA_ERR_CRASHED;
 
275
            my_errno= HA_ERR_CRASHED;
294
276
            goto err;
295
277
          }
296
278
          if (pos->type == HA_KEYTYPE_TEXT ||
299
281
          {
300
282
            if (!pos->language)
301
283
              pos->charset=default_charset_info;
302
 
            else if (!(pos->charset= get_charset(pos->language)))
 
284
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
303
285
            {
304
 
              errno=HA_ERR_UNKNOWN_CHARSET;
 
286
              my_errno=HA_ERR_UNKNOWN_CHARSET;
305
287
              goto err;
306
288
            }
307
289
          }
331
313
          {
332
314
            if (!pos->language)
333
315
              pos->charset=default_charset_info;
334
 
            else if (!(pos->charset= get_charset(pos->language)))
 
316
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
335
317
            {
336
 
              errno=HA_ERR_UNKNOWN_CHARSET;
 
318
              my_errno=HA_ERR_UNKNOWN_CHARSET;
337
319
              goto err;
338
320
            }
339
321
          }
365
347
    share->rec[i].type=(int) FIELD_LAST;        /* End marker */
366
348
    if (offset > share->base.reclength)
367
349
    {
368
 
      errno= HA_ERR_CRASHED;
 
350
      /* purecov: begin inspected */
 
351
      my_errno= HA_ERR_CRASHED;
369
352
      goto err;
 
353
      /* purecov: end */
370
354
    }
371
355
 
372
356
    if (! lock_error)
389
373
    share->base.margin_key_file_length=(share->base.max_key_file_length -
390
374
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
391
375
                                         share->blocksize * keys : 0));
392
 
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
 
376
    share->blocksize=min(IO_SIZE,myisam_block_size);
393
377
    share->data_file_type=STATIC_RECORD;
394
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
378
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
379
    {
 
380
      share->data_file_type = COMPRESSED_RECORD;
 
381
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
382
      info.s=share;
 
383
      if (_mi_read_pack_info(&info,
 
384
                             (bool)
 
385
                             test(!(share->options &
 
386
                                    (HA_OPTION_PACK_RECORD |
 
387
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
388
        goto err;
 
389
    }
 
390
    else if (share->options & HA_OPTION_PACK_RECORD)
395
391
      share->data_file_type = DYNAMIC_RECORD;
396
 
    free(disk_cache);
397
 
    disk_cache= NULL;
 
392
    my_afree(disk_cache);
398
393
    mi_setup_functions(share);
399
394
    share->is_log_table= false;
400
 
    if (myisam_concurrent_insert)
 
395
    thr_lock_init(&share->lock);
 
396
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
 
397
    for (i=0; i<keys; i++)
 
398
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
399
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
 
400
    if (!thr_lock_inited)
 
401
    {
 
402
      /* Probably a single threaded program; Don't use concurrent inserts */
 
403
      myisam_concurrent_insert=0;
 
404
    }
 
405
    else if (myisam_concurrent_insert)
401
406
    {
402
407
      share->concurrent_insert=
403
408
        ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
406
411
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
407
412
      if (share->concurrent_insert)
408
413
      {
409
 
        assert(0);
 
414
        share->lock.get_status= mi_get_status;
 
415
        share->lock.copy_status= mi_copy_status;
 
416
        share->lock.update_status= mi_update_status;
 
417
        share->lock.restore_status= mi_restore_status;
 
418
        share->lock.check_status= mi_check_status;
410
419
      }
411
420
    }
 
421
    /*
 
422
      Memory mapping can only be requested after initializing intern_lock.
 
423
    */
 
424
    if (open_flags & HA_OPEN_MMAP)
 
425
    {
 
426
      info.s= share;
 
427
      mi_extra(&info, HA_EXTRA_MMAP, 0);
 
428
    }
412
429
  }
413
430
  else
414
431
  {
415
432
    share= old_info->s;
416
433
    if (mode == O_RDWR && share->mode == O_RDONLY)
417
434
    {
418
 
      errno=EACCES;                             /* Can't open in write mode */
 
435
      my_errno=EACCES;                          /* Can't open in write mode */
419
436
      goto err;
420
437
    }
421
438
    if (mi_open_datafile(&info, share, old_info->dfile))
425
442
  }
426
443
 
427
444
  /* alloc and set up private structure parts */
428
 
  if (!drizzled::memory::multi_malloc(MY_WME,
429
 
         &m_info,sizeof(MI_INFO),
430
 
         &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
431
 
         &info.buff,(share->base.max_key_block_length*2+
432
 
                     share->base.max_key_length),
433
 
         &info.lastkey,share->base.max_key_length*3+1,
434
 
         &info.first_mbr_key, share->base.max_key_length,
435
 
         &info.filename, identifier.getPath().length()+1,
436
 
         &info.rtree_recursion_state,have_rtree ? 1024 : 0,
437
 
         NULL))
 
445
  if (!my_multi_malloc(MY_WME,
 
446
                       &m_info,sizeof(MI_INFO),
 
447
                       &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
 
448
                       &info.buff,(share->base.max_key_block_length*2+
 
449
                                   share->base.max_key_length),
 
450
                       &info.lastkey,share->base.max_key_length*3+1,
 
451
                       &info.first_mbr_key, share->base.max_key_length,
 
452
                       &info.filename,strlen(name)+1,
 
453
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
 
454
                       NullS))
438
455
    goto err;
439
456
  errpos=6;
440
457
 
441
458
  if (!have_rtree)
442
459
    info.rtree_recursion_state= NULL;
443
460
 
444
 
  strcpy(info.filename, identifier.getPath().c_str());
 
461
  strmov(info.filename,name);
445
462
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
446
463
  info.lastkey2=info.lastkey+share->base.max_key_length;
447
464
 
462
479
  info.bulk_insert=0;
463
480
  info.errkey= -1;
464
481
  info.page_changed=1;
 
482
  pthread_mutex_lock(&share->intern_lock);
465
483
  info.read_record=share->read_record;
466
484
  share->reopen++;
467
485
  share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
476
494
  {
477
495
    share->temporary=share->delay_key_write=1;
478
496
    share->write_flag=MYF(MY_NABP);
479
 
    /*
480
 
     * The following two statements are commented out as a fix of
481
 
     * bug https://bugs.launchpad.net/drizzle/+bug/387627
482
 
     *
483
 
     * UPDATE can be TRUNCATE on TEMPORARY TABLE (MyISAM).
484
 
     * The root cause of why this makes a difference hasn't
485
 
     * been found, but this fixes things for now.
486
 
     */
487
 
//    share->w_locks++;                 // We don't have to update status
488
 
//    share->tot_locks++;
 
497
    share->w_locks++;                   /* We don't have to update status */
 
498
    share->tot_locks++;
489
499
    info.lock_type=F_WRLCK;
490
500
  }
491
 
 
492
 
  share->delay_key_write= 1;
 
501
  if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
 
502
      (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
 
503
      myisam_delay_key_write)
 
504
    share->delay_key_write=1;
493
505
  info.state= &share->state.state;      /* Change global values by default */
 
506
  pthread_mutex_unlock(&share->intern_lock);
494
507
 
495
508
  /* Allocate buffer for one record */
496
509
 
497
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
498
 
  if (!mi_alloc_rec_buff(&info, SIZE_MAX, &info.rec_buff))
 
510
  /* prerequisites: bzero(info) && info->s=share; are met. */
 
511
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
499
512
    goto err;
500
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
513
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
501
514
 
502
515
  *m_info=info;
503
 
  myisam_open_list.push_front(m_info);
 
516
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
 
517
  m_info->open_list.data=(void*) m_info;
 
518
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
504
519
 
505
 
  THR_LOCK_myisam.unlock();
 
520
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
521
  if (myisam_log_file >= 0)
 
522
  {
 
523
    intern_filename(name_buff,share->index_file_name);
 
524
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
525
  }
506
526
  return(m_info);
507
527
 
508
528
err:
509
 
  if (disk_cache != NULL)
510
 
    free(disk_cache);
511
 
  save_errno=errno ? errno : HA_ERR_END_OF_FILE;
 
529
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
512
530
  if ((save_errno == HA_ERR_CRASHED) ||
513
531
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
514
532
      (save_errno == HA_ERR_CRASHED_ON_REPAIR))
515
 
    mi_report_error(save_errno, identifier.getPath().c_str());
 
533
    mi_report_error(save_errno, name);
516
534
  switch (errpos) {
517
535
  case 6:
518
 
    free((unsigned char*) m_info);
 
536
    my_free((uchar*) m_info,MYF(0));
519
537
    /* fall through */
520
538
  case 5:
521
 
    internal::my_close(info.dfile,MYF(0));
 
539
    VOID(my_close(info.dfile,MYF(0)));
522
540
    if (old_info)
523
541
      break;                                    /* Don't remove open table */
524
542
    /* fall through */
525
543
  case 4:
526
 
    free((unsigned char*) share);
 
544
    my_free((uchar*) share,MYF(0));
527
545
    /* fall through */
528
546
  case 3:
529
547
    /* fall through */
 
548
  case 2:
 
549
    my_afree(disk_cache);
 
550
    /* fall through */
530
551
  case 1:
531
 
    internal::my_close(kfile,MYF(0));
 
552
    VOID(my_close(kfile,MYF(0)));
532
553
    /* fall through */
533
554
  case 0:
534
555
  default:
535
556
    break;
536
557
  }
537
 
  THR_LOCK_myisam.unlock();
538
 
  errno=save_errno;
 
558
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
559
  my_errno=save_errno;
539
560
  return (NULL);
540
561
} /* mi_open */
541
562
 
542
563
 
543
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
 
564
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
544
565
{
545
 
  uint32_t extra;
546
 
  uint32_t old_length= 0;
 
566
  uint extra;
 
567
  uint32 old_length= 0;
547
568
 
548
569
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
549
570
  {
550
 
    unsigned char *newptr = *buf;
 
571
    uchar *newptr = *buf;
551
572
 
552
573
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
553
 
    if (length == SIZE_MAX)
 
574
    if (length == (ulong) -1)
554
575
    {
555
576
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
556
577
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
557
578
      else
558
579
        length= info->s->base.pack_reclength;
559
 
      length= max((uint32_t)length, info->s->base.max_key_length);
 
580
      length= max(length, info->s->base.max_key_length);
560
581
      /* Avoid unnecessary realloc */
561
582
      if (newptr && length == old_length)
562
583
        return newptr;
567
588
            MI_REC_BUFF_OFFSET : 0);
568
589
    if (extra && newptr)
569
590
      newptr-= MI_REC_BUFF_OFFSET;
570
 
    void *tmpnewptr= NULL;
571
 
    if (!(tmpnewptr= realloc(newptr, length+extra+8))) 
 
591
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
 
592
                                     MYF(MY_ALLOW_ZERO_PTR))))
572
593
      return newptr;
573
 
    newptr= (unsigned char *)tmpnewptr;
574
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
594
    *((uint32 *) newptr)= (uint32) length;
575
595
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
576
596
  }
577
597
  return *buf;
578
598
}
579
599
 
580
600
 
581
 
static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
601
uint64_t mi_safe_mul(uint64_t a, uint64_t b)
582
602
{
583
 
  uint64_t max_val= ~ (uint64_t) 0;             /* internal::my_off_t is unsigned */
 
603
  uint64_t max_val= ~ (uint64_t) 0;             /* my_off_t is unsigned */
584
604
 
585
605
  if (!a || max_val / a < b)
586
606
    return max_val;
591
611
 
592
612
void mi_setup_functions(register MYISAM_SHARE *share)
593
613
{
594
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
614
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
615
  {
 
616
    share->read_record=_mi_read_pack_record;
 
617
    share->read_rnd=_mi_read_rnd_pack_record;
 
618
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
619
      share->calc_checksum=0;                           /* No checksum */
 
620
    else if (share->options & HA_OPTION_PACK_RECORD)
 
621
      share->calc_checksum= mi_checksum;
 
622
    else
 
623
      share->calc_checksum= mi_static_checksum;
 
624
  }
 
625
  else if (share->options & HA_OPTION_PACK_RECORD)
595
626
  {
596
627
    share->read_record=_mi_read_dynamic_record;
597
628
    share->read_rnd=_mi_read_rnd_dynamic_record;
626
657
  }
627
658
  share->file_read= mi_nommap_pread;
628
659
  share->file_write= mi_nommap_pwrite;
629
 
  share->calc_checksum=0;
 
660
  if (!(share->options & HA_OPTION_CHECKSUM))
 
661
    share->calc_checksum=0;
 
662
  return;
630
663
}
631
664
 
632
665
 
687
720
   Function to save and store the header in the index file (.MYI)
688
721
*/
689
722
 
690
 
uint32_t mi_state_info_write(int file, MI_STATE_INFO *state, uint32_t pWrite)
 
723
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
691
724
{
692
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
693
 
  unsigned char *ptr=buff;
 
725
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
726
  uchar *ptr=buff;
694
727
  uint  i, keys= (uint) state->header.keys,
695
728
        key_blocks=state->header.max_block_size_index;
696
729
 
697
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
730
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
698
731
  ptr+=sizeof(state->header);
699
732
 
700
733
  /* open_count must be first because of _mi_mark_file_changed ! */
701
734
  mi_int2store(ptr,state->open_count);          ptr +=2;
702
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
735
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
703
736
  mi_rowstore(ptr,state->state.records);        ptr +=8;
704
737
  mi_rowstore(ptr,state->state.del);            ptr +=8;
705
738
  mi_rowstore(ptr,state->split);                ptr +=8;
727
760
  }
728
761
  if (pWrite & 2)                               /* From isamchk */
729
762
  {
730
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
763
    uint key_parts= mi_uint2korr(state->header.key_parts);
731
764
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
732
765
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
733
766
    mi_int4store(ptr,state->version);           ptr +=4;
745
778
  if (pWrite & 1)
746
779
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
747
780
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
748
 
  return(internal::my_write(file, buff, (size_t) (ptr-buff),
 
781
  return(my_write(file, buff, (size_t) (ptr-buff),
749
782
                       MYF(MY_NABP)) != 0);
750
783
}
751
784
 
752
785
 
753
 
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
786
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
754
787
{
755
 
  uint32_t i,keys,key_parts,key_blocks;
756
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
788
  uint i,keys,key_parts,key_blocks;
 
789
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
757
790
  ptr +=sizeof(state->header);
758
791
  keys=(uint) state->header.keys;
759
792
  key_parts=mi_uint2korr(state->header.key_parts);
771
804
  state->state.empty    = mi_sizekorr(ptr);     ptr +=8;
772
805
  state->state.key_empty= mi_sizekorr(ptr);     ptr +=8;
773
806
  state->auto_increment=mi_uint8korr(ptr);      ptr +=8;
774
 
  state->state.checksum=(internal::ha_checksum) mi_uint8korr(ptr);      ptr +=8;
 
807
  state->state.checksum=(ha_checksum) mi_uint8korr(ptr);        ptr +=8;
775
808
  state->process= mi_uint4korr(ptr);            ptr +=4;
776
809
  state->unique = mi_uint4korr(ptr);            ptr +=4;
777
810
  state->status = mi_uint4korr(ptr);            ptr +=4;
803
836
}
804
837
 
805
838
 
806
 
uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead)
 
839
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
807
840
{
808
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
841
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
809
842
 
810
 
  if (pRead)
 
843
  if (!myisam_single_user)
811
844
  {
812
 
    if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
 
845
    if (pRead)
 
846
    {
 
847
      if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
 
848
        return 1;
 
849
    }
 
850
    else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
813
851
      return 1;
 
852
    mi_state_info_read(buff, state);
814
853
  }
815
 
  else if (internal::my_read(file, buff, state->state_length,MYF(MY_NABP)))
816
 
    return 1;
817
 
  mi_state_info_read(buff, state);
818
 
 
819
854
  return 0;
820
855
}
821
856
 
824
859
**  store and read of MI_BASE_INFO
825
860
****************************************************************************/
826
861
 
827
 
uint32_t mi_base_info_write(int file, MI_BASE_INFO *base)
 
862
uint mi_base_info_write(File file, MI_BASE_INFO *base)
828
863
{
829
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
864
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
830
865
 
831
866
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
832
867
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
851
886
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
852
887
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
853
888
  *ptr++= base->extra_alloc_procent;
854
 
  /* old raid info  slots */
855
 
  *ptr++= 0;
856
 
  mi_int2store(ptr,UINT16_C(0));                        ptr +=2;
857
 
  mi_int4store(ptr,UINT32_C(0));                        ptr +=4;
858
 
 
859
 
  memset(ptr, 0, 6);                                    ptr +=6; /* extra */
860
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
889
  *ptr++= base->raid_type;
 
890
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
891
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
892
  bzero(ptr,6);                                         ptr +=6; /* extra */
 
893
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
861
894
}
862
895
 
863
896
 
864
 
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
897
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
865
898
{
866
899
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
867
900
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
887
920
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
888
921
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
889
922
  base->extra_alloc_procent = *ptr++;
890
 
 
891
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
892
 
  ptr+= 7;
 
923
  base->raid_type= *ptr++;
 
924
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
925
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
926
  /* TO BE REMOVED: Fix for old RAID files */
 
927
  if (base->raid_type == 0)
 
928
  {
 
929
    base->raid_chunks=0;
 
930
    base->raid_chunksize=0;
 
931
  }
893
932
 
894
933
  ptr+=6;
895
934
  return ptr;
899
938
  mi_keydef
900
939
---------------------------------------------------------------------------*/
901
940
 
902
 
uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef)
 
941
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
903
942
{
904
 
  unsigned char buff[MI_KEYDEF_SIZE];
905
 
  unsigned char *ptr=buff;
 
943
  uchar buff[MI_KEYDEF_SIZE];
 
944
  uchar *ptr=buff;
906
945
 
907
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
946
  *ptr++ = (uchar) keydef->keysegs;
908
947
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
909
948
  mi_int2store(ptr,keydef->flag);               ptr +=2;
910
949
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
911
950
  mi_int2store(ptr,keydef->keylength);          ptr +=2;
912
951
  mi_int2store(ptr,keydef->minlength);          ptr +=2;
913
952
  mi_int2store(ptr,keydef->maxlength);          ptr +=2;
914
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
953
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
915
954
}
916
955
 
917
 
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
956
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
918
957
{
919
958
   keydef->keysegs      = (uint) *ptr++;
920
959
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
934
973
**  mi_keyseg
935
974
***************************************************************************/
936
975
 
937
 
int mi_keyseg_write(int file, const HA_KEYSEG *keyseg)
 
976
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
938
977
{
939
 
  unsigned char buff[HA_KEYSEG_SIZE];
940
 
  unsigned char *ptr=buff;
 
978
  uchar buff[HA_KEYSEG_SIZE];
 
979
  uchar *ptr=buff;
941
980
  ulong pos;
942
981
 
943
982
  *ptr++= keyseg->type;
952
991
  pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
953
992
  mi_int4store(ptr, pos);
954
993
  ptr+=4;
955
 
 
956
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
994
  
 
995
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
957
996
}
958
997
 
959
998
 
960
 
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
999
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
961
1000
{
962
1001
   keyseg->type         = *ptr++;
963
1002
   keyseg->language     = *ptr++;
971
1010
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
972
1011
   keyseg->charset=0;                           /* Will be filled in later */
973
1012
   if (keyseg->null_bit)
974
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1013
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
975
1014
   else
976
1015
   {
977
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1016
     keyseg->bit_pos= (uint16)keyseg->null_pos;
978
1017
     keyseg->null_pos= 0;
979
1018
   }
980
1019
   return ptr;
984
1023
  mi_uniquedef
985
1024
---------------------------------------------------------------------------*/
986
1025
 
987
 
uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *def)
 
1026
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
988
1027
{
989
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
990
 
  unsigned char *ptr=buff;
 
1028
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1029
  uchar *ptr=buff;
991
1030
 
992
1031
  mi_int2store(ptr,def->keysegs);               ptr+=2;
993
 
  *ptr++=  (unsigned char) def->key;
994
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1032
  *ptr++=  (uchar) def->key;
 
1033
  *ptr++ = (uchar) def->null_are_equal;
995
1034
 
996
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1035
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
997
1036
}
998
1037
 
999
 
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1038
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1000
1039
{
1001
1040
   def->keysegs = mi_uint2korr(ptr);
1002
1041
   def->key     = ptr[2];
1008
1047
**  MI_COLUMNDEF
1009
1048
***************************************************************************/
1010
1049
 
1011
 
uint32_t mi_recinfo_write(int file, MI_COLUMNDEF *recinfo)
 
1050
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1012
1051
{
1013
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1014
 
  unsigned char *ptr=buff;
 
1052
  uchar buff[MI_COLUMNDEF_SIZE];
 
1053
  uchar *ptr=buff;
1015
1054
 
1016
1055
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1017
1056
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1018
1057
  *ptr++ = recinfo->null_bit;
1019
1058
  mi_int2store(ptr,recinfo->null_pos);  ptr+= 2;
1020
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1059
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1021
1060
}
1022
1061
 
1023
 
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1062
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1024
1063
{
1025
1064
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1026
1065
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1027
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1066
   recinfo->null_bit= (uint8) *ptr++;
1028
1067
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1029
1068
   return ptr;
1030
1069
}
1031
1070
 
1032
1071
/**************************************************************************
1033
 
Open data file
 
1072
Open data file with or without RAID
1034
1073
We can't use dup() here as the data file descriptors need to have different
1035
1074
active seek-positions.
1036
1075
 
1038
1077
exist a dup()-like call that would give us two different file descriptors.
1039
1078
*************************************************************************/
1040
1079
 
1041
 
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
 
1080
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
 
1081
                     File file_to_dup __attribute__((unused)))
1042
1082
{
1043
 
  (void)file_to_dup; 
1044
 
  info->dfile=internal::my_open(share->data_file_name, share->mode,
1045
 
                      MYF(MY_WME));
 
1083
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
 
1084
                        MYF(MY_WME));
1046
1085
  return info->dfile >= 0 ? 0 : 1;
1047
1086
}
1048
1087
 
1049
1088
 
1050
1089
int mi_open_keyfile(MYISAM_SHARE *share)
1051
1090
{
1052
 
  if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
 
1091
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1053
1092
                            MYF(MY_WME))) < 0)
1054
1093
    return 1;
1055
1094
  return 0;