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 (lm->lm_unmount) {
  58                        fs_err(sdp, "telling LM to unmount\n");
  59                        lm->lm_unmount(sdp);
  60                }
  61                fs_err(sdp, "withdrawn\n");
  62                dump_stack();
  63        }
  64
  65        if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
  66                panic("GFS2: fsid=%s: panic requested.\n", sdp->sd_fsname);
  67
  68        return -1;
  69}
  70
  71/**
  72 * gfs2_assert_withdraw_i - Cause the machine to withdraw if @assertion is false
  73 * Returns: -1 if this call withdrew the machine,
  74 *          -2 if it was already withdrawn
  75 */
  76
  77int gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
  78                           const char *function, char *file, unsigned int line)
  79{
  80        int me;
  81        me = gfs2_lm_withdraw(sdp,
  82                "GFS2: fsid=%s: fatal: assertion \"%s\" failed\n"
  83                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
  84                sdp->sd_fsname, assertion,
  85                sdp->sd_fsname, function, file, line);
  86        dump_stack();
  87        return (me) ? -1 : -2;
  88}
  89
  90/**
  91 * gfs2_assert_warn_i - Print a message to the console if @assertion is false
  92 * Returns: -1 if we printed something
  93 *          -2 if we didn't
  94 */
  95
  96int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
  97                       const char *function, char *file, unsigned int line)
  98{
  99        if (time_before(jiffies,
 100                        sdp->sd_last_warning +
 101                        gfs2_tune_get(sdp, gt_complain_secs) * HZ))
 102                return -2;
 103
 104        if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW)
 105                printk(KERN_WARNING
 106                       "GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
 107                       "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 108                       sdp->sd_fsname, assertion,
 109                       sdp->sd_fsname, function, file, line);
 110
 111        if (sdp->sd_args.ar_debug)
 112                BUG();
 113        else
 114                dump_stack();
 115
 116        if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
 117                panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n"
 118                      "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 119                      sdp->sd_fsname, assertion,
 120                      sdp->sd_fsname, function, file, line);
 121
 122        sdp->sd_last_warning = jiffies;
 123
 124        return -1;
 125}
 126
 127/**
 128 * gfs2_consist_i - Flag a filesystem consistency error and withdraw
 129 * Returns: -1 if this call withdrew the machine,
 130 *          0 if it was already withdrawn
 131 */
 132
 133int gfs2_consist_i(struct gfs2_sbd *sdp, int cluster_wide, const char *function,
 134                   char *file, unsigned int line)
 135{
 136        int rv;
 137        rv = gfs2_lm_withdraw(sdp,
 138                "GFS2: fsid=%s: fatal: filesystem consistency error\n"
 139                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 140                sdp->sd_fsname,
 141                sdp->sd_fsname, function, file, line);
 142        return rv;
 143}
 144
 145/**
 146 * gfs2_consist_inode_i - Flag an inode consistency error and withdraw
 147 * Returns: -1 if this call withdrew the machine,
 148 *          0 if it was already withdrawn
 149 */
 150
 151int gfs2_consist_inode_i(struct gfs2_inode *ip, int cluster_wide,
 152                         const char *function, char *file, unsigned int line)
 153{
 154        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 155        int rv;
 156        rv = gfs2_lm_withdraw(sdp,
 157                "GFS2: fsid=%s: fatal: filesystem consistency error\n"
 158                "GFS2: fsid=%s:   inode = %llu %llu\n"
 159                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 160                sdp->sd_fsname,
 161                sdp->sd_fsname, (unsigned long long)ip->i_no_formal_ino,
 162                (unsigned long long)ip->i_no_addr,
 163                sdp->sd_fsname, function, file, line);
 164        return rv;
 165}
 166
 167/**
 168 * gfs2_consist_rgrpd_i - Flag a RG consistency error and withdraw
 169 * Returns: -1 if this call withdrew the machine,
 170 *          0 if it was already withdrawn
 171 */
 172
 173int gfs2_consist_rgrpd_i(struct gfs2_rgrpd *rgd, int cluster_wide,
 174                         const char *function, char *file, unsigned int line)
 175{
 176        struct gfs2_sbd *sdp = rgd->rd_sbd;
 177        int rv;
 178        rv = gfs2_lm_withdraw(sdp,
 179                "GFS2: fsid=%s: fatal: filesystem consistency error\n"
 180                "GFS2: fsid=%s:   RG = %llu\n"
 181                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 182                sdp->sd_fsname,
 183                sdp->sd_fsname, (unsigned long long)rgd->rd_addr,
 184                sdp->sd_fsname, function, file, line);
 185        return rv;
 186}
 187
 188/**
 189 * gfs2_meta_check_ii - Flag a magic number consistency error and withdraw
 190 * Returns: -1 if this call withdrew the machine,
 191 *          -2 if it was already withdrawn
 192 */
 193
 194int gfs2_meta_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
 195                       const char *type, const char *function, char *file,
 196                       unsigned int line)
 197{
 198        int me;
 199        me = gfs2_lm_withdraw(sdp,
 200                "GFS2: fsid=%s: fatal: invalid metadata block\n"
 201                "GFS2: fsid=%s:   bh = %llu (%s)\n"
 202                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 203                sdp->sd_fsname,
 204                sdp->sd_fsname, (unsigned long long)bh->b_blocknr, type,
 205                sdp->sd_fsname, function, file, line);
 206        return (me) ? -1 : -2;
 207}
 208
 209/**
 210 * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw
 211 * Returns: -1 if this call withdrew the machine,
 212 *          -2 if it was already withdrawn
 213 */
 214
 215int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
 216                           u16 type, u16 t, const char *function,
 217                           char *file, unsigned int line)
 218{
 219        int me;
 220        me = gfs2_lm_withdraw(sdp,
 221                "GFS2: fsid=%s: fatal: invalid metadata block\n"
 222                "GFS2: fsid=%s:   bh = %llu (type: exp=%u, found=%u)\n"
 223                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 224                sdp->sd_fsname,
 225                sdp->sd_fsname, (unsigned long long)bh->b_blocknr, type, t,
 226                sdp->sd_fsname, function, file, line);
 227        return (me) ? -1 : -2;
 228}
 229
 230/**
 231 * gfs2_io_error_i - Flag an I/O error and withdraw
 232 * Returns: -1 if this call withdrew the machine,
 233 *          0 if it was already withdrawn
 234 */
 235
 236int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
 237                    unsigned int line)
 238{
 239        int rv;
 240        rv = gfs2_lm_withdraw(sdp,
 241                "GFS2: fsid=%s: fatal: I/O error\n"
 242                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 243                sdp->sd_fsname,
 244                sdp->sd_fsname, function, file, line);
 245        return rv;
 246}
 247
 248/**
 249 * gfs2_io_error_bh_i - Flag a buffer I/O error and withdraw
 250 * Returns: -1 if this call withdrew the machine,
 251 *          0 if it was already withdrawn
 252 */
 253
 254int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh,
 255                       const char *function, char *file, unsigned int line)
 256{
 257        int rv;
 258        rv = gfs2_lm_withdraw(sdp,
 259                "GFS2: fsid=%s: fatal: I/O error\n"
 260                "GFS2: fsid=%s:   block = %llu\n"
 261                "GFS2: fsid=%s:   function = %s, file = %s, line = %u\n",
 262                sdp->sd_fsname,
 263                sdp->sd_fsname, (unsigned long long)bh->b_blocknr,
 264                sdp->sd_fsname, function, file, line);
 265        return rv;
 266}
 267
 268void gfs2_icbit_munge(struct gfs2_sbd *sdp, unsigned char **bitmap,
 269                      unsigned int bit, int new_value)
 270{
 271        unsigned int c, o, b = bit;
 272        int old_value;
 273
 274        c = b / (8 * PAGE_SIZE);
 275        b %= 8 * PAGE_SIZE;
 276        o = b / 8;
 277        b %= 8;
 278
 279        old_value = (bitmap[c][o] & (1 << b));
 280        gfs2_assert_withdraw(sdp, !old_value != !new_value);
 281
 282        if (new_value)
 283                bitmap[c][o] |= 1 << b;
 284        else
 285                bitmap[c][o] &= ~(1 << b);
 286}
 287
 288
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.