~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/myisam/mi_open.c

  • Committer: Brian Aker
  • Date: 2008-06-29 20:10:28 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: brian@tangent.org-20080629201028-923bdzz0qcjmd6cm
Cleaned up show status.

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 "fulltext.h"
 
19
#include "sp_defs.h"
 
20
#include "rt_index.h"
 
21
#include <m_ctype.h>
 
22
 
 
23
#if defined(MSDOS) || defined(__WIN__)
 
24
#ifdef __WIN__
 
25
#include <fcntl.h>
 
26
#else
 
27
#include <process.h>                    /* Prototype for getpid */
 
28
#endif
 
29
#endif
 
30
#ifdef VMS
 
31
#include "static.c"
 
32
#endif
36
33
 
37
34
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);
 
35
#define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \
 
36
                                        pos+=size;}
 
37
 
45
38
 
46
39
#define disk_pos_assert(pos, end_pos) \
47
40
if (pos > end_pos)             \
48
41
{                              \
49
 
  errno=HA_ERR_CRASHED;     \
 
42
  my_errno=HA_ERR_CRASHED;     \
50
43
  goto err;                    \
51
44
}
52
45
 
58
51
 
59
52
MI_INFO *test_if_reopen(char *filename)
60
53
{
61
 
  list<MI_INFO *>::iterator it= myisam_open_list.begin();
62
 
  while (it != myisam_open_list.end())
 
54
  LIST *pos;
 
55
 
 
56
  for (pos=myisam_open_list ; pos ; pos=pos->next)
63
57
  {
64
 
    MI_INFO *info= *it;
 
58
    MI_INFO *info=(MI_INFO*) pos->data;
65
59
    MYISAM_SHARE *share=info->s;
66
60
    if (!strcmp(share->unique_file_name,filename) && share->last_version)
67
61
      return info;
68
 
    ++it;
69
62
  }
70
63
  return 0;
71
64
}
79
72
  have an open count of 0.
80
73
******************************************************************************/
81
74
 
82
 
MI_INFO *mi_open(const drizzled::TableIdentifier &identifier, int mode, uint32_t open_flags)
 
75
MI_INFO *mi_open(const char *name, int mode, uint open_flags)
83
76
{
84
77
  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,
 
78
  uint i,j,len,errpos,head_length,base_pos,offset,info_length,keys,
86
79
    key_parts,unique_key_parts,fulltext_keys,uniques;
87
80
  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;
 
81
       data_name[FN_REFLEN];
 
82
  uchar *disk_cache, *disk_pos, *end_pos;
91
83
  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];
98
 
  uint64_t max_key_file_length, max_data_file_length;
 
84
  MYISAM_SHARE share_buff,*share;
 
85
  ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
 
86
  my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
 
87
  ulonglong max_key_file_length, max_data_file_length;
 
88
  DBUG_ENTER("mi_open");
99
89
 
100
90
  kfile= -1;
101
91
  lock_error=1;
102
92
  errpos=0;
103
93
  head_length=sizeof(share_buff.state.header);
104
 
  memset(&info, 0, sizeof(info));
 
94
  bzero((uchar*) &info,sizeof(info));
105
95
 
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();
 
96
  my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,
 
97
                                   MY_UNPACK_FILENAME),MYF(0));
 
98
  pthread_mutex_lock(&THR_LOCK_myisam);
116
99
  if (!(old_info=test_if_reopen(name_buff)))
117
100
  {
118
101
    share= &share_buff;
119
 
    memset(&share_buff, 0, sizeof(share_buff));
 
102
    bzero((uchar*) &share_buff,sizeof(share_buff));
120
103
    share_buff.state.rec_per_key_part=rec_per_key_part;
121
104
    share_buff.state.key_root=key_root;
122
105
    share_buff.state.key_del=key_del;
123
 
    share_buff.setKeyCache();
 
106
    share_buff.key_cache= multi_key_cache_search((uchar*) name_buff,
 
107
                                                 strlen(name_buff));
124
108
 
125
 
    if ((kfile=internal::my_open(name_buff,(open_mode=O_RDWR),MYF(0))) < 0)
 
109
    DBUG_EXECUTE_IF("myisam_pretend_crashed_table_on_open",
 
110
                    if (strstr(name, "/t1"))
 
111
                    {
 
112
                      my_errno= HA_ERR_CRASHED;
 
113
                      goto err;
 
114
                    });
 
115
    if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
126
116
    {
127
117
      if ((errno != EROFS && errno != EACCES) ||
128
118
          mode != O_RDONLY ||
129
 
          (kfile=internal::my_open(name_buff,(open_mode=O_RDONLY),MYF(0))) < 0)
 
119
          (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
130
120
        goto err;
131
121
    }
132
122
    share->mode=open_mode;
133
123
    errpos=1;
134
 
    if (internal::my_read(kfile, share->state.header.file_version, head_length,
 
124
    if (my_read(kfile, share->state.header.file_version, head_length,
135
125
                MYF(MY_NABP)))
136
126
    {
137
 
      errno= HA_ERR_NOT_A_TABLE;
 
127
      my_errno= HA_ERR_NOT_A_TABLE;
138
128
      goto err;
139
129
    }
140
 
    if (memcmp(share->state.header.file_version, myisam_file_magic, 4))
 
130
    if (memcmp((uchar*) share->state.header.file_version,
 
131
               (uchar*) myisam_file_magic, 4))
141
132
    {
142
 
      errno=HA_ERR_NOT_A_TABLE;
 
133
      DBUG_PRINT("error",("Wrong header in %s",name_buff));
 
134
      DBUG_DUMP("error_dump",(uchar*) share->state.header.file_version,
 
135
                head_length);
 
136
      my_errno=HA_ERR_NOT_A_TABLE;
143
137
      goto err;
144
138
    }
145
139
    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
 
 
 
140
    if (share->options &
 
141
        ~(HA_OPTION_PACK_RECORD | HA_OPTION_PACK_KEYS |
 
142
          HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA |
 
143
          HA_OPTION_TEMP_COMPRESS_RECORD | HA_OPTION_CHECKSUM |
 
144
          HA_OPTION_TMP_TABLE | HA_OPTION_DELAY_KEY_WRITE |
 
145
          HA_OPTION_RELIES_ON_SQL_LAYER))
 
146
    {
 
147
      DBUG_PRINT("error",("wrong options: 0x%lx", share->options));
 
148
      my_errno=HA_ERR_OLD_FILE;
 
149
      goto err;
 
150
    }
 
151
    if ((share->options & HA_OPTION_RELIES_ON_SQL_LAYER) &&
 
152
        ! (open_flags & HA_OPEN_FROM_SQL_LAYER))
 
153
    {
 
154
      DBUG_PRINT("error", ("table cannot be openned from non-sql layer"));
 
155
      my_errno= HA_ERR_UNSUPPORTED;
 
156
      goto err;
 
157
    }
157
158
    /* 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);
 
159
    if (!strcmp(name_buff, org_name) ||
 
160
        my_readlink(index_name, org_name, MYF(0)) == -1)
 
161
      (void) strmov(index_name, org_name);
163
162
    *strrchr(org_name, '.')= '\0';
164
 
    (void) internal::fn_format(data_name,org_name,"",MI_NAME_DEXT,
 
163
    (void) fn_format(data_name,org_name,"",MI_NAME_DEXT,
165
164
                     MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS);
166
165
 
167
166
    info_length=mi_uint2korr(share->state.header.header_length);
168
167
    base_pos=mi_uint2korr(share->state.header.base_pos);
169
 
    if (!(disk_cache= (unsigned char*) malloc(info_length+128)))
 
168
    if (!(disk_cache= (uchar*) my_alloca(info_length+128)))
170
169
    {
171
 
      errno=ENOMEM;
 
170
      my_errno=ENOMEM;
172
171
      goto err;
173
172
    }
174
173
    end_pos=disk_cache+info_length;
175
174
    errpos=2;
176
175
 
177
 
    lseek(kfile,0,SEEK_SET);
 
176
    VOID(my_seek(kfile,0L,MY_SEEK_SET,MYF(0)));
 
177
    if (!(open_flags & HA_OPEN_TMP_TABLE))
 
178
    {
 
179
      if ((lock_error=my_lock(kfile,F_RDLCK,0L,F_TO_EOF,
 
180
                              MYF(open_flags & HA_OPEN_WAIT_IF_LOCKED ?
 
181
                                  0 : MY_DONT_WAIT))) &&
 
182
          !(open_flags & HA_OPEN_IGNORE_IF_LOCKED))
 
183
        goto err;
 
184
    }
178
185
    errpos=3;
179
 
    if (internal::my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
 
186
    if (my_read(kfile,disk_cache,info_length,MYF(MY_NABP)))
180
187
    {
181
 
      errno=HA_ERR_CRASHED;
 
188
      my_errno=HA_ERR_CRASHED;
182
189
      goto err;
183
190
    }
184
191
    len=mi_uint2korr(share->state.header.state_info_length);
187
194
    fulltext_keys= (uint) share->state.header.fulltext_keys;
188
195
    key_parts= mi_uint2korr(share->state.header.key_parts);
189
196
    unique_key_parts= mi_uint2korr(share->state.header.unique_key_parts);
 
197
    if (len != MI_STATE_INFO_SIZE)
 
198
    {
 
199
      DBUG_PRINT("warning",
 
200
                 ("saved_state_info_length: %d  state_info_length: %d",
 
201
                  len,MI_STATE_INFO_SIZE));
 
202
    }
190
203
    share->state_diff_length=len-MI_STATE_INFO_SIZE;
191
204
 
192
205
    mi_state_info_read(disk_cache, &share->state);
193
206
    len= mi_uint2korr(share->state.header.base_info_length);
 
207
    if (len != MI_BASE_INFO_SIZE)
 
208
    {
 
209
      DBUG_PRINT("warning",("saved_base_info_length: %d  base_info_length: %d",
 
210
                            len,MI_BASE_INFO_SIZE));
 
211
    }
194
212
    disk_pos= my_n_base_info_read(disk_cache + base_pos, &share->base);
195
213
    share->state.state_length=base_pos;
196
214
 
197
 
    if (share->state.changed & STATE_CRASHED)
 
215
    if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
 
216
        ((share->state.changed & STATE_CRASHED) ||
 
217
         ((open_flags & HA_OPEN_ABORT_IF_CRASHED) &&
 
218
          (my_disable_locking && share->state.open_count))))
198
219
    {
199
 
      errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
 
220
      DBUG_PRINT("error",("Table is marked as crashed. open_flags: %u  "
 
221
                          "changed: %u  open_count: %u  !locking: %d",
 
222
                          open_flags, share->state.changed,
 
223
                          share->state.open_count, my_disable_locking));
 
224
      my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
200
225
                HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
201
226
      goto err;
202
227
    }
204
229
    /* sanity check */
205
230
    if (share->base.keystart > 65535 || share->base.rec_reflength > 8)
206
231
    {
207
 
      errno=HA_ERR_CRASHED;
 
232
      my_errno=HA_ERR_CRASHED;
208
233
      goto err;
209
234
    }
210
235
 
 
236
    key_parts+=fulltext_keys*FT_SEGS;
211
237
    if (share->base.max_key_length > MI_MAX_KEY_BUFF || keys > MI_MAX_KEY ||
212
238
        key_parts > MI_MAX_KEY * MI_MAX_KEY_SEG)
213
239
    {
214
 
      errno=HA_ERR_UNSUPPORTED;
 
240
      DBUG_PRINT("error",("Wrong key info:  Max_key_length: %d  keys: %d  key_parts: %d", share->base.max_key_length, keys, key_parts));
 
241
      my_errno=HA_ERR_UNSUPPORTED;
215
242
      goto err;
216
243
    }
217
244
 
218
245
    /* Correct max_file_length based on length of sizeof(off_t) */
219
246
    max_data_file_length=
220
247
      (share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ?
221
 
      (((uint64_t) 1 << (share->base.rec_reflength*8))-1) :
 
248
      (((ulonglong) 1 << (share->base.rec_reflength*8))-1) :
222
249
      (mi_safe_mul(share->base.pack_reclength,
223
 
                   (uint64_t) 1 << (share->base.rec_reflength*8))-1);
 
250
                   (ulonglong) 1 << (share->base.rec_reflength*8))-1);
224
251
    max_key_file_length=
225
252
      mi_safe_mul(MI_MIN_KEY_BLOCK_LENGTH,
226
 
                  ((uint64_t) 1 << (share->base.key_reflength*8))-1);
 
253
                  ((ulonglong) 1 << (share->base.key_reflength*8))-1);
227
254
#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);
 
255
    set_if_smaller(max_data_file_length, INT_MAX32);
 
256
    set_if_smaller(max_key_file_length, INT_MAX32);
230
257
#endif
 
258
#if USE_RAID && SYSTEM_SIZEOF_OFF_T == 4
 
259
    set_if_smaller(max_key_file_length, INT_MAX32);
 
260
    if (!share->base.raid_type)
 
261
    {
 
262
      set_if_smaller(max_data_file_length, INT_MAX32);
 
263
    }
 
264
    else
 
265
    {
 
266
      set_if_smaller(max_data_file_length,
 
267
                     (ulonglong) share->base.raid_chunks << 31);
 
268
    }
 
269
#elif !defined(USE_RAID)
231
270
    if (share->base.raid_type)
232
271
    {
233
 
      errno=HA_ERR_UNSUPPORTED;
 
272
      DBUG_PRINT("error",("Table uses RAID but we don't have RAID support"));
 
273
      my_errno=HA_ERR_UNSUPPORTED;
234
274
      goto err;
235
275
    }
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;
 
276
#endif
 
277
    share->base.max_data_file_length=(my_off_t) max_data_file_length;
 
278
    share->base.max_key_file_length=(my_off_t) max_key_file_length;
238
279
 
239
280
    if (share->options & HA_OPTION_COMPRESS_RECORD)
240
281
      share->base.max_key_length+=2;    /* For safety */
242
283
    /* Add space for node pointer */
243
284
    share->base.max_key_length+= share->base.key_reflength;
244
285
 
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))
 
286
    if (!my_multi_malloc(MY_WME,
 
287
                         &share,sizeof(*share),
 
288
                         &share->state.rec_per_key_part,sizeof(long)*key_parts,
 
289
                         &share->keyinfo,keys*sizeof(MI_KEYDEF),
 
290
                         &share->uniqueinfo,uniques*sizeof(MI_UNIQUEDEF),
 
291
                         &share->keyparts,
 
292
                         (key_parts+unique_key_parts+keys+uniques) *
 
293
                         sizeof(HA_KEYSEG),
 
294
                         &share->rec,
 
295
                         (share->base.fields+1)*sizeof(MI_COLUMNDEF),
 
296
                         &share->blobs,sizeof(MI_BLOB)*share->base.blobs,
 
297
                         &share->unique_file_name,strlen(name_buff)+1,
 
298
                         &share->index_file_name,strlen(index_name)+1,
 
299
                         &share->data_file_name,strlen(data_name)+1,
 
300
                         &share->state.key_root,keys*sizeof(my_off_t),
 
301
                         &share->state.key_del,
 
302
                         (share->state.header.max_block_size_index*sizeof(my_off_t)),
 
303
#ifdef THREAD
 
304
                         &share->key_root_lock,sizeof(rw_lock_t)*keys,
 
305
#endif
 
306
                         &share->mmap_lock,sizeof(rw_lock_t),
 
307
                         NullS))
261
308
      goto err;
262
309
    errpos=4;
263
310
    *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);
 
311
    memcpy((char*) share->state.rec_per_key_part,
 
312
           (char*) rec_per_key_part, sizeof(long)*key_parts);
 
313
    memcpy((char*) share->state.key_root,
 
314
           (char*) key_root, sizeof(my_off_t)*keys);
 
315
    memcpy((char*) share->state.key_del,
 
316
           (char*) key_del, (sizeof(my_off_t) *
 
317
                             share->state.header.max_block_size_index));
 
318
    strmov(share->unique_file_name, name_buff);
271
319
    share->unique_name_length= strlen(name_buff);
272
 
    strcpy(share->index_file_name,  index_name);
273
 
    strcpy(share->data_file_name,   data_name);
 
320
    strmov(share->index_file_name,  index_name);
 
321
    strmov(share->data_file_name,   data_name);
274
322
 
275
 
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
 
323
    share->blocksize=min(IO_SIZE,myisam_block_size);
276
324
    {
277
325
      HA_KEYSEG *pos=share->keyparts;
278
326
      for (i=0 ; i < keys ; i++)
281
329
        disk_pos=mi_keydef_read(disk_pos, &share->keyinfo[i]);
282
330
        disk_pos_assert(disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
283
331
                        end_pos);
284
 
        set_if_smaller(share->blocksize,(uint)share->keyinfo[i].block_length);
 
332
        if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
 
333
          have_rtree=1;
 
334
        set_if_smaller(share->blocksize,share->keyinfo[i].block_length);
285
335
        share->keyinfo[i].seg=pos;
286
336
        for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
287
337
        {
290
340
              ! (share->options & (HA_OPTION_COMPRESS_RECORD |
291
341
                                   HA_OPTION_PACK_RECORD)))
292
342
          {
293
 
            errno= HA_ERR_CRASHED;
 
343
            my_errno= HA_ERR_CRASHED;
294
344
            goto err;
295
345
          }
296
346
          if (pos->type == HA_KEYTYPE_TEXT ||
299
349
          {
300
350
            if (!pos->language)
301
351
              pos->charset=default_charset_info;
302
 
            else if (!(pos->charset= get_charset(pos->language)))
 
352
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
303
353
            {
304
 
              errno=HA_ERR_UNKNOWN_CHARSET;
 
354
              my_errno=HA_ERR_UNKNOWN_CHARSET;
305
355
              goto err;
306
356
            }
307
357
          }
308
358
          else if (pos->type == HA_KEYTYPE_BINARY)
309
359
            pos->charset= &my_charset_bin;
310
360
        }
 
361
        if (share->keyinfo[i].flag & HA_SPATIAL)
 
362
        {
 
363
#ifdef HAVE_SPATIAL
 
364
          uint sp_segs=SPDIMS*2;
 
365
          share->keyinfo[i].seg=pos-sp_segs;
 
366
          share->keyinfo[i].keysegs--;
 
367
#else
 
368
          my_errno=HA_ERR_UNSUPPORTED;
 
369
          goto err;
 
370
#endif
 
371
        }
 
372
        else if (share->keyinfo[i].flag & HA_FULLTEXT)
 
373
        {
 
374
          if (!fulltext_keys)
 
375
          { /* 4.0 compatibility code, to be removed in 5.0 */
 
376
            share->keyinfo[i].seg=pos-FT_SEGS;
 
377
            share->keyinfo[i].keysegs-=FT_SEGS;
 
378
          }
 
379
          else
 
380
          {
 
381
            uint k;
 
382
            share->keyinfo[i].seg=pos;
 
383
            for (k=0; k < FT_SEGS; k++)
 
384
            {
 
385
              *pos= ft_keysegs[k];
 
386
              pos[0].language= pos[-1].language;
 
387
              if (!(pos[0].charset= pos[-1].charset))
 
388
              {
 
389
                my_errno=HA_ERR_CRASHED;
 
390
                goto err;
 
391
              }
 
392
              pos++;
 
393
            }
 
394
          }
 
395
          if (!share->ft2_keyinfo.seg)
 
396
          {
 
397
            memcpy(& share->ft2_keyinfo, & share->keyinfo[i], sizeof(MI_KEYDEF));
 
398
            share->ft2_keyinfo.keysegs=1;
 
399
            share->ft2_keyinfo.flag=0;
 
400
            share->ft2_keyinfo.keylength=
 
401
            share->ft2_keyinfo.minlength=
 
402
            share->ft2_keyinfo.maxlength=HA_FT_WLEN+share->base.rec_reflength;
 
403
            share->ft2_keyinfo.seg=pos-1;
 
404
            share->ft2_keyinfo.end=pos;
 
405
            setup_key_functions(& share->ft2_keyinfo);
 
406
          }
 
407
        }
311
408
        setup_key_functions(share->keyinfo+i);
312
409
        share->keyinfo[i].end=pos;
313
410
        pos->type=HA_KEYTYPE_END;                       /* End */
331
428
          {
332
429
            if (!pos->language)
333
430
              pos->charset=default_charset_info;
334
 
            else if (!(pos->charset= get_charset(pos->language)))
 
431
            else if (!(pos->charset= get_charset(pos->language, MYF(MY_WME))))
335
432
            {
336
 
              errno=HA_ERR_UNKNOWN_CHARSET;
 
433
              my_errno=HA_ERR_UNKNOWN_CHARSET;
337
434
              goto err;
338
435
            }
339
436
          }
344
441
        pos->flag=0;
345
442
        pos++;
346
443
      }
 
444
      share->ftparsers= 0;
347
445
    }
348
446
 
349
447
    disk_pos_assert(disk_pos + share->base.fields *MI_COLUMNDEF_SIZE, end_pos);
365
463
    share->rec[i].type=(int) FIELD_LAST;        /* End marker */
366
464
    if (offset > share->base.reclength)
367
465
    {
368
 
      errno= HA_ERR_CRASHED;
 
466
      /* purecov: begin inspected */
 
467
      my_errno= HA_ERR_CRASHED;
369
468
      goto err;
 
469
      /* purecov: end */
370
470
    }
371
471
 
372
472
    if (! lock_error)
373
473
    {
 
474
      VOID(my_lock(kfile,F_UNLCK,0L,F_TO_EOF,MYF(MY_SEEK_NOT_DONE)));
374
475
      lock_error=1;                     /* Database unlocked */
375
476
    }
376
477
 
389
490
    share->base.margin_key_file_length=(share->base.max_key_file_length -
390
491
                                        (keys ? MI_INDEX_BLOCK_MARGIN *
391
492
                                         share->blocksize * keys : 0));
392
 
    share->blocksize=min((uint32_t)IO_SIZE,myisam_block_size);
 
493
    share->blocksize=min(IO_SIZE,myisam_block_size);
393
494
    share->data_file_type=STATIC_RECORD;
394
 
    if (share->options & HA_OPTION_PACK_RECORD)
 
495
    if (share->options & HA_OPTION_COMPRESS_RECORD)
 
496
    {
 
497
      share->data_file_type = COMPRESSED_RECORD;
 
498
      share->options|= HA_OPTION_READ_ONLY_DATA;
 
499
      info.s=share;
 
500
      if (_mi_read_pack_info(&info,
 
501
                             (pbool)
 
502
                             test(!(share->options &
 
503
                                    (HA_OPTION_PACK_RECORD |
 
504
                                     HA_OPTION_TEMP_COMPRESS_RECORD)))))
 
505
        goto err;
 
506
    }
 
507
    else if (share->options & HA_OPTION_PACK_RECORD)
395
508
      share->data_file_type = DYNAMIC_RECORD;
396
 
    free(disk_cache);
397
 
    disk_cache= NULL;
 
509
    my_afree(disk_cache);
398
510
    mi_setup_functions(share);
399
 
    share->is_log_table= false;
400
 
    if (myisam_concurrent_insert)
 
511
    share->is_log_table= FALSE;
 
512
#ifdef THREAD
 
513
    thr_lock_init(&share->lock);
 
514
    VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST));
 
515
    for (i=0; i<keys; i++)
 
516
      VOID(my_rwlock_init(&share->key_root_lock[i], NULL));
 
517
    VOID(my_rwlock_init(&share->mmap_lock, NULL));
 
518
    if (!thr_lock_inited)
 
519
    {
 
520
      /* Probably a single threaded program; Don't use concurrent inserts */
 
521
      myisam_concurrent_insert=0;
 
522
    }
 
523
    else if (myisam_concurrent_insert)
401
524
    {
402
525
      share->concurrent_insert=
403
526
        ((share->options & (HA_OPTION_READ_ONLY_DATA | HA_OPTION_TMP_TABLE |
404
527
                           HA_OPTION_COMPRESS_RECORD |
405
528
                           HA_OPTION_TEMP_COMPRESS_RECORD)) ||
406
 
         (open_flags & HA_OPEN_TMP_TABLE) || have_rtree) ? 0 : 1;
 
529
         (open_flags & HA_OPEN_TMP_TABLE) ||
 
530
         have_rtree) ? 0 : 1;
407
531
      if (share->concurrent_insert)
408
532
      {
409
 
        assert(0);
 
533
        share->lock.get_status=mi_get_status;
 
534
        share->lock.copy_status=mi_copy_status;
 
535
        share->lock.update_status=mi_update_status;
 
536
        share->lock.restore_status= mi_restore_status;
 
537
        share->lock.check_status=mi_check_status;
410
538
      }
411
539
    }
 
540
#endif
 
541
    /*
 
542
      Memory mapping can only be requested after initializing intern_lock.
 
543
    */
 
544
    if (open_flags & HA_OPEN_MMAP)
 
545
    {
 
546
      info.s= share;
 
547
      mi_extra(&info, HA_EXTRA_MMAP, 0);
 
548
    }
412
549
  }
413
550
  else
414
551
  {
415
552
    share= old_info->s;
416
553
    if (mode == O_RDWR && share->mode == O_RDONLY)
417
554
    {
418
 
      errno=EACCES;                             /* Can't open in write mode */
 
555
      my_errno=EACCES;                          /* Can't open in write mode */
419
556
      goto err;
420
557
    }
421
558
    if (mi_open_datafile(&info, share, old_info->dfile))
425
562
  }
426
563
 
427
564
  /* 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))
 
565
  if (!my_multi_malloc(MY_WME,
 
566
                       &m_info,sizeof(MI_INFO),
 
567
                       &info.blobs,sizeof(MI_BLOB)*share->base.blobs,
 
568
                       &info.buff,(share->base.max_key_block_length*2+
 
569
                                   share->base.max_key_length),
 
570
                       &info.lastkey,share->base.max_key_length*3+1,
 
571
                       &info.first_mbr_key, share->base.max_key_length,
 
572
                       &info.filename,strlen(name)+1,
 
573
                       &info.rtree_recursion_state,have_rtree ? 1024 : 0,
 
574
                       NullS))
438
575
    goto err;
439
576
  errpos=6;
440
577
 
441
578
  if (!have_rtree)
442
579
    info.rtree_recursion_state= NULL;
443
580
 
444
 
  strcpy(info.filename, identifier.getPath().c_str());
 
581
  strmov(info.filename,name);
445
582
  memcpy(info.blobs,share->blobs,sizeof(MI_BLOB)*share->base.blobs);
446
583
  info.lastkey2=info.lastkey+share->base.max_key_length;
447
584
 
460
597
  info.lock_type=F_UNLCK;
461
598
  info.quick_mode=0;
462
599
  info.bulk_insert=0;
 
600
  info.ft1_to_ft2=0;
463
601
  info.errkey= -1;
464
602
  info.page_changed=1;
 
603
  pthread_mutex_lock(&share->intern_lock);
465
604
  info.read_record=share->read_record;
466
605
  share->reopen++;
467
606
  share->write_flag=MYF(MY_NABP | MY_WAIT_IF_FULL);
476
615
  {
477
616
    share->temporary=share->delay_key_write=1;
478
617
    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++;
 
618
    share->w_locks++;                   /* We don't have to update status */
 
619
    share->tot_locks++;
489
620
    info.lock_type=F_WRLCK;
490
621
  }
491
 
 
492
 
  share->delay_key_write= 1;
 
622
  if (((open_flags & HA_OPEN_DELAY_KEY_WRITE) ||
 
623
      (share->options & HA_OPTION_DELAY_KEY_WRITE)) &&
 
624
      myisam_delay_key_write)
 
625
    share->delay_key_write=1;
493
626
  info.state= &share->state.state;      /* Change global values by default */
 
627
  pthread_mutex_unlock(&share->intern_lock);
494
628
 
495
629
  /* Allocate buffer for one record */
496
630
 
497
 
  /* prerequisites: memset(info, 0) && info->s=share; are met. */
498
 
  if (!mi_alloc_rec_buff(&info, SIZE_MAX, &info.rec_buff))
 
631
  /* prerequisites: bzero(info) && info->s=share; are met. */
 
632
  if (!mi_alloc_rec_buff(&info, -1, &info.rec_buff))
499
633
    goto err;
500
 
  memset(info.rec_buff, 0, mi_get_rec_buff_len(&info, info.rec_buff));
 
634
  bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
501
635
 
502
636
  *m_info=info;
503
 
  myisam_open_list.push_front(m_info);
 
637
#ifdef THREAD
 
638
  thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
 
639
#endif
 
640
  m_info->open_list.data=(void*) m_info;
 
641
  myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
504
642
 
505
 
  THR_LOCK_myisam.unlock();
506
 
  return(m_info);
 
643
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
644
  if (myisam_log_file >= 0)
 
645
  {
 
646
    intern_filename(name_buff,share->index_file_name);
 
647
    _myisam_log(MI_LOG_OPEN, m_info, (uchar*) name_buff, strlen(name_buff));
 
648
  }
 
649
  DBUG_RETURN(m_info);
507
650
 
508
651
err:
509
 
  if (disk_cache != NULL)
510
 
    free(disk_cache);
511
 
  save_errno=errno ? errno : HA_ERR_END_OF_FILE;
 
652
  save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
512
653
  if ((save_errno == HA_ERR_CRASHED) ||
513
654
      (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
514
655
      (save_errno == HA_ERR_CRASHED_ON_REPAIR))
515
 
    mi_report_error(save_errno, identifier.getPath().c_str());
 
656
    mi_report_error(save_errno, name);
516
657
  switch (errpos) {
517
658
  case 6:
518
 
    free((unsigned char*) m_info);
 
659
    my_free((uchar*) m_info,MYF(0));
519
660
    /* fall through */
520
661
  case 5:
521
 
    internal::my_close(info.dfile,MYF(0));
 
662
    VOID(my_close(info.dfile,MYF(0)));
522
663
    if (old_info)
523
664
      break;                                    /* Don't remove open table */
524
665
    /* fall through */
525
666
  case 4:
526
 
    free((unsigned char*) share);
 
667
    my_free((uchar*) share,MYF(0));
527
668
    /* fall through */
528
669
  case 3:
 
670
    if (! lock_error)
 
671
      VOID(my_lock(kfile, F_UNLCK, 0L, F_TO_EOF, MYF(MY_SEEK_NOT_DONE)));
 
672
    /* fall through */
 
673
  case 2:
 
674
    my_afree(disk_cache);
529
675
    /* fall through */
530
676
  case 1:
531
 
    internal::my_close(kfile,MYF(0));
 
677
    VOID(my_close(kfile,MYF(0)));
532
678
    /* fall through */
533
679
  case 0:
534
680
  default:
535
681
    break;
536
682
  }
537
 
  THR_LOCK_myisam.unlock();
538
 
  errno=save_errno;
539
 
  return (NULL);
 
683
  pthread_mutex_unlock(&THR_LOCK_myisam);
 
684
  my_errno=save_errno;
 
685
  DBUG_RETURN (NULL);
540
686
} /* mi_open */
541
687
 
542
688
 
543
 
unsigned char *mi_alloc_rec_buff(MI_INFO *info, size_t length, unsigned char **buf)
 
689
uchar *mi_alloc_rec_buff(MI_INFO *info, ulong length, uchar **buf)
544
690
{
545
 
  uint32_t extra;
546
 
  uint32_t old_length= 0;
 
691
  uint extra;
 
692
  uint32 old_length= 0;
547
693
 
548
694
  if (! *buf || length > (old_length=mi_get_rec_buff_len(info, *buf)))
549
695
  {
550
 
    unsigned char *newptr = *buf;
 
696
    uchar *newptr = *buf;
551
697
 
552
698
    /* to simplify initial init of info->rec_buf in mi_open and mi_extra */
553
 
    if (length == SIZE_MAX)
 
699
    if (length == (ulong) -1)
554
700
    {
555
701
      if (info->s->options & HA_OPTION_COMPRESS_RECORD)
556
702
        length= max(info->s->base.pack_reclength, info->s->max_pack_length);
557
703
      else
558
704
        length= info->s->base.pack_reclength;
559
 
      length= max((uint32_t)length, info->s->base.max_key_length);
 
705
      length= max(length, info->s->base.max_key_length);
560
706
      /* Avoid unnecessary realloc */
561
707
      if (newptr && length == old_length)
562
708
        return newptr;
567
713
            MI_REC_BUFF_OFFSET : 0);
568
714
    if (extra && newptr)
569
715
      newptr-= MI_REC_BUFF_OFFSET;
570
 
    void *tmpnewptr= NULL;
571
 
    if (!(tmpnewptr= realloc(newptr, length+extra+8))) 
 
716
    if (!(newptr=(uchar*) my_realloc((uchar*)newptr, length+extra+8,
 
717
                                     MYF(MY_ALLOW_ZERO_PTR))))
572
718
      return newptr;
573
 
    newptr= (unsigned char *)tmpnewptr;
574
 
    *((uint32_t *) newptr)= (uint32_t) length;
 
719
    *((uint32 *) newptr)= (uint32) length;
575
720
    *buf= newptr+(extra ?  MI_REC_BUFF_OFFSET : 0);
576
721
  }
577
722
  return *buf;
578
723
}
579
724
 
580
725
 
581
 
static uint64_t mi_safe_mul(uint64_t a, uint64_t b)
 
726
ulonglong mi_safe_mul(ulonglong a, ulonglong b)
582
727
{
583
 
  uint64_t max_val= ~ (uint64_t) 0;             /* internal::my_off_t is unsigned */
 
728
  ulonglong max_val= ~ (ulonglong) 0;           /* my_off_t is unsigned */
584
729
 
585
730
  if (!a || max_val / a < b)
586
731
    return max_val;
591
736
 
592
737
void mi_setup_functions(register MYISAM_SHARE *share)
593
738
{
594
 
  if (share->options & HA_OPTION_PACK_RECORD)
 
739
  if (share->options & HA_OPTION_COMPRESS_RECORD)
 
740
  {
 
741
    share->read_record=_mi_read_pack_record;
 
742
    share->read_rnd=_mi_read_rnd_pack_record;
 
743
    if (!(share->options & HA_OPTION_TEMP_COMPRESS_RECORD))
 
744
      share->calc_checksum=0;                           /* No checksum */
 
745
    else if (share->options & HA_OPTION_PACK_RECORD)
 
746
      share->calc_checksum= mi_checksum;
 
747
    else
 
748
      share->calc_checksum= mi_static_checksum;
 
749
  }
 
750
  else if (share->options & HA_OPTION_PACK_RECORD)
595
751
  {
596
752
    share->read_record=_mi_read_dynamic_record;
597
753
    share->read_rnd=_mi_read_rnd_dynamic_record;
626
782
  }
627
783
  share->file_read= mi_nommap_pread;
628
784
  share->file_write= mi_nommap_pwrite;
629
 
  share->calc_checksum=0;
 
785
  if (!(share->options & HA_OPTION_CHECKSUM))
 
786
    share->calc_checksum=0;
 
787
  return;
630
788
}
631
789
 
632
790
 
633
791
static void setup_key_functions(register MI_KEYDEF *keyinfo)
634
792
{
 
793
  if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
 
794
  {
 
795
#ifdef HAVE_RTREE_KEYS
 
796
    keyinfo->ck_insert = rtree_insert;
 
797
    keyinfo->ck_delete = rtree_delete;
 
798
#else
 
799
    DBUG_ASSERT(0); /* mi_open should check it never happens */
 
800
#endif
 
801
  }
 
802
  else
635
803
  {
636
804
    keyinfo->ck_insert = _mi_ck_write;
637
805
    keyinfo->ck_delete = _mi_ck_delete;
687
855
   Function to save and store the header in the index file (.MYI)
688
856
*/
689
857
 
690
 
uint32_t mi_state_info_write(int file, MI_STATE_INFO *state, uint32_t pWrite)
 
858
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
691
859
{
692
 
  unsigned char  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
693
 
  unsigned char *ptr=buff;
 
860
  uchar  buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
861
  uchar *ptr=buff;
694
862
  uint  i, keys= (uint) state->header.keys,
695
863
        key_blocks=state->header.max_block_size_index;
 
864
  DBUG_ENTER("mi_state_info_write");
696
865
 
697
 
  memcpy(ptr,&state->header,sizeof(state->header));
 
866
  memcpy_fixed(ptr,&state->header,sizeof(state->header));
698
867
  ptr+=sizeof(state->header);
699
868
 
700
869
  /* open_count must be first because of _mi_mark_file_changed ! */
701
870
  mi_int2store(ptr,state->open_count);          ptr +=2;
702
 
  *ptr++= (unsigned char)state->changed; *ptr++= state->sortkey;
 
871
  *ptr++= (uchar)state->changed; *ptr++= state->sortkey;
703
872
  mi_rowstore(ptr,state->state.records);        ptr +=8;
704
873
  mi_rowstore(ptr,state->state.del);            ptr +=8;
705
874
  mi_rowstore(ptr,state->split);                ptr +=8;
709
878
  mi_sizestore(ptr,state->state.empty);         ptr +=8;
710
879
  mi_sizestore(ptr,state->state.key_empty);     ptr +=8;
711
880
  mi_int8store(ptr,state->auto_increment);      ptr +=8;
712
 
  mi_int8store(ptr,(uint64_t) state->state.checksum);ptr +=8;
 
881
  mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
713
882
  mi_int4store(ptr,state->process);             ptr +=4;
714
883
  mi_int4store(ptr,state->unique);              ptr +=4;
715
884
  mi_int4store(ptr,state->status);              ptr +=4;
727
896
  }
728
897
  if (pWrite & 2)                               /* From isamchk */
729
898
  {
730
 
    uint32_t key_parts= mi_uint2korr(state->header.key_parts);
 
899
    uint key_parts= mi_uint2korr(state->header.key_parts);
731
900
    mi_int4store(ptr,state->sec_index_changed); ptr +=4;
732
901
    mi_int4store(ptr,state->sec_index_used);    ptr +=4;
733
902
    mi_int4store(ptr,state->version);           ptr +=4;
734
903
    mi_int8store(ptr,state->key_map);           ptr +=8;
735
 
    mi_int8store(ptr,(uint64_t) state->create_time);    ptr +=8;
736
 
    mi_int8store(ptr,(uint64_t) state->recover_time);   ptr +=8;
737
 
    mi_int8store(ptr,(uint64_t) state->check_time);     ptr +=8;
 
904
    mi_int8store(ptr,(ulonglong) state->create_time);   ptr +=8;
 
905
    mi_int8store(ptr,(ulonglong) state->recover_time);  ptr +=8;
 
906
    mi_int8store(ptr,(ulonglong) state->check_time);    ptr +=8;
738
907
    mi_sizestore(ptr,state->rec_per_key_rows);  ptr+=8;
739
908
    for (i=0 ; i < key_parts ; i++)
740
909
    {
743
912
  }
744
913
 
745
914
  if (pWrite & 1)
746
 
    return(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
 
915
    DBUG_RETURN(my_pwrite(file, buff, (size_t) (ptr-buff), 0L,
747
916
                          MYF(MY_NABP | MY_THREADSAFE)) != 0);
748
 
  return(internal::my_write(file, buff, (size_t) (ptr-buff),
 
917
  DBUG_RETURN(my_write(file, buff, (size_t) (ptr-buff),
749
918
                       MYF(MY_NABP)) != 0);
750
919
}
751
920
 
752
921
 
753
 
static unsigned char *mi_state_info_read(unsigned char *ptr, MI_STATE_INFO *state)
 
922
uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
754
923
{
755
 
  uint32_t i,keys,key_parts,key_blocks;
756
 
  memcpy(&state->header,ptr, sizeof(state->header));
 
924
  uint i,keys,key_parts,key_blocks;
 
925
  memcpy_fixed(&state->header,ptr, sizeof(state->header));
757
926
  ptr +=sizeof(state->header);
758
927
  keys=(uint) state->header.keys;
759
928
  key_parts=mi_uint2korr(state->header.key_parts);
771
940
  state->state.empty    = mi_sizekorr(ptr);     ptr +=8;
772
941
  state->state.key_empty= mi_sizekorr(ptr);     ptr +=8;
773
942
  state->auto_increment=mi_uint8korr(ptr);      ptr +=8;
774
 
  state->state.checksum=(internal::ha_checksum) mi_uint8korr(ptr);      ptr +=8;
 
943
  state->state.checksum=(ha_checksum) mi_uint8korr(ptr);        ptr +=8;
775
944
  state->process= mi_uint4korr(ptr);            ptr +=4;
776
945
  state->unique = mi_uint4korr(ptr);            ptr +=4;
777
946
  state->status = mi_uint4korr(ptr);            ptr +=4;
803
972
}
804
973
 
805
974
 
806
 
uint32_t mi_state_info_read_dsk(int file, MI_STATE_INFO *state, bool pRead)
 
975
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead)
807
976
{
808
 
  unsigned char buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
 
977
  uchar buff[MI_STATE_INFO_SIZE + MI_STATE_EXTRA_SIZE];
809
978
 
810
 
  if (pRead)
 
979
  if (!myisam_single_user)
811
980
  {
812
 
    if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
 
981
    if (pRead)
 
982
    {
 
983
      if (my_pread(file, buff, state->state_length,0L, MYF(MY_NABP)))
 
984
        return 1;
 
985
    }
 
986
    else if (my_read(file, buff, state->state_length,MYF(MY_NABP)))
813
987
      return 1;
 
988
    mi_state_info_read(buff, state);
814
989
  }
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
990
  return 0;
820
991
}
821
992
 
824
995
**  store and read of MI_BASE_INFO
825
996
****************************************************************************/
826
997
 
827
 
uint32_t mi_base_info_write(int file, MI_BASE_INFO *base)
 
998
uint mi_base_info_write(File file, MI_BASE_INFO *base)
828
999
{
829
 
  unsigned char buff[MI_BASE_INFO_SIZE], *ptr=buff;
 
1000
  uchar buff[MI_BASE_INFO_SIZE], *ptr=buff;
830
1001
 
831
1002
  mi_sizestore(ptr,base->keystart);                     ptr +=8;
832
1003
  mi_sizestore(ptr,base->max_data_file_length);         ptr +=8;
851
1022
  mi_int2store(ptr,base->max_key_length);               ptr +=2;
852
1023
  mi_int2store(ptr,base->extra_alloc_bytes);            ptr +=2;
853
1024
  *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;
 
1025
  *ptr++= base->raid_type;
 
1026
  mi_int2store(ptr,base->raid_chunks);                  ptr +=2;
 
1027
  mi_int4store(ptr,base->raid_chunksize);               ptr +=4;
 
1028
  bzero(ptr,6);                                         ptr +=6; /* extra */
 
1029
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
861
1030
}
862
1031
 
863
1032
 
864
 
static unsigned char *my_n_base_info_read(unsigned char *ptr, MI_BASE_INFO *base)
 
1033
uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
865
1034
{
866
1035
  base->keystart = mi_sizekorr(ptr);                    ptr +=8;
867
1036
  base->max_data_file_length = mi_sizekorr(ptr);        ptr +=8;
887
1056
  base->max_key_length = mi_uint2korr(ptr);             ptr +=2;
888
1057
  base->extra_alloc_bytes = mi_uint2korr(ptr);          ptr +=2;
889
1058
  base->extra_alloc_procent = *ptr++;
890
 
 
891
 
  /* advance past raid_type (1) raid_chunks (2) and raid_chunksize (4) */
892
 
  ptr+= 7;
 
1059
  base->raid_type= *ptr++;
 
1060
  base->raid_chunks= mi_uint2korr(ptr);                 ptr +=2;
 
1061
  base->raid_chunksize= mi_uint4korr(ptr);              ptr +=4;
 
1062
  /* TO BE REMOVED: Fix for old RAID files */
 
1063
  if (base->raid_type == 0)
 
1064
  {
 
1065
    base->raid_chunks=0;
 
1066
    base->raid_chunksize=0;
 
1067
  }
893
1068
 
894
1069
  ptr+=6;
895
1070
  return ptr;
899
1074
  mi_keydef
900
1075
---------------------------------------------------------------------------*/
901
1076
 
902
 
uint32_t mi_keydef_write(int file, MI_KEYDEF *keydef)
 
1077
uint mi_keydef_write(File file, MI_KEYDEF *keydef)
903
1078
{
904
 
  unsigned char buff[MI_KEYDEF_SIZE];
905
 
  unsigned char *ptr=buff;
 
1079
  uchar buff[MI_KEYDEF_SIZE];
 
1080
  uchar *ptr=buff;
906
1081
 
907
 
  *ptr++ = (unsigned char) keydef->keysegs;
 
1082
  *ptr++ = (uchar) keydef->keysegs;
908
1083
  *ptr++ = keydef->key_alg;                     /* Rtree or Btree */
909
1084
  mi_int2store(ptr,keydef->flag);               ptr +=2;
910
1085
  mi_int2store(ptr,keydef->block_length);       ptr +=2;
911
1086
  mi_int2store(ptr,keydef->keylength);          ptr +=2;
912
1087
  mi_int2store(ptr,keydef->minlength);          ptr +=2;
913
1088
  mi_int2store(ptr,keydef->maxlength);          ptr +=2;
914
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1089
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
915
1090
}
916
1091
 
917
 
static unsigned char *mi_keydef_read(unsigned char *ptr, MI_KEYDEF *keydef)
 
1092
uchar *mi_keydef_read(uchar *ptr, MI_KEYDEF *keydef)
918
1093
{
919
1094
   keydef->keysegs      = (uint) *ptr++;
920
1095
   keydef->key_alg      = *ptr++;               /* Rtree or Btree */
927
1102
   keydef->block_size_index= keydef->block_length/MI_MIN_KEY_BLOCK_LENGTH-1;
928
1103
   keydef->underflow_block_length=keydef->block_length/3;
929
1104
   keydef->version      = 0;                    /* Not saved */
 
1105
   keydef->parser       = &ft_default_parser;
 
1106
   keydef->ftparser_nr  = 0;
930
1107
   return ptr;
931
1108
}
932
1109
 
934
1111
**  mi_keyseg
935
1112
***************************************************************************/
936
1113
 
937
 
int mi_keyseg_write(int file, const HA_KEYSEG *keyseg)
 
1114
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
938
1115
{
939
 
  unsigned char buff[HA_KEYSEG_SIZE];
940
 
  unsigned char *ptr=buff;
 
1116
  uchar buff[HA_KEYSEG_SIZE];
 
1117
  uchar *ptr=buff;
941
1118
  ulong pos;
942
1119
 
943
1120
  *ptr++= keyseg->type;
952
1129
  pos= keyseg->null_bit ? keyseg->null_pos : keyseg->bit_pos;
953
1130
  mi_int4store(ptr, pos);
954
1131
  ptr+=4;
955
 
 
956
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1132
  
 
1133
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
957
1134
}
958
1135
 
959
1136
 
960
 
static unsigned char *mi_keyseg_read(unsigned char *ptr, HA_KEYSEG *keyseg)
 
1137
uchar *mi_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg)
961
1138
{
962
1139
   keyseg->type         = *ptr++;
963
1140
   keyseg->language     = *ptr++;
971
1148
   keyseg->null_pos     = mi_uint4korr(ptr);  ptr +=4;
972
1149
   keyseg->charset=0;                           /* Will be filled in later */
973
1150
   if (keyseg->null_bit)
974
 
     keyseg->bit_pos= (uint16_t)(keyseg->null_pos + (keyseg->null_bit == 7));
 
1151
     keyseg->bit_pos= (uint16)(keyseg->null_pos + (keyseg->null_bit == 7));
975
1152
   else
976
1153
   {
977
 
     keyseg->bit_pos= (uint16_t)keyseg->null_pos;
 
1154
     keyseg->bit_pos= (uint16)keyseg->null_pos;
978
1155
     keyseg->null_pos= 0;
979
1156
   }
980
1157
   return ptr;
984
1161
  mi_uniquedef
985
1162
---------------------------------------------------------------------------*/
986
1163
 
987
 
uint32_t mi_uniquedef_write(int file, MI_UNIQUEDEF *def)
 
1164
uint mi_uniquedef_write(File file, MI_UNIQUEDEF *def)
988
1165
{
989
 
  unsigned char buff[MI_UNIQUEDEF_SIZE];
990
 
  unsigned char *ptr=buff;
 
1166
  uchar buff[MI_UNIQUEDEF_SIZE];
 
1167
  uchar *ptr=buff;
991
1168
 
992
1169
  mi_int2store(ptr,def->keysegs);               ptr+=2;
993
 
  *ptr++=  (unsigned char) def->key;
994
 
  *ptr++ = (unsigned char) def->null_are_equal;
 
1170
  *ptr++=  (uchar) def->key;
 
1171
  *ptr++ = (uchar) def->null_are_equal;
995
1172
 
996
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1173
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
997
1174
}
998
1175
 
999
 
static unsigned char *mi_uniquedef_read(unsigned char *ptr, MI_UNIQUEDEF *def)
 
1176
uchar *mi_uniquedef_read(uchar *ptr, MI_UNIQUEDEF *def)
1000
1177
{
1001
1178
   def->keysegs = mi_uint2korr(ptr);
1002
1179
   def->key     = ptr[2];
1008
1185
**  MI_COLUMNDEF
1009
1186
***************************************************************************/
1010
1187
 
1011
 
uint32_t mi_recinfo_write(int file, MI_COLUMNDEF *recinfo)
 
1188
uint mi_recinfo_write(File file, MI_COLUMNDEF *recinfo)
1012
1189
{
1013
 
  unsigned char buff[MI_COLUMNDEF_SIZE];
1014
 
  unsigned char *ptr=buff;
 
1190
  uchar buff[MI_COLUMNDEF_SIZE];
 
1191
  uchar *ptr=buff;
1015
1192
 
1016
1193
  mi_int2store(ptr,recinfo->type);      ptr +=2;
1017
1194
  mi_int2store(ptr,recinfo->length);    ptr +=2;
1018
1195
  *ptr++ = recinfo->null_bit;
1019
1196
  mi_int2store(ptr,recinfo->null_pos);  ptr+= 2;
1020
 
  return internal::my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
 
1197
  return my_write(file, buff, (size_t) (ptr-buff), MYF(MY_NABP)) != 0;
1021
1198
}
1022
1199
 
1023
 
static unsigned char *mi_recinfo_read(unsigned char *ptr, MI_COLUMNDEF *recinfo)
 
1200
uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo)
1024
1201
{
1025
1202
   recinfo->type=  mi_sint2korr(ptr);   ptr +=2;
1026
1203
   recinfo->length=mi_uint2korr(ptr);   ptr +=2;
1027
 
   recinfo->null_bit= (uint8_t) *ptr++;
 
1204
   recinfo->null_bit= (uint8) *ptr++;
1028
1205
   recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
1029
1206
   return ptr;
1030
1207
}
1031
1208
 
1032
1209
/**************************************************************************
1033
 
Open data file
 
1210
Open data file with or without RAID
1034
1211
We can't use dup() here as the data file descriptors need to have different
1035
1212
active seek-positions.
1036
1213
 
1038
1215
exist a dup()-like call that would give us two different file descriptors.
1039
1216
*************************************************************************/
1040
1217
 
1041
 
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, int file_to_dup)
 
1218
int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share,
 
1219
                     File file_to_dup __attribute__((unused)))
1042
1220
{
1043
 
  (void)file_to_dup; 
1044
 
  info->dfile=internal::my_open(share->data_file_name, share->mode,
1045
 
                      MYF(MY_WME));
 
1221
#ifdef USE_RAID
 
1222
  if (share->base.raid_type)
 
1223
  {
 
1224
    info->dfile=my_raid_open(share->data_file_name,
 
1225
                             share->mode | O_SHARE,
 
1226
                             share->base.raid_type,
 
1227
                             share->base.raid_chunks,
 
1228
                             share->base.raid_chunksize,
 
1229
                             MYF(MY_WME | MY_RAID));
 
1230
  }
 
1231
  else
 
1232
#endif
 
1233
    info->dfile=my_open(share->data_file_name, share->mode | O_SHARE,
 
1234
                        MYF(MY_WME));
1046
1235
  return info->dfile >= 0 ? 0 : 1;
1047
1236
}
1048
1237
 
1049
1238
 
1050
1239
int mi_open_keyfile(MYISAM_SHARE *share)
1051
1240
{
1052
 
  if ((share->kfile=internal::my_open(share->unique_file_name, share->mode,
 
1241
  if ((share->kfile=my_open(share->unique_file_name, share->mode | O_SHARE,
1053
1242
                            MYF(MY_WME))) < 0)
1054
1243
    return 1;
1055
1244
  return 0;