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