From patchwork Tue Mar 1 05:34:02 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 84895 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 70E4EB7148 for ; Tue, 1 Mar 2011 16:34:08 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752646Ab1CAFeE (ORCPT ); Tue, 1 Mar 2011 00:34:04 -0500 Received: from mail-qw0-f46.google.com ([209.85.216.46]:36909 "EHLO mail-qw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754672Ab1CAFeD (ORCPT ); Tue, 1 Mar 2011 00:34:03 -0500 Received: by qwd7 with SMTP id 7so3409291qwd.19 for ; Mon, 28 Feb 2011 21:34:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:date:message-id:subject:from:to:cc :content-type; bh=7D3q2HR1vCyaLGjNF3NpwQpJ3iAgvqB9kNKaVcpSh5w=; b=UD6MwoINosr0pCSy9Lyzo6zYiboiSUvz+6TipmLdVYbpwCDhc8IqV+otKvz2oD9iOU L+gbOkHvJyENe4ngWmNQ2bvDoroQEXaBnSwZA0UzZIT4/NADkh3kRfleH9wDuKlTaIV6 NrEWvU2ALVTkAI0lCdyDClKUtt/TpyVa7Ge8w= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:cc:content-type; b=fufC5Wv8+5Dhryepf4IiEzcljnhxUteRhrzmzdQ7hh6XlSIRAZWcrhkZLdKl/ZajYX SJN7PlVVfQPzHyTHWMeaMLjZdvh1bAUk7GocnT94rA1GyxKaaF+BordNzZrlsYMFTFVn d8itbM9FREdK5xzqjVUCWooezXws24rK5RNPA= MIME-Version: 1.0 Received: by 10.229.229.209 with SMTP id jj17mr4921665qcb.273.1298957642137; Mon, 28 Feb 2011 21:34:02 -0800 (PST) Received: by 10.229.96.71 with HTTP; Mon, 28 Feb 2011 21:34:02 -0800 (PST) Date: Tue, 1 Mar 2011 07:34:02 +0200 Message-ID: Subject: [PATCH] e2fsck: display recorded error messages From: Amir Goldstein To: Theodore Tso Cc: Ric Wheeler , Ext4 Developers List Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Hi Ted, This is the latest patch to go with ext4: record error messages in message buffer Amir. ---------- Forwarded message ---------- From: Amir Goldstein Date: Sat, Jan 8, 2011 at 10:06 PM Subject: Re: Regular ext4 error warning with HD in USB dock To: Ted Ts'o , Rogier Wolff Cc: Ric Wheeler , Con Kolivas , adilger.kernel@dilger.ca, linux-ext4@vger.kernel.org On Sat, Jan 8, 2011 at 10:05 AM, Rogier Wolff wrote: > On Fri, Jan 07, 2011 at 11:07:23PM +0200, Amir Goldstein wrote: >> On Fri, Jan 7, 2011 at 9:41 PM, Amir Goldstein wrote: >> > On Fri, Jan 7, 2011 at 7:26 AM, Ted Ts'o wrote: >> >> Am I missing something?  The kernel stores up to 3k worth of data, on >> >> a 4k block file system.  Whereas e2fsck patch blindly assume 2k worhth >> >> of data regardless of the block size.  The kernel patch looks ok, but >> >> the e2fsprogs patch seems badly broken.... >> >> So it's not badly broken, it copies blocksize-2K, which is clumsily >> written like this: >> +     int len = ctx->fs->blocksize - 2*SUPERBLOCK_OFFSET; > > So this should be: > >  int len = ctx->fs->blocksize - SUPERBLOCK_OFFSET - sizeof (); > > Although those two numbers are equal right now, there is no reason to > assume that they will remain so in the future. So if the superblock > size (or the offset) changes in the future, it's much better to have > programmed this so that it will keep on working as opposed to getting > to deal with ugly bugs in code that hasn't changed in years... > Very well, here is a less ugly version of the e2fsck patch: e2fsck: display recorded error messages Ext4 error messages are recorded in a message buffer after the journal super block.  After journal recovery, the journal message buffer is copied to the file system message buffer.  On fsck, if the message buffer is not empty, the recorded messages are printed to stdout and the buffer is cleared. Signed-off-by: Amir Goldstein diff --git a/e2fsck/journal.c b/e2fsck/journal.c index 93f685c..00d4d8f 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -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; diff --git a/e2fsck/super.c b/e2fsck/super.c index b6923c6..f3274df 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -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;  } diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index a204eb7..5b73c2a 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -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