static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs, struct out_dir *outdir, ext2_ino_t ino, int compress) { struct write_dir_struct wd; errcode_t retval; struct ext2_inode inode; retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num); if (retval) return retval; wd.outdir = outdir; wd.err = 0; wd.ctx = ctx; wd.cleared = 0; retval = ext2fs_block_iterate2(fs, ino, 0, 0, write_dir_block, &wd); if (retval) return retval; if (wd.err) return wd.err; e2fsck_read_inode(ctx, ino, &inode, "rehash_dir"); if (compress) inode.i_flags &= ~EXT2_INDEX_FL; else inode.i_flags |= EXT2_INDEX_FL; inode.i_size = outdir->num * fs->blocksize; ext2fs_iblk_sub_blocks(fs, &inode, wd.cleared); e2fsck_write_inode(ctx, ino, &inode, "rehash_dir"); return 0; }
/* * This routine will connect a file to lost+found */ int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino) { ext2_filsys fs = ctx->fs; errcode_t retval; char name[80]; struct problem_context pctx; struct ext2_inode inode; int file_type = 0; clear_problem_context(&pctx); pctx.ino = ino; if (!ctx->bad_lost_and_found && !ctx->lost_and_found) { if (e2fsck_get_lost_and_found(ctx, 1) == 0) ctx->bad_lost_and_found++; } if (ctx->bad_lost_and_found) { fix_problem(ctx, PR_3_NO_LPF, &pctx); return 1; } sprintf(name, "#%u", ino); if (ext2fs_read_inode(fs, ino, &inode) == 0) file_type = ext2_file_type(inode.i_mode); retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type); if (retval == EXT2_ET_DIR_NO_SPACE) { if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx)) return 1; retval = e2fsck_expand_directory(ctx, ctx->lost_and_found, 1, 0); if (retval) { pctx.errcode = retval; fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx); return 1; } retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type); } if (retval) { pctx.errcode = retval; fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx); return 1; } e2fsck_adjust_inode_count(ctx, ino, 1); return 0; }
static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs, struct out_dir *outdir, ext2_ino_t ino, struct ext2_inode *inode, int compress) { struct write_dir_struct wd; errcode_t retval; retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num); if (retval) return retval; wd.outdir = outdir; wd.err = 0; wd.ino = ino; wd.ctx = ctx; wd.dir = ino; retval = ext2fs_block_iterate3(fs, ino, 0, NULL, write_dir_block, &wd); if (retval) return retval; if (wd.err) return wd.err; e2fsck_read_inode(ctx, ino, inode, "rehash_dir"); if (compress) inode->i_flags &= ~EXT2_INDEX_FL; else inode->i_flags |= EXT2_INDEX_FL; #ifdef REHASH_DEBUG printf("%u: set inode size to %u blocks = %u bytes\n", ino, outdir->num, outdir->num * fs->blocksize); #endif retval = ext2fs_inode_size_set(fs, inode, (ext2_off64_t)outdir->num * fs->blocksize); if (retval) return retval; /* ext2fs_punch() calls ext2fs_write_inode() which writes the size */ return ext2fs_punch(fs, ino, inode, NULL, outdir->num, ~0ULL); }