1 /* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; version 2 of the License.
6 
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11 
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
15 
16 #include "ma_fulltext.h"
17 
18 /*
19   Stop usage of Maria
20 
21   SYNOPSIS
22      maria_panic()
23      flag	HA_PANIC_CLOSE:  All maria files (tables and log) are closed.
24 				 maria_end() is called.
25                 HA_PANIC_WRITE:  All misam files are unlocked and
26                                  all changed data in single user maria is
27                                  written to file
28                 HA_PANIC_READ    All maria files that was locked when
29 			         maria_panic(HA_PANIC_WRITE) was done is
30                                  locked. A maria_readinfo() is done for
31                                  all single user files to get changes
32                                  in database
33 
34   RETURN
35     0  ok
36     #  error number in case of error
37 */
38 
maria_panic(enum ha_panic_function flag)39 int maria_panic(enum ha_panic_function flag)
40 {
41   int error=0;
42   LIST *list_element,*next_open;
43   MARIA_HA *info;
44   DBUG_ENTER("maria_panic");
45 
46   if (!maria_inited)
47     DBUG_RETURN(0);
48   mysql_mutex_lock(&THR_LOCK_maria);
49   for (list_element=maria_open_list ; list_element ; list_element=next_open)
50   {
51     next_open=list_element->next;		/* Save if close */
52     info=(MARIA_HA*) list_element->data;
53     switch (flag) {
54     case HA_PANIC_CLOSE:
55       /*
56         If bad luck (if some tables would be used now, which normally does not
57         happen in MySQL), as we release the mutex, the list may change and so
58         we may crash.
59       */
60       mysql_mutex_unlock(&THR_LOCK_maria);
61       if (maria_close(info))
62 	error=my_errno;
63       mysql_mutex_lock(&THR_LOCK_maria);
64       break;
65     case HA_PANIC_WRITE:		/* Do this to free databases */
66 #ifdef CANT_OPEN_FILES_TWICE
67       if (info->s->options & HA_OPTION_READ_ONLY_DATA)
68 	break;
69 #endif
70       if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
71                                 FLUSH_RELEASE, FLUSH_RELEASE))
72 	error=my_errno;
73       if (info->opt_flag & WRITE_CACHE_USED)
74 	if (flush_io_cache(&info->rec_cache))
75 	  error=my_errno;
76       if (info->opt_flag & READ_CACHE_USED)
77       {
78 	if (flush_io_cache(&info->rec_cache))
79 	  error=my_errno;
80 	reinit_io_cache(&info->rec_cache,READ_CACHE,0,
81 		       (pbool) (info->lock_type != F_UNLCK),1);
82       }
83       if (info->lock_type != F_UNLCK && ! info->was_locked)
84       {
85 	info->was_locked=info->lock_type;
86 	if (maria_lock_database(info,F_UNLCK))
87 	  error=my_errno;
88       }
89 #ifdef CANT_OPEN_FILES_TWICE
90       if (info->s->kfile.file >= 0 && mysql_file_close(info->s->kfile.file, MYF(0)))
91 	error = my_errno;
92       if (info->dfile.file >= 0 && mysql_file_close(info->dfile.file, MYF(0)))
93 	error = my_errno;
94       info->s->kfile.file= info->dfile.file= -1;/* Files aren't open anymore */
95 #endif
96       break;
97     case HA_PANIC_READ:			/* Restore to before WRITE */
98 #ifdef CANT_OPEN_FILES_TWICE
99       {					/* Open closed files */
100 	char name_buff[FN_REFLEN];
101         MARIA_SHARE *share= info->s;
102 	if (share->kfile.file < 0)
103         {
104 
105 	  if ((share->kfile.file= mysql_file_open(key_file_kfile,
106                                        fn_format(name_buff, info->filename, "",
107                                                  N_NAME_IEXT,4),
108                                        info->mode, MYF(MY_WME))) < 0)
109 	    error = my_errno;
110         }
111 	if (info->dfile.file < 0)
112 	{
113 	  if ((info->dfile.file= mysql_file_open(key_file_dfile,
114                                      fn_format(name_buff, info->filename,
115                                                "", N_NAME_DEXT, 4),
116                                       info->mode, MYF(MY_WME))) < 0)
117 	    error = my_errno;
118 	  info->rec_cache.file= info->dfile.file;
119 	}
120 	if (share->bitmap.file.file < 0)
121 	  share->bitmap.file.file= info->dfile.file;
122       }
123 #endif
124       if (info->was_locked)
125       {
126 	if (maria_lock_database(info, info->was_locked))
127 	  error=my_errno;
128 	info->was_locked=0;
129       }
130       break;
131     }
132   }
133   mysql_mutex_unlock(&THR_LOCK_maria);
134   if (flag == HA_PANIC_CLOSE)
135     maria_end();
136   if (!error)
137     DBUG_RETURN(0);
138   DBUG_RETURN(my_errno=error);
139 } /* maria_panic */
140