aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/inode.c
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/ocfs2/inode.c
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/ocfs2/inode.c')
-rw-r--r--fs/ocfs2/inode.c136
1 files changed, 98 insertions, 38 deletions
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}