+ /* The inode may have changed on disk, so we have to re-read it */
+ e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&dp->inode),
+ sizeof(dp->inode), "clone file EA");
+ blk = ext2fs_file_acl_block(fs, EXT2_INODE(&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(fs, EXT2_INODE(&dp->inode), new_blk);
+ e2fsck_write_inode_full(ctx, ino, EXT2_INODE(&dp->inode),
+ sizeof(dp->inode), "clone file EA");
+ /*
+ * If we cloned the EA block, find all other inodes
+ * which referred to that EA block, and modify
+ * them to point to the new EA block.
+ */
+ n = dict_lookup(&clstr_dict,
+ INT_TO_VOIDPTR(EXT2FS_B2C(fs, 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;
+ }
+ dc = (struct dup_cluster *) dnode_get(n);
+ for (ino_el = dc->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(fs,
+ EXT2_INODE(&di->inode)) == blk) {
+ ext2fs_file_acl_block_set(fs,
+ EXT2_INODE(&di->inode),
+ ext2fs_file_acl_block(fs, EXT2_INODE(&dp->inode)));
+ e2fsck_write_inode_full(ctx, ino_el->inode,
+ EXT2_INODE(&di->inode),
+ sizeof(di->inode), "clone file EA");
+ decrement_badcount(ctx, blk, dc);
+ }
+ }
+ }
+ retval = 0;
+errout:
+ ext2fs_free_mem(&cs.buf);
+ return retval;