blob: 86965e6089c6c6985b510d3ad4c6eae0534813b8 [file] [log] [blame]
Thomas Gleixner7336d0e2019-05-31 01:09:56 -07001// SPDX-License-Identifier: GPL-2.0-only
David Teiglandb3b94fa2006-01-16 16:50:04 +00002/*
3 * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
Steven Whitehouse3a8a9a12006-05-18 15:09:15 -04004 * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
David Teiglandb3b94fa2006-01-16 16:50:04 +00005 */
6
Joe Perchesd77d1b52014-03-06 12:10:45 -08007#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
David Teiglandb3b94fa2006-01-16 16:50:04 +00009#include <linux/spinlock.h>
10#include <linux/completion.h>
11#include <linux/buffer_head.h>
12#include <linux/crc32.h>
Steven Whitehouse5c676f62006-02-27 17:23:27 -050013#include <linux/gfs2_ondisk.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080014#include <linux/uaccess.h>
David Teiglandb3b94fa2006-01-16 16:50:04 +000015
16#include "gfs2.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050017#include "incore.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000018#include "glock.h"
Bob Peterson0d910612019-02-18 08:37:25 -070019#include "lops.h"
20#include "recovery.h"
Bob Peterson72244b62018-08-15 12:09:49 -050021#include "rgrp.h"
Bob Peterson0d910612019-02-18 08:37:25 -070022#include "super.h"
Steven Whitehouse5c676f62006-02-27 17:23:27 -050023#include "util.h"
David Teiglandb3b94fa2006-01-16 16:50:04 +000024
Christoph Lametere18b8902006-12-06 20:33:20 -080025struct kmem_cache *gfs2_glock_cachep __read_mostly;
Steven Whitehouse009d8512009-12-08 12:12:13 +000026struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly;
Christoph Lametere18b8902006-12-06 20:33:20 -080027struct kmem_cache *gfs2_inode_cachep __read_mostly;
28struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
Bob Peterson6bdd9be2008-01-28 17:20:26 -060029struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
Steven Whitehouse37b2c832008-11-17 14:25:37 +000030struct kmem_cache *gfs2_quotad_cachep __read_mostly;
Bob Petersonb54e9a02015-10-26 10:40:28 -050031struct kmem_cache *gfs2_qadata_cachep __read_mostly;
Steven Whitehousee8c92ed2012-04-16 09:28:31 +010032mempool_t *gfs2_page_pool __read_mostly;
David Teiglandb3b94fa2006-01-16 16:50:04 +000033
David Teiglandb3b94fa2006-01-16 16:50:04 +000034void gfs2_assert_i(struct gfs2_sbd *sdp)
35{
Joe Perches8382e262014-03-06 12:10:46 -080036 fs_emerg(sdp, "fatal assertion failed\n");
David Teiglandb3b94fa2006-01-16 16:50:04 +000037}
38
Bob Peterson0d910612019-02-18 08:37:25 -070039/**
40 * check_journal_clean - Make sure a journal is clean for a spectator mount
41 * @sdp: The GFS2 superblock
42 * @jd: The journal descriptor
43 *
44 * Returns: 0 if the journal is clean or locked, else an error
45 */
46int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
47{
48 int error;
49 struct gfs2_holder j_gh;
50 struct gfs2_log_header_host head;
51 struct gfs2_inode *ip;
52
53 ip = GFS2_I(jd->jd_inode);
54 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_NOEXP |
55 GL_EXACT | GL_NOCACHE, &j_gh);
56 if (error) {
57 fs_err(sdp, "Error locking journal for spectator mount.\n");
58 return -EPERM;
59 }
60 error = gfs2_jdesc_check(jd);
61 if (error) {
62 fs_err(sdp, "Error checking journal for spectator mount.\n");
63 goto out_unlock;
64 }
65 error = gfs2_find_jhead(jd, &head, false);
66 if (error) {
67 fs_err(sdp, "Error parsing journal for spectator mount.\n");
68 goto out_unlock;
69 }
70 if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
71 error = -EPERM;
72 fs_err(sdp, "jid=%u: Journal is dirty, so the first mounter "
73 "must not be a spectator.\n", jd->jd_jid);
74 }
75
76out_unlock:
77 gfs2_glock_dq_uninit(&j_gh);
78 return error;
79}
80
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +010081void gfs2_lm(struct gfs2_sbd *sdp, const char *fmt, ...)
82{
83 struct va_format vaf;
84 va_list args;
85
86 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
87 test_bit(SDF_WITHDRAWN, &sdp->sd_flags))
88 return;
89
90 va_start(args, fmt);
91 vaf.fmt = fmt;
92 vaf.va = &args;
93 fs_err(sdp, "%pV", &vaf);
94 va_end(args);
95}
96
97int gfs2_withdraw(struct gfs2_sbd *sdp)
Steven Whitehouseda755fd2008-01-30 15:34:04 +000098{
Steven Whitehousef057f6c2009-01-12 10:43:39 +000099 struct lm_lockstruct *ls = &sdp->sd_lockstruct;
100 const struct lm_lockops *lm = ls->ls_ops;
Steven Whitehouseda755fd2008-01-30 15:34:04 +0000101
Bob Petersond34843d2009-08-24 10:44:18 +0100102 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
Bob Peterson04aea0c2019-05-07 13:27:44 -0500103 test_and_set_bit(SDF_WITHDRAWN, &sdp->sd_flags))
Steven Whitehouseda755fd2008-01-30 15:34:04 +0000104 return 0;
105
Bob Petersond34843d2009-08-24 10:44:18 +0100106 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) {
107 fs_err(sdp, "about to withdraw this file system\n");
108 BUG_ON(sdp->sd_args.ar_debug);
Steven Whitehouseda755fd2008-01-30 15:34:04 +0000109
Bob Petersond34843d2009-08-24 10:44:18 +0100110 kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
Steven Whitehousef057f6c2009-01-12 10:43:39 +0000111
Steven Whitehousefd95e812013-02-13 12:21:40 +0000112 if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
113 wait_for_completion(&sdp->sd_wdack);
114
Bob Petersond34843d2009-08-24 10:44:18 +0100115 if (lm->lm_unmount) {
116 fs_err(sdp, "telling LM to unmount\n");
117 lm->lm_unmount(sdp);
118 }
Benjamin Marzinski3e11e5302016-03-23 14:29:59 -0400119 set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
Bob Petersond34843d2009-08-24 10:44:18 +0100120 fs_err(sdp, "withdrawn\n");
121 dump_stack();
Steven Whitehousef057f6c2009-01-12 10:43:39 +0000122 }
Bob Petersond34843d2009-08-24 10:44:18 +0100123
124 if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
Joe Perchesd77d1b52014-03-06 12:10:45 -0800125 panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname);
Steven Whitehouseda755fd2008-01-30 15:34:04 +0000126
127 return -1;
128}
129
David Teiglandb3b94fa2006-01-16 16:50:04 +0000130/**
131 * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false
David Teiglandb3b94fa2006-01-16 16:50:04 +0000132 */
133
Andreas Gruenbacher8e28ef12020-01-23 19:36:21 +0100134void gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
135 const char *function, char *file, unsigned int line)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000136{
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100137 gfs2_lm(sdp,
138 "fatal: assertion \"%s\" failed\n"
139 " function = %s, file = %s, line = %u\n",
140 assertion, function, file, line);
Andreas Gruenbacher8e28ef12020-01-23 19:36:21 +0100141 gfs2_withdraw(sdp);
Steven Whitehouse18ec7d52006-02-08 11:50:51 +0000142 dump_stack();
David Teiglandb3b94fa2006-01-16 16:50:04 +0000143}
144
145/**
146 * gfs2_assert_warn_i - Print a message to the console if @assertion is false
David Teiglandb3b94fa2006-01-16 16:50:04 +0000147 */
148
Andreas Gruenbacher8e28ef12020-01-23 19:36:21 +0100149void gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
150 const char *function, char *file, unsigned int line)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000151{
152 if (time_before(jiffies,
153 sdp->sd_last_warning +
154 gfs2_tune_get(sdp, gt_complain_secs) * HZ))
Andreas Gruenbacher8e28ef12020-01-23 19:36:21 +0100155 return;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000156
Bob Petersond34843d2009-08-24 10:44:18 +0100157 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
Joe Perches8382e262014-03-06 12:10:46 -0800158 fs_warn(sdp, "warning: assertion \"%s\" failed at function = %s, file = %s, line = %u\n",
159 assertion, function, file, line);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000160
161 if (sdp->sd_args.ar_debug)
162 BUG();
Steven Whitehouse18ec7d52006-02-08 11:50:51 +0000163 else
164 dump_stack();
David Teiglandb3b94fa2006-01-16 16:50:04 +0000165
Bob Petersond34843d2009-08-24 10:44:18 +0100166 if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
167 panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
168 "GFS2: fsid=%s: function = %s, file = %s, line = %u\n",
169 sdp->sd_fsname, assertion,
170 sdp->sd_fsname, function, file, line);
171
David Teiglandb3b94fa2006-01-16 16:50:04 +0000172 sdp->sd_last_warning = jiffies;
David Teiglandb3b94fa2006-01-16 16:50:04 +0000173}
174
175/**
176 * gfs2_consist_i - Flag a filesystem consistency error and withdraw
David Teiglandb3b94fa2006-01-16 16:50:04 +0000177 */
178
Andreas Gruenbachera5ca2f12020-01-23 19:31:06 +0100179void gfs2_consist_i(struct gfs2_sbd *sdp, const char *function,
180 char *file, unsigned int line)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000181{
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100182 gfs2_lm(sdp,
183 "fatal: filesystem consistency error - function = %s, file = %s, line = %u\n",
184 function, file, line);
Andreas Gruenbachera5ca2f12020-01-23 19:31:06 +0100185 gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000186}
187
188/**
189 * gfs2_consist_inode_i - Flag an inode consistency error and withdraw
David Teiglandb3b94fa2006-01-16 16:50:04 +0000190 */
191
Andreas Gruenbachera5ca2f12020-01-23 19:31:06 +0100192void gfs2_consist_inode_i(struct gfs2_inode *ip,
193 const char *function, char *file, unsigned int line)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000194{
Steven Whitehousefeaa7bb2006-06-14 15:32:57 -0400195 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100196
197 gfs2_lm(sdp,
198 "fatal: filesystem consistency error\n"
199 " inode = %llu %llu\n"
200 " function = %s, file = %s, line = %u\n",
201 (unsigned long long)ip->i_no_formal_ino,
202 (unsigned long long)ip->i_no_addr,
203 function, file, line);
Andreas Gruenbachera5ca2f12020-01-23 19:31:06 +0100204 gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000205}
206
207/**
208 * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw
David Teiglandb3b94fa2006-01-16 16:50:04 +0000209 */
210
Andreas Gruenbachera5ca2f12020-01-23 19:31:06 +0100211void gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd,
212 const char *function, char *file, unsigned int line)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000213{
214 struct gfs2_sbd *sdp = rgd->rd_sbd;
Bob Peterson98fb0572019-08-13 09:25:15 -0400215 char fs_id_buf[sizeof(sdp->sd_fsname) + 7];
Bob Peterson72244b62018-08-15 12:09:49 -0500216
Bob Peterson3792ce92019-05-09 09:21:48 -0500217 sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname);
218 gfs2_rgrp_dump(NULL, rgd->rd_gl, fs_id_buf);
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100219 gfs2_lm(sdp,
220 "fatal: filesystem consistency error\n"
221 " RG = %llu\n"
222 " function = %s, file = %s, line = %u\n",
223 (unsigned long long)rgd->rd_addr,
224 function, file, line);
Andreas Gruenbachera5ca2f12020-01-23 19:31:06 +0100225 gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000226}
227
228/**
229 * gfs2_meta_check_ii - Flag a magic number consistency error and withdraw
230 * Returns: -1 if this call withdrew the machine,
231 * -2 if it was already withdrawn
232 */
233
234int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
235 const char *type, const char *function, char *file,
236 unsigned int line)
237{
238 int me;
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100239
240 gfs2_lm(sdp,
241 "fatal: invalid metadata block\n"
242 " bh = %llu (%s)\n"
243 " function = %s, file = %s, line = %u\n",
244 (unsigned long long)bh->b_blocknr, type,
245 function, file, line);
246 me = gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000247 return (me) ? -1 : -2;
248}
249
250/**
251 * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw
252 * Returns: -1 if this call withdrew the machine,
253 * -2 if it was already withdrawn
254 */
255
256int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
Steven Whitehousecd915492006-09-04 12:49:07 -0400257 u16 type, u16 t, const char *function,
David Teiglandb3b94fa2006-01-16 16:50:04 +0000258 char *file, unsigned int line)
259{
260 int me;
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100261
262 gfs2_lm(sdp,
263 "fatal: invalid metadata block\n"
264 " bh = %llu (type: exp=%u, found=%u)\n"
265 " function = %s, file = %s, line = %u\n",
266 (unsigned long long)bh->b_blocknr, type, t,
267 function, file, line);
268 me = gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000269 return (me) ? -1 : -2;
270}
271
272/**
273 * gfs2_io_error_i - Flag an I/O error and withdraw
274 * Returns: -1 if this call withdrew the machine,
275 * 0 if it was already withdrawn
276 */
277
278int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
279 unsigned int line)
280{
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100281 gfs2_lm(sdp,
282 "fatal: I/O error\n"
283 " function = %s, file = %s, line = %u\n",
284 function, file, line);
285 return gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000286}
287
288/**
Andreas Gruenbacher9e1a9ec2018-06-07 11:56:46 +0100289 * gfs2_io_error_bh_i - Flag a buffer I/O error
290 * @withdraw: withdraw the filesystem
David Teiglandb3b94fa2006-01-16 16:50:04 +0000291 */
292
Andreas Gruenbacher9e1a9ec2018-06-07 11:56:46 +0100293void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
294 const char *function, char *file, unsigned int line,
295 bool withdraw)
David Teiglandb3b94fa2006-01-16 16:50:04 +0000296{
Bob Peterson69511082019-02-12 13:43:55 -0700297 if (gfs2_withdrawn(sdp))
298 return;
299
300 fs_err(sdp, "fatal: I/O error\n"
301 " block = %llu\n"
302 " function = %s, file = %s, line = %u\n",
303 (unsigned long long)bh->b_blocknr, function, file, line);
Andreas Gruenbacher9e1a9ec2018-06-07 11:56:46 +0100304 if (withdraw)
Andreas Gruenbacherbadb55e2020-01-23 18:41:00 +0100305 gfs2_withdraw(sdp);
David Teiglandb3b94fa2006-01-16 16:50:04 +0000306}
307