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