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