diff -Naurp mysql-cluster-gpl-7.1.3/mysql-test/r/symlink.result mysql-cluster-gpl-7.1.3.oden/mysql-test/r/symlink.result --- mysql-cluster-gpl-7.1.3/mysql-test/r/symlink.result 2010-03-29 17:16:21.000000000 +0200 +++ mysql-cluster-gpl-7.1.3.oden/mysql-test/r/symlink.result 2010-05-26 13:55:19.277301020 +0200 @@ -168,4 +168,16 @@ Warning 1618 <DATA DIRECTORY> option ign Warning 1618 <INDEX DIRECTORY> option ignored DROP TABLE t1; SET @@SQL_MODE=@OLD_SQL_MODE; +# +# BUG#40980 - Drop table can remove another MyISAM table's +# data and index files +# +CREATE TABLE user(a INT) DATA DIRECTORY='MYSQL_TMP_DIR/mysql' + INDEX DIRECTORY='MYSQL_TMP_DIR/mysql'; +FLUSH TABLE user; +# Symlinking mysql database to tmpdir +FLUSH TABLE mysql.user; +DROP TABLE user; +FLUSH TABLE mysql.user; +SELECT * FROM mysql.user; End of 5.1 tests diff -Naurp mysql-cluster-gpl-7.1.3/mysql-test/t/symlink.test mysql-cluster-gpl-7.1.3.oden/mysql-test/t/symlink.test --- mysql-cluster-gpl-7.1.3/mysql-test/t/symlink.test 2010-03-29 17:15:52.000000000 +0200 +++ mysql-cluster-gpl-7.1.3.oden/mysql-test/t/symlink.test 2010-05-26 13:55:19.278300392 +0200 @@ -249,4 +249,26 @@ eval CREATE TABLE t1(a INT) DATA DIRECTO DROP TABLE t1; SET @@SQL_MODE=@OLD_SQL_MODE; +--echo # +--echo # BUG#40980 - Drop table can remove another MyISAM table's +--echo # data and index files +--echo # +--mkdir $MYSQL_TMP_DIR/mysql +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +eval CREATE TABLE user(a INT) DATA DIRECTORY='$MYSQL_TMP_DIR/mysql' + INDEX DIRECTORY='$MYSQL_TMP_DIR/mysql'; +FLUSH TABLE user; +--echo # Symlinking mysql database to tmpdir +--remove_file $MYSQL_TMP_DIR/mysql/user.MYD +--remove_file $MYSQL_TMP_DIR/mysql/user.MYI +--rmdir $MYSQL_TMP_DIR/mysql +--exec ln -s $MYSQLD_DATADIR/mysql $MYSQL_TMP_DIR/mysql +FLUSH TABLE mysql.user; +DROP TABLE user; +FLUSH TABLE mysql.user; +--disable_result_log +SELECT * FROM mysql.user; +--enable_result_log +--remove_file $MYSQL_TMP_DIR/mysql + --echo End of 5.1 tests diff -Naurp mysql-cluster-gpl-7.1.3/storage/myisam/mi_delete_table.c mysql-cluster-gpl-7.1.3.oden/storage/myisam/mi_delete_table.c --- mysql-cluster-gpl-7.1.3/storage/myisam/mi_delete_table.c 2010-03-29 16:51:37.000000000 +0200 +++ mysql-cluster-gpl-7.1.3.oden/storage/myisam/mi_delete_table.c 2010-05-26 13:55:19.278300392 +0200 @@ -22,6 +22,41 @@ #include "fulltext.h" + +/** + Remove MyISAM data/index file safely + + @details + If name is a symlink and file it is pointing to is not in + data directory, file is also removed. + + @param name file to remove + + @returns + 0 on success or my_errno on failure +*/ + +static int _mi_safe_delete_file(const char *name) +{ + DBUG_ENTER("_mi_safe_delete_file"); + if (my_is_symlink(name) && (*myisam_test_invalid_symlink)(name)) + { + /* + Symlink is pointing to file in data directory. + Remove symlink, keep file. + */ + if (my_delete(name, MYF(MY_WME))) + DBUG_RETURN(my_errno); + } + else + { + if (my_delete_with_symlink(name, MYF(MY_WME))) + DBUG_RETURN(my_errno); + } + DBUG_RETURN(0); +} + + int mi_delete_table(const char *name) { char from[FN_REFLEN]; @@ -61,12 +96,12 @@ int mi_delete_table(const char *name) #endif /* USE_RAID */ fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); - if (my_delete_with_symlink(from, MYF(MY_WME))) + if (_mi_safe_delete_file(from)) DBUG_RETURN(my_errno); fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); #ifdef USE_RAID if (raid_type) DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0); #endif - DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0); + DBUG_RETURN(_mi_safe_delete_file(from)); }