]>
Commit | Line | Data |
---|---|---|
7336d0e6 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
b3b94faa DT |
2 | /* |
3 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | |
3a8a9a10 | 4 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
b3b94faa DT |
5 | */ |
6 | ||
d77d1b58 JP |
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
8 | ||
b3b94faa DT |
9 | #include <linux/spinlock.h> |
10 | #include <linux/completion.h> | |
11 | #include <linux/buffer_head.h> | |
f66af88e | 12 | #include <linux/kthread.h> |
b3b94faa | 13 | #include <linux/crc32.h> |
5c676f6d | 14 | #include <linux/gfs2_ondisk.h> |
601ef0d5 | 15 | #include <linux/delay.h> |
7c0f6ba6 | 16 | #include <linux/uaccess.h> |
b3b94faa DT |
17 | |
18 | #include "gfs2.h" | |
5c676f6d | 19 | #include "incore.h" |
b3b94faa | 20 | #include "glock.h" |
601ef0d5 BP |
21 | #include "glops.h" |
22 | #include "log.h" | |
0d91061a BP |
23 | #include "lops.h" |
24 | #include "recovery.h" | |
72244b6b | 25 | #include "rgrp.h" |
0d91061a | 26 | #include "super.h" |
5c676f6d | 27 | #include "util.h" |
b3b94faa | 28 | |
e18b890b | 29 | struct kmem_cache *gfs2_glock_cachep __read_mostly; |
009d8518 | 30 | struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly; |
e18b890b CL |
31 | struct kmem_cache *gfs2_inode_cachep __read_mostly; |
32 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; | |
6bdd9be6 | 33 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; |
37b2c837 | 34 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; |
b54e9a0b | 35 | struct kmem_cache *gfs2_qadata_cachep __read_mostly; |
b839dada | 36 | struct kmem_cache *gfs2_trans_cachep __read_mostly; |
e8c92ed7 | 37 | mempool_t *gfs2_page_pool __read_mostly; |
b3b94faa | 38 | |
b3b94faa DT |
39 | void gfs2_assert_i(struct gfs2_sbd *sdp) |
40 | { | |
8382e26b | 41 | fs_emerg(sdp, "fatal assertion failed\n"); |
b3b94faa DT |
42 | } |
43 | ||
0d91061a BP |
44 | /** |
45 | * check_journal_clean - Make sure a journal is clean for a spectator mount | |
46 | * @sdp: The GFS2 superblock | |
47 | * @jd: The journal descriptor | |
c551f66c | 48 | * @verbose: Show more prints in the log |
0d91061a BP |
49 | * |
50 | * Returns: 0 if the journal is clean or locked, else an error | |
51 | */ | |
7d9f9249 BP |
52 | int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, |
53 | bool verbose) | |
0d91061a BP |
54 | { |
55 | int error; | |
56 | struct gfs2_holder j_gh; | |
57 | struct gfs2_log_header_host head; | |
58 | struct gfs2_inode *ip; | |
59 | ||
60 | ip = GFS2_I(jd->jd_inode); | |
61 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_NOEXP | | |
62 | GL_EXACT | GL_NOCACHE, &j_gh); | |
63 | if (error) { | |
7d9f9249 BP |
64 | if (verbose) |
65 | fs_err(sdp, "Error %d locking journal for spectator " | |
66 | "mount.\n", error); | |
0d91061a BP |
67 | return -EPERM; |
68 | } | |
69 | error = gfs2_jdesc_check(jd); | |
70 | if (error) { | |
7d9f9249 BP |
71 | if (verbose) |
72 | fs_err(sdp, "Error checking journal for spectator " | |
73 | "mount.\n"); | |
0d91061a BP |
74 | goto out_unlock; |
75 | } | |
76 | error = gfs2_find_jhead(jd, &head, false); | |
77 | if (error) { | |
7d9f9249 BP |
78 | if (verbose) |
79 | fs_err(sdp, "Error parsing journal for spectator " | |
80 | "mount.\n"); | |
0d91061a BP |
81 | goto out_unlock; |
82 | } | |
83 | if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) { | |
84 | error = -EPERM; | |
7d9f9249 BP |
85 | if (verbose) |
86 | fs_err(sdp, "jid=%u: Journal is dirty, so the first " | |
87 | "mounter must not be a spectator.\n", | |
88 | jd->jd_jid); | |
0d91061a BP |
89 | } |
90 | ||
91 | out_unlock: | |
92 | gfs2_glock_dq_uninit(&j_gh); | |
93 | return error; | |
94 | } | |
95 | ||
c77b52c0 | 96 | /** |
e392edd5 | 97 | * gfs2_freeze_lock_shared - hold the freeze glock |
c77b52c0 | 98 | * @sdp: the superblock |
c77b52c0 | 99 | */ |
6c7410f4 | 100 | int gfs2_freeze_lock_shared(struct gfs2_sbd *sdp) |
c77b52c0 | 101 | { |
c77b52c0 BP |
102 | int error; |
103 | ||
432928c9 BP |
104 | error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, |
105 | LM_FLAG_NOEXP | GL_EXACT, | |
6c7410f4 | 106 | &sdp->sd_freeze_gh); |
432928c9 | 107 | if (error) |
af1abe11 | 108 | fs_err(sdp, "can't lock the freeze glock: %d\n", error); |
c77b52c0 BP |
109 | return error; |
110 | } | |
111 | ||
112 | void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh) | |
113 | { | |
114 | if (gfs2_holder_initialized(freeze_gh)) | |
115 | gfs2_glock_dq_uninit(freeze_gh); | |
116 | } | |
117 | ||
601ef0d5 BP |
118 | static void signal_our_withdraw(struct gfs2_sbd *sdp) |
119 | { | |
f5f02fde | 120 | struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl; |
d5bf630f BP |
121 | struct inode *inode; |
122 | struct gfs2_inode *ip; | |
123 | struct gfs2_glock *i_gl; | |
124 | u64 no_formal_ino; | |
601ef0d5 BP |
125 | int ret = 0; |
126 | int tries; | |
127 | ||
d5bf630f | 128 | if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc) |
601ef0d5 BP |
129 | return; |
130 | ||
f5456b5d | 131 | gfs2_ail_drain(sdp); /* frees all transactions */ |
d5bf630f BP |
132 | inode = sdp->sd_jdesc->jd_inode; |
133 | ip = GFS2_I(inode); | |
134 | i_gl = ip->i_gl; | |
135 | no_formal_ino = ip->i_no_formal_ino; | |
136 | ||
601ef0d5 BP |
137 | /* Prevent any glock dq until withdraw recovery is complete */ |
138 | set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); | |
139 | /* | |
140 | * Don't tell dlm we're bailing until we have no more buffers in the | |
141 | * wind. If journal had an IO error, the log code should just purge | |
142 | * the outstanding buffers rather than submitting new IO. Making the | |
143 | * file system read-only will flush the journal, etc. | |
144 | * | |
145 | * During a normal unmount, gfs2_make_fs_ro calls gfs2_log_shutdown | |
146 | * which clears SDF_JOURNAL_LIVE. In a withdraw, we must not write | |
147 | * any UNMOUNT log header, so we can't call gfs2_log_shutdown, and | |
148 | * therefore we need to clear SDF_JOURNAL_LIVE manually. | |
149 | */ | |
150 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | |
96b1454f | 151 | if (!sb_rdonly(sdp->sd_vfs)) { |
b77b4a48 AG |
152 | bool locked = mutex_trylock(&sdp->sd_freeze_mutex); |
153 | ||
fe4f7940 AG |
154 | wake_up(&sdp->sd_logd_waitq); |
155 | wake_up(&sdp->sd_quota_wait); | |
f66af88e AG |
156 | |
157 | wait_event_timeout(sdp->sd_log_waitq, | |
158 | gfs2_log_is_empty(sdp), | |
159 | HZ * 5); | |
160 | ||
161 | sdp->sd_vfs->s_flags |= SB_RDONLY; | |
b77b4a48 AG |
162 | |
163 | if (locked) | |
164 | mutex_unlock(&sdp->sd_freeze_mutex); | |
165 | ||
053640a7 BP |
166 | /* |
167 | * Dequeue any pending non-system glock holders that can no | |
168 | * longer be granted because the file system is withdrawn. | |
169 | */ | |
170 | gfs2_gl_dq_holders(sdp); | |
96b1454f | 171 | } |
601ef0d5 | 172 | |
53af80ce BP |
173 | if (sdp->sd_lockstruct.ls_ops->lm_lock == NULL) { /* lock_nolock */ |
174 | if (!ret) | |
175 | ret = -EIO; | |
176 | clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); | |
177 | goto skip_recovery; | |
178 | } | |
601ef0d5 BP |
179 | /* |
180 | * Drop the glock for our journal so another node can recover it. | |
181 | */ | |
182 | if (gfs2_holder_initialized(&sdp->sd_journal_gh)) { | |
183 | gfs2_glock_dq_wait(&sdp->sd_journal_gh); | |
184 | gfs2_holder_uninit(&sdp->sd_journal_gh); | |
185 | } | |
186 | sdp->sd_jinode_gh.gh_flags |= GL_NOCACHE; | |
187 | gfs2_glock_dq(&sdp->sd_jinode_gh); | |
b77b4a48 AG |
188 | gfs2_thaw_freeze_initiator(sdp->sd_vfs); |
189 | wait_on_bit(&i_gl->gl_flags, GLF_DEMOTE, TASK_UNINTERRUPTIBLE); | |
601ef0d5 BP |
190 | |
191 | /* | |
192 | * holder_uninit to force glock_put, to force dlm to let go | |
193 | */ | |
194 | gfs2_holder_uninit(&sdp->sd_jinode_gh); | |
195 | ||
196 | /* | |
197 | * Note: We need to be careful here: | |
198 | * Our iput of jd_inode will evict it. The evict will dequeue its | |
199 | * glock, but the glock dq will wait for the withdraw unless we have | |
200 | * exception code in glock_dq. | |
201 | */ | |
202 | iput(inode); | |
04133b60 | 203 | sdp->sd_jdesc->jd_inode = NULL; |
601ef0d5 BP |
204 | /* |
205 | * Wait until the journal inode's glock is freed. This allows try locks | |
206 | * on other nodes to be successful, otherwise we remain the owner of | |
207 | * the glock as far as dlm is concerned. | |
208 | */ | |
f5f02fde BP |
209 | if (i_gl->gl_ops->go_free) { |
210 | set_bit(GLF_FREEING, &i_gl->gl_flags); | |
211 | wait_on_bit(&i_gl->gl_flags, GLF_FREEING, TASK_UNINTERRUPTIBLE); | |
601ef0d5 BP |
212 | } |
213 | ||
601ef0d5 BP |
214 | /* |
215 | * Dequeue the "live" glock, but keep a reference so it's never freed. | |
216 | */ | |
f5f02fde | 217 | gfs2_glock_hold(live_gl); |
601ef0d5 BP |
218 | gfs2_glock_dq_wait(&sdp->sd_live_gh); |
219 | /* | |
220 | * We enqueue the "live" glock in EX so that all other nodes | |
221 | * get a demote request and act on it. We don't really want the | |
222 | * lock in EX, so we send a "try" lock with 1CB to produce a callback. | |
223 | */ | |
224 | fs_warn(sdp, "Requesting recovery of jid %d.\n", | |
225 | sdp->sd_lockstruct.ls_jid); | |
ebdc416c AG |
226 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, |
227 | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | GL_NOPID, | |
601ef0d5 BP |
228 | &sdp->sd_live_gh); |
229 | msleep(GL_GLOCK_MAX_HOLD); | |
230 | /* | |
231 | * This will likely fail in a cluster, but succeed standalone: | |
232 | */ | |
233 | ret = gfs2_glock_nq(&sdp->sd_live_gh); | |
234 | ||
235 | /* | |
236 | * If we actually got the "live" lock in EX mode, there are no other | |
237 | * nodes available to replay our journal. So we try to replay it | |
238 | * ourselves. We hold the "live" glock to prevent other mounters | |
239 | * during recovery, then just dequeue it and reacquire it in our | |
240 | * normal SH mode. Just in case the problem that caused us to | |
241 | * withdraw prevents us from recovering our journal (e.g. io errors | |
242 | * and such) we still check if the journal is clean before proceeding | |
243 | * but we may wait forever until another mounter does the recovery. | |
244 | */ | |
245 | if (ret == 0) { | |
246 | fs_warn(sdp, "No other mounters found. Trying to recover our " | |
247 | "own journal jid %d.\n", sdp->sd_lockstruct.ls_jid); | |
248 | if (gfs2_recover_journal(sdp->sd_jdesc, 1)) | |
249 | fs_warn(sdp, "Unable to recover our journal jid %d.\n", | |
250 | sdp->sd_lockstruct.ls_jid); | |
251 | gfs2_glock_dq_wait(&sdp->sd_live_gh); | |
ebdc416c AG |
252 | gfs2_holder_reinit(LM_ST_SHARED, |
253 | LM_FLAG_NOEXP | GL_EXACT | GL_NOPID, | |
601ef0d5 BP |
254 | &sdp->sd_live_gh); |
255 | gfs2_glock_nq(&sdp->sd_live_gh); | |
256 | } | |
257 | ||
f5f02fde | 258 | gfs2_glock_queue_put(live_gl); /* drop extra reference we acquired */ |
601ef0d5 BP |
259 | clear_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); |
260 | ||
261 | /* | |
262 | * At this point our journal is evicted, so we need to get a new inode | |
263 | * for it. Once done, we need to call gfs2_find_jhead which | |
264 | * calls gfs2_map_journal_extents to map it for us again. | |
265 | * | |
266 | * Note that we don't really want it to look up a FREE block. The | |
267 | * GFS2_BLKST_FREE simply overrides a block check in gfs2_inode_lookup | |
268 | * which would otherwise fail because it requires grabbing an rgrp | |
269 | * glock, which would fail with -EIO because we're withdrawing. | |
270 | */ | |
271 | inode = gfs2_inode_lookup(sdp->sd_vfs, DT_UNKNOWN, | |
272 | sdp->sd_jdesc->jd_no_addr, no_formal_ino, | |
273 | GFS2_BLKST_FREE); | |
274 | if (IS_ERR(inode)) { | |
275 | fs_warn(sdp, "Reprocessing of jid %d failed with %ld.\n", | |
276 | sdp->sd_lockstruct.ls_jid, PTR_ERR(inode)); | |
277 | goto skip_recovery; | |
278 | } | |
279 | sdp->sd_jdesc->jd_inode = inode; | |
1b8550b5 | 280 | d_mark_dontcache(inode); |
601ef0d5 BP |
281 | |
282 | /* | |
283 | * Now wait until recovery is complete. | |
284 | */ | |
285 | for (tries = 0; tries < 10; tries++) { | |
7d9f9249 | 286 | ret = check_journal_clean(sdp, sdp->sd_jdesc, false); |
601ef0d5 BP |
287 | if (!ret) |
288 | break; | |
289 | msleep(HZ); | |
290 | fs_warn(sdp, "Waiting for journal recovery jid %d.\n", | |
291 | sdp->sd_lockstruct.ls_jid); | |
292 | } | |
293 | skip_recovery: | |
294 | if (!ret) | |
295 | fs_warn(sdp, "Journal recovery complete for jid %d.\n", | |
296 | sdp->sd_lockstruct.ls_jid); | |
297 | else | |
7392fbb0 | 298 | fs_warn(sdp, "Journal recovery skipped for jid %d until next " |
601ef0d5 BP |
299 | "mount.\n", sdp->sd_lockstruct.ls_jid); |
300 | fs_warn(sdp, "Glock dequeues delayed: %lu\n", sdp->sd_glock_dqs_held); | |
301 | sdp->sd_glock_dqs_held = 0; | |
302 | wake_up_bit(&sdp->sd_flags, SDF_WITHDRAW_RECOVERY); | |
303 | } | |
304 | ||
badb55ec AG |
305 | void gfs2_lm(struct gfs2_sbd *sdp, const char *fmt, ...) |
306 | { | |
307 | struct va_format vaf; | |
308 | va_list args; | |
309 | ||
310 | if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW && | |
311 | test_bit(SDF_WITHDRAWN, &sdp->sd_flags)) | |
312 | return; | |
313 | ||
314 | va_start(args, fmt); | |
315 | vaf.fmt = fmt; | |
316 | vaf.va = &args; | |
317 | fs_err(sdp, "%pV", &vaf); | |
318 | va_end(args); | |
319 | } | |
320 | ||
321 | int gfs2_withdraw(struct gfs2_sbd *sdp) | |
da755fdb | 322 | { |
f057f6cd SW |
323 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
324 | const struct lm_lockops *lm = ls->ls_ops; | |
da755fdb | 325 | |
d34843d0 | 326 | if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) { |
e3da6be3 AG |
327 | unsigned long old = READ_ONCE(sdp->sd_flags), new; |
328 | ||
329 | do { | |
330 | if (old & BIT(SDF_WITHDRAWN)) { | |
331 | wait_on_bit(&sdp->sd_flags, | |
332 | SDF_WITHDRAW_IN_PROG, | |
333 | TASK_UNINTERRUPTIBLE); | |
334 | return -1; | |
335 | } | |
336 | new = old | BIT(SDF_WITHDRAWN) | BIT(SDF_WITHDRAW_IN_PROG); | |
337 | } while (unlikely(!try_cmpxchg(&sdp->sd_flags, &old, new))); | |
338 | ||
d34843d0 BP |
339 | fs_err(sdp, "about to withdraw this file system\n"); |
340 | BUG_ON(sdp->sd_args.ar_debug); | |
da755fdb | 341 | |
601ef0d5 BP |
342 | signal_our_withdraw(sdp); |
343 | ||
d34843d0 | 344 | kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE); |
f057f6cd | 345 | |
fd95e81c SW |
346 | if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm")) |
347 | wait_for_completion(&sdp->sd_wdack); | |
348 | ||
d34843d0 BP |
349 | if (lm->lm_unmount) { |
350 | fs_err(sdp, "telling LM to unmount\n"); | |
351 | lm->lm_unmount(sdp); | |
352 | } | |
3e11e530 | 353 | set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags); |
601ef0d5 | 354 | fs_err(sdp, "File system withdrawn\n"); |
d34843d0 | 355 | dump_stack(); |
601ef0d5 BP |
356 | clear_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags); |
357 | smp_mb__after_atomic(); | |
358 | wake_up_bit(&sdp->sd_flags, SDF_WITHDRAW_IN_PROG); | |
f057f6cd | 359 | } |
d34843d0 BP |
360 | |
361 | if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) | |
d77d1b58 | 362 | panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname); |
da755fdb SW |
363 | |
364 | return -1; | |
365 | } | |
366 | ||
c551f66c | 367 | /* |
b3b94faa | 368 | * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false |
b3b94faa DT |
369 | */ |
370 | ||
8e28ef1f | 371 | void gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion, |
ca399c96 BP |
372 | const char *function, char *file, unsigned int line, |
373 | bool delayed) | |
b3b94faa | 374 | { |
ca399c96 BP |
375 | if (gfs2_withdrawn(sdp)) |
376 | return; | |
377 | ||
378 | fs_err(sdp, | |
379 | "fatal: assertion \"%s\" failed\n" | |
380 | " function = %s, file = %s, line = %u\n", | |
381 | assertion, function, file, line); | |
382 | ||
383 | /* | |
384 | * If errors=panic was specified on mount, it won't help to delay the | |
385 | * withdraw. | |
386 | */ | |
387 | if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) | |
388 | delayed = false; | |
389 | ||
390 | if (delayed) | |
391 | gfs2_withdraw_delayed(sdp); | |
392 | else | |
393 | gfs2_withdraw(sdp); | |
18ec7d5c | 394 | dump_stack(); |
b3b94faa DT |
395 | } |
396 | ||
c551f66c | 397 | /* |
b3b94faa | 398 | * gfs2_assert_warn_i - Print a message to the console if @assertion is false |
b3b94faa DT |
399 | */ |
400 | ||
8e28ef1f AG |
401 | void gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion, |
402 | const char *function, char *file, unsigned int line) | |
b3b94faa DT |
403 | { |
404 | if (time_before(jiffies, | |
405 | sdp->sd_last_warning + | |
406 | gfs2_tune_get(sdp, gt_complain_secs) * HZ)) | |
8e28ef1f | 407 | return; |
b3b94faa | 408 | |
d34843d0 | 409 | if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) |
8382e26b JP |
410 | fs_warn(sdp, "warning: assertion \"%s\" failed at function = %s, file = %s, line = %u\n", |
411 | assertion, function, file, line); | |
b3b94faa DT |
412 | |
413 | if (sdp->sd_args.ar_debug) | |
414 | BUG(); | |
18ec7d5c SW |
415 | else |
416 | dump_stack(); | |
b3b94faa | 417 | |
d34843d0 BP |
418 | if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) |
419 | panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n" | |
420 | "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", | |
421 | sdp->sd_fsname, assertion, | |
422 | sdp->sd_fsname, function, file, line); | |
423 | ||
b3b94faa | 424 | sdp->sd_last_warning = jiffies; |
b3b94faa DT |
425 | } |
426 | ||
c551f66c | 427 | /* |
b3b94faa | 428 | * gfs2_consist_i - Flag a filesystem consistency error and withdraw |
b3b94faa DT |
429 | */ |
430 | ||
a5ca2f1c AG |
431 | void gfs2_consist_i(struct gfs2_sbd *sdp, const char *function, |
432 | char *file, unsigned int line) | |
b3b94faa | 433 | { |
badb55ec AG |
434 | gfs2_lm(sdp, |
435 | "fatal: filesystem consistency error - function = %s, file = %s, line = %u\n", | |
436 | function, file, line); | |
a5ca2f1c | 437 | gfs2_withdraw(sdp); |
b3b94faa DT |
438 | } |
439 | ||
c551f66c | 440 | /* |
b3b94faa | 441 | * gfs2_consist_inode_i - Flag an inode consistency error and withdraw |
b3b94faa DT |
442 | */ |
443 | ||
a5ca2f1c AG |
444 | void gfs2_consist_inode_i(struct gfs2_inode *ip, |
445 | const char *function, char *file, unsigned int line) | |
b3b94faa | 446 | { |
feaa7bba | 447 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
badb55ec AG |
448 | |
449 | gfs2_lm(sdp, | |
450 | "fatal: filesystem consistency error\n" | |
451 | " inode = %llu %llu\n" | |
452 | " function = %s, file = %s, line = %u\n", | |
453 | (unsigned long long)ip->i_no_formal_ino, | |
454 | (unsigned long long)ip->i_no_addr, | |
455 | function, file, line); | |
a739765c | 456 | gfs2_dump_glock(NULL, ip->i_gl, 1); |
a5ca2f1c | 457 | gfs2_withdraw(sdp); |
b3b94faa DT |
458 | } |
459 | ||
c551f66c | 460 | /* |
b3b94faa | 461 | * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw |
b3b94faa DT |
462 | */ |
463 | ||
a5ca2f1c AG |
464 | void gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, |
465 | const char *function, char *file, unsigned int line) | |
b3b94faa DT |
466 | { |
467 | struct gfs2_sbd *sdp = rgd->rd_sbd; | |
98fb0574 | 468 | char fs_id_buf[sizeof(sdp->sd_fsname) + 7]; |
72244b6b | 469 | |
3792ce97 | 470 | sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname); |
0e539ca1 | 471 | gfs2_rgrp_dump(NULL, rgd, fs_id_buf); |
badb55ec AG |
472 | gfs2_lm(sdp, |
473 | "fatal: filesystem consistency error\n" | |
474 | " RG = %llu\n" | |
475 | " function = %s, file = %s, line = %u\n", | |
476 | (unsigned long long)rgd->rd_addr, | |
477 | function, file, line); | |
a739765c | 478 | gfs2_dump_glock(NULL, rgd->rd_gl, 1); |
a5ca2f1c | 479 | gfs2_withdraw(sdp); |
b3b94faa DT |
480 | } |
481 | ||
c551f66c | 482 | /* |
b3b94faa DT |
483 | * gfs2_meta_check_ii - Flag a magic number consistency error and withdraw |
484 | * Returns: -1 if this call withdrew the machine, | |
485 | * -2 if it was already withdrawn | |
486 | */ | |
487 | ||
488 | int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, | |
489 | const char *type, const char *function, char *file, | |
490 | unsigned int line) | |
491 | { | |
492 | int me; | |
badb55ec AG |
493 | |
494 | gfs2_lm(sdp, | |
495 | "fatal: invalid metadata block\n" | |
496 | " bh = %llu (%s)\n" | |
497 | " function = %s, file = %s, line = %u\n", | |
498 | (unsigned long long)bh->b_blocknr, type, | |
499 | function, file, line); | |
500 | me = gfs2_withdraw(sdp); | |
b3b94faa DT |
501 | return (me) ? -1 : -2; |
502 | } | |
503 | ||
c551f66c | 504 | /* |
b3b94faa DT |
505 | * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw |
506 | * Returns: -1 if this call withdrew the machine, | |
507 | * -2 if it was already withdrawn | |
508 | */ | |
509 | ||
510 | int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, | |
cd915493 | 511 | u16 type, u16 t, const char *function, |
b3b94faa DT |
512 | char *file, unsigned int line) |
513 | { | |
514 | int me; | |
badb55ec AG |
515 | |
516 | gfs2_lm(sdp, | |
517 | "fatal: invalid metadata block\n" | |
518 | " bh = %llu (type: exp=%u, found=%u)\n" | |
519 | " function = %s, file = %s, line = %u\n", | |
520 | (unsigned long long)bh->b_blocknr, type, t, | |
521 | function, file, line); | |
522 | me = gfs2_withdraw(sdp); | |
b3b94faa DT |
523 | return (me) ? -1 : -2; |
524 | } | |
525 | ||
c551f66c | 526 | /* |
b3b94faa DT |
527 | * gfs2_io_error_i - Flag an I/O error and withdraw |
528 | * Returns: -1 if this call withdrew the machine, | |
529 | * 0 if it was already withdrawn | |
530 | */ | |
531 | ||
532 | int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file, | |
533 | unsigned int line) | |
534 | { | |
badb55ec AG |
535 | gfs2_lm(sdp, |
536 | "fatal: I/O error\n" | |
537 | " function = %s, file = %s, line = %u\n", | |
538 | function, file, line); | |
539 | return gfs2_withdraw(sdp); | |
b3b94faa DT |
540 | } |
541 | ||
c551f66c | 542 | /* |
9e1a9ecd AG |
543 | * gfs2_io_error_bh_i - Flag a buffer I/O error |
544 | * @withdraw: withdraw the filesystem | |
b3b94faa DT |
545 | */ |
546 | ||
9e1a9ecd AG |
547 | void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, |
548 | const char *function, char *file, unsigned int line, | |
549 | bool withdraw) | |
b3b94faa | 550 | { |
69511080 BP |
551 | if (gfs2_withdrawn(sdp)) |
552 | return; | |
553 | ||
554 | fs_err(sdp, "fatal: I/O error\n" | |
555 | " block = %llu\n" | |
556 | " function = %s, file = %s, line = %u\n", | |
557 | (unsigned long long)bh->b_blocknr, function, file, line); | |
9e1a9ecd | 558 | if (withdraw) |
badb55ec | 559 | gfs2_withdraw(sdp); |
b3b94faa DT |
560 | } |
561 |