From patchwork Tue Jul 20 15:16:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 59327 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 1FE88B6EEA for ; Wed, 21 Jul 2010 01:17:42 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932340Ab0GTPRk (ORCPT ); Tue, 20 Jul 2010 11:17:40 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:42770 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932328Ab0GTPRh (ORCPT ); Tue, 20 Jul 2010 11:17:37 -0400 Received: by mail-ww0-f44.google.com with SMTP id 40so968910wwj.1 for ; Tue, 20 Jul 2010 08:17:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=4J5om3HGCqp6ZqqdJx8XSMtK4GqQdkoXTao2NMln1jg=; b=GbJ6fIJPSKoy3k9RdQ03tIgit1sFT/KXlyAW+f8COTbHSTgLT8XODzglDCDcOF6/Oj F+Wn6Mq58JerAUfhdvlrcWTDipWo1IBb72iU6huy9/kFoVj6h7QyVWtyrKD25TEUj68x rpdvCrHlQHS4cX2MItKz3eO/eoCgNWVb+ksVo= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=AKCF7tDIZJJEgOxDZbndemC1tlIVNyS97q0gVx8yuWR/mI2YGD3hP5/CjBxQrZciUa Vsnx8ucXvSA1TE1MKOHQA05ViBpnPtXGomms+TNb3gQg8FOoNAWQJJ5+GuBReP6jpF6p SLv4UQpR5i1WOPGhNIeuoTdtmmE+xa06sIMLM= Received: by 10.227.146.147 with SMTP id h19mr1566036wbv.222.1279639056330; Tue, 20 Jul 2010 08:17:36 -0700 (PDT) Received: from localhost.localdomain (bzq-218-153-66.cablep.bezeqint.net [81.218.153.66]) by mx.google.com with ESMTPS id b18sm47610461wbb.19.2010.07.20.08.17.34 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 20 Jul 2010 08:17:35 -0700 (PDT) From: Amir Goldstein To: tytso@mit.edu, andreas.dilger@oracle.com, jack@suse.cz Cc: linux-ext4@vger.kernel.org, Amir Goldstein Subject: [PATCH 08/12] e2fsprogs: Check Next3 snapshot list on fsck Date: Tue, 20 Jul 2010 18:16:09 +0300 Message-Id: <1279638973-14561-9-git-send-email-amir73il@users.sf.net> X-Mailer: git-send-email 1.6.6 In-Reply-To: <1279638973-14561-1-git-send-email-amir73il@users.sf.net> References: <1279638973-14561-1-git-send-email-amir73il@users.sf.net> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Check that all inodes on snapshot list are valid snapshots and prompt to terminate list when bad inode is found. Signed-off-by: Amir Goldstein --- e2fsck/problem.c | 11 ++++++- e2fsck/problem.h | 3 ++ e2fsck/super.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 0a2d31d..0b6b892 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -40,7 +40,8 @@ #define PROMPT_UNLINK 17 #define PROMPT_CLEAR_HTREE 18 #define PROMPT_RECREATE 19 -#define PROMPT_NULL 20 +#define PROMPT_TERMINATE_LIST 20 +#define PROMPT_NULL 22 /* * These are the prompts which are used to ask the user if they want @@ -67,7 +68,8 @@ static const char *prompt[] = { N_("Unlink"), /* 17 */ N_("Clear HTree index"),/* 18 */ N_("Recreate"), /* 19 */ - "", /* 20 */ + N_("Terminate list"), /* 20 */ + "", /* 22 */ }; /* @@ -342,6 +344,11 @@ static struct e2fsck_problem problem_table[] = { N_("Exclude @i not valid. "), PROMPT_RECREATE, 0 }, + /* Bad snapshot on list */ + { PR_0_BAD_SNAPSHOT, + N_("Bad @i found on snapshot list. "), + PROMPT_TERMINATE_LIST, PR_PREEN_OK }, + /* Last mount time is in the future */ { PR_0_FUTURE_SB_LAST_MOUNT, N_("@S last mount time (%t,\n\tnow = %T) is in the future.\n"), diff --git a/e2fsck/problem.h b/e2fsck/problem.h index da52597..1e63b52 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -234,6 +234,9 @@ struct problem_context { /* Exclude inode invalid */ #define PR_0_EXCLUDE_INODE_INVALID 0x000101 +/* Bas snapshot on list */ +#define PR_0_BAD_SNAPSHOT 0x000102 + /* * Pass 1 errors diff --git a/e2fsck/super.c b/e2fsck/super.c index a9cf0d9..8e24c18 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -516,6 +516,75 @@ void check_exclude_inode(e2fsck_t ctx) } /* + * Check that snapshot list contains valid snapshot files. + * Returns the number of valid snapshots on list. + * + * TODO: cleanup orphan snapshot files (not found on list) + */ +static int check_snapshot_list(e2fsck_t ctx) +{ + ext2_filsys fs = ctx->fs; + struct ext2_super_block *sb = fs->super; + struct ext2_inode inode; + struct ext2_inode inode_prev; + ext2_ino_t ino = sb->s_snapshot_list; + ext2_ino_t ino_prev = 0; + errcode_t retval = 0; + struct problem_context pctx; + int i = 0; + + if (!ino && sb->s_snapshot_inum) { + /* reset snapshot list head to active snapshot */ + ino = sb->s_snapshot_list = sb->s_snapshot_inum; + ext2fs_mark_super_dirty(fs); + } + if (ino) + fputs(_("Checking snapshots: "), stderr); + + while (ino) { + retval = ext2fs_read_inode(fs, ino, &inode); + if (retval || !(inode.i_flags & EXT4_SNAPFILE_FL) || + !LINUX_S_ISREG(inode.i_mode) || + inode.i_dtime) { + if (ino == sb->s_snapshot_list) { + /* reset list head */ + sb->s_snapshot_list = 0; + ext2fs_mark_super_dirty(fs); + ino = sb->s_snapshot_inum; + continue; + } + clear_problem_context(&pctx); + if (!fix_problem(ctx, PR_0_BAD_SNAPSHOT, &pctx)) + break; + + /* disconnect inode from snapshot list */ + if (ino == sb->s_snapshot_inum) { + /* reset active snapshot */ + sb->s_snapshot_inum = 0; + ext2fs_mark_super_dirty(fs); + } + if (ino_prev) { + /* terminate list at prev inode */ + inode_prev.i_next_snapshot = 0; + e2fsck_write_inode(ctx, ino_prev, &inode_prev, + "terminate snapshot list"); + } + break; + } + + fprintf(stderr, _("%u,"), inode.i_generation); + inode_prev = inode; + ino_prev = ino; + ino = inode.i_next_snapshot; + i++; + } + + if (ino_prev && !ino) + fputs(_("done\n"), stderr); + return i; +} + +/* * This function checks if the file system has snapshots */ void check_snapshots(e2fsck_t ctx) @@ -528,6 +597,10 @@ void check_snapshots(e2fsck_t ctx) /* no snapshots */ return; + if (!check_snapshot_list(ctx)) + /* no valid snapshots on list */ + return; + if (!sb->s_snapshot_inum) /* no active snapshot */ return;