+2000-08-20 <tytso@valinux.com>
+
+ * journal.c (e2fsck_journal_load): Fix **nasty** bug which caused
+ e2fsck_check_ext3_journal to smash the journal because
+ journal->j_transaction_sequence wasn't getting
+ initialized.
+
+ * journal.c: (recover_ext3_journal, e2fsck_run_ext3_journal): Move
+ call to e2fsck_clear_recover from recover_ext3_journal to
+ after the filesystem has been closed and reopened.
+ Otherwise, the superblock in the filesystem handle will
+ probably be stale, and will overwrite the newer version of
+ the superblock written by the log recovery.
+
+ * message.c (expand_inode_expression): Add support for %Iu and %Ig
+
+ * problem.h (PR_0_CLEAR_ORPHAN_INODE): Add new problem code.
+
+ * super.c (release_orphan_inodes, release_inode_block,
+ release_inode_blocks): Update the block group descriptor
+ counts when freeing the orphan inode. Use
+ PR_0_CLEAR_ORPHAN_INODE to report when we clear an orphan.
+
+ * journal.c (e2fsck_run_ext3_journal): Fix a bug where we
+ attempted to reopen the filesystem using the device name
+ instead of the filesystem name.
+
2000-08-18 <tytso@valinux.com>
* Makefile.in: Update the make dependencies
}
journal->j_tail_sequence = ntohl(jsb->s_sequence);
+ journal->j_transaction_sequence = journal->j_tail_sequence;
journal->j_tail = ntohl(jsb->s_start);
journal->j_first = ntohl(jsb->s_first);
journal->j_last = ntohl(jsb->s_maxlen);
retval = e2fsck_get_journal(ctx, &journal);
if (retval)
- goto exit;
+ return retval;
+
retval = e2fsck_journal_load(journal);
if (retval)
- goto exit;
+ return retval;
retval = -journal_recover(journal);
-
e2fsck_journal_release(ctx, journal, 1);
- if (retval)
- goto exit;
-
-exit:
- e2fsck_clear_recover(ctx, retval);
return retval;
}
{
io_manager io_ptr = ctx->fs->io->manager;
int blocksize = ctx->fs->blocksize;
- errcode_t retval;
+ errcode_t retval, recover_retval;
- if ((retval = recover_ext3_journal(ctx)))
- return retval;
+ if (ctx->options & E2F_OPT_READONLY) {
+ printf("%s: won't do journal recovery while read-only\n",
+ ctx->device_name);
+ return EXT2_ET_FILE_RO;
+ }
+
+ recover_retval = recover_ext3_journal(ctx);
/*
* Reload the filesystem context to get up-to-date data from disk
* because journal recovery will change the filesystem under us.
*/
ext2fs_close(ctx->fs);
- retval = ext2fs_open(ctx->device_name, EXT2_FLAG_RW,
+ retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
ctx->superblock, blocksize, io_ptr,
&ctx->fs);
}
ctx->fs->priv_data = ctx;
- return 0;
+ /* Set the superblock flags */
+ e2fsck_clear_recover(ctx, recover_retval);
+ return recover_retval;
}
* %IF <inode> -> i_faddr
* %If <inode> -> i_file_acl
* %Id <inode> -> i_dir_acl
+ * %Iu <inode> -> i_uid
+ * %Ig <inode> -> i_gid
* %j <ino2> inode number
* %m <com_err error message>
* %N <num>
}
/*
- * This function expands '%kX' expressions
+ * This function expands '%IX' expressions
*/
static _INLINE_ void expand_inode_expression(char ch,
struct problem_context *ctx)
printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
inode->i_dir_acl : 0));
break;
+ case 'u':
+ printf("%d", (inode->i_uid |
+ (inode->osd2.linux2.l_i_uid_high << 16)));
+ break;
+ case 'g':
+ printf("%d", (inode->i_gid |
+ (inode->osd2.linux2.l_i_gid_high << 16)));
+ break;
default:
no_inode:
printf("%%I%c", ch);
N_("ext3 recovery flag clear, but journal has data.\n"),
PROMPT_CLEAR, PR_PREEN_OK|PR_PREEN_NOMSG },
+ /* Clearing orphan inode */
+ { PR_0_CLEAR_ORPHAN_INODE,
+ N_("Clearing @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
+ PROMPT_NONE, 0 },
+
/* Illegal block found in orphaned inode */
{ PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
N_("@I @b #%B (%b) found in @o @i %i.\n"),
/* Superblock recovery flag clear - journal needs to be reset */
#define PR_0_JOURNAL_RESET_PROMPT 0x000019
+/* Clearing orphan inode */
+#define PR_0_CLEAR_ORPHAN_INODE 0x000020
+
/* Illegal block found in orphaned inode */
-#define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000020
+#define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021
/* Already cleared block found in orphaned inode */
-#define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000021
+#define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022
/* Illegal orphan inode in superblock */
-#define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000022
+#define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023
/* Illegal inode in orphaned inode list */
-#define PR_0_ORPHAN_ILLEGAL_INODE 0x000023
+#define PR_0_ORPHAN_ILLEGAL_INODE 0x000024
/* Orphan inode has a non-zero link count */
-#define PR_0_ORPHAN_INODE_INUSE 0x000024
+#define PR_0_ORPHAN_INODE_INUSE 0x000025
-
/*
* Pass 1 errors
*/
}
ext2fs_unmark_block_bitmap(fs->block_map, blk);
+ fs->group_desc[ext2fs_group_of_blk(fs, blk)].bg_free_blocks_count++;
+ fs->super->s_free_blocks_count++;
return 0;
}
if (pb.abort)
return 1;
- ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
- ext2fs_mark_ib_dirty(fs);
ext2fs_mark_bb_dirty(fs);
return 0;
}
static int release_orphan_inodes(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
+ int group;
ino_t ino, next_ino;
struct ext2_inode inode;
struct problem_context pctx;
e2fsck_read_bitmaps(ctx);
while (ino) {
-#ifdef JFS_DEBUG
- printf("Clearing orphan inode %d\n", ino);
-#endif
-
e2fsck_read_inode(ctx, ino, &inode, "delete_file");
clear_problem_context(&pctx);
- pctx.ino;
+ pctx.ino = ino;
pctx.inode = &inode;
+ fix_problem(ctx, PR_0_CLEAR_ORPHAN_INODE, &pctx);
+
if (inode.i_links_count) {
fix_problem(ctx, PR_0_ORPHAN_INODE_INUSE, &pctx);
goto abort;
inode.i_dtime = time(0);
e2fsck_write_inode(ctx, ino, &inode, "delete_file");
+
+ ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
+ ext2fs_mark_ib_dirty(fs);
+ group = ext2fs_group_of_ino(fs, ino);
+ fs->group_desc[group].bg_free_inodes_count++;
+ fs->super->s_free_inodes_count++;
+ if (LINUX_S_ISDIR(inode.i_mode))
+ fs->group_desc[group].bg_used_dirs_count--;
+
ino = next_ino;
}
return 0;