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