[Ocfs2-tools-commits] zab commits r1034 - in trunk: fsck.ocfs2
libocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Wed Aug 10 12:12:22 CDT 2005
Author: zab
Signed-off-by: mfasheh
Signed-off-by: jlbec
Date: 2005-08-10 12:12:19 -0500 (Wed, 10 Aug 2005)
New Revision: 1034
Modified:
trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in
trunk/fsck.ocfs2/pass0.c
trunk/fsck.ocfs2/pass1.c
trunk/libocfs2/chainalloc.c
Log:
Check i_size in fsck.
o be sure to update i_size and i_clusters for chain allocator inodes as
groups are added and removed, both in fsck and libocfs2.
o check chain allocator i_size/i_clusters in pass0 as we validate the
allocators
o then only check i_size/i_clusters for inodes that have i_list in pass1
Signed-off-by: mfasheh
Signed-off-by: jlbec
Modified: trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in
===================================================================
--- trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in 2005-08-09 18:34:07 UTC (rev 1033)
+++ trunk/fsck.ocfs2/fsck.ocfs2.checks.8.in 2005-08-10 17:12:19 UTC (rev 1034)
@@ -183,6 +183,23 @@
Answering yes will remove the unused chain and shift the remaining chains
forward in the list.
+.SS "CHAIN_I_CLUSTERS"
+Chain allocator inodes have an i_clusters value that represents the number
+of clusters used by the allocator. An inode was found whose i_clusters
+value doesn't match the number of clusters its chains cover.
+
+Answering yes updates i_clusters in the inode to reflect what was actually
+found by walking the chain.
+
+.SS "CHAIN_I_SIZE"
+Chain allocator inodes multiply the number of bytes per cluster
+by the their i_clusters value and store it in i_size. An inode was found
+which didn't have the correct value in its i_size.
+
+Answering yes updates i_size to be the product of i_clusters and the cluster
+size. Nothing else uses this value, and previous versions of tools didn't
+calculate it properly, so don't be too worried if this error appears.
+
.SS "CHAIN_GROUP_BITS"
The inode that contains an embedded chain list has fields which record the
total number of bits covered by the chain as well as the amount free. These
@@ -423,6 +440,17 @@
Answering yes to this question clears the directorie's inode and so
deletes the directory.
+.SS "INODE_SIZE"
+Certain inodes record the size of the data they reference in an i_size field.
+This can be the number of bytes in a file, directory, or symlink target
+which are stored in data mapped by extents of clusters. This error occurs
+when the extent lists are walked and the amount of data found does not match
+what is stored in i_size.
+
+Answering yes to this question updates the inode's i_size to match the amount
+of data referenced by the extent lists. It is vitally important that i_size
+matches the extent lists and so answering yes is strongly encouraged.
+
.SS "INODE_CLUSTERS"
Inodes contain a record of how many clusters are allocated to them. An inode
was found whose recorded number of clusters doesn't match the number of blocks
Modified: trunk/fsck.ocfs2/pass0.c
===================================================================
--- trunk/fsck.ocfs2/pass0.c 2005-08-09 18:34:07 UTC (rev 1033)
+++ trunk/fsck.ocfs2/pass0.c 2005-08-10 17:12:19 UTC (rev 1034)
@@ -245,6 +245,8 @@
cr->c_total -= bg->bg_bits;
di->id1.bitmap1.i_used -= bg->bg_bits - bg->bg_free_bits_count;
di->id1.bitmap1.i_total -= bg->bg_bits;
+ di->i_clusters -= (bg->bg_bits / cl->cl_bpc);
+ di->i_size = (uint64_t)di->i_clusters * ost->ost_fs->fs_clustersize;
ret = ocfs2_write_inode(ost->ost_fs, di->i_blkno, (char *)di);
if (ret) {
@@ -451,6 +453,7 @@
uint32_t free = 0, total = 0;
int changed = 0, trust_next_free = 1;
errcode_t ret = 0;
+ uint64_t chain_bytes;
if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
strlen(OCFS2_INODE_SIGNATURE))) {
@@ -543,6 +546,7 @@
};
ret = check_chain(ost, di, &cs, cr, buf1, buf2, &changed,
allowed, forbidden);
+ /* XXX what? not checking ret? */
if (cr->c_blkno != 0) {
free += cs.cs_free_bits;
@@ -597,6 +601,30 @@
}
}
+ total /= cl->cl_bpc;
+
+ if (di->i_clusters != total &&
+ prompt(ost, PY, PR_CHAIN_I_CLUSTERS,
+ "Allocator inode %"PRIu64" has %"PRIu32" clusters "
+ "represtented in its allocator chains but has an "
+ "i_clusters value of %"PRIu32". Fix this by updating "
+ "i_clusters?", di->i_blkno, total, di->i_clusters)) {
+ di->i_clusters = total;
+ changed = 1;
+ }
+
+ chain_bytes = (uint64_t)total * ost->ost_fs->fs_clustersize;
+ if (di->i_size != chain_bytes &&
+ prompt(ost, PY, PR_CHAIN_I_SIZE,
+ "Allocator inode %"PRIu64" has %"PRIu32" clusters "
+ "represtented in its allocator chain which accounts for "
+ "%"PRIu64" total bytes, but its i_size is %"PRIu64". "
+ "Fix this by updating i_size?", di->i_blkno,
+ di->id1.bitmap1.i_total, chain_bytes, di->i_size)) {
+ di->i_size = chain_bytes;
+ changed = 1;
+ }
+
if (changed) {
ret = ocfs2_write_inode(ost->ost_fs, di->i_blkno, (char *)di);
if (ret) {
@@ -781,6 +809,9 @@
di->id1.bitmap1.i_used += bg->bg_bits - bg->bg_free_bits_count;
di->id1.bitmap1.i_total += bg->bg_bits;
+ di->i_clusters += (bg->bg_bits / di->id2.i_chain.cl_bpc);
+ di->i_size = (uint64_t)di->i_clusters *
+ ost->ost_fs->fs_clustersize;
ret = ocfs2_write_inode(ost->ost_fs, di->i_blkno, (char *)di);
if (ret) {
Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c 2005-08-09 18:34:07 UTC (rev 1033)
+++ trunk/fsck.ocfs2/pass1.c 2005-08-10 17:12:19 UTC (rev 1034)
@@ -698,22 +698,10 @@
return 0;
}
-/* XXX this is only really building up the vb data so that the caller can
- * verify the chain allocator inode's fields. I wonder if we shouldn't have
- * already done that in pass 0. */
-static int check_gd_block(ocfs2_filesys *fs, uint64_t gd_blkno, int chain_num,
- void *priv_data)
-{
- struct verifying_blocks *vb = priv_data;
- verbosef("found gd block %"PRIu64"\n", gd_blkno);
- /* XXX should arguably be verifying that pass 0 marked the group desc
- * blocks found */
- /* don't have bcount */
- vb_saw_block(vb, vb->vb_num_blocks);
- return 0;
-}
-
-
+/*
+ * this verifies i_size and i_clusters for inodes that use i_list to
+ * reference extents of data.
+ */
static errcode_t o2fsck_check_blocks(ocfs2_filesys *fs, o2fsck_state *ost,
uint64_t blkno, ocfs2_dinode *di)
{
@@ -724,28 +712,21 @@
.vb_di = di,
};
- /*
- * ISLNK && clusters == 0 is the only sign of an inode that doesn't
- * have an extent list when i_flags would have us believe it did.
- * We might be able to be very clever about discovering the
- * difference between i_symlink and i_list, but we don't try yet.
- */
- if (di->i_flags & OCFS2_LOCAL_ALLOC_FL ||
- di->i_flags & OCFS2_DEALLOC_FL)
- ret = 0;
- else if (di->i_flags & OCFS2_CHAIN_FL)
- ret = ocfs2_chain_iterate(fs, blkno, check_gd_block, &vb);
- else if (S_ISLNK(di->i_mode) && di->i_clusters == 0)
- ret = 0;
- else {
- ret = o2fsck_check_extents(ost, di);
- if (ret == 0)
- ret = ocfs2_block_iterate_inode(fs, di, 0,
- verify_block, &vb);
- if (vb.vb_ret)
- ret = vb.vb_ret;
- }
+ /* don't bother to verify for inodes that don't have i_list,
+ * we have to trust i_mode/i_clusters to tell us that a symlink
+ * has put target data in the union instead of i_list */
+ if ((di->i_flags & (OCFS2_SUPER_BLOCK_FL | OCFS2_LOCAL_ALLOC_FL |
+ OCFS2_BITMAP_FL | OCFS2_CHAIN_FL |
+ OCFS2_DEALLOC_FL)) ||
+ (S_ISLNK(di->i_mode) && di->i_clusters == 0))
+ return 0;
+ ret = o2fsck_check_extents(ost, di);
+ if (ret == 0)
+ ret = ocfs2_block_iterate_inode(fs, di, 0, verify_block, &vb);
+ if (vb.vb_ret)
+ ret = vb.vb_ret;
+
if (ret) {
com_err(whoami, ret, "while iterating over the blocks for "
"inode %"PRIu64, di->i_blkno);
@@ -778,19 +759,18 @@
/* XXX clear valid flag and stuff? */
}
-#if 0 /* boy, this is just broken */
if (vb.vb_num_blocks > 0)
expected = (vb.vb_last_block + 1) * fs->fs_blocksize;
/* i_size is checked for symlinks elsewhere */
if (!S_ISLNK(di->i_mode) && di->i_size > expected &&
- prompt(ost, PY, 0, "Inode %"PRIu64" has a size of %"PRIu64" but has "
- "%"PRIu64" bytes of actual data. Correct the file size?",
+ prompt(ost, PY, PR_INODE_SIZE, "Inode %"PRIu64" has a size of "
+ "%"PRIu64" but has %"PRIu64" bytes of actual data. "
+ "Correct the file size?",
di->i_blkno, di->i_size, expected)) {
di->i_size = expected;
o2fsck_write_inode(ost, blkno, di);
}
-#endif
if (vb.vb_num_blocks > 0)
expected = ocfs2_clusters_in_blocks(fs, vb.vb_last_block + 1);
Modified: trunk/libocfs2/chainalloc.c
===================================================================
--- trunk/libocfs2/chainalloc.c 2005-08-09 18:34:07 UTC (rev 1033)
+++ trunk/libocfs2/chainalloc.c 2005-08-10 17:12:19 UTC (rev 1034)
@@ -534,6 +534,8 @@
rec->c_blkno = blkno;
cinode->ci_inode->i_clusters += cinode->ci_inode->id2.i_chain.cl_cpg;
+ cinode->ci_inode->i_size = (uint64_t)cinode->ci_inode->i_clusters *
+ fs->fs_clustersize;
cinode->ci_inode->id1.bitmap1.i_total += gd->bg_bits;
cinode->ci_inode->id1.bitmap1.i_used += gd->bg_bits -
gd->bg_free_bits_count;
@@ -564,6 +566,8 @@
cinode->ci_inode->i_clusters -=
cinode->ci_inode->id2.i_chain.cl_cpg;
+ cinode->ci_inode->i_size = (uint64_t)cinode->ci_inode->i_clusters *
+ fs->fs_clustersize;
cinode->ci_inode->id1.bitmap1.i_total -= gd->bg_bits;
cinode->ci_inode->id1.bitmap1.i_used -= gd->bg_bits -
gd->bg_free_bits_count;
More information about the Ocfs2-tools-commits
mailing list