at v5.1 272 lines 7.6 kB view raw
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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12#include <linux/spinlock.h> 13#include <linux/completion.h> 14#include <linux/buffer_head.h> 15#include <linux/crc32.h> 16#include <linux/gfs2_ondisk.h> 17#include <linux/uaccess.h> 18 19#include "gfs2.h" 20#include "incore.h" 21#include "glock.h" 22#include "rgrp.h" 23#include "util.h" 24 25struct kmem_cache *gfs2_glock_cachep __read_mostly; 26struct kmem_cache *gfs2_glock_aspace_cachep __read_mostly; 27struct kmem_cache *gfs2_inode_cachep __read_mostly; 28struct kmem_cache *gfs2_bufdata_cachep __read_mostly; 29struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; 30struct kmem_cache *gfs2_quotad_cachep __read_mostly; 31struct kmem_cache *gfs2_qadata_cachep __read_mostly; 32mempool_t *gfs2_page_pool __read_mostly; 33 34void gfs2_assert_i(struct gfs2_sbd *sdp) 35{ 36 fs_emerg(sdp, "fatal assertion failed\n"); 37} 38 39int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...) 40{ 41 struct lm_lockstruct *ls = &sdp->sd_lockstruct; 42 const struct lm_lockops *lm = ls->ls_ops; 43 va_list args; 44 struct va_format vaf; 45 46 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW && 47 test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 48 return 0; 49 50 if (fmt) { 51 va_start(args, fmt); 52 53 vaf.fmt = fmt; 54 vaf.va = &args; 55 56 fs_err(sdp, "%pV", &vaf); 57 58 va_end(args); 59 } 60 61 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) { 62 fs_err(sdp, "about to withdraw this file system\n"); 63 BUG_ON(sdp->sd_args.ar_debug); 64 65 kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE); 66 67 if (!strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm")) 68 wait_for_completion(&sdp->sd_wdack); 69 70 if (lm->lm_unmount) { 71 fs_err(sdp, "telling LM to unmount\n"); 72 lm->lm_unmount(sdp); 73 } 74 set_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags); 75 fs_err(sdp, "withdrawn\n"); 76 dump_stack(); 77 } 78 79 if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) 80 panic("GFS2: fsid=%s: panic requested\n", sdp->sd_fsname); 81 82 return -1; 83} 84 85/** 86 * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false 87 * Returns: -1 if this call withdrew the machine, 88 * -2 if it was already withdrawn 89 */ 90 91int gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion, 92 const char *function, char *file, unsigned int line) 93{ 94 int me; 95 me = gfs2_lm_withdraw(sdp, 96 "fatal: assertion \"%s\" failed\n" 97 " function = %s, file = %s, line = %u\n", 98 assertion, function, file, line); 99 dump_stack(); 100 return (me) ? -1 : -2; 101} 102 103/** 104 * gfs2_assert_warn_i - Print a message to the console if @assertion is false 105 * Returns: -1 if we printed something 106 * -2 if we didn't 107 */ 108 109int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion, 110 const char *function, char *file, unsigned int line) 111{ 112 if (time_before(jiffies, 113 sdp->sd_last_warning + 114 gfs2_tune_get(sdp, gt_complain_secs) * HZ)) 115 return -2; 116 117 if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) 118 fs_warn(sdp, "warning: assertion \"%s\" failed at function = %s, file = %s, line = %u\n", 119 assertion, function, file, line); 120 121 if (sdp->sd_args.ar_debug) 122 BUG(); 123 else 124 dump_stack(); 125 126 if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) 127 panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n" 128 "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", 129 sdp->sd_fsname, assertion, 130 sdp->sd_fsname, function, file, line); 131 132 sdp->sd_last_warning = jiffies; 133 134 return -1; 135} 136 137/** 138 * gfs2_consist_i - Flag a filesystem consistency error and withdraw 139 * Returns: -1 if this call withdrew the machine, 140 * 0 if it was already withdrawn 141 */ 142 143int gfs2_consist_i(struct gfs2_sbd *sdp, int cluster_wide, const char *function, 144 char *file, unsigned int line) 145{ 146 int rv; 147 rv = gfs2_lm_withdraw(sdp, 148 "fatal: filesystem consistency error - function = %s, file = %s, line = %u\n", 149 function, file, line); 150 return rv; 151} 152 153/** 154 * gfs2_consist_inode_i - Flag an inode consistency error and withdraw 155 * Returns: -1 if this call withdrew the machine, 156 * 0 if it was already withdrawn 157 */ 158 159int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide, 160 const char *function, char *file, unsigned int line) 161{ 162 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 163 int rv; 164 rv = gfs2_lm_withdraw(sdp, 165 "fatal: filesystem consistency error\n" 166 " inode = %llu %llu\n" 167 " function = %s, file = %s, line = %u\n", 168 (unsigned long long)ip->i_no_formal_ino, 169 (unsigned long long)ip->i_no_addr, 170 function, file, line); 171 return rv; 172} 173 174/** 175 * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw 176 * Returns: -1 if this call withdrew the machine, 177 * 0 if it was already withdrawn 178 */ 179 180int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide, 181 const char *function, char *file, unsigned int line) 182{ 183 struct gfs2_sbd *sdp = rgd->rd_sbd; 184 int rv; 185 186 gfs2_rgrp_dump(NULL, rgd->rd_gl); 187 rv = gfs2_lm_withdraw(sdp, 188 "fatal: filesystem consistency error\n" 189 " RG = %llu\n" 190 " function = %s, file = %s, line = %u\n", 191 (unsigned long long)rgd->rd_addr, 192 function, file, line); 193 return rv; 194} 195 196/** 197 * gfs2_meta_check_ii - Flag a magic number consistency error and withdraw 198 * Returns: -1 if this call withdrew the machine, 199 * -2 if it was already withdrawn 200 */ 201 202int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, 203 const char *type, const char *function, char *file, 204 unsigned int line) 205{ 206 int me; 207 me = gfs2_lm_withdraw(sdp, 208 "fatal: invalid metadata block\n" 209 " bh = %llu (%s)\n" 210 " function = %s, file = %s, line = %u\n", 211 (unsigned long long)bh->b_blocknr, type, 212 function, file, line); 213 return (me) ? -1 : -2; 214} 215 216/** 217 * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw 218 * Returns: -1 if this call withdrew the machine, 219 * -2 if it was already withdrawn 220 */ 221 222int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh, 223 u16 type, u16 t, const char *function, 224 char *file, unsigned int line) 225{ 226 int me; 227 me = gfs2_lm_withdraw(sdp, 228 "fatal: invalid metadata block\n" 229 " bh = %llu (type: exp=%u, found=%u)\n" 230 " function = %s, file = %s, line = %u\n", 231 (unsigned long long)bh->b_blocknr, type, t, 232 function, file, line); 233 return (me) ? -1 : -2; 234} 235 236/** 237 * gfs2_io_error_i - Flag an I/O error and withdraw 238 * Returns: -1 if this call withdrew the machine, 239 * 0 if it was already withdrawn 240 */ 241 242int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file, 243 unsigned int line) 244{ 245 int rv; 246 rv = gfs2_lm_withdraw(sdp, 247 "fatal: I/O error\n" 248 " function = %s, file = %s, line = %u\n", 249 function, file, line); 250 return rv; 251} 252 253/** 254 * gfs2_io_error_bh_i - Flag a buffer I/O error 255 * @withdraw: withdraw the filesystem 256 */ 257 258void gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, 259 const char *function, char *file, unsigned int line, 260 bool withdraw) 261{ 262 if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) 263 fs_err(sdp, 264 "fatal: I/O error\n" 265 " block = %llu\n" 266 " function = %s, file = %s, line = %u\n", 267 (unsigned long long)bh->b_blocknr, 268 function, file, line); 269 if (withdraw) 270 gfs2_lm_withdraw(sdp, NULL); 271} 272