[Ocfs2-tools-commits] zab commits r1177 - trunk/fsck.ocfs2
svn-commits@oss.oracle.com
svn-commits at oss.oracle.com
Tue Apr 18 17:42:52 CDT 2006
Author: zab
Signed-off-by: mfasheh
Date: 2006-04-18 17:42:51 -0500 (Tue, 18 Apr 2006)
New Revision: 1177
Modified:
trunk/fsck.ocfs2/pass2.c
Log:
o don't check directory blocks that are beyond i_size. I don't know what
jokers masqueraded as Mark and me to produce and sign off on the last fix
that checked for zeroed blocks, but boy are they in trouble.
Signed-off-by: mfasheh
Modified: trunk/fsck.ocfs2/pass2.c
===================================================================
--- trunk/fsck.ocfs2/pass2.c 2006-04-17 21:23:12 UTC (rev 1176)
+++ trunk/fsck.ocfs2/pass2.c 2006-04-18 22:42:51 UTC (rev 1177)
@@ -65,7 +65,8 @@
struct dirblock_data {
o2fsck_state *ost;
ocfs2_filesys *fs;
- char *buf;
+ char *dirblock_buf;
+ char *inoblock_buf;
errcode_t ret;
o2fsck_strings strings;
uint64_t last_ino;
@@ -596,16 +597,6 @@
return 1;
}
-static size_t nr_zeros(unsigned char *buf, size_t len)
-{
- size_t ret = 0;
-
- while(len-- > 0 && *(buf++) == 0)
- ret++;
-
- return ret;
-}
-
/* this could certainly be more clever to issue reads in groups */
static unsigned pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
void *priv_data)
@@ -613,46 +604,53 @@
struct dirblock_data *dd = priv_data;
struct ocfs2_dir_entry *dirent, *prev = NULL;
unsigned int offset = 0, ret_flags = 0;
- errcode_t ret;
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)dd->inoblock_buf;
+ errcode_t ret = 0;
if (!o2fsck_test_inode_allocated(dd->ost, dbe->e_ino)) {
printf("Directory block %"PRIu64" belongs to directory inode "
"%"PRIu64" which isn't allocated. Ignoring this "
"block.", dbe->e_blkno, dbe->e_ino);
- return 0;
+ goto out;
}
if (dbe->e_ino != dd->last_ino) {
o2fsck_strings_free(&dd->strings);
dd->last_ino = dbe->e_ino;
+
+ ret = ocfs2_read_inode(dd->ost->ost_fs, dbe->e_ino,
+ dd->inoblock_buf);
+ if (ret) {
+ com_err(whoami, ret, "while reading dir inode %"PRIu64,
+ dbe->e_ino);
+ ret_flags |= OCFS2_DIRENT_ABORT;
+ goto out;
+ }
+
+ verbosef("dir inode %"PRIu64" i_size %"PRIu64"\n",
+ dbe->e_ino, di->i_size);
+
}
- ret = ocfs2_read_dir_block(dd->fs, dbe->e_blkno, dd->buf);
+ verbosef("dir block %"PRIu64" block offs %"PRIu64" in ino\n",
+ dbe->e_blkno, dbe->e_blkcount);
+
+ if (dbe->e_blkcount >= ocfs2_blocks_in_bytes(dd->fs, di->i_size))
+ goto out;
+
+ ret = ocfs2_read_dir_block(dd->fs, dbe->e_blkno, dd->dirblock_buf);
if (ret && ret != OCFS2_ET_DIR_CORRUPTED) {
com_err(whoami, ret, "while reading dir block %"PRIu64,
dbe->e_blkno);
goto out;
}
- /*
- * pass1 records all the blocks that have been allocated to the
- * dir so that it can verify i_clusters and make sure dirs don't
- * share blocks, etc. Unfortunately allocated blocks that are
- * beyond i_size aren't initialized.. we special case a block of
- * all 0s as an uninitialized dir block, though we don't actually
- * make sure that it's outside i_size.
- */
- if (nr_zeros(dd->buf, dd->fs->fs_blocksize) == dd->fs->fs_blocksize)
- return 0;
-
- verbosef("dir block %"PRIu64"\n", dbe->e_blkno);
-
while (offset < dd->fs->fs_blocksize) {
- dirent = (struct ocfs2_dir_entry *)(dd->buf + offset);
+ dirent = (struct ocfs2_dir_entry *)(dd->dirblock_buf + offset);
- verbosef("checking dirent offset %d, ino %"PRIu64" rec_len "
- "%"PRIu16" name_len %"PRIu8" file_type %"PRIu8"\n",
- offset, dirent->inode, dirent->rec_len,
+ verbosef("checking dirent offset %d, rec_len %"PRIu16" "
+ "name_len %"PRIu8" file_type %"PRIu8"\n",
+ offset, dirent->rec_len,
dirent->name_len, dirent->file_type);
/* XXX I wonder if we should be checking that the padding
@@ -735,7 +733,8 @@
}
if (ret_flags & OCFS2_DIRENT_CHANGED) {
- ret = ocfs2_write_dir_block(dd->fs, dbe->e_blkno, dd->buf);
+ ret = ocfs2_write_dir_block(dd->fs, dbe->e_blkno,
+ dd->dirblock_buf);
if (ret) {
com_err(whoami, ret, "while writing dir block %"PRIu64,
dbe->e_blkno);
@@ -751,8 +750,8 @@
errcode_t o2fsck_pass2(o2fsck_state *ost)
{
- errcode_t retval;
o2fsck_dir_parent *dp;
+ errcode_t ret;
struct dirblock_data dd = {
.ost = ost,
.fs = ost->ost_fs,
@@ -763,10 +762,20 @@
o2fsck_strings_init(&dd.strings);
- retval = ocfs2_malloc_block(ost->ost_fs->fs_io, &dd.buf);
- if (retval)
- return retval;
+ ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &dd.dirblock_buf);
+ if (ret) {
+ com_err(whoami, ret, "while allocating a block buffer to "
+ "store directory blocks.");
+ goto out;
+ }
+ ret = ocfs2_malloc_block(ost->ost_fs->fs_io, &dd.inoblock_buf);
+ if (ret) {
+ com_err(whoami, ret, "while allocating a block buffer to "
+ "store a directory inode.");
+ goto out;
+ }
+
/*
* Mark the root directory's dirent parent as itself if we found the
* inode during inode scanning. The dir will be created in pass3
@@ -786,6 +795,10 @@
o2fsck_dir_block_iterate(&ost->ost_dirblocks, pass2_dir_block_iterate,
&dd);
o2fsck_strings_free(&dd.strings);
- ocfs2_free(&dd.buf);
- return 0;
+out:
+ if (dd.dirblock_buf)
+ ocfs2_free(&dd.dirblock_buf);
+ if (dd.inoblock_buf)
+ ocfs2_free(&dd.inoblock_buf);
+ return ret;
}
More information about the Ocfs2-tools-commits
mailing list