Index: sql/sql_parse.cc
===================================================================
--- sql/sql_parse.cc.orig
+++ sql/sql_parse.cc
@@ -3094,17 +3094,45 @@ mysql_execute_command(THD *thd)
     create_info.data_file_name= create_info.index_file_name= NULL;
 #else
 
-    if (test_if_data_home_dir(lex->create_info.data_file_name))
+    char dirpath[FN_REFLEN];
+
+    /*
+      data_file_name and index_file_name include the table name without
+      extension. Mostly this does not refer to an existing file. When
+      comparing data_file_name or index_file_name against the data
+      directory, we try to resolve all symbolic links. On some systems,
+      we use realpath(3) for the resolution. This returns ENOENT if the
+      resolved path does not refer to an existing file. my_realpath()
+      does then copy the requested path verbatim, without symlink
+      resolution. Thereafter the comparison can fail even if the
+      requested path is within the data directory. E.g. if symlinks to
+      another file system are used. To make realpath(3) return the
+      resolved path, we strip the table name and compare the directory
+      path only. If the directory doesn't exist either, table creation
+      will fail anyway. But we can't strip blindly anything so we keep
+      the previous check too, just to be sure.
+    */
+    if (lex->create_info.data_file_name)
     {
-      my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECTORY");
-      res= -1;
-      break;
+      dirname_part(dirpath, lex->create_info.data_file_name);
+      if (test_if_data_home_dir(dirpath) 
+          || test_if_data_home_dir(lex->create_info.data_file_name) )
+      {
+        my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
+        res= -1;
+        break;
+      }
     }
-    if (test_if_data_home_dir(lex->create_info.index_file_name))
+    if (lex->create_info.index_file_name)
     {
-      my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECTORY");
-      res= -1;
-      break;
+      dirname_part(dirpath, lex->create_info.index_file_name);
+      if (test_if_data_home_dir(dirpath)
+          || test_if_data_home_dir(lex->create_info.index_file_name) )
+      {
+        my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
+        res= -1;
+        break;
+      }
     }
 
     /* Fix names if symlinked tables */
Index: libmysqld/sql_parse.cc
===================================================================
--- libmysqld/sql_parse.cc.orig
+++ libmysqld/sql_parse.cc
@@ -3095,17 +3095,45 @@ mysql_execute_command(THD *thd)
     create_info.data_file_name= create_info.index_file_name= NULL;
 #else
 
-    if (test_if_data_home_dir(lex->create_info.data_file_name))
+    char dirpath[FN_REFLEN];
+
+    /*
+      data_file_name and index_file_name include the table name without
+      extension. Mostly this does not refer to an existing file. When
+      comparing data_file_name or index_file_name against the data
+      directory, we try to resolve all symbolic links. On some systems,
+      we use realpath(3) for the resolution. This returns ENOENT if the
+      resolved path does not refer to an existing file. my_realpath()
+      does then copy the requested path verbatim, without symlink
+      resolution. Thereafter the comparison can fail even if the
+      requested path is within the data directory. E.g. if symlinks to
+      another file system are used. To make realpath(3) return the
+      resolved path, we strip the table name and compare the directory
+      path only. If the directory doesn't exist either, table creation
+      will fail anyway. But we can't strip blindly anything so we keep
+      the previous check too, just to be sure.
+    */
+    if (lex->create_info.data_file_name)
     {
-      my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY");
-      res= -1;
-      break;
+      dirname_part(dirpath, lex->create_info.data_file_name);
+      if (test_if_data_home_dir(dirpath) 
+          || test_if_data_home_dir(lex->create_info.data_file_name) )
+      {
+        my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
+        res= -1;
+        break;
+      }
     }
-    if (test_if_data_home_dir(lex->create_info.index_file_name))
+    if (lex->create_info.index_file_name)
     {
-      my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY");
-      res= -1;
-      break;
+      dirname_part(dirpath, lex->create_info.index_file_name);
+      if (test_if_data_home_dir(dirpath)
+          || test_if_data_home_dir(lex->create_info.index_file_name) )
+      {
+        my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
+        res= -1;
+        break;
+      }
     }
 
     /* Fix names if symlinked tables */
