aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-13 17:49:19 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:36:53 -0500
commit970e4936d7d15f35d00fd15a14f5343ba78b2fc8 (patch)
tree92057c7deab6b9d8e5c3889d6a354b5989a3b68d /fs
parent4ae1d69bedc8d174cb8a558694607e013157cde1 (diff)
ocfs2: Validate metadata only when it's read from disk.
Add an optional validation hook to ocfs2_read_blocks(). Now the validation function is only called when a block was actually read off of disk. It is not called when the buffer was in cache. We add a buffer state bit BH_NeedsValidate to flag these buffers. It must always be one higher than the last JBD2 buffer state bit. The dinode, dirblock, extent_block, and xattr_block validators are lifted to this scheme directly. The group_descriptor validator needs to be split into two pieces. The first part only needs the gd buffer and is passed to ocfs2_read_block(). The second part requires the dinode as well, and is called every time. It's only 3 compares, so it's tiny. This also allows us to clean up the non-fatal gd check used by resize.c. It now has no magic argument. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/alloc.c17
-rw-r--r--fs/ocfs2/buffer_head_io.c33
-rw-r--r--fs/ocfs2/buffer_head_io.h27
-rw-r--r--fs/ocfs2/dir.c13
-rw-r--r--fs/ocfs2/inode.c18
-rw-r--r--fs/ocfs2/resize.c2
-rw-r--r--fs/ocfs2/slot_map.c4
-rw-r--r--fs/ocfs2/suballoc.c91
-rw-r--r--fs/ocfs2/suballoc.h15
-rw-r--r--fs/ocfs2/xattr.c26
10 files changed, 149 insertions, 97 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index f430cc6e0f35..e823a27ba340 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -684,6 +684,9 @@ static int ocfs2_validate_extent_block(struct super_block *sb,
684 struct ocfs2_extent_block *eb = 684 struct ocfs2_extent_block *eb =
685 (struct ocfs2_extent_block *)bh->b_data; 685 (struct ocfs2_extent_block *)bh->b_data;
686 686
687 mlog(0, "Validating extent block %llu\n",
688 (unsigned long long)bh->b_blocknr);
689
687 if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) { 690 if (!OCFS2_IS_VALID_EXTENT_BLOCK(eb)) {
688 ocfs2_error(sb, 691 ocfs2_error(sb,
689 "Extent block #%llu has bad signature %.*s", 692 "Extent block #%llu has bad signature %.*s",
@@ -719,21 +722,13 @@ int ocfs2_read_extent_block(struct inode *inode, u64 eb_blkno,
719 int rc; 722 int rc;
720 struct buffer_head *tmp = *bh; 723 struct buffer_head *tmp = *bh;
721 724
722 rc = ocfs2_read_block(inode, eb_blkno, &tmp); 725 rc = ocfs2_read_block(inode, eb_blkno, &tmp,
723 if (rc) 726 ocfs2_validate_extent_block);
724 goto out;
725
726 rc = ocfs2_validate_extent_block(inode->i_sb, tmp);
727 if (rc) {
728 brelse(tmp);
729 goto out;
730 }
731 727
732 /* If ocfs2_read_block() got us a new bh, pass it up. */ 728 /* If ocfs2_read_block() got us a new bh, pass it up. */
733 if (!*bh) 729 if (!rc && !*bh)
734 *bh = tmp; 730 *bh = tmp;
735 731
736out:
737 return rc; 732 return rc;
738} 733}
739 734
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index 3a178ec48d7c..0e9eed0c223f 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -39,6 +39,19 @@
39 39
40#include "buffer_head_io.h" 40#include "buffer_head_io.h"
41 41
42/*
43 * Bits on bh->b_state used by ocfs2.
44 *
45 * These MUST be after the JBD2 bits. Currently BH_Unshadow is the last
46 * JBD2 bit.
47 */
48enum ocfs2_state_bits {
49 BH_NeedsValidate = BH_Unshadow + 1,
50};
51
52/* Expand the magic b_state functions */
53BUFFER_FNS(NeedsValidate, needs_validate);
54
42int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, 55int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
43 struct inode *inode) 56 struct inode *inode)
44{ 57{
@@ -166,7 +179,9 @@ bail:
166} 179}
167 180
168int ocfs2_read_blocks(struct inode *inode, u64 block, int nr, 181int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
169 struct buffer_head *bhs[], int flags) 182 struct buffer_head *bhs[], int flags,
183 int (*validate)(struct super_block *sb,
184 struct buffer_head *bh))
170{ 185{
171 int status = 0; 186 int status = 0;
172 int i, ignore_cache = 0; 187 int i, ignore_cache = 0;
@@ -298,6 +313,8 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
298 313
299 clear_buffer_uptodate(bh); 314 clear_buffer_uptodate(bh);
300 get_bh(bh); /* for end_buffer_read_sync() */ 315 get_bh(bh); /* for end_buffer_read_sync() */
316 if (validate)
317 set_buffer_needs_validate(bh);
301 bh->b_end_io = end_buffer_read_sync; 318 bh->b_end_io = end_buffer_read_sync;
302 submit_bh(READ, bh); 319 submit_bh(READ, bh);
303 continue; 320 continue;
@@ -328,6 +345,20 @@ int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
328 bhs[i] = NULL; 345 bhs[i] = NULL;
329 continue; 346 continue;
330 } 347 }
348
349 if (buffer_needs_validate(bh)) {
350 /* We never set NeedsValidate if the
351 * buffer was held by the journal, so
352 * that better not have changed */
353 BUG_ON(buffer_jbd(bh));
354 clear_buffer_needs_validate(bh);
355 status = validate(inode->i_sb, bh);
356 if (status) {
357 put_bh(bh);
358 bhs[i] = NULL;
359 continue;
360 }
361 }
331 } 362 }
332 363
333 /* Always set the buffer in the cache, even if it was 364 /* Always set the buffer in the cache, even if it was
diff --git a/fs/ocfs2/buffer_head_io.h b/fs/ocfs2/buffer_head_io.h
index 75e1dcb1ade7..c75d682dadd8 100644
--- a/fs/ocfs2/buffer_head_io.h
+++ b/fs/ocfs2/buffer_head_io.h
@@ -31,21 +31,24 @@
31void ocfs2_end_buffer_io_sync(struct buffer_head *bh, 31void ocfs2_end_buffer_io_sync(struct buffer_head *bh,
32 int uptodate); 32 int uptodate);
33 33
34static inline int ocfs2_read_block(struct inode *inode,
35 u64 off,
36 struct buffer_head **bh);
37
38int ocfs2_write_block(struct ocfs2_super *osb, 34int ocfs2_write_block(struct ocfs2_super *osb,
39 struct buffer_head *bh, 35 struct buffer_head *bh,
40 struct inode *inode); 36 struct inode *inode);
41int ocfs2_read_blocks(struct inode *inode,
42 u64 block,
43 int nr,
44 struct buffer_head *bhs[],
45 int flags);
46int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block, 37int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
47 unsigned int nr, struct buffer_head *bhs[]); 38 unsigned int nr, struct buffer_head *bhs[]);
48 39
40/*
41 * If not NULL, validate() will be called on a buffer that is freshly
42 * read from disk. It will not be called if the buffer was in cache.
43 * Note that if validate() is being used for this buffer, it needs to
44 * be set even for a READAHEAD call, as it marks the buffer for later
45 * validation.
46 */
47int ocfs2_read_blocks(struct inode *inode, u64 block, int nr,
48 struct buffer_head *bhs[], int flags,
49 int (*validate)(struct super_block *sb,
50 struct buffer_head *bh));
51
49int ocfs2_write_super_or_backup(struct ocfs2_super *osb, 52int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
50 struct buffer_head *bh); 53 struct buffer_head *bh);
51 54
@@ -53,7 +56,9 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
53#define OCFS2_BH_READAHEAD 8 56#define OCFS2_BH_READAHEAD 8
54 57
55static inline int ocfs2_read_block(struct inode *inode, u64 off, 58static inline int ocfs2_read_block(struct inode *inode, u64 off,
56 struct buffer_head **bh) 59 struct buffer_head **bh,
60 int (*validate)(struct super_block *sb,
61 struct buffer_head *bh))
57{ 62{
58 int status = 0; 63 int status = 0;
59 64
@@ -63,7 +68,7 @@ static inline int ocfs2_read_block(struct inode *inode, u64 off,
63 goto bail; 68 goto bail;
64 } 69 }
65 70
66 status = ocfs2_read_blocks(inode, off, 1, bh, 0); 71 status = ocfs2_read_blocks(inode, off, 1, bh, 0, validate);
67 72
68bail: 73bail:
69 return status; 74 return status;
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index c2f3fd93be5c..7e863d40380d 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -214,6 +214,8 @@ static int ocfs2_validate_dir_block(struct super_block *sb,
214 * Nothing yet. We don't validate dirents here, that's handled 214 * Nothing yet. We don't validate dirents here, that's handled
215 * in-place when the code walks them. 215 * in-place when the code walks them.
216 */ 216 */
217 mlog(0, "Validating dirblock %llu\n",
218 (unsigned long long)bh->b_blocknr);
217 219
218 return 0; 220 return 0;
219} 221}
@@ -255,20 +257,13 @@ static int ocfs2_read_dir_block(struct inode *inode, u64 v_block,
255 goto out; 257 goto out;
256 } 258 }
257 259
258 rc = ocfs2_read_blocks(inode, p_blkno, 1, &tmp, flags); 260 rc = ocfs2_read_blocks(inode, p_blkno, 1, &tmp, flags,
261 ocfs2_validate_dir_block);
259 if (rc) { 262 if (rc) {
260 mlog_errno(rc); 263 mlog_errno(rc);
261 goto out; 264 goto out;
262 } 265 }
263 266
264 if (!(flags & OCFS2_BH_READAHEAD)) {
265 rc = ocfs2_validate_dir_block(inode->i_sb, tmp);
266 if (rc) {
267 brelse(tmp);
268 goto out;
269 }
270 }
271
272 /* If ocfs2_read_blocks() got us a new bh, pass it up. */ 267 /* If ocfs2_read_blocks() got us a new bh, pass it up. */
273 if (!*bh) 268 if (!*bh)
274 *bh = tmp; 269 *bh = tmp;
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 9eb701b86466..ec3497bafda6 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -1255,6 +1255,9 @@ int ocfs2_validate_inode_block(struct super_block *sb,
1255 int rc = -EINVAL; 1255 int rc = -EINVAL;
1256 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; 1256 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
1257 1257
1258 mlog(0, "Validating dinode %llu\n",
1259 (unsigned long long)bh->b_blocknr);
1260
1258 BUG_ON(!buffer_uptodate(bh)); 1261 BUG_ON(!buffer_uptodate(bh));
1259 1262
1260 if (!OCFS2_IS_VALID_DINODE(di)) { 1263 if (!OCFS2_IS_VALID_DINODE(di)) {
@@ -1300,23 +1303,12 @@ int ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh,
1300 struct buffer_head *tmp = *bh; 1303 struct buffer_head *tmp = *bh;
1301 1304
1302 rc = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, &tmp, 1305 rc = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, &tmp,
1303 flags); 1306 flags, ocfs2_validate_inode_block);
1304 if (rc)
1305 goto out;
1306
1307 if (!(flags & OCFS2_BH_READAHEAD)) {
1308 rc = ocfs2_validate_inode_block(inode->i_sb, tmp);
1309 if (rc) {
1310 brelse(tmp);
1311 goto out;
1312 }
1313 }
1314 1307
1315 /* If ocfs2_read_blocks() got us a new bh, pass it up. */ 1308 /* If ocfs2_read_blocks() got us a new bh, pass it up. */
1316 if (!*bh) 1309 if (!rc && !*bh)
1317 *bh = tmp; 1310 *bh = tmp;
1318 1311
1319out:
1320 return rc; 1312 return rc;
1321} 1313}
1322 1314
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
index 252baff5eb84..867de3ebfcaf 100644
--- a/fs/ocfs2/resize.c
+++ b/fs/ocfs2/resize.c
@@ -394,7 +394,7 @@ static int ocfs2_check_new_group(struct inode *inode,
394 (struct ocfs2_group_desc *)group_bh->b_data; 394 (struct ocfs2_group_desc *)group_bh->b_data;
395 u16 cl_bpc = le16_to_cpu(di->id2.i_chain.cl_bpc); 395 u16 cl_bpc = le16_to_cpu(di->id2.i_chain.cl_bpc);
396 396
397 ret = ocfs2_validate_group_descriptor(inode->i_sb, di, group_bh, 1); 397 ret = ocfs2_check_group_descriptor(inode->i_sb, di, group_bh);
398 if (ret) 398 if (ret)
399 goto out; 399 goto out;
400 400
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index bdda2d8f8508..40661e7824e9 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -151,7 +151,7 @@ int ocfs2_refresh_slot_info(struct ocfs2_super *osb)
151 * this is not true, the read of -1 (UINT64_MAX) will fail. 151 * this is not true, the read of -1 (UINT64_MAX) will fail.
152 */ 152 */
153 ret = ocfs2_read_blocks(si->si_inode, -1, si->si_blocks, si->si_bh, 153 ret = ocfs2_read_blocks(si->si_inode, -1, si->si_blocks, si->si_bh,
154 OCFS2_BH_IGNORE_CACHE); 154 OCFS2_BH_IGNORE_CACHE, NULL);
155 if (ret == 0) { 155 if (ret == 0) {
156 spin_lock(&osb->osb_lock); 156 spin_lock(&osb->osb_lock);
157 ocfs2_update_slot_info(si); 157 ocfs2_update_slot_info(si);
@@ -405,7 +405,7 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb,
405 405
406 bh = NULL; /* Acquire a fresh bh */ 406 bh = NULL; /* Acquire a fresh bh */
407 status = ocfs2_read_blocks(si->si_inode, blkno, 1, &bh, 407 status = ocfs2_read_blocks(si->si_inode, blkno, 1, &bh,
408 OCFS2_BH_IGNORE_CACHE); 408 OCFS2_BH_IGNORE_CACHE, NULL);
409 if (status < 0) { 409 if (status < 0) {
410 mlog_errno(status); 410 mlog_errno(status);
411 goto bail; 411 goto bail;
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 766a00b26441..226fe21f2608 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -145,14 +145,6 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl)
145 return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); 145 return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc);
146} 146}
147 147
148int ocfs2_validate_group_descriptor(struct super_block *sb,
149 struct ocfs2_dinode *di,
150 struct buffer_head *bh,
151 int clean_error)
152{
153 unsigned int max_bits;
154 struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
155
156#define do_error(fmt, ...) \ 148#define do_error(fmt, ...) \
157 do{ \ 149 do{ \
158 if (clean_error) \ 150 if (clean_error) \
@@ -161,6 +153,12 @@ int ocfs2_validate_group_descriptor(struct super_block *sb,
161 ocfs2_error(sb, fmt, ##__VA_ARGS__); \ 153 ocfs2_error(sb, fmt, ##__VA_ARGS__); \
162 } while (0) 154 } while (0)
163 155
156static int ocfs2_validate_gd_self(struct super_block *sb,
157 struct buffer_head *bh,
158 int clean_error)
159{
160 struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
161
164 if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { 162 if (!OCFS2_IS_VALID_GROUP_DESC(gd)) {
165 do_error("Group descriptor #%llu has bad signature %.*s", 163 do_error("Group descriptor #%llu has bad signature %.*s",
166 (unsigned long long)bh->b_blocknr, 7, 164 (unsigned long long)bh->b_blocknr, 7,
@@ -184,6 +182,35 @@ int ocfs2_validate_group_descriptor(struct super_block *sb,
184 return -EINVAL; 182 return -EINVAL;
185 } 183 }
186 184
185 if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) {
186 do_error("Group descriptor #%llu has bit count %u but "
187 "claims that %u are free",
188 (unsigned long long)bh->b_blocknr,
189 le16_to_cpu(gd->bg_bits),
190 le16_to_cpu(gd->bg_free_bits_count));
191 return -EINVAL;
192 }
193
194 if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {
195 do_error("Group descriptor #%llu has bit count %u but "
196 "max bitmap bits of %u",
197 (unsigned long long)bh->b_blocknr,
198 le16_to_cpu(gd->bg_bits),
199 8 * le16_to_cpu(gd->bg_size));
200 return -EINVAL;
201 }
202
203 return 0;
204}
205
206static int ocfs2_validate_gd_parent(struct super_block *sb,
207 struct ocfs2_dinode *di,
208 struct buffer_head *bh,
209 int clean_error)
210{
211 unsigned int max_bits;
212 struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
213
187 if (di->i_blkno != gd->bg_parent_dinode) { 214 if (di->i_blkno != gd->bg_parent_dinode) {
188 do_error("Group descriptor #%llu has bad parent " 215 do_error("Group descriptor #%llu has bad parent "
189 "pointer (%llu, expected %llu)", 216 "pointer (%llu, expected %llu)",
@@ -209,26 +236,35 @@ int ocfs2_validate_group_descriptor(struct super_block *sb,
209 return -EINVAL; 236 return -EINVAL;
210 } 237 }
211 238
212 if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { 239 return 0;
213 do_error("Group descriptor #%llu has bit count %u but " 240}
214 "claims that %u are free",
215 (unsigned long long)bh->b_blocknr,
216 le16_to_cpu(gd->bg_bits),
217 le16_to_cpu(gd->bg_free_bits_count));
218 return -EINVAL;
219 }
220 241
221 if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) {
222 do_error("Group descriptor #%llu has bit count %u but "
223 "max bitmap bits of %u",
224 (unsigned long long)bh->b_blocknr,
225 le16_to_cpu(gd->bg_bits),
226 8 * le16_to_cpu(gd->bg_size));
227 return -EINVAL;
228 }
229#undef do_error 242#undef do_error
230 243
231 return 0; 244/*
245 * This version only prints errors. It does not fail the filesystem, and
246 * exists only for resize.
247 */
248int ocfs2_check_group_descriptor(struct super_block *sb,
249 struct ocfs2_dinode *di,
250 struct buffer_head *bh)
251{
252 int rc;
253
254 rc = ocfs2_validate_gd_self(sb, bh, 1);
255 if (!rc)
256 rc = ocfs2_validate_gd_parent(sb, di, bh, 1);
257
258 return rc;
259}
260
261static int ocfs2_validate_group_descriptor(struct super_block *sb,
262 struct buffer_head *bh)
263{
264 mlog(0, "Validating group descriptor %llu\n",
265 (unsigned long long)bh->b_blocknr);
266
267 return ocfs2_validate_gd_self(sb, bh, 0);
232} 268}
233 269
234int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di, 270int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
@@ -237,11 +273,12 @@ int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
237 int rc; 273 int rc;
238 struct buffer_head *tmp = *bh; 274 struct buffer_head *tmp = *bh;
239 275
240 rc = ocfs2_read_block(inode, gd_blkno, &tmp); 276 rc = ocfs2_read_block(inode, gd_blkno, &tmp,
277 ocfs2_validate_group_descriptor);
241 if (rc) 278 if (rc)
242 goto out; 279 goto out;
243 280
244 rc = ocfs2_validate_group_descriptor(inode->i_sb, di, tmp, 0); 281 rc = ocfs2_validate_gd_parent(inode->i_sb, di, tmp, 0);
245 if (rc) { 282 if (rc) {
246 brelse(tmp); 283 brelse(tmp);
247 goto out; 284 goto out;
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index 43de4fd826d3..e3c13c77f9e8 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -165,16 +165,15 @@ void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac);
165u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster); 165u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster);
166 166
167/* 167/*
168 * By default, ocfs2_validate_group_descriptor() calls ocfs2_error() when it 168 * By default, ocfs2_read_group_descriptor() calls ocfs2_error() when it
169 * finds a problem. A caller that wants to check a group descriptor 169 * finds a problem. A caller that wants to check a group descriptor
170 * without going readonly passes a nonzero clean_error. This is only 170 * without going readonly should read the block with ocfs2_read_block[s]()
171 * resize, really. Everyone else should be using 171 * and then checking it with this function. This is only resize, really.
172 * ocfs2_read_group_descriptor(). 172 * Everyone else should be using ocfs2_read_group_descriptor().
173 */ 173 */
174int ocfs2_validate_group_descriptor(struct super_block *sb, 174int ocfs2_check_group_descriptor(struct super_block *sb,
175 struct ocfs2_dinode *di, 175 struct ocfs2_dinode *di,
176 struct buffer_head *bh, 176 struct buffer_head *bh);
177 int clean_error);
178/* 177/*
179 * Read a group descriptor block into *bh. If *bh is NULL, a bh will be 178 * Read a group descriptor block into *bh. If *bh is NULL, a bh will be
180 * allocated. This is a cached read. The descriptor will be validated with 179 * allocated. This is a cached read. The descriptor will be validated with
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index ef4aa5482d01..8af29b3bd6de 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -266,7 +266,8 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket,
266 int rc; 266 int rc;
267 267
268 rc = ocfs2_read_blocks(bucket->bu_inode, xb_blkno, 268 rc = ocfs2_read_blocks(bucket->bu_inode, xb_blkno,
269 bucket->bu_blocks, bucket->bu_bhs, 0); 269 bucket->bu_blocks, bucket->bu_bhs, 0,
270 NULL);
270 if (rc) 271 if (rc)
271 ocfs2_xattr_bucket_relse(bucket); 272 ocfs2_xattr_bucket_relse(bucket);
272 return rc; 273 return rc;
@@ -359,12 +360,8 @@ static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno,
359 int rc; 360 int rc;
360 struct buffer_head *tmp = *bh; 361 struct buffer_head *tmp = *bh;
361 362
362 rc = ocfs2_read_block(inode, xb_blkno, &tmp); 363 rc = ocfs2_read_block(inode, xb_blkno, &tmp,
363 if (!rc) { 364 ocfs2_validate_xattr_block);
364 rc = ocfs2_validate_xattr_block(inode->i_sb, tmp);
365 if (rc)
366 brelse(tmp);
367 }
368 365
369 /* If ocfs2_read_block() got us a new bh, pass it up. */ 366 /* If ocfs2_read_block() got us a new bh, pass it up. */
370 if (!rc && !*bh) 367 if (!rc && !*bh)
@@ -925,7 +922,7 @@ static int ocfs2_xattr_get_value_outside(struct inode *inode,
925 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); 922 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
926 /* Copy ocfs2_xattr_value */ 923 /* Copy ocfs2_xattr_value */
927 for (i = 0; i < num_clusters * bpc; i++, blkno++) { 924 for (i = 0; i < num_clusters * bpc; i++, blkno++) {
928 ret = ocfs2_read_block(inode, blkno, &bh); 925 ret = ocfs2_read_block(inode, blkno, &bh, NULL);
929 if (ret) { 926 if (ret) {
930 mlog_errno(ret); 927 mlog_errno(ret);
931 goto out; 928 goto out;
@@ -1174,7 +1171,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode,
1174 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); 1171 blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
1175 1172
1176 for (i = 0; i < num_clusters * bpc; i++, blkno++) { 1173 for (i = 0; i < num_clusters * bpc; i++, blkno++) {
1177 ret = ocfs2_read_block(inode, blkno, &bh); 1174 ret = ocfs2_read_block(inode, blkno, &bh, NULL);
1178 if (ret) { 1175 if (ret) {
1179 mlog_errno(ret); 1176 mlog_errno(ret);
1180 goto out; 1177 goto out;
@@ -2206,7 +2203,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
2206 base = xis->base; 2203 base = xis->base;
2207 credits += OCFS2_INODE_UPDATE_CREDITS; 2204 credits += OCFS2_INODE_UPDATE_CREDITS;
2208 } else { 2205 } else {
2209 int i, block_off; 2206 int i, block_off = 0;
2210 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data; 2207 xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
2211 xe = xbs->here; 2208 xe = xbs->here;
2212 name_offset = le16_to_cpu(xe->xe_name_offset); 2209 name_offset = le16_to_cpu(xe->xe_name_offset);
@@ -2840,6 +2837,7 @@ static int ocfs2_find_xe_in_bucket(struct inode *inode,
2840 break; 2837 break;
2841 } 2838 }
2842 2839
2840
2843 xe_name = bucket_block(bucket, block_off) + new_offset; 2841 xe_name = bucket_block(bucket, block_off) + new_offset;
2844 if (!memcmp(name, xe_name, name_len)) { 2842 if (!memcmp(name, xe_name, name_len)) {
2845 *xe_index = i; 2843 *xe_index = i;
@@ -3598,7 +3596,7 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
3598 goto out; 3596 goto out;
3599 } 3597 }
3600 3598
3601 ret = ocfs2_read_block(inode, prev_blkno, &old_bh); 3599 ret = ocfs2_read_block(inode, prev_blkno, &old_bh, NULL);
3602 if (ret < 0) { 3600 if (ret < 0) {
3603 mlog_errno(ret); 3601 mlog_errno(ret);
3604 brelse(new_bh); 3602 brelse(new_bh);
@@ -3990,7 +3988,7 @@ static int ocfs2_cp_xattr_cluster(struct inode *inode,
3990 ocfs2_journal_dirty(handle, first_bh); 3988 ocfs2_journal_dirty(handle, first_bh);
3991 3989
3992 /* update the new bucket header. */ 3990 /* update the new bucket header. */
3993 ret = ocfs2_read_block(inode, to_blk_start, &bh); 3991 ret = ocfs2_read_block(inode, to_blk_start, &bh, NULL);
3994 if (ret < 0) { 3992 if (ret < 0) {
3995 mlog_errno(ret); 3993 mlog_errno(ret);
3996 goto out; 3994 goto out;
@@ -4337,7 +4335,7 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4337 goto out; 4335 goto out;
4338 } 4336 }
4339 4337
4340 ret = ocfs2_read_block(inode, p_blkno, &first_bh); 4338 ret = ocfs2_read_block(inode, p_blkno, &first_bh, NULL);
4341 if (ret) { 4339 if (ret) {
4342 mlog_errno(ret); 4340 mlog_errno(ret);
4343 goto out; 4341 goto out;
@@ -4635,7 +4633,7 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
4635 BUG_ON(value_blk != (offset + OCFS2_XATTR_ROOT_SIZE - 1) / blocksize); 4633 BUG_ON(value_blk != (offset + OCFS2_XATTR_ROOT_SIZE - 1) / blocksize);
4636 value_blk += header_bh->b_blocknr; 4634 value_blk += header_bh->b_blocknr;
4637 4635
4638 ret = ocfs2_read_block(inode, value_blk, &value_bh); 4636 ret = ocfs2_read_block(inode, value_blk, &value_bh, NULL);
4639 if (ret) { 4637 if (ret) {
4640 mlog_errno(ret); 4638 mlog_errno(ret);
4641 goto out; 4639 goto out;