summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@sun.com>2010-04-01 22:17:34 +0400
committerSergey Vojtovich <svoj@sun.com>2010-04-01 22:17:34 +0400
commit645ee41e26aceb579ddde12839fe97cbfb96c6af (patch)
treec86be8db4bb43e71ac2c0853507518201598a473
parentc9ed4d0bfc656f6b2e68cf3781ea7994592bd68f (diff)
parent4050910f03a41938ab3d475b5cc067488332e197 (diff)
downloadmariadb-git-645ee41e26aceb579ddde12839fe97cbfb96c6af.tar.gz
Merge fix for BUG40980 to mysql-5.1-bugteam.
-rw-r--r--mysql-test/r/symlink.result12
-rw-r--r--mysql-test/t/symlink.test22
-rw-r--r--storage/myisam/mi_delete_table.c39
3 files changed, 71 insertions, 2 deletions
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index 245dcec04da..4dac7443135 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -168,4 +168,16 @@ Warning 1618 <DATA DIRECTORY> option ignored
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 --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index c805dd40fe8..073fcd28246 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -249,4 +249,26 @@ eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX 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 --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index a3c0dede581..c4797187bec 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -19,6 +19,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];
@@ -58,12 +93,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));
}