• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <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_glock_aspace_cachep __read_mostly;
26  struct kmem_cache *gfs2_inode_cachep __read_mostly;
27  struct kmem_cache *gfs2_bufdata_cachep __read_mostly;
28  struct kmem_cache *gfs2_rgrpd_cachep __read_mostly;
29  struct kmem_cache *gfs2_quotad_cachep __read_mostly;
30  struct kmem_cache *gfs2_qadata_cachep __read_mostly;
31  mempool_t *gfs2_page_pool __read_mostly;
32  
gfs2_assert_i(struct gfs2_sbd * sdp)33  void gfs2_assert_i(struct gfs2_sbd *sdp)
34  {
35  	fs_emerg(sdp, "fatal assertion failed\n");
36  }
37  
gfs2_lm_withdraw(struct gfs2_sbd * sdp,const char * fmt,...)38  int gfs2_lm_withdraw(struct gfs2_sbd *sdp, const char *fmt, ...)
39  {
40  	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
41  	const struct lm_lockops *lm = ls->ls_ops;
42  	va_list args;
43  	struct va_format vaf;
44  
45  	if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW &&
46  	    test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags))
47  		return 0;
48  
49  	va_start(args, fmt);
50  
51  	vaf.fmt = fmt;
52  	vaf.va = &args;
53  
54  	fs_err(sdp, "%pV", &vaf);
55  
56  	va_end(args);
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  
gfs2_assert_withdraw_i(struct gfs2_sbd * sdp,char * assertion,const char * function,char * file,unsigned int line)88  int 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  
gfs2_assert_warn_i(struct gfs2_sbd * sdp,char * assertion,const char * function,char * file,unsigned int line)106  int 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  
gfs2_consist_i(struct gfs2_sbd * sdp,int cluster_wide,const char * function,char * file,unsigned int line)140  int 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  
gfs2_consist_inode_i(struct gfs2_inode * ip,int cluster_wide,const char * function,char * file,unsigned int line)156  int 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  
gfs2_consist_rgrpd_i(struct gfs2_rgrpd * rgd,int cluster_wide,const char * function,char * file,unsigned int line)177  int 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  	int rv;
182  	rv = gfs2_lm_withdraw(sdp,
183  			      "fatal: filesystem consistency error\n"
184  			      "  RG = %llu\n"
185  			      "  function = %s, file = %s, line = %u\n",
186  			      (unsigned long long)rgd->rd_addr,
187  			      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  
gfs2_meta_check_ii(struct gfs2_sbd * sdp,struct buffer_head * bh,const char * type,const char * function,char * file,unsigned int line)197  int 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  			      "fatal: invalid metadata block\n"
204  			      "  bh = %llu (%s)\n"
205  			      "  function = %s, file = %s, line = %u\n",
206  			      (unsigned long long)bh->b_blocknr, type,
207  			      function, file, line);
208  	return (me) ? -1 : -2;
209  }
210  
211  /**
212   * gfs2_metatype_check_ii - Flag a metadata type consistency error and withdraw
213   * Returns: -1 if this call withdrew the machine,
214   *          -2 if it was already withdrawn
215   */
216  
gfs2_metatype_check_ii(struct gfs2_sbd * sdp,struct buffer_head * bh,u16 type,u16 t,const char * function,char * file,unsigned int line)217  int gfs2_metatype_check_ii(struct gfs2_sbd *sdp, struct buffer_head *bh,
218  			   u16 type, u16 t, const char *function,
219  			   char *file, unsigned int line)
220  {
221  	int me;
222  	me = gfs2_lm_withdraw(sdp,
223  			      "fatal: invalid metadata block\n"
224  			      "  bh = %llu (type: exp=%u, found=%u)\n"
225  			      "  function = %s, file = %s, line = %u\n",
226  			      (unsigned long long)bh->b_blocknr, type, t,
227  			      function, file, line);
228  	return (me) ? -1 : -2;
229  }
230  
231  /**
232   * gfs2_io_error_i - Flag an I/O error and withdraw
233   * Returns: -1 if this call withdrew the machine,
234   *          0 if it was already withdrawn
235   */
236  
gfs2_io_error_i(struct gfs2_sbd * sdp,const char * function,char * file,unsigned int line)237  int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function, char *file,
238  		    unsigned int line)
239  {
240  	int rv;
241  	rv = gfs2_lm_withdraw(sdp,
242  			      "fatal: I/O error\n"
243  			      "  function = %s, file = %s, line = %u\n",
244  			      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  
gfs2_io_error_bh_i(struct gfs2_sbd * sdp,struct buffer_head * bh,const char * function,char * file,unsigned int line)254  int 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  			      "fatal: I/O error\n"
260  			      "  block = %llu\n"
261  			      "  function = %s, file = %s, line = %u\n",
262  			      (unsigned long long)bh->b_blocknr,
263  			      function, file, line);
264  	return rv;
265  }
266  
267