From patchwork Thu Mar 16 15:39:48 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Whitney X-Patchwork-Id: 739902 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 3vkXh81MdDz9rxm for ; Fri, 17 Mar 2017 02:39:04 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HInqEqaC"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752886AbdCPPjB (ORCPT ); Thu, 16 Mar 2017 11:39:01 -0400 Received: from mail-qk0-f194.google.com ([209.85.220.194]:36181 "EHLO mail-qk0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752305AbdCPPjA (ORCPT ); Thu, 16 Mar 2017 11:39:00 -0400 Received: by mail-qk0-f194.google.com with SMTP id n141so6446107qke.3 for ; Thu, 16 Mar 2017 08:38:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=li8Hb4mKMm/LKwozS3e6GBY/KWQrOK5ieZxsqEn4VRU=; b=HInqEqaCh8JdWJq2EN4kabgqUbFH9sYbAEyzNDF2k4ZKgxL4AyFooUkm0m4SYjmdVS SP2rxVw7+iFg+zRNrw5DXIv//Ew8DHwHH5tI9Iz8xhnWoW9QBFHH+C4TMlFodhjH/xrE 43xSpRZg4uyjGyBl5GFLK4graU6zfPGMJRoJETfqn2zakKikIbgpChO0c+jEXgPHM31m Fx3ZTE9HOxA9hjXdQkrJPU7mLg9njK0qjycoDWrnvI+AFLurGcOnWwly8TOh1QNb4Ecw vIwVBTiXoP1uOikeqsc8O6FzHIb9zWent3cJmppR78q4DZwudjEQ9v+TPKXVr2sk6+44 O4DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=li8Hb4mKMm/LKwozS3e6GBY/KWQrOK5ieZxsqEn4VRU=; b=CBGRfa658YRSDbQ20zJOIfyaWfgPM91IkiD9l8lv4aPccmQIHuYdWl2QI8hX3/O7QD 8K6JtFp6EVgQw0qgB+cifRUQ7RnolmKpR5TonUrQX2Ocj+wHYD8NMKHFpOBJssL+q9sf mQT/AF2xDj3jjjsG/Bd4DfOIlGLosDYFptCUGkbXS3S4fQ+cGITYKpOzEHdIZWDdOAsd nLIGTBcrro49ATZ8UCv+RI4h++CsBa03GyBFcyN+EDUmN5ooskit3qz843pSALQquW+U 5QoFWSd3zwvu4DkMFxJzfUMWJWD1JFqbhD5fdL1+u3fm7mxOaQYjrX2veb/vNbIML/UH IoCg== X-Gm-Message-State: AFeK/H2QwFNL8zrXQYxDmIA95lRAYyyHVPxJP5HL2AaC4arV8K2KpfEYNx04dORojRFXlg== X-Received: by 10.55.4.146 with SMTP id 140mr9172853qke.23.1489678738478; Thu, 16 Mar 2017 08:38:58 -0700 (PDT) Received: from localhost.localdomain (c-73-60-235-182.hsd1.nh.comcast.net. [73.60.235.182]) by smtp.gmail.com with ESMTPSA id c6sm3881711qte.30.2017.03.16.08.38.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Mar 2017 08:38:57 -0700 (PDT) Date: Thu, 16 Mar 2017 11:39:48 -0400 From: Eric Whitney To: linux-ext4@vger.kernel.org Cc: tytso@mit.edu Subject: [PATCH] e2fsck: recreate extent mapped lost+found Message-ID: <20170316153948.GA20690@localhost.localdomain> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org When e2fsck recreates a missing lost+found directory, it uses indirect block mapping. It does this even if the file system being repaired is extent mapped and where the original lost+found was extent mapped when created by mkfs. This inconsistency exists because the kernel code handling indirect block mapping was considered more trustworthy in ext4's early days; today, the extent handling code is robust. This inconsistency also causes potential behavioral problems on bigalloc file systems. The ext4 kernel code does not support indirect block mapped directories when bigalloc is enabled. For example, it is not possible to extend lost+found on a mounted bigalloc file system with the current implementation, so the behavior of that directory differs from all others, potentially surprising users. To make the handling of lost+found more consistent, and to avoid behavioral problems on bigalloc file systems, recreate lost+found with extent mapping if the file system under repair is extent mapped. Signed-off-by: Eric Whitney --- e2fsck/pass3.c | 29 +++++++++++++++++++++++++++-- e2fsck/problem.c | 10 ++++++++++ e2fsck/problem.h | 6 ++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 44203ca..259c978 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -378,7 +378,7 @@ static int check_directory(e2fsck_t ctx, ext2_ino_t dir, ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) { ext2_filsys fs = ctx->fs; - ext2_ino_t ino; + ext2_ino_t ino; blk64_t blk; errcode_t retval; struct ext2_inode_large inode; @@ -386,6 +386,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) static const char name[] = "lost+found"; struct problem_context pctx; int will_rehash, flags; + ext2_extent_handle_t handle; if (ctx->lost_and_found) return ctx->lost_and_found; @@ -520,7 +521,10 @@ skip_new_block: inode.i_atime = inode.i_ctime = inode.i_mtime = ctx->now; inode.i_links_count = 2; ext2fs_iblk_set(fs, EXT2_INODE(&inode), 1); - inode.i_block[0] = blk; + if (ext2fs_has_feature_extents(fs->super)) + inode.i_flags |= EXT4_EXTENTS_FL; + else + inode.i_block[0] = blk; /* * Next, write out the inode. @@ -553,6 +557,27 @@ skip_new_block: } /* + * If the new lost+found is extent mapped, map its first new + * directory block + */ + if (ext2fs_has_feature_extents(fs->super)) { + retval = ext2fs_extent_open2(fs, ino, EXT2_INODE(&inode), + &handle); + if (retval) { + pctx.errcode = retval; + fix_problem(ctx, PR_3_ERR_LPF_OPEN_EXTENT, &pctx); + return 0; + } + retval = ext2fs_extent_set_bmap(handle, 0, blk, 0); + ext2fs_extent_free(handle); + if (retval) { + pctx.errcode = retval; + fix_problem(ctx, PR_3_ERR_LPF_SET_BMAP, &pctx); + return 0; + } + } + + /* * Finally, create the directory link */ pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR); diff --git a/e2fsck/problem.c b/e2fsck/problem.c index c3e4f6a..736b822 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -1791,6 +1791,16 @@ static struct e2fsck_problem problem_table[] = { N_("/@l is encrypted\n"), PROMPT_CLEAR, 0 }, + /* Error while creating an extent for /lost+found */ + { PR_3_ERR_LPF_OPEN_EXTENT, + N_("ext2fs_@x_open2: %m while creating an @x for /@l\n"), + PROMPT_NONE, 0 }, + + /* Error while mapping a directory block for /lost+found */ + { PR_3_ERR_LPF_SET_BMAP, + N_("ext2fs_@x_set_bmap: %m while mapping a @d @b for /@l\n"), + PROMPT_NONE, 0 }, + /* Pass 3A Directory Optimization */ /* Pass 3A: Optimizing directories */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index d291e26..dfdb6d0 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -1078,6 +1078,12 @@ struct problem_context { /* Lost+found is encrypted */ #define PR_3_LPF_ENCRYPTED 0x03001B +/* Error while creating an extent for /lost+found */ +#define PR_3_ERR_LPF_OPEN_EXTENT 0x03001C + +/* Error while mapping a directory block for /lost+found */ +#define PR_3_ERR_LPF_SET_BMAP 0x03001D + /* * Pass 3a --- rehashing diretories */