aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-13 17:49:11 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:36:52 -0500
commitb657c95c11088d77fc1bfc9c84d940f778bf9d12 (patch)
tree7e52e73aabbdbc55f644ad26735edc25a652ac32 /fs
parenta68979b857283daf4acc405e476dcc8812a3ff2b (diff)
ocfs2: Wrap inode block reads in a dedicated function.
The ocfs2 code currently reads inodes off disk with a simple ocfs2_read_block() call. Each place that does this has a different set of sanity checks it performs. Some check only the signature. A couple validate the block number (the block read vs di->i_blkno). A couple others check for VALID_FL. Only one place validates i_fs_generation. A couple check nothing. Even when an error is found, they don't all do the same thing. We wrap inode reading into ocfs2_read_inode_block(). This will validate all the above fields, going readonly if they are invalid (they never should be). ocfs2_read_inode_block_full() is provided for the places that want to pass read_block flags. Every caller is passing a struct inode with a valid ip_blkno, so we don't need a separate blkno argument either. We will remove the validation checks from the rest of the code in a later commit, as they are no longer necessary. 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.c2
-rw-r--r--fs/ocfs2/aops.c11
-rw-r--r--fs/ocfs2/dir.c6
-rw-r--r--fs/ocfs2/dlmglue.c12
-rw-r--r--fs/ocfs2/extent_map.c2
-rw-r--r--fs/ocfs2/file.c21
-rw-r--r--fs/ocfs2/inode.c136
-rw-r--r--fs/ocfs2/inode.h16
-rw-r--r--fs/ocfs2/journal.c3
-rw-r--r--fs/ocfs2/localalloc.c8
-rw-r--r--fs/ocfs2/namei.c14
-rw-r--r--fs/ocfs2/symlink.c2
12 files changed, 136 insertions, 97 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 5592a2f6335b..9c598adc9475 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -5658,7 +5658,7 @@ static int ocfs2_get_truncate_log_info(struct ocfs2_super *osb,
5658 goto bail; 5658 goto bail;
5659 } 5659 }
5660 5660
5661 status = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &bh); 5661 status = ocfs2_read_inode_block(inode, &bh);
5662 if (status < 0) { 5662 if (status < 0) {
5663 iput(inode); 5663 iput(inode);
5664 mlog_errno(status); 5664 mlog_errno(status);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index c22543b33420..e219f8b546ac 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -68,20 +68,13 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
68 goto bail; 68 goto bail;
69 } 69 }
70 70
71 status = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &bh); 71 status = ocfs2_read_inode_block(inode, &bh);
72 if (status < 0) { 72 if (status < 0) {
73 mlog_errno(status); 73 mlog_errno(status);
74 goto bail; 74 goto bail;
75 } 75 }
76 fe = (struct ocfs2_dinode *) bh->b_data; 76 fe = (struct ocfs2_dinode *) bh->b_data;
77 77
78 if (!OCFS2_IS_VALID_DINODE(fe)) {
79 mlog(ML_ERROR, "Invalid dinode #%llu: signature = %.*s\n",
80 (unsigned long long)le64_to_cpu(fe->i_blkno), 7,
81 fe->i_signature);
82 goto bail;
83 }
84
85 if ((u64)iblock >= ocfs2_clusters_to_blocks(inode->i_sb, 78 if ((u64)iblock >= ocfs2_clusters_to_blocks(inode->i_sb,
86 le32_to_cpu(fe->i_clusters))) { 79 le32_to_cpu(fe->i_clusters))) {
87 mlog(ML_ERROR, "block offset is outside the allocated size: " 80 mlog(ML_ERROR, "block offset is outside the allocated size: "
@@ -262,7 +255,7 @@ static int ocfs2_readpage_inline(struct inode *inode, struct page *page)
262 BUG_ON(!PageLocked(page)); 255 BUG_ON(!PageLocked(page));
263 BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)); 256 BUG_ON(!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
264 257
265 ret = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &di_bh); 258 ret = ocfs2_read_inode_block(inode, &di_bh);
266 if (ret) { 259 if (ret) {
267 mlog_errno(ret); 260 mlog_errno(ret);
268 goto out; 261 goto out;
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 026e6eb85187..5777045f1a67 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -231,7 +231,7 @@ static struct buffer_head *ocfs2_find_entry_id(const char *name,
231 struct ocfs2_dinode *di; 231 struct ocfs2_dinode *di;
232 struct ocfs2_inline_data *data; 232 struct ocfs2_inline_data *data;
233 233
234 ret = ocfs2_read_block(dir, OCFS2_I(dir)->ip_blkno, &di_bh); 234 ret = ocfs2_read_inode_block(dir, &di_bh);
235 if (ret) { 235 if (ret) {
236 mlog_errno(ret); 236 mlog_errno(ret);
237 goto out; 237 goto out;
@@ -458,7 +458,7 @@ static inline int ocfs2_delete_entry_id(handle_t *handle,
458 struct ocfs2_dinode *di; 458 struct ocfs2_dinode *di;
459 struct ocfs2_inline_data *data; 459 struct ocfs2_inline_data *data;
460 460
461 ret = ocfs2_read_block(dir, OCFS2_I(dir)->ip_blkno, &di_bh); 461 ret = ocfs2_read_inode_block(dir, &di_bh);
462 if (ret) { 462 if (ret) {
463 mlog_errno(ret); 463 mlog_errno(ret);
464 goto out; 464 goto out;
@@ -636,7 +636,7 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
636 struct ocfs2_inline_data *data; 636 struct ocfs2_inline_data *data;
637 struct ocfs2_dir_entry *de; 637 struct ocfs2_dir_entry *de;
638 638
639 ret = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &di_bh); 639 ret = ocfs2_read_inode_block(inode, &di_bh);
640 if (ret) { 640 if (ret) {
641 mlog(ML_ERROR, "Unable to read inode block for dir %llu\n", 641 mlog(ML_ERROR, "Unable to read inode block for dir %llu\n",
642 (unsigned long long)OCFS2_I(inode)->ip_blkno); 642 (unsigned long long)OCFS2_I(inode)->ip_blkno);
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 6e6cc0a2e5f7..9f2a7f75d1b3 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2024,7 +2024,7 @@ static int ocfs2_inode_lock_update(struct inode *inode,
2024 } else { 2024 } else {
2025 /* Boo, we have to go to disk. */ 2025 /* Boo, we have to go to disk. */
2026 /* read bh, cast, ocfs2_refresh_inode */ 2026 /* read bh, cast, ocfs2_refresh_inode */
2027 status = ocfs2_read_block(inode, oi->ip_blkno, bh); 2027 status = ocfs2_read_inode_block(inode, bh);
2028 if (status < 0) { 2028 if (status < 0) {
2029 mlog_errno(status); 2029 mlog_errno(status);
2030 goto bail_refresh; 2030 goto bail_refresh;
@@ -2032,18 +2032,14 @@ static int ocfs2_inode_lock_update(struct inode *inode,
2032 fe = (struct ocfs2_dinode *) (*bh)->b_data; 2032 fe = (struct ocfs2_dinode *) (*bh)->b_data;
2033 2033
2034 /* This is a good chance to make sure we're not 2034 /* This is a good chance to make sure we're not
2035 * locking an invalid object. 2035 * locking an invalid object. ocfs2_read_inode_block()
2036 * already checked that the inode block is sane.
2036 * 2037 *
2037 * We bug on a stale inode here because we checked 2038 * We bug on a stale inode here because we checked
2038 * above whether it was wiped from disk. The wiping 2039 * above whether it was wiped from disk. The wiping
2039 * node provides a guarantee that we receive that 2040 * node provides a guarantee that we receive that
2040 * message and can mark the inode before dropping any 2041 * message and can mark the inode before dropping any
2041 * locks associated with it. */ 2042 * locks associated with it. */
2042 if (!OCFS2_IS_VALID_DINODE(fe)) {
2043 OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
2044 status = -EIO;
2045 goto bail_refresh;
2046 }
2047 mlog_bug_on_msg(inode->i_generation != 2043 mlog_bug_on_msg(inode->i_generation !=
2048 le32_to_cpu(fe->i_generation), 2044 le32_to_cpu(fe->i_generation),
2049 "Invalid dinode %llu disk generation: %u " 2045 "Invalid dinode %llu disk generation: %u "
@@ -2085,7 +2081,7 @@ static int ocfs2_assign_bh(struct inode *inode,
2085 return 0; 2081 return 0;
2086 } 2082 }
2087 2083
2088 status = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, ret_bh); 2084 status = ocfs2_read_inode_block(inode, ret_bh);
2089 if (status < 0) 2085 if (status < 0)
2090 mlog_errno(status); 2086 mlog_errno(status);
2091 2087
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index 2baedac58234..b686b31cf49c 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -630,7 +630,7 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
630 if (ret == 0) 630 if (ret == 0)
631 goto out; 631 goto out;
632 632
633 ret = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &di_bh); 633 ret = ocfs2_read_inode_block(inode, &di_bh);
634 if (ret) { 634 if (ret) {
635 mlog_errno(ret); 635 mlog_errno(ret);
636 goto out; 636 goto out;
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 4636aa6b0117..41001d515fae 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -402,12 +402,9 @@ static int ocfs2_truncate_file(struct inode *inode,
402 (unsigned long long)OCFS2_I(inode)->ip_blkno, 402 (unsigned long long)OCFS2_I(inode)->ip_blkno,
403 (unsigned long long)new_i_size); 403 (unsigned long long)new_i_size);
404 404
405 /* We trust di_bh because it comes from ocfs2_inode_lock(), which
406 * already validated it */
405 fe = (struct ocfs2_dinode *) di_bh->b_data; 407 fe = (struct ocfs2_dinode *) di_bh->b_data;
406 if (!OCFS2_IS_VALID_DINODE(fe)) {
407 OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
408 status = -EIO;
409 goto bail;
410 }
411 408
412 mlog_bug_on_msg(le64_to_cpu(fe->i_size) != i_size_read(inode), 409 mlog_bug_on_msg(le64_to_cpu(fe->i_size) != i_size_read(inode),
413 "Inode %llu, inode i_size = %lld != di " 410 "Inode %llu, inode i_size = %lld != di "
@@ -546,18 +543,12 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
546 */ 543 */
547 BUG_ON(mark_unwritten && !ocfs2_sparse_alloc(osb)); 544 BUG_ON(mark_unwritten && !ocfs2_sparse_alloc(osb));
548 545
549 status = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, &bh); 546 status = ocfs2_read_inode_block(inode, &bh);
550 if (status < 0) { 547 if (status < 0) {
551 mlog_errno(status); 548 mlog_errno(status);
552 goto leave; 549 goto leave;
553 } 550 }
554
555 fe = (struct ocfs2_dinode *) bh->b_data; 551 fe = (struct ocfs2_dinode *) bh->b_data;
556 if (!OCFS2_IS_VALID_DINODE(fe)) {
557 OCFS2_RO_ON_INVALID_DINODE(inode->i_sb, fe);
558 status = -EIO;
559 goto leave;
560 }
561 552
562restart_all: 553restart_all:
563 BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters); 554 BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters);
@@ -1135,9 +1126,8 @@ static int ocfs2_write_remove_suid(struct inode *inode)
1135{ 1126{
1136 int ret; 1127 int ret;
1137 struct buffer_head *bh = NULL; 1128 struct buffer_head *bh = NULL;
1138 struct ocfs2_inode_info *oi = OCFS2_I(inode);
1139 1129
1140 ret = ocfs2_read_block(inode, oi->ip_blkno, &bh); 1130 ret = ocfs2_read_inode_block(inode, &bh);
1141 if (ret < 0) { 1131 if (ret < 0) {
1142 mlog_errno(ret); 1132 mlog_errno(ret);
1143 goto out; 1133 goto out;
@@ -1163,8 +1153,7 @@ static int ocfs2_allocate_unwritten_extents(struct inode *inode,
1163 struct buffer_head *di_bh = NULL; 1153 struct buffer_head *di_bh = NULL;
1164 1154
1165 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { 1155 if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
1166 ret = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, 1156 ret = ocfs2_read_inode_block(inode, &di_bh);
1167 &di_bh);
1168 if (ret) { 1157 if (ret) {
1169 mlog_errno(ret); 1158 mlog_errno(ret);
1170 goto out; 1159 goto out;
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 7aa00d511874..9eb701b86466 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -214,12 +214,11 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque)
214 return 0; 214 return 0;
215} 215}
216 216
217int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, 217void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
218 int create_ino) 218 int create_ino)
219{ 219{
220 struct super_block *sb; 220 struct super_block *sb;
221 struct ocfs2_super *osb; 221 struct ocfs2_super *osb;
222 int status = -EINVAL;
223 int use_plocks = 1; 222 int use_plocks = 1;
224 223
225 mlog_entry("(0x%p, size:%llu)\n", inode, 224 mlog_entry("(0x%p, size:%llu)\n", inode,
@@ -232,25 +231,17 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
232 ocfs2_mount_local(osb) || !ocfs2_stack_supports_plocks()) 231 ocfs2_mount_local(osb) || !ocfs2_stack_supports_plocks())
233 use_plocks = 0; 232 use_plocks = 0;
234 233
235 /* this means that read_inode cannot create a superblock inode 234 /*
236 * today. change if needed. */ 235 * These have all been checked by ocfs2_read_inode_block() or set
237 if (!OCFS2_IS_VALID_DINODE(fe) || 236 * by ocfs2_mknod_locked(), so a failure is a code bug.
238 !(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL))) { 237 */
239 mlog(0, "Invalid dinode: i_ino=%lu, i_blkno=%llu, " 238 BUG_ON(!OCFS2_IS_VALID_DINODE(fe)); /* This means that read_inode
240 "signature = %.*s, flags = 0x%x\n", 239 cannot create a superblock
241 inode->i_ino, 240 inode today. change if
242 (unsigned long long)le64_to_cpu(fe->i_blkno), 7, 241 that is needed. */
243 fe->i_signature, le32_to_cpu(fe->i_flags)); 242 BUG_ON(!(fe->i_flags & cpu_to_le32(OCFS2_VALID_FL)));
244 goto bail; 243 BUG_ON(le32_to_cpu(fe->i_fs_generation) != osb->fs_generation);
245 }
246 244
247 if (le32_to_cpu(fe->i_fs_generation) != osb->fs_generation) {
248 mlog(ML_ERROR, "file entry generation does not match "
249 "superblock! osb->fs_generation=%x, "
250 "fe->i_fs_generation=%x\n",
251 osb->fs_generation, le32_to_cpu(fe->i_fs_generation));
252 goto bail;
253 }
254 245
255 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); 246 OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
256 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); 247 OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
@@ -354,10 +345,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
354 345
355 ocfs2_set_inode_flags(inode); 346 ocfs2_set_inode_flags(inode);
356 347
357 status = 0; 348 mlog_exit_void();
358bail:
359 mlog_exit(status);
360 return status;
361} 349}
362 350
363static int ocfs2_read_locked_inode(struct inode *inode, 351static int ocfs2_read_locked_inode(struct inode *inode,
@@ -460,11 +448,14 @@ static int ocfs2_read_locked_inode(struct inode *inode,
460 } 448 }
461 } 449 }
462 450
463 if (can_lock) 451 if (can_lock) {
464 status = ocfs2_read_blocks(inode, args->fi_blkno, 1, &bh, 452 status = ocfs2_read_inode_block_full(inode, &bh,
465 OCFS2_BH_IGNORE_CACHE); 453 OCFS2_BH_IGNORE_CACHE);
466 else 454 } else {
467 status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh); 455 status = ocfs2_read_blocks_sync(osb, args->fi_blkno, 1, &bh);
456 if (!status)
457 status = ocfs2_validate_inode_block(osb->sb, bh);
458 }
468 if (status < 0) { 459 if (status < 0) {
469 mlog_errno(status); 460 mlog_errno(status);
470 goto bail; 461 goto bail;
@@ -472,12 +463,6 @@ static int ocfs2_read_locked_inode(struct inode *inode,
472 463
473 status = -EINVAL; 464 status = -EINVAL;
474 fe = (struct ocfs2_dinode *) bh->b_data; 465 fe = (struct ocfs2_dinode *) bh->b_data;
475 if (!OCFS2_IS_VALID_DINODE(fe)) {
476 mlog(0, "Invalid dinode #%llu: signature = %.*s\n",
477 (unsigned long long)args->fi_blkno, 7,
478 fe->i_signature);
479 goto bail;
480 }
481 466
482 /* 467 /*
483 * This is a code bug. Right now the caller needs to 468 * This is a code bug. Right now the caller needs to
@@ -491,10 +476,9 @@ static int ocfs2_read_locked_inode(struct inode *inode,
491 476
492 if (S_ISCHR(le16_to_cpu(fe->i_mode)) || 477 if (S_ISCHR(le16_to_cpu(fe->i_mode)) ||
493 S_ISBLK(le16_to_cpu(fe->i_mode))) 478 S_ISBLK(le16_to_cpu(fe->i_mode)))
494 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev)); 479 inode->i_rdev = huge_decode_dev(le64_to_cpu(fe->id1.dev1.i_rdev));
495 480
496 if (ocfs2_populate_inode(inode, fe, 0) < 0) 481 ocfs2_populate_inode(inode, fe, 0);
497 goto bail;
498 482
499 BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno)); 483 BUG_ON(args->fi_blkno != le64_to_cpu(fe->i_blkno));
500 484
@@ -1264,3 +1248,79 @@ void ocfs2_refresh_inode(struct inode *inode,
1264 1248
1265 spin_unlock(&OCFS2_I(inode)->ip_lock); 1249 spin_unlock(&OCFS2_I(inode)->ip_lock);
1266} 1250}
1251
1252int ocfs2_validate_inode_block(struct super_block *sb,
1253 struct buffer_head *bh)
1254{
1255 int rc = -EINVAL;
1256 struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
1257
1258 BUG_ON(!buffer_uptodate(bh));
1259
1260 if (!OCFS2_IS_VALID_DINODE(di)) {
1261 ocfs2_error(sb, "Invalid dinode #%llu: signature = %.*s\n",
1262 (unsigned long long)bh->b_blocknr, 7,
1263 di->i_signature);
1264 goto bail;
1265 }
1266
1267 if (le64_to_cpu(di->i_blkno) != bh->b_blocknr) {
1268 ocfs2_error(sb, "Invalid dinode #%llu: i_blkno is %llu\n",
1269 (unsigned long long)bh->b_blocknr,
1270 (unsigned long long)le64_to_cpu(di->i_blkno));
1271 goto bail;
1272 }
1273
1274 if (!(di->i_flags & cpu_to_le32(OCFS2_VALID_FL))) {
1275 ocfs2_error(sb,
1276 "Invalid dinode #%llu: OCFS2_VALID_FL not set\n",
1277 (unsigned long long)bh->b_blocknr);
1278 goto bail;
1279 }
1280
1281 if (le32_to_cpu(di->i_fs_generation) !=
1282 OCFS2_SB(sb)->fs_generation) {
1283 ocfs2_error(sb,
1284 "Invalid dinode #%llu: fs_generation is %u\n",
1285 (unsigned long long)bh->b_blocknr,
1286 le32_to_cpu(di->i_fs_generation));
1287 goto bail;
1288 }
1289
1290 rc = 0;
1291
1292bail:
1293 return rc;
1294}
1295
1296int ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh,
1297 int flags)
1298{
1299 int rc;
1300 struct buffer_head *tmp = *bh;
1301
1302 rc = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, &tmp,
1303 flags);
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
1315 /* If ocfs2_read_blocks() got us a new bh, pass it up. */
1316 if (!*bh)
1317 *bh = tmp;
1318
1319out:
1320 return rc;
1321}
1322
1323int ocfs2_read_inode_block(struct inode *inode, struct buffer_head **bh)
1324{
1325 return ocfs2_read_inode_block_full(inode, bh, 0);
1326}
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index 2f37af9bcc4a..b79c371a9d27 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -128,8 +128,8 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 feoff, unsigned flags,
128 int sysfile_type); 128 int sysfile_type);
129int ocfs2_inode_init_private(struct inode *inode); 129int ocfs2_inode_init_private(struct inode *inode);
130int ocfs2_inode_revalidate(struct dentry *dentry); 130int ocfs2_inode_revalidate(struct dentry *dentry);
131int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, 131void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
132 int create_ino); 132 int create_ino);
133void ocfs2_read_inode(struct inode *inode); 133void ocfs2_read_inode(struct inode *inode);
134void ocfs2_read_inode2(struct inode *inode, void *opaque); 134void ocfs2_read_inode2(struct inode *inode, void *opaque);
135ssize_t ocfs2_rw_direct(int rw, struct file *filp, char *buf, 135ssize_t ocfs2_rw_direct(int rw, struct file *filp, char *buf,
@@ -153,4 +153,16 @@ static inline blkcnt_t ocfs2_inode_sector_count(struct inode *inode)
153 return (blkcnt_t)(OCFS2_I(inode)->ip_clusters << c_to_s_bits); 153 return (blkcnt_t)(OCFS2_I(inode)->ip_clusters << c_to_s_bits);
154} 154}
155 155
156/* Validate that a bh contains a valid inode */
157int ocfs2_validate_inode_block(struct super_block *sb,
158 struct buffer_head *bh);
159/*
160 * Read an inode block into *bh. If *bh is NULL, a bh will be allocated.
161 * This is a cached read. The inode will be validated with
162 * ocfs2_validate_inode_block().
163 */
164int ocfs2_read_inode_block(struct inode *inode, struct buffer_head **bh);
165/* The same, but can be passed OCFS2_BH_* flags */
166int ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh,
167 int flags);
156#endif /* OCFS2_INODE_H */ 168#endif /* OCFS2_INODE_H */
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 99fe9d584f3c..877aaa05e199 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -1135,8 +1135,7 @@ static int ocfs2_read_journal_inode(struct ocfs2_super *osb,
1135 } 1135 }
1136 SET_INODE_JOURNAL(inode); 1136 SET_INODE_JOURNAL(inode);
1137 1137
1138 status = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, bh, 1138 status = ocfs2_read_inode_block_full(inode, bh, OCFS2_BH_IGNORE_CACHE);
1139 OCFS2_BH_IGNORE_CACHE);
1140 if (status < 0) { 1139 if (status < 0) {
1141 mlog_errno(status); 1140 mlog_errno(status);
1142 goto bail; 1141 goto bail;
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 687b28713c32..19cfb1b9ce09 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -248,8 +248,8 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb)
248 goto bail; 248 goto bail;
249 } 249 }
250 250
251 status = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, 251 status = ocfs2_read_inode_block_full(inode, &alloc_bh,
252 &alloc_bh, OCFS2_BH_IGNORE_CACHE); 252 OCFS2_BH_IGNORE_CACHE);
253 if (status < 0) { 253 if (status < 0) {
254 mlog_errno(status); 254 mlog_errno(status);
255 goto bail; 255 goto bail;
@@ -459,8 +459,8 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
459 459
460 mutex_lock(&inode->i_mutex); 460 mutex_lock(&inode->i_mutex);
461 461
462 status = ocfs2_read_blocks(inode, OCFS2_I(inode)->ip_blkno, 1, 462 status = ocfs2_read_inode_block_full(inode, &alloc_bh,
463 &alloc_bh, OCFS2_BH_IGNORE_CACHE); 463 OCFS2_BH_IGNORE_CACHE);
464 if (status < 0) { 464 if (status < 0) {
465 mlog_errno(status); 465 mlog_errno(status);
466 goto bail; 466 goto bail;
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 765514512096..0134bafdab9e 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -531,15 +531,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
531 goto leave; 531 goto leave;
532 } 532 }
533 533
534 if (ocfs2_populate_inode(inode, fe, 1) < 0) { 534 ocfs2_populate_inode(inode, fe, 1);
535 mlog(ML_ERROR, "populate inode failed! bh->b_blocknr=%llu, "
536 "i_blkno=%llu, i_ino=%lu\n",
537 (unsigned long long)(*new_fe_bh)->b_blocknr,
538 (unsigned long long)le64_to_cpu(fe->i_blkno),
539 inode->i_ino);
540 BUG();
541 }
542
543 ocfs2_inode_set_new(osb, inode); 535 ocfs2_inode_set_new(osb, inode);
544 if (!ocfs2_mount_local(osb)) { 536 if (!ocfs2_mount_local(osb)) {
545 status = ocfs2_create_new_inode_locks(inode); 537 status = ocfs2_create_new_inode_locks(inode);
@@ -1864,9 +1856,7 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
1864 1856
1865 mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); 1857 mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
1866 1858
1867 status = ocfs2_read_block(orphan_dir_inode, 1859 status = ocfs2_read_inode_block(orphan_dir_inode, &orphan_dir_bh);
1868 OCFS2_I(orphan_dir_inode)->ip_blkno,
1869 &orphan_dir_bh);
1870 if (status < 0) { 1860 if (status < 0) {
1871 mlog_errno(status); 1861 mlog_errno(status);
1872 goto leave; 1862 goto leave;
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index cbd03dfdc7b9..ed0a0cfd68d2 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -84,7 +84,7 @@ static char *ocfs2_fast_symlink_getlink(struct inode *inode,
84 84
85 mlog_entry_void(); 85 mlog_entry_void();
86 86
87 status = ocfs2_read_block(inode, OCFS2_I(inode)->ip_blkno, bh); 87 status = ocfs2_read_inode_block(inode, bh);
88 if (status < 0) { 88 if (status < 0) {
89 mlog_errno(status); 89 mlog_errno(status);
90 link = ERR_PTR(status); 90 link = ERR_PTR(status);