@@ -837,6 +837,22 @@ static errcode_t recover_ext3_journal(e2fsck_t ctx)
if (journal->j_superblock->s_errno) {
+ /* journal message buffer at journal super block + 1K */
+ char *buf = ((char *) journal->j_superblock) +
+ SUPERBLOCK_OFFSET;
+ int n, len = ctx->fs->blocksize - MSGBUF_OFFSET;
+
+ if (len >= MSGBUF_OFFSET && *buf) {
+ /* keep it simple - write in MSGBUF_OFFSET blocksize */
+ io_channel_set_blksize(ctx->fs->io, MSGBUF_OFFSET);
+ n = len / MSGBUF_OFFSET;
+ /* write journal message buffer to super block + 2K */
+ retval = io_channel_write_blk(ctx->fs->io, 1, n, buf);
+ io_channel_set_blksize(ctx->fs->io, ctx->fs->blocksize);
+ /* clear journal message buffer */
+ memset(buf, 0, len);
+ }
+
ctx->fs->super->s_state |= EXT2_ERROR_FS;
ext2fs_mark_super_dirty(ctx->fs);
journal->j_superblock->s_errno = 0;
@@ -452,6 +452,45 @@ static void e2fsck_fix_dirhash_hint(e2fsck_t ctx)
}
}
+/*
+ * This function prints the message buffer at the end of super block.
+ */
+static void e2fsck_print_message_buffer(e2fsck_t ctx)
+{
+ char *buf;
+ int n, len = ctx->fs->blocksize - MSGBUF_OFFSET;
+ unsigned offset = 0;
+ int retval;
+
+ if (len < MSGBUF_OFFSET)
+ /* 1K or 2K fs->blocksize */
+ return;
+
+ buf = (char *) e2fsck_allocate_memory(ctx, len, "message buffer");
+
+ /* keep it simple - write in MSGBUF_OFFSET blocksize */
+ io_channel_set_blksize(ctx->fs->io, MSGBUF_OFFSET);
+ n = len / MSGBUF_OFFSET;
+ /* read message buffer from super block + 2K */
+ retval = io_channel_read_blk(ctx->fs->io, 1, n, buf);
+ if (retval || !*buf)
+ goto out;
+
+ /* print messages in buffer */
+ puts("Error messages recorded in message buffer:");
+ while (offset < len && buf[offset]) {
+ puts(buf+offset);
+ offset += MSGBUF_RECLEN;
+ }
+ /* clear message buffer */
+ memset(buf, 0, len);
+ retval = io_channel_write_blk(ctx->fs->io, 2, 2, buf);
+ puts("End of message buffer.");
+out:
+ io_channel_set_blksize(ctx->fs->io, ctx->fs->blocksize);
+ ext2fs_free_mem(&buf);
+}
+
void check_super_block(e2fsck_t ctx)
{
@@ -874,6 +913,11 @@ void check_super_block(e2fsck_t ctx)
*/
e2fsck_fix_dirhash_hint(ctx);
+ /*
+ * Print message buffer if necessary
+ */
+ e2fsck_print_message_buffer(ctx);
+
return;
}
@@ -38,6 +38,12 @@ extern "C" {
*/
#define SUPERBLOCK_OFFSET 1024
#define SUPERBLOCK_SIZE 1024
+/*
+ * When blocksize > 2K, the space after the superblock is used as
+ * a buffer to record error messages (in 256 bytes records).
+ */
+#define MSGBUF_OFFSET (SUPERBLOCK_OFFSET+SUPERBLOCK_SIZE)
+#define MSGBUF_RECLEN 256
/*
* The last ext2fs revision level that this version of the library is