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