+ _("returned from clone_file_block"));
+ retval = cs.errcode;
+ goto errout;
+ }
+ /* The inode may have changed on disk, so we have to re-read it */
+ e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
+ blk = ext2fs_file_acl_block(&dp->inode);
+ new_blk = blk;
+ if (blk && (clone_file_block(fs, &new_blk,
+ BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
+ BLOCK_CHANGED)) {
+ ext2fs_file_acl_block_set(&dp->inode, new_blk);
+ e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
+ /*
+ * If we cloned the EA block, find all other inodes
+ * which refered to that EA block, and modify
+ * them to point to the new EA block.
+ */
+ n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
+ if (!n) {
+ com_err("clone_file", 0,
+ _("internal error: couldn't lookup EA "
+ "block record for %llu"), blk);
+ retval = 0; /* OK to stumble on... */
+ goto errout;
+ }
+ db = (struct dup_block *) dnode_get(n);
+ for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
+ if (ino_el->inode == ino)
+ continue;
+ n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
+ if (!n) {
+ com_err("clone_file", 0,
+ _("internal error: couldn't lookup EA "
+ "inode record for %u"),
+ ino_el->inode);
+ retval = 0; /* OK to stumble on... */
+ goto errout;
+ }
+ di = (struct dup_inode *) dnode_get(n);
+ if (ext2fs_file_acl_block(&di->inode) == blk) {
+ ext2fs_file_acl_block_set(&di->inode,
+ ext2fs_file_acl_block(&dp->inode));
+ e2fsck_write_inode(ctx, ino_el->inode,
+ &di->inode, "clone file EA");
+ decrement_badcount(ctx, blk, db);
+ }
+ }
+ }
+ retval = 0;
+errout:
+ ext2fs_free_mem(&cs.buf);
+ return retval;
+}
+
+/*
+ * This routine returns 1 if a block overlaps with one of the superblocks,
+ * group descriptors, inode bitmaps, or block bitmaps.
+ */
+static int check_if_fs_block(e2fsck_t ctx, blk64_t test_block)
+{
+ ext2_filsys fs = ctx->fs;
+ blk64_t first_block;
+ dgrp_t i;
+
+ first_block = fs->super->s_first_data_block;
+ for (i = 0; i < fs->group_desc_count; i++) {
+
+ /* Check superblocks/block group descriptors */
+ if (ext2fs_bg_has_super(fs, i)) {
+ if (test_block >= first_block &&
+ (test_block <= first_block + fs->desc_blocks))
+ return 1;
+ }
+
+ /* Check the inode table */
+ if ((ext2fs_inode_table_loc(fs, i)) &&
+ (test_block >= ext2fs_inode_table_loc(fs, i)) &&
+ (test_block < (ext2fs_inode_table_loc(fs, i) +
+ fs->inode_blocks_per_group)))
+ return 1;
+
+ /* Check the bitmap blocks */
+ if ((test_block == ext2fs_block_bitmap_loc(fs, i)) ||
+ (test_block == ext2fs_inode_bitmap_loc(fs, i)))
+ return 1;
+
+ first_block += fs->super->s_blocks_per_group;