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 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 int 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 91 int 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 109 int 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 143 int 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 159 int 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 180 int 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 202 int 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 222 int 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 242 int 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 258 void 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 273