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