[Ocfs2-tools-commits] zab commits r387 - in trunk: fsck.ocfs2
fsck.ocfs2/include libocfs2 libocfs2/include
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Wed Nov 10 21:04:24 CST 2004
Author: zab
Date: 2004-11-10 21:04:23 -0600 (Wed, 10 Nov 2004)
New Revision: 387
Modified:
trunk/fsck.ocfs2/Makefile
trunk/fsck.ocfs2/icount.c
trunk/fsck.ocfs2/include/util.h
trunk/fsck.ocfs2/pass0.c
trunk/fsck.ocfs2/pass1.c
trunk/fsck.ocfs2/pass4.c
trunk/fsck.ocfs2/util.c
trunk/libocfs2/Makefile
trunk/libocfs2/bitmap.c
trunk/libocfs2/chainalloc.c
trunk/libocfs2/include/bitmap.h
Log:
o get rid of more fatal errors
o introduce some state when io fails so we can keep the fs dirty later
o be more careful when iterating over potentially uninitialized inodes
o yet more restrictive debugging
o remove the requirement of byte-alignment of bit regions in libocfs2.. mkfs
puts the system inode at block 4 and so its bitmap isn't byte aligned. the
fs may well do the same.
Modified: trunk/fsck.ocfs2/Makefile
===================================================================
--- trunk/fsck.ocfs2/Makefile 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/Makefile 2004-11-11 03:04:23 UTC (rev 387)
@@ -8,7 +8,7 @@
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
ifdef OCFS_DEBUG
-OPTS += -O -g
+OPTS += -ggdb
else
OPTS += -O2
endif
Modified: trunk/fsck.ocfs2/icount.c
===================================================================
--- trunk/fsck.ocfs2/icount.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/icount.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -117,16 +117,20 @@
{
icount_node *in;
int was_set;
+ uint16_t ret = 0;
ocfs2_bitmap_test(icount->ic_single_bm, blkno, &was_set);
- if (was_set)
- return 1;
+ if (was_set) {
+ ret = 1;
+ goto out;
+ }
in = icount_search(icount, blkno);
if (in)
- return in->in_icount;
+ ret = in->in_icount;
- return 0;
+out:
+ return ret;
}
/* again, simple before efficient. We just find the old value and
Modified: trunk/fsck.ocfs2/include/util.h
===================================================================
--- trunk/fsck.ocfs2/include/util.h 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/include/util.h 2004-11-11 03:04:23 UTC (rev 387)
@@ -25,6 +25,7 @@
#define __O2FSCK_UTIL_H__
#include <stdlib.h>
+#include "fsck.h"
/* we duplicate e2fsck's error codes to make everyone's life easy */
#define FSCK_OK 0 /* No errors */
@@ -42,7 +43,7 @@
exit(FSCK_ERROR); \
} while (0)
-void o2fsck_write_inode(ocfs2_filesys *fs, uint64_t blkno, ocfs2_dinode *di);
+void o2fsck_write_inode(o2fsck_state *ost, uint64_t blkno, ocfs2_dinode *di);
#endif /* __O2FSCK_UTIL_H__ */
Modified: trunk/fsck.ocfs2/pass0.c
===================================================================
--- trunk/fsck.ocfs2/pass0.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/pass0.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -302,7 +302,8 @@
cl = &di->id2.i_chain;
- verbosef("cl count %u next %u\n", cl->cl_count, cl->cl_next_free_rec);
+ verbosef("cl cpg %u bpc %u count %u next %u\n",
+ cl->cl_cpg, cl->cl_bpc, cl->cl_count, cl->cl_next_free_rec);
max_count = ocfs2_chain_recs_per_inode(ost->ost_fs->fs_blocksize);
Modified: trunk/fsck.ocfs2/pass1.c
===================================================================
--- trunk/fsck.ocfs2/pass1.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/pass1.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -167,7 +167,7 @@
"allocated?",
blkno, di->i_suballoc_node, node)) {
di->i_suballoc_node = node;
- o2fsck_write_inode(ost->ost_fs, di->i_blkno, di);
+ o2fsck_write_inode(ost, di->i_blkno, di);
}
out:
return;
@@ -193,12 +193,13 @@
/* XXX need to compare the lifetime of inodes (uninitialized?
* in use? orphaned? deleted? garbage?) to understand what
* fsck can do to fix it up */
- if (memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
- strlen(OCFS2_INODE_SIGNATURE)) &&
- prompt(ost, PY, "Inode %"PRIu64" doesn't have a valid signature. "
- "Clear it?", blkno)) {
- clear = 1;
- goto out;
+
+ if (di->i_blkno != blkno &&
+ prompt(ost, PY, "Inode read from block %"PRIu64" has i_blkno set "
+ "to %"PRIu64". Set the inode's i_blkno value to reflect "
+ "its location on disk?", blkno, di->i_blkno)) {
+ di->i_blkno = blkno;
+ o2fsck_write_inode(ost, blkno, di);
}
if (di->i_links_count)
@@ -215,14 +216,14 @@
o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno,
di->i_links_count);
- o2fsck_write_inode(fs, blkno, di);
+ o2fsck_write_inode(ost, blkno, di);
}
if (di->i_dtime && prompt(ost, PY, "Inode %"PRIu64" is in use but has "
"a non-zero dtime. Reset the dtime to 0?",
di->i_blkno)) {
di->i_dtime = 0ULL;
- o2fsck_write_inode(fs, blkno, di);
+ o2fsck_write_inode(ost, blkno, di);
}
if (S_ISDIR(di->i_mode)) {
@@ -247,7 +248,7 @@
out:
if (clear) {
di->i_flags &= ~OCFS2_SUPER_BLOCK_FL;
- o2fsck_write_inode(fs, blkno, di);
+ o2fsck_write_inode(ost, blkno, di);
}
}
@@ -342,7 +343,7 @@
"the length on disk?",
di->i_blkno, vb->vb_link_len, di->i_size)) {
di->i_size = vb->vb_link_len;
- o2fsck_write_inode(ost->ost_fs, di->i_blkno, di);
+ o2fsck_write_inode(ost, di->i_blkno, di);
return;
}
}
@@ -481,7 +482,7 @@
o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno,
di->i_links_count);
di->i_dtime = time(0);
- o2fsck_write_inode(fs, di->i_blkno, di);
+ o2fsck_write_inode(ost, di->i_blkno, di);
/* XXX clear valid flag and stuff? */
}
@@ -495,7 +496,7 @@
"%"PRIu64" bytes of actual data. Correct the file size?",
di->i_blkno, di->i_size, expected)) {
di->i_size = expected;
- o2fsck_write_inode(fs, blkno, di);
+ o2fsck_write_inode(ost, blkno, di);
}
#endif
@@ -507,7 +508,7 @@
"blocks fit in %"PRIu64" clusters. Correct the number of "
"clusters?", di->i_blkno, di->i_clusters, expected)) {
di->i_clusters = expected;
- o2fsck_write_inode(fs, blkno, di);
+ o2fsck_write_inode(ost, blkno, di);
}
}
@@ -549,6 +550,7 @@
ocfs2_dinode *di;
ocfs2_inode_scan *scan;
ocfs2_filesys *fs = ost->ost_fs;
+ int valid;
printf("Pass 1: Checking inodes and blocks.\n");
@@ -582,19 +584,23 @@
if (blkno == 0)
break;
+ valid = 0;
+
/* scanners have to skip over uninitialized inodes */
- if (di->i_flags & OCFS2_VALID_FL) {
+ if (!memcmp(di->i_signature, OCFS2_INODE_SIGNATURE,
+ strlen(OCFS2_INODE_SIGNATURE)) &&
+ di->i_flags & OCFS2_VALID_FL) {
o2fsck_verify_inode_fields(fs, ost, blkno, di);
/* XXX be able to mark the blocks in the inode as
* bad if the inode was bad */
o2fsck_check_blocks(fs, ost, blkno, di);
+ valid = di->i_flags & OCFS2_VALID_FL;
}
verbosef("blkno %"PRIu64" ino %"PRIu64"\n", blkno,
di->i_blkno);
- update_inode_alloc(ost, di, blkno,
- di->i_flags & OCFS2_VALID_FL);
+ update_inode_alloc(ost, di, blkno, valid);
}
if (ocfs2_bitmap_get_set_bits(ost->ost_dup_blocks))
Modified: trunk/fsck.ocfs2/pass4.c
===================================================================
--- trunk/fsck.ocfs2/pass4.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/pass4.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -73,7 +73,7 @@
di->i_links_count = refs;
o2fsck_icount_set(ost->ost_icount_in_inodes, di->i_blkno,
refs);
- o2fsck_write_inode(ost->ost_fs, di->i_blkno, di);
+ o2fsck_write_inode(ost, di->i_blkno, di);
}
out:
Modified: trunk/fsck.ocfs2/util.c
===================================================================
--- trunk/fsck.ocfs2/util.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/fsck.ocfs2/util.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -30,16 +30,23 @@
#include "util.h"
-void o2fsck_write_inode(ocfs2_filesys *fs, uint64_t blkno, ocfs2_dinode *di)
+void o2fsck_write_inode(o2fsck_state *ost, uint64_t blkno, ocfs2_dinode *di)
{
errcode_t ret;
+ char *whoami = "o2fsck_write_inode";
- if (blkno != di->i_blkno)
- fatal_error(0, "Asked to write inode with i_blkno %"PRIu64
- " to different block %"PRIu64".\n",
- di->i_blkno, blkno);
+ if (blkno != di->i_blkno) {
+ com_err(whoami, OCFS2_ET_INTERNAL_FAILURE, "when asked to "
+ "write an inode with an i_blkno of %"PRIu64" to block "
+ "%"PRIu64, di->i_blkno, blkno);
+ ost->ost_write_error = 1;
+ return;
+ }
- ret = ocfs2_write_inode(fs, blkno, (char *)di);
- if (ret)
- fatal_error(ret, "while writing inode %"PRIu64, di->i_blkno);
+ ret = ocfs2_write_inode(ost->ost_fs, blkno, (char *)di);
+ if (ret) {
+ com_err(whoami, ret, "while writing inode %"PRIu64,
+ di->i_blkno);
+ ost->ost_write_error = 1;
+ }
}
Modified: trunk/libocfs2/Makefile
===================================================================
--- trunk/libocfs2/Makefile 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/Makefile 2004-11-11 03:04:23 UTC (rev 387)
@@ -6,7 +6,7 @@
-Wmissing-declarations
ifdef OCFS_DEBUG
-OPTS += -O -g
+OPTS += -ggdb
else
OPTS += -O2
endif
Modified: trunk/libocfs2/bitmap.c
===================================================================
--- trunk/libocfs2/bitmap.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/bitmap.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -212,18 +212,9 @@
return ret;
}
-static void ocfs2_region_align(uint64_t *start_bit, int *total_bits)
+static size_t ocfs2_align_total(int total_bits)
{
- uint64_t byte_mask = ~7ULL;
-
- if (start_bit)
- *start_bit &= byte_mask;
-
- if (total_bits) {
- *total_bits += 7;
- *total_bits &= (int)byte_mask;
- }
-
+ return (total_bits + 7) / 8;
}
errcode_t ocfs2_bitmap_alloc_region(ocfs2_bitmap *bitmap,
@@ -237,16 +228,16 @@
if (total_bits < 0)
return OCFS2_ET_INVALID_BIT;
- ocfs2_region_align(&start_bit, &total_bits);
-
ret = ocfs2_malloc0(sizeof(struct ocfs2_bitmap_region), &br);
if (ret)
return ret;
+
+ br->br_bytes = ocfs2_align_total(total_bits);
br->br_start_bit = start_bit;
br->br_total_bits = total_bits;
- ret = ocfs2_malloc0(br->br_total_bits / 8, &br->br_bitmap);
+ ret = ocfs2_malloc0(br->br_bytes, &br->br_bitmap);
if (ret)
ocfs2_free(&br);
else
@@ -267,20 +258,20 @@
int total_bits)
{
errcode_t ret;
+ size_t new_bytes;
if ((br->br_start_bit + total_bits) > bitmap->b_total_bits)
return OCFS2_ET_INVALID_BIT;
- ocfs2_region_align(NULL, &total_bits);
+ new_bytes = ocfs2_align_total(total_bits);
- if (total_bits > br->br_total_bits) {
- ret = ocfs2_realloc0(total_bits / 8,
- &br->br_bitmap,
- br->br_total_bits / 8);
+ if (new_bytes > br->br_bytes) {
+ ret = ocfs2_realloc0(new_bytes, &br->br_bitmap, br->br_bytes);
if (ret)
return ret;
- br->br_total_bits = total_bits;
+ br->br_bytes = new_bytes;
}
+ br->br_total_bits = total_bits;
return 0;
}
@@ -315,7 +306,8 @@
{
errcode_t ret;
uint64_t new_bits;
- int prev_bits;
+ size_t prev_bytes;
+ uint8_t *pbm, *nbm, offset, diff;
if ((prev->br_start_bit + prev->br_total_bits) !=
next->br_start_bit)
@@ -330,15 +322,46 @@
if (new_bits > INT_MAX)
return OCFS2_ET_INVALID_BIT;
- prev_bits = prev->br_total_bits;
+ /* grab before realloc changes them */
+ prev_bytes = prev->br_bytes;
+ offset = prev->br_total_bits % 8;
+
ret = ocfs2_bitmap_realloc_region(bitmap, prev, (int)new_bits);
if (ret)
return ret;
- memcpy(prev->br_bitmap + (prev_bits / 8), next->br_bitmap,
- next->br_total_bits / 8);
+ /* if prev's last bit ends on a byte boundary then we can just
+ * copy everything over */
+ if (offset == 0) {
+ memcpy(prev->br_bitmap + prev_bytes, next->br_bitmap,
+ next->br_bytes);
+ goto done;
+ }
+
+ /* otherwise we have to shift next in. we're about to free
+ * next, so we consume it as we go. */
+ pbm = &prev->br_bitmap[prev_bytes - 1];
+ nbm = &next->br_bitmap[0];
+ diff = 8 - offset;
+ while(next->br_bytes-- && next->br_total_bits > 0) {
+ /* mask off just the offset bytes in the prev */
+ *pbm &= ((1 << offset) - 1);
+ /* move 'diff' LSB from next into prevs MSB */
+ *pbm |= (*nbm & ((1 << diff) - 1)) << offset;
+ pbm++;
+ next->br_total_bits -= diff;
+
+ if (next->br_total_bits > 0) {
+ /* then set prev's LSB to the next offset MSB. this relies
+ * on 0s being shifted into the MSB */
+ *pbm = *nbm >> diff;
+ nbm++;
+ next->br_total_bits -= offset;
+ }
+ }
+
+done:
prev->br_set_bits = prev->br_set_bits + next->br_set_bits;
-
rb_erase(&next->br_node, &bitmap->b_regions);
ocfs2_bitmap_free_region(next);
Modified: trunk/libocfs2/chainalloc.c
===================================================================
--- trunk/libocfs2/chainalloc.c 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/chainalloc.c 2004-11-11 03:04:23 UTC (rev 387)
@@ -94,7 +94,7 @@
cr->cr_ag = (ocfs2_group_desc *)gd_buf;
cb->cb_errcode = OCFS2_ET_CORRUPT_GROUP_DESC;
- if (cr->cr_ag->bg_bits % 8)
+ if (cr->cr_ag->bg_size != ocfs2_group_bitmap_size(fs->fs_blocksize))
goto out_free_cr;
cb->cb_errcode = ocfs2_bitmap_alloc_region(bitmap,
@@ -105,10 +105,8 @@
goto out_free_cr;
br->br_private = cr;
- memcpy(br->br_bitmap, cr->cr_ag->bg_bitmap,
- cr->cr_ag->bg_bits / 8);
- br->br_set_bits = cr->cr_ag->bg_bits -
- cr->cr_ag->bg_free_bits_count;
+ memcpy(br->br_bitmap, cr->cr_ag->bg_bitmap, br->br_bytes);
+ br->br_set_bits = cr->cr_ag->bg_bits - cr->cr_ag->bg_free_bits_count;
cb->cb_errcode = ocfs2_bitmap_insert_region(bitmap, br);
if (cb->cb_errcode)
@@ -152,12 +150,10 @@
ocfs2_filesys *fs = private_data;
errcode_t ret = 0;
- printf("want to write desc %"PRIu64"\n", cr->cr_ag->bg_blkno);
-
if (!cr->cr_dirty)
return 0;
- memcpy(cr->cr_ag->bg_bitmap, br->br_bitmap, cr->cr_ag->bg_bits / 8);
+ memcpy(cr->cr_ag->bg_bitmap, br->br_bitmap, br->br_bytes);
ret = ocfs2_write_group_desc(fs, cr->cr_ag->bg_blkno,
(char *)cr->cr_ag);
Modified: trunk/libocfs2/include/bitmap.h
===================================================================
--- trunk/libocfs2/include/bitmap.h 2004-11-11 00:36:56 UTC (rev 386)
+++ trunk/libocfs2/include/bitmap.h 2004-11-11 03:04:23 UTC (rev 387)
@@ -32,11 +32,11 @@
struct ocfs2_bitmap_region {
struct rb_node br_node;
- uint64_t br_start_bit; /* Bit offset. Must be
- byte-aligned */
+ uint64_t br_start_bit; /* Bit offset. */
int br_total_bits; /* set_bit() and friends can't
handle bitmaps larger than
int offsets */
+ size_t br_bytes;
int br_set_bits;
char *br_bitmap;
void *br_private;
More information about the Ocfs2-tools-commits
mailing list