-
- pb.ino = dp->ino;
- pb.dup_blocks = dp->num_dupblocks;
-
- retval = ext2fs_block_iterate(fs, dp->ino, 0, block_buf,
- delete_file_block, &pb);
- if (retval)
- com_err("delete_file", retval,
- "while calling ext2fs_block_iterate for inode %d",
- dp->ino);
- ext2fs_unmark_inode_bitmap(inode_used_map, dp->ino);
- ext2fs_unmark_inode_bitmap(inode_dir_map, dp->ino);
- if (inode_bad_map)
- ext2fs_unmark_inode_bitmap(inode_bad_map, dp->ino);
- ext2fs_unmark_inode_bitmap(fs->inode_map, dp->ino);
- ext2fs_mark_ib_dirty(fs);
- ext2fs_mark_bb_dirty(fs);
- e2fsck_read_inode(fs, dp->ino, &inode, "delete_file");
- inode.i_links_count = 0;
- inode.i_dtime = time(0);
- e2fsck_write_inode(fs, dp->ino, &inode, "delete_file");
+ struct problem_context pctx;
+ unsigned int count;
+
+ clear_problem_context(&pctx);
+ pctx.ino = pb.ino = ino;
+ pb.dup_blocks = 0;
+ pb.ctx = ctx;
+ pctx.str = "delete_file";
+ pb.cur_cluster = ~0;
+
+ e2fsck_read_inode(ctx, ino, &inode, "delete_file");
+ if (ext2fs_inode_has_valid_blocks2(fs, &inode))
+ pctx.errcode = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY,
+ block_buf, delete_file_block, &pb);
+ if (pctx.errcode)
+ fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
+ if (ctx->inode_bad_map)
+ ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino);
+ ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
+ quota_data_sub(ctx->qctx, &inode, ino, pb.dup_blocks * fs->blocksize);
+ quota_data_inodes(ctx->qctx, &inode, ino, -1);
+
+ /* Inode may have changed by block_iterate, so reread it */
+ e2fsck_read_inode(ctx, ino, &inode, "delete_file");
+ e2fsck_clear_inode(ctx, ino, &inode, 0, "delete_file");
+ if (ext2fs_file_acl_block(fs, &inode) &&
+ (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
+ count = 1;
+ pctx.errcode = ext2fs_adjust_ea_refcount2(fs,
+ ext2fs_file_acl_block(fs, &inode),
+ block_buf, -1, &count);
+ if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
+ pctx.errcode = 0;
+ count = 1;
+ }
+ if (pctx.errcode) {
+ pctx.blk = ext2fs_file_acl_block(fs, &inode);
+ fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
+ }
+ /*
+ * If the count is zero, then arrange to have the
+ * block deleted. If the block is in the block_dup_map,
+ * also call delete_file_block since it will take care
+ * of keeping the accounting straight.
+ */
+ if ((count == 0) ||
+ ext2fs_test_block_bitmap2(ctx->block_dup_map,
+ ext2fs_file_acl_block(fs, &inode))) {
+ blk64_t blk = ext2fs_file_acl_block(fs, &inode);
+ delete_file_block(fs, &blk,
+ BLOCK_COUNT_EXTATTR, 0, 0, &pb);
+ ext2fs_file_acl_block_set(fs, &inode, blk);
+ quota_data_sub(ctx->qctx, &inode, ino, fs->blocksize);
+ }
+ }