gfs2: move check_journal_clean to util.c for future use
[linux-2.6-microblaze.git] / fs / gfs2 / util.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
4  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
5  */
6
7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8
9 #include <linux/spinlock.h>
10 #include <linux/completion.h>
11 #include <linux/buffer_head.h>
12 #include <linux/crc32.h>
13 #include <linux/gfs2_ondisk.h>
14 #include <linux/uaccess.h>
15
16 #include "gfs2.h"
17 #include "incore.h"
18 #include "glock.h"
19 #include "lops.h"
20 #include "recovery.h"
21 #include "rgrp.h"
22 #include "super.h"
23 #include "util.h"
24
25 struct kmem_cache *gfs2_glock_cachep __read_mostly;
26 struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly;
27 struct kmem_cache *gfs2_inode_cachep __read_mostly;
28 struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
29 struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
30 struct kmem_cache *gfs2_quotad_cachep __read_mostly;
31 struct kmem_cache *gfs2_qadata_cachep __read_mostly;
32 mempool_t *gfs2_page_pool __read_mostly;
33
34 void gfs2_assert_i(struct gfs2_sbd *sdp)
35 {
36         fs_emerg(sdp, "fatal assertion failed\n");
37 }
38
39 /**
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  */
46 int 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
76 out_unlock:
77         gfs2_glock_dq_uninit(&j_gh);
78         return error;
79 }
80
81 void 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
97 int gfs2_withdraw(struct gfs2_sbd *sdp)
98 {
99         struct lm_lockstruct *ls = &sdp->sd_lockstruct;
100         const struct lm_lockops *lm = ls->ls_ops;
101
102         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
103             test_and_set_bit(SDF_WITHDRAWN, &sdp->sd_flags))
104                 return 0;
105
106         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);
109
110                 kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE);
111
112                 if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
113                         wait_for_completion(&sdp->sd_wdack);
114
115                 if (lm->lm_unmount) {
116                         fs_err(sdp, "telling LM to unmount\n");
117                         lm->lm_unmount(sdp);
118                 }
119                 set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags);
120                 fs_err(sdp, "withdrawn\n");
121                 dump_stack();
122         }
123
124         if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
125                 panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname);
126
127         return -1;
128 }
129
130 /**
131  * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false
132  */
133
134 void gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
135                             const char *function, char *file, unsigned int line)
136 {
137         gfs2_lm(sdp,
138                 "fatal: assertion \"%s\" failed\n"
139                 "   function = %s, file = %s, line = %u\n",
140                 assertion, function, file, line);
141         gfs2_withdraw(sdp);
142         dump_stack();
143 }
144
145 /**
146  * gfs2_assert_warn_i - Print a message to the console if @assertion is false
147  */
148
149 void gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
150                         const char *function, char *file, unsigned int line)
151 {
152         if (time_before(jiffies,
153                         sdp->sd_last_warning +
154                         gfs2_tune_get(sdp, gt_complain_secs) * HZ))
155                 return;
156
157         if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
158                 fs_warn(sdp, "warning: assertion \"%s\" failed at function = %s, file = %s, line = %u\n",
159                         assertion, function, file, line);
160
161         if (sdp->sd_args.ar_debug)
162                 BUG();
163         else
164                 dump_stack();
165
166         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
172         sdp->sd_last_warning = jiffies;
173 }
174
175 /**
176  * gfs2_consist_i - Flag a filesystem consistency error and withdraw
177  */
178
179 void gfs2_consist_i(struct gfs2_sbd *sdp, const char *function,
180                     char *file, unsigned int line)
181 {
182         gfs2_lm(sdp,
183                 "fatal: filesystem consistency error - function = %s, file = %s, line = %u\n",
184                 function, file, line);
185         gfs2_withdraw(sdp);
186 }
187
188 /**
189  * gfs2_consist_inode_i - Flag an inode consistency error and withdraw
190  */
191
192 void gfs2_consist_inode_i(struct gfs2_inode *ip,
193                           const char *function, char *file, unsigned int line)
194 {
195         struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
196
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);
204         gfs2_withdraw(sdp);
205 }
206
207 /**
208  * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw
209  */
210
211 void gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd,
212                           const char *function, char *file, unsigned int line)
213 {
214         struct gfs2_sbd *sdp = rgd->rd_sbd;
215         char fs_id_buf[sizeof(sdp->sd_fsname) + 7];
216
217         sprintf(fs_id_buf, "fsid=%s: ", sdp->sd_fsname);
218         gfs2_rgrp_dump(NULL, rgd->rd_gl, fs_id_buf);
219         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);
225         gfs2_withdraw(sdp);
226 }
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
234 int 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;
239
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);
247         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
256 int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
257                            u16 type, u16 t, const char *function,
258                            char *file, unsigned int line)
259 {
260         int me;
261
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);
269         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
278 int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
279                     unsigned int line)
280 {
281         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);
286 }
287
288 /**
289  * gfs2_io_error_bh_i - Flag a buffer I/O error
290  * @withdraw: withdraw the filesystem
291  */
292
293 void 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)
296 {
297         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);
304         if (withdraw)
305                 gfs2_withdraw(sdp);
306 }
307