Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-block.git] / fs / gfs2 / util.c
1 /*
2  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
4  *
5  * This copyrighted material is made available to anyone wishing to use,
6  * modify, copy, or redistribute it subject to the terms and conditions
7  * of the GNU General Public License version 2.
8  */
9
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
12 #include <linux/spinlock.h>
13 #include <linux/completion.h>
14 #include <linux/buffer_head.h>
15 #include <linux/crc32.h>
16 #include <linux/gfs2_ondisk.h>
17 #include <linux/uaccess.h>
18
19 #include "gfs2.h"
20 #include "incore.h"
21 #include "glock.h"
22 #include "rgrp.h"
23 #include "util.h"
24
25 struct kmem_cache *gfs2_glock_cachep __read_mostly;
26 struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly;
27 struct kmem_cache *gfs2_inode_cachep __read_mostly;
28 struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
29 struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
30 struct kmem_cache *gfs2_quotad_cachep __read_mostly;
31 struct kmem_cache *gfs2_qadata_cachep __read_mostly;
32 mempool_t *gfs2_page_pool __read_mostly;
33
34 void gfs2_assert_i(struct gfs2_sbd *sdp)
35 {
36         fs_emerg(sdp, "fatal assertion failed\n");
37 }
38
39 int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...)
40 {
41         struct lm_lockstruct *ls = &sdp->sd_lockstruct;
42         const struct lm_lockops *lm = ls->ls_ops;
43         va_list args;
44         struct va_format vaf;
45
46         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
47             test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
48                 return 0;
49
50         if (fmt) {
51                 va_start(args, fmt);
52
53                 vaf.fmt = fmt;
54                 vaf.va = &args;
55
56                 fs_err(sdp, "%pV", &vaf);
57
58                 va_end(args);
59         }
60
61         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
62                 fs_err(sdp, "about to withdraw this file system\n");
63                 BUG_ON(sdp->sd_args.ar_debug);
64
65                 kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
66
67                 if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
68                         wait_for_completion(&sdp->sd_wdack);
69
70                 if (lm->lm_unmount) {
71                         fs_err(sdp, "telling LM to unmount\n");
72                         lm->lm_unmount(sdp);
73                 }
74                 set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
75                 fs_err(sdp, "withdrawn\n");
76                 dump_stack();
77         }
78
79         if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
80                 panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname);
81
82         return -1;
83 }
84
85 /**
86  * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false
87  * Returns: -1 if this call withdrew the machine,
88  *          -2 if it was already withdrawn
89  */
90
91 int gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
92                            const char *function, char *file, unsigned int line)
93 {
94         int me;
95         me = gfs2_lm_withdraw(sdp,
96                               "fatal: assertion \"%s\" failed\n"
97                               "   function = %s, file = %s, line = %u\n",
98                               assertion, function, file, line);
99         dump_stack();
100         return (me) ? -1 : -2;
101 }
102
103 /**
104  * gfs2_assert_warn_i - Print a message to the console if @assertion is false
105  * Returns: -1 if we printed something
106  *          -2 if we didn't
107  */
108
109 int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
110                        const char *function, char *file, unsigned int line)
111 {
112         if (time_before(jiffies,
113                         sdp->sd_last_warning +
114                         gfs2_tune_get(sdp, gt_complain_secs) * HZ))
115                 return -2;
116
117         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
118                 fs_warn(sdp, "warning: assertion \"%s\" failed at function = %s, file = %s, line = %u\n",
119                         assertion, function, file, line);
120
121         if (sdp->sd_args.ar_debug)
122                 BUG();
123         else
124                 dump_stack();
125
126         if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
127                 panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
128                       "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
129                       sdp->sd_fsname, assertion,
130                       sdp->sd_fsname, function, file, line);
131
132         sdp->sd_last_warning = jiffies;
133
134         return -1;
135 }
136
137 /**
138  * gfs2_consist_i - Flag a filesystem consistency error and withdraw
139  * Returns: -1 if this call withdrew the machine,
140  *          0 if it was already withdrawn
141  */
142
143 int gfs2_consist_i(struct gfs2_sbd *sdp, int cluster_wide, const char *function,
144                    char *file, unsigned int line)
145 {
146         int rv;
147         rv = gfs2_lm_withdraw(sdp,
148                               "fatal: filesystem consistency error - function = %s, file = %s, line = %u\n",
149                               function, file, line);
150         return rv;
151 }
152
153 /**
154  * gfs2_consist_inode_i - Flag an inode consistency error and withdraw
155  * Returns: -1 if this call withdrew the machine,
156  *          0 if it was already withdrawn
157  */
158
159 int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
160                          const char *function, char *file, unsigned int line)
161 {
162         struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
163         int rv;
164         rv = gfs2_lm_withdraw(sdp,
165                               "fatal: filesystem consistency error\n"
166                               "  inode = %llu %llu\n"
167                               "  function = %s, file = %s, line = %u\n",
168                               (unsigned long long)ip->i_no_formal_ino,
169                               (unsigned long long)ip->i_no_addr,
170                               function, file, line);
171         return rv;
172 }
173
174 /**
175  * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw
176  * Returns: -1 if this call withdrew the machine,
177  *          0 if it was already withdrawn
178  */
179
180 int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide,
181                          const char *function, char *file, unsigned int line)
182 {
183         struct gfs2_sbd *sdp = rgd->rd_sbd;
184         int rv;
185
186         gfs2_rgrp_dump(NULL, rgd->rd_gl);
187         rv = gfs2_lm_withdraw(sdp,
188                               "fatal: filesystem consistency error\n"
189                               "  RG = %llu\n"
190                               "  function = %s, file = %s, line = %u\n",
191                               (unsigned long long)rgd->rd_addr,
192                               function, file, line);
193         return rv;
194 }
195
196 /**
197  * gfs2_meta_check_ii - Flag a magic number consistency error and withdraw
198  * Returns: -1 if this call withdrew the machine,
199  *          -2 if it was already withdrawn
200  */
201
202 int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
203                        const char *type, const char *function, char *file,
204                        unsigned int line)
205 {
206         int me;
207         me = gfs2_lm_withdraw(sdp,
208                               "fatal: invalid metadata block\n"
209                               "  bh = %llu (%s)\n"
210                               "  function = %s, file = %s, line = %u\n",
211                               (unsigned long long)bh->b_blocknr, type,
212                               function, file, line);
213         return (me) ? -1 : -2;
214 }
215
216 /**
217  * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw
218  * Returns: -1 if this call withdrew the machine,
219  *          -2 if it was already withdrawn
220  */
221
222 int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
223                            u16 type, u16 t, const char *function,
224                            char *file, unsigned int line)
225 {
226         int me;
227         me = gfs2_lm_withdraw(sdp,
228                               "fatal: invalid metadata block\n"
229                               "  bh = %llu (type: exp=%u, found=%u)\n"
230                               "  function = %s, file = %s, line = %u\n",
231                               (unsigned long long)bh->b_blocknr, type, t,
232                               function, file, line);
233         return (me) ? -1 : -2;
234 }
235
236 /**
237  * gfs2_io_error_i - Flag an I/O error and withdraw
238  * Returns: -1 if this call withdrew the machine,
239  *          0 if it was already withdrawn
240  */
241
242 int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
243                     unsigned int line)
244 {
245         int rv;
246         rv = gfs2_lm_withdraw(sdp,
247                               "fatal: I/O error\n"
248                               "  function = %s, file = %s, line = %u\n",
249                               function, file, line);
250         return rv;
251 }
252
253 /**
254  * gfs2_io_error_bh_i - Flag a buffer I/O error
255  * @withdraw: withdraw the filesystem
256  */
257
258 void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
259                         const char *function, char *file, unsigned int line,
260                         bool withdraw)
261 {
262         if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))
263                 fs_err(sdp,
264                        "fatal: I/O error\n"
265                        "  block = %llu\n"
266                        "  function = %s, file = %s, line = %u\n",
267                        (unsigned long long)bh->b_blocknr,
268                        function, file, line);
269         if (withdraw)
270                 gfs2_lm_withdraw(sdp, NULL);
271 }
272