diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-03-03 01:37:54 +0200 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-03-03 01:37:54 +0200 |
commit | 1acfa942edb72fedcf92dd017ae5fef8694382e5 (patch) | |
tree | 721fcd9a479ce34633659c936f36fa1e20856620 /storage/myisam | |
parent | cc413ce9a368b930aba5e63c0ab013f7b3ab3c04 (diff) | |
parent | 5a0fff50f87e20c4e95a84143a0a3bb67e03e29e (diff) | |
download | mariadb-git-1acfa942edb72fedcf92dd017ae5fef8694382e5.tar.gz |
Merge branch '5.5' into 10.0
Diffstat (limited to 'storage/myisam')
-rw-r--r-- | storage/myisam/ha_myisam.cc | 15 | ||||
-rw-r--r-- | storage/myisam/mi_check.c | 18 | ||||
-rw-r--r-- | storage/myisam/mi_create.c | 53 | ||||
-rw-r--r-- | storage/myisam/mi_delete_table.c | 36 | ||||
-rw-r--r-- | storage/myisam/mi_open.c | 66 | ||||
-rw-r--r-- | storage/myisam/mi_static.c | 8 | ||||
-rw-r--r-- | storage/myisam/myisamchk.c | 2 | ||||
-rw-r--r-- | storage/myisam/myisamdef.h | 3 |
8 files changed, 85 insertions, 116 deletions
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 730a63067ac..2b70518c8fd 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1896,15 +1896,22 @@ int ha_myisam::info(uint flag) Set data_file_name and index_file_name to point at the symlink value if table is symlinked (Ie; Real name is not same as generated name) */ + char buf[FN_REFLEN]; data_file_name= index_file_name= 0; fn_format(name_buff, file->filename, "", MI_NAME_DEXT, MY_APPEND_EXT | MY_UNPACK_FILENAME); - if (strcmp(name_buff, misam_info.data_file_name)) - data_file_name=misam_info.data_file_name; + if (my_is_symlink(name_buff)) + { + my_readlink(buf, name_buff, MYF(0)); + data_file_name= ha_thd()->strdup(buf); + } fn_format(name_buff, file->filename, "", MI_NAME_IEXT, MY_APPEND_EXT | MY_UNPACK_FILENAME); - if (strcmp(name_buff, misam_info.index_file_name)) - index_file_name=misam_info.index_file_name; + if (my_is_symlink(name_buff)) + { + my_readlink(buf, name_buff, MYF(0)); + index_file_name= ha_thd()->strdup(buf); + } } if (flag & HA_STATUS_ERRKEY) { diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index ec72e0b430a..bbe45aa3c26 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -80,8 +80,7 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks, uint buffer_length); static ha_checksum mi_byte_checksum(const uchar *buf, uint length); static void set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share); -static int replace_data_file(HA_CHECK *param, MI_INFO *info, - const char *name, File new_file); +static int replace_data_file(HA_CHECK *param, MI_INFO *info, File new_file); void myisamchk_init(HA_CHECK *param) { @@ -1715,7 +1714,7 @@ err: /* Replace the actual file with the temporary file */ if (new_file >= 0) { - got_error= replace_data_file(param, info, name, new_file); + got_error= replace_data_file(param, info, new_file); new_file= -1; param->retry_repair= 0; } @@ -2528,7 +2527,7 @@ err: /* Replace the actual file with the temporary file */ if (new_file >= 0) { - got_error= replace_data_file(param, info, name, new_file); + got_error= replace_data_file(param, info, new_file); new_file= -1; } } @@ -2542,7 +2541,7 @@ err: (void) mysql_file_delete(mi_key_file_datatmp, param->temp_filename, MYF(MY_WME)); if (info->dfile == new_file) /* Retry with key cache */ - if (unlikely(mi_open_datafile(info, share, name, -1))) + if (unlikely(mi_open_datafile(info, share))) param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); @@ -3063,7 +3062,7 @@ err: /* Replace the actual file with the temporary file */ if (new_file >= 0) { - got_error= replace_data_file(param, info, name, new_file); + got_error= replace_data_file(param, info, new_file); new_file= -1; } } @@ -3077,7 +3076,7 @@ err: (void) mysql_file_delete(mi_key_file_datatmp, param->temp_filename, MYF(MY_WME)); if (info->dfile == new_file) /* Retry with key cache */ - if (unlikely(mi_open_datafile(info, share, name, -1))) + if (unlikely(mi_open_datafile(info, share))) param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); @@ -4760,8 +4759,7 @@ int mi_make_backup_of_index(MI_INFO *info, time_t backup_time, myf flags) } -static int replace_data_file(HA_CHECK *param, MI_INFO *info, - const char *name, File new_file) +static int replace_data_file(HA_CHECK *param, MI_INFO *info, File new_file) { MYISAM_SHARE *share=info->s; @@ -4796,7 +4794,7 @@ static int replace_data_file(HA_CHECK *param, MI_INFO *info, DATA_TMP_EXT, param->backup_time, (param->testflag & T_BACKUP_DATA ? MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || - mi_open_datafile(info, share, name, -1)) + mi_open_datafile(info, share)) return 1; return 0; } diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 88b9da6f8a9..aa85a3718de 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -46,7 +46,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, uint aligned_key_start, block_length, res; uint internal_table= flags & HA_CREATE_INTERNAL_TABLE; ulong reclength, real_reclength,min_pack_length; - char filename[FN_REFLEN],linkname[FN_REFLEN], *linkname_ptr; + char kfilename[FN_REFLEN],klinkname[FN_REFLEN], *klinkname_ptr; + char dfilename[FN_REFLEN],dlinkname[FN_REFLEN], *dlinkname_ptr; ulong pack_reclength; ulonglong tot_length,max_rows, tmp; enum en_fieldtype type; @@ -594,19 +595,19 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, /* chop off the table name, tempory tables use generated name */ if ((path= strrchr(ci->index_file_name, FN_LIBCHAR))) *path= '\0'; - fn_format(filename, name, ci->index_file_name, MI_NAME_IEXT, + fn_format(kfilename, name, ci->index_file_name, MI_NAME_IEXT, MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | MY_APPEND_EXT); } else { - fn_format(filename, ci->index_file_name, "", MI_NAME_IEXT, + fn_format(kfilename, ci->index_file_name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); } - fn_format(linkname, name, "", MI_NAME_IEXT, + fn_format(klinkname, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME|MY_APPEND_EXT); - linkname_ptr=linkname; + klinkname_ptr= klinkname; /* Don't create the table if the link or file exists to ensure that one doesn't accidently destroy another table. @@ -617,10 +618,10 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { char *iext= strrchr(name, '.'); int have_iext= iext && !strcmp(iext, MI_NAME_IEXT); - fn_format(filename, name, "", MI_NAME_IEXT, + fn_format(kfilename, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); - linkname_ptr=0; + klinkname_ptr= 0; /* Replace the current file */ create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD; } @@ -635,7 +636,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, NOTE: The filename is compared against unique_file_name of every open table. Hence we need a real path here. */ - if (!internal_table && test_if_reopen(filename)) + if (!internal_table && test_if_reopen(kfilename)) { my_printf_error(HA_ERR_TABLE_EXIST, "MyISAM table '%s' is in use " "(most likely by a MERGE table). Try FLUSH TABLES.", @@ -645,7 +646,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, } if ((file= mysql_file_create_with_symlink(mi_key_file_kfile, - linkname_ptr, filename, 0, + klinkname_ptr, kfilename, 0, create_mode, MYF(MY_WME | create_flag))) < 0) goto err; @@ -665,31 +666,31 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, /* chop off the table name, tempory tables use generated name */ if ((path= strrchr(ci->data_file_name, FN_LIBCHAR))) *path= '\0'; - fn_format(filename, name, ci->data_file_name, MI_NAME_DEXT, + fn_format(dfilename, name, ci->data_file_name, MI_NAME_DEXT, MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_APPEND_EXT); } else { - fn_format(filename, ci->data_file_name, "", MI_NAME_DEXT, + fn_format(dfilename, ci->data_file_name, "", MI_NAME_DEXT, MY_UNPACK_FILENAME | (have_dext ? MY_REPLACE_EXT : MY_APPEND_EXT)); } - fn_format(linkname, name, "",MI_NAME_DEXT, + fn_format(dlinkname, name, "",MI_NAME_DEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT); - linkname_ptr=linkname; + dlinkname_ptr= dlinkname; create_flag=0; } else { - fn_format(filename,name,"", MI_NAME_DEXT, + fn_format(dfilename,name,"", MI_NAME_DEXT, MY_UNPACK_FILENAME | MY_APPEND_EXT); - linkname_ptr=0; + dlinkname_ptr= 0; create_flag=(flags & HA_CREATE_KEEP_FILES) ? 0 : MY_DELETE_OLD; } if ((dfile= mysql_file_create_with_symlink(mi_key_file_dfile, - linkname_ptr, filename, 0, + dlinkname_ptr, dfilename, 0, create_mode, MYF(MY_WME | create_flag))) < 0) goto err; @@ -843,19 +844,21 @@ err_no_lock: (void) mysql_file_close(dfile, MYF(0)); /* fall through */ case 2: - if (! (flags & HA_DONT_TOUCH_DATA)) - mysql_file_delete_with_symlink(mi_key_file_dfile, - fn_format(filename, name, "", MI_NAME_DEXT, - MY_UNPACK_FILENAME | MY_APPEND_EXT), - MYF(0)); + if (! (flags & HA_DONT_TOUCH_DATA)) + { + mysql_file_delete(mi_key_file_dfile, dfilename, MYF(0)); + if (dlinkname_ptr) + mysql_file_delete(mi_key_file_dfile, dlinkname_ptr, MYF(0)); + } /* fall through */ case 1: (void) mysql_file_close(file, MYF(0)); if (! (flags & HA_DONT_TOUCH_DATA)) - mysql_file_delete_with_symlink(mi_key_file_kfile, - fn_format(filename, name, "", MI_NAME_IEXT, - MY_UNPACK_FILENAME | MY_APPEND_EXT), - MYF(0)); + { + mysql_file_delete(mi_key_file_kfile, kfilename, MYF(0)); + if (klinkname_ptr) + mysql_file_delete(mi_key_file_kfile, klinkname_ptr, MYF(0)); + } } my_free(rec_per_key_part); DBUG_RETURN(my_errno=save_errno); /* return the fatal errno */ diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c index 7da960011ca..a72a94b06d2 100644 --- a/storage/myisam/mi_delete_table.c +++ b/storage/myisam/mi_delete_table.c @@ -26,30 +26,6 @@ #define mi_key_file_dfile 0 #endif -static int delete_one_file(const char *name, const char *ext, - PSI_file_key pskey __attribute__((unused)), - myf flags) -{ - char from[FN_REFLEN]; - DBUG_ENTER("delete_one_file"); - fn_format(from,name, "", ext, MY_UNPACK_FILENAME | MY_APPEND_EXT); - if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from)) - { - /* - Symlink is pointing to file in data directory. - Remove symlink, keep file. - */ - if (mysql_file_delete(pskey, from, flags)) - DBUG_RETURN(my_errno); - } - else - { - if (mysql_file_delete_with_symlink(pskey, from, flags)) - DBUG_RETURN(my_errno); - } - DBUG_RETURN(0); -} - int mi_delete_table(const char *name) { int res; @@ -59,14 +35,14 @@ int mi_delete_table(const char *name) check_table_is_closed(name,"delete"); #endif - if ((res= delete_one_file(name, MI_NAME_IEXT, mi_key_file_kfile, MYF(MY_WME)))) - DBUG_RETURN(res); - if ((res= delete_one_file(name, MI_NAME_DEXT, mi_key_file_dfile, MYF(MY_WME)))) - DBUG_RETURN(res); + if (my_handler_delete_with_symlink(mi_key_file_kfile, name, MI_NAME_IEXT, MYF(MY_WME)) || + my_handler_delete_with_symlink(mi_key_file_dfile, name, MI_NAME_DEXT, MYF(MY_WME))) + DBUG_RETURN(my_errno); + // optionally present: - delete_one_file(name, ".OLD", mi_key_file_dfile, MYF(0)); - delete_one_file(name, ".TMD", mi_key_file_dfile, MYF(0)); + my_handler_delete_with_symlink(mi_key_file_dfile, name, ".OLD", MYF(0)); + my_handler_delete_with_symlink(mi_key_file_dfile, name, ".TMD", MYF(0)); DBUG_RETURN(0); } diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 060017f10ad..31612b0e902 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -105,7 +105,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) realpath_err= my_realpath(name_buff, fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0)); if (my_is_symlink(org_name) && - (realpath_err || (*myisam_test_invalid_symlink)(name_buff))) + (realpath_err || mysys_test_invalid_symlink(name_buff))) { my_errno= HA_WRONG_CREATE_OPTION; DBUG_RETURN (NULL); @@ -131,15 +131,17 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) my_errno= HA_ERR_CRASHED; goto err; }); - if ((kfile= mysql_file_open(mi_key_file_kfile, - name_buff, - (open_mode= O_RDWR) | O_SHARE, MYF(0))) < 0) + + DEBUG_SYNC_C("mi_open_kfile"); + if ((kfile= mysql_file_open(mi_key_file_kfile, name_buff, + (open_mode= O_RDWR) | O_SHARE | O_NOFOLLOW, + MYF(MY_NOSYMLINKS))) < 0) { if ((errno != EROFS && errno != EACCES) || mode != O_RDONLY || - (kfile= mysql_file_open(mi_key_file_kfile, - name_buff, - (open_mode= O_RDONLY) | O_SHARE, MYF(0))) < 0) + (kfile= mysql_file_open(mi_key_file_kfile, name_buff, + (open_mode= O_RDONLY) | O_SHARE| O_NOFOLLOW, + MYF(MY_NOSYMLINKS))) < 0) goto err; } share->mode=open_mode; @@ -183,7 +185,18 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) (void) strmov(index_name, org_name); *strrchr(org_name, '.')= '\0'; (void) fn_format(data_name,org_name,"",MI_NAME_DEXT, - MY_APPEND_EXT|MY_UNPACK_FILENAME|MY_RESOLVE_SYMLINKS); + MY_APPEND_EXT|MY_UNPACK_FILENAME); + if (my_is_symlink(data_name)) + { + if (my_realpath(data_name, data_name, MYF(0))) + goto err; + if (mysys_test_invalid_symlink(data_name)) + { + my_errno= HA_WRONG_CREATE_OPTION; + goto err; + } + share->mode|= O_NOFOLLOW; /* all symlinks are resolved by realpath() */ + } info_length=mi_uint2korr(share->state.header.header_length); base_pos=mi_uint2korr(share->state.header.base_pos); @@ -497,7 +510,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) lock_error=1; /* Database unlocked */ } - if (mi_open_datafile(&info, share, name, -1)) + if (mi_open_datafile(&info, share)) goto err; errpos=5; @@ -578,7 +591,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) my_errno=EACCES; /* Can't open in write mode */ goto err; } - if (mi_open_datafile(&info, share, name, old_info->dfile)) + if (mi_open_datafile(&info, share)) goto err; errpos=5; have_rtree= old_info->rtree_recursion_state != NULL; @@ -1250,33 +1263,14 @@ uchar *mi_recinfo_read(uchar *ptr, MI_COLUMNDEF *recinfo) Open data file. We can't use dup() here as the data file descriptors need to have different active seek-positions. - -The argument file_to_dup is here for the future if there would on some OS -exist a dup()-like call that would give us two different file descriptors. *************************************************************************/ -int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name, - File file_to_dup __attribute__((unused))) +int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share) { - char *data_name= share->data_file_name; - char real_data_name[FN_REFLEN]; - - if (org_name) - { - fn_format(real_data_name,org_name,"",MI_NAME_DEXT,4); - if (my_is_symlink(real_data_name)) - { - if (my_realpath(real_data_name, real_data_name, MYF(0)) || - (*myisam_test_invalid_symlink)(real_data_name)) - { - my_errno= HA_WRONG_CREATE_OPTION; - return 1; - } - data_name= real_data_name; - } - } - info->dfile= mysql_file_open(mi_key_file_dfile, - data_name, share->mode | O_SHARE, MYF(MY_WME)); + myf flags= MY_WME | (share->mode & O_NOFOLLOW ? MY_NOSYMLINKS: 0); + DEBUG_SYNC_C("mi_open_datafile"); + info->dfile= mysql_file_open(mi_key_file_dfile, share->data_file_name, + share->mode | O_SHARE, MYF(flags)); return info->dfile >= 0 ? 0 : 1; } @@ -1285,8 +1279,8 @@ int mi_open_keyfile(MYISAM_SHARE *share) { if ((share->kfile= mysql_file_open(mi_key_file_kfile, share->unique_file_name, - share->mode | O_SHARE, - MYF(MY_WME))) < 0) + share->mode | O_SHARE | O_NOFOLLOW, + MYF(MY_NOSYMLINKS | MY_WME))) < 0) return 1; return 0; } diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c index d77f4f6b8e2..49019fb861c 100644 --- a/storage/myisam/mi_static.c +++ b/storage/myisam/mi_static.c @@ -42,14 +42,6 @@ ulong myisam_data_pointer_size=4; ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0; my_bool (*mi_killed)(MI_INFO *)= mi_killed_standalone; -static int always_valid(const char *filename __attribute__((unused))) -{ - return 0; -} - -int (*myisam_test_invalid_symlink)(const char *filename)= always_valid; - - /* read_vec[] is used for converting between P_READ_KEY.. and SEARCH_ Position is , == , >= , <= , > , < diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 7835ab83531..edbe235e190 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1047,7 +1047,7 @@ static int myisamchk(HA_CHECK *param, char * filename) MYF(MY_WME)); /* Close new file */ error|=change_to_newfile(filename, MI_NAME_DEXT, DATA_TMP_EXT, 0, MYF(0)); - if (mi_open_datafile(info,info->s, NULL, -1)) + if (mi_open_datafile(info, info->s)) error=1; param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */ param->read_cache.file=info->dfile; diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h index 07c4a5b473a..92fc5e45d5d 100644 --- a/storage/myisam/myisamdef.h +++ b/storage/myisam/myisamdef.h @@ -713,8 +713,7 @@ void mi_disable_indexes_for_rebuild(MI_INFO *info, ha_rows rows, my_bool all_keys); extern MI_INFO *test_if_reopen(char *filename); my_bool check_table_is_closed(const char *name, const char *where); -int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *orn_name, - File file_to_dup); +int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share); int mi_open_keyfile(MYISAM_SHARE *share); void mi_setup_functions(register MYISAM_SHARE *share); |