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