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