1 /* Copyright (c) 2000, 2003, 2005, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
2    Use is subject to license terms.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
16 
17 #include "fulltext.h"
18 
19 	/* if flag == HA_PANIC_CLOSE then all misam files are closed */
20 	/* if flag == HA_PANIC_WRITE then all misam files are unlocked and
21 	   all changed data in single user misam is written to file */
22 	/* if flag == HA_PANIC_READ then all misam files that was locked when
23 	   mi_panic(HA_PANIC_WRITE) was done is locked. A mi_readinfo() is
24 	   done for all single user files to get changes in database */
25 
26 
mi_panic(enum ha_panic_function flag)27 int mi_panic(enum ha_panic_function flag)
28 {
29   int error=0;
30   LIST *list_element,*next_open;
31   MI_INFO *info;
32   DBUG_ENTER("mi_panic");
33 
34   mysql_mutex_lock(&THR_LOCK_myisam);
35   for (list_element=myisam_open_list ; list_element ; list_element=next_open)
36   {
37     next_open=list_element->next;		/* Save if close */
38     info=(MI_INFO*) list_element->data;
39     switch (flag) {
40     case HA_PANIC_CLOSE:
41       mysql_mutex_unlock(&THR_LOCK_myisam);     /* Not exactly right... */
42       if (mi_close(info))
43 	error=my_errno;
44       mysql_mutex_lock(&THR_LOCK_myisam);
45       break;
46     case HA_PANIC_WRITE:		/* Do this to free databases */
47 #ifdef CANT_OPEN_FILES_TWICE
48       if (info->s->options & HA_OPTION_READ_ONLY_DATA)
49 	break;
50 #endif
51       if (flush_key_blocks(info->s->key_cache, info->s->kfile,
52                            &info->s->dirty_part_map, FLUSH_RELEASE))
53 	error=my_errno;
54       if (info->opt_flag & WRITE_CACHE_USED)
55 	if (flush_io_cache(&info->rec_cache))
56 	  error=my_errno;
57       if (info->opt_flag & READ_CACHE_USED)
58       {
59 	if (flush_io_cache(&info->rec_cache))
60 	  error=my_errno;
61 	reinit_io_cache(&info->rec_cache,READ_CACHE,0,
62 		       (pbool) (info->lock_type != F_UNLCK),1);
63       }
64       if (info->lock_type != F_UNLCK && ! info->was_locked)
65       {
66 	info->was_locked=info->lock_type;
67 	if (mi_lock_database(info,F_UNLCK))
68 	  error=my_errno;
69       }
70 #ifdef CANT_OPEN_FILES_TWICE
71       if (info->s->kfile >= 0 && mysql_file_close(info->s->kfile, MYF(0)))
72 	error = my_errno;
73       if (info->dfile >= 0 && mysql_file_close(info->dfile, MYF(0)))
74 	error = my_errno;
75       info->s->kfile=info->dfile= -1;	/* Files aren't open anymore */
76 #endif
77       break;
78     case HA_PANIC_READ:			/* Restore to before WRITE */
79 #ifdef CANT_OPEN_FILES_TWICE
80       {					/* Open closed files */
81 	char name_buff[FN_REFLEN];
82 	if (info->s->kfile < 0)
83           if ((info->s->kfile= mysql_file_open(mi_key_file_kfile,
84                                                fn_format(name_buff,
85                                                          info->filename, "",
86                                                          N_NAME_IEXT, 4),
87                                                info->mode, MYF(MY_WME))) < 0)
88 	    error = my_errno;
89 	if (info->dfile < 0)
90 	{
91           if ((info->dfile= mysql_file_open(mi_key_file_dfile,
92                                             fn_format(name_buff,
93                                                       info->filename, "",
94                                                       N_NAME_DEXT, 4),
95                                             info->mode, MYF(MY_WME))) < 0)
96 	    error = my_errno;
97 	  info->rec_cache.file=info->dfile;
98 	}
99       }
100 #endif
101       if (info->was_locked)
102       {
103 	if (mi_lock_database(info, info->was_locked))
104 	  error=my_errno;
105 	info->was_locked=0;
106       }
107       break;
108     }
109   }
110   if (flag == HA_PANIC_CLOSE)
111   {
112     (void) mi_log(0);				/* Close log if neaded */
113     ft_free_stopwords();
114   }
115   mysql_mutex_unlock(&THR_LOCK_myisam);
116   if (!error)
117     DBUG_RETURN(0);
118   DBUG_RETURN(my_errno=error);
119 } /* mi_panic */
120