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