From patchwork Wed Jun 16 10:57:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492879 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=B7TVgy9P; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=1wqHALJ9; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwq6FFtz9sWl for ; Wed, 16 Jun 2021 20:57:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231490AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from smtp-out2.suse.de ([195.135.220.29]:35792 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231294AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id 9867D1FD49; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X7pU2ek3/cmj0H8tjQ1+AqDwww25R7hx11P5k70j6k4=; b=B7TVgy9PYDxMRFOoe63qqSZb6ENUUueJ4wIArxNa3w/4oeGXudJaCBLphaUmESJc+vyLD6 AOA/rVb9kVy3wRk7UsRaNJY1tTjyi2koAqggxF7qvLHmTO31y81rksDxOm95Ii6IihO1M3 pyXF2AboOqxfTJhmuKNi22/AFKMGcio= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X7pU2ek3/cmj0H8tjQ1+AqDwww25R7hx11P5k70j6k4=; b=1wqHALJ9lGxd3iE2uJQM0jJtMzgAaFKX2+hDZASskFqd7tjyWodazoB3r9VJ9JRoVI501s EzOQZZFysh4JTABQ== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id 863B9A3B81; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 5CD531F2CB9; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 1/9] ext2fs: Drop HAS_SNAPSHOT feature Date: Wed, 16 Jun 2021 12:57:27 +0200 Message-Id: <20210616105735.5424-2-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org It has never been implemented and is dead for quite some time and unused AFAICT. Signed-off-by: Jan Kara --- lib/ext2fs/ext2_fs.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index e92a045205a9..6f1d5db4b482 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -825,7 +825,6 @@ struct ext2_super_block { #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 -#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 /* @@ -926,7 +925,6 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(huge_file, 4, HUGE_FILE) EXT4_FEATURE_RO_COMPAT_FUNCS(gdt_csum, 4, GDT_CSUM) EXT4_FEATURE_RO_COMPAT_FUNCS(dir_nlink, 4, DIR_NLINK) EXT4_FEATURE_RO_COMPAT_FUNCS(extra_isize, 4, EXTRA_ISIZE) -EXT4_FEATURE_RO_COMPAT_FUNCS(has_snapshot, 4, HAS_SNAPSHOT) EXT4_FEATURE_RO_COMPAT_FUNCS(quota, 4, QUOTA) EXT4_FEATURE_RO_COMPAT_FUNCS(bigalloc, 4, BIGALLOC) EXT4_FEATURE_RO_COMPAT_FUNCS(metadata_csum, 4, METADATA_CSUM) From patchwork Wed Jun 16 10:57:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492878 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=ncy9UNxj; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=3XrAraFO; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwq39Ckz9sW8 for ; Wed, 16 Jun 2021 20:57:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231474AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from smtp-out1.suse.de ([195.135.220.28]:40674 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230442AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id 9FF0F219D6; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=o5rEfG7aB6VAs4bnjkgZIQtiuA8OYJfyMHGtZHye36Y=; b=ncy9UNxj917KET6VfA0a57n8LT49kb97BqozHwm9AEje8UM8Ba1WXmnHKT6vLgP8AM89Rs 1JW6wf4ARvMxOrg/PXrWGFMVSFHoAab/ysLQ7Giy+QhbUm8jSWkNntaHcUhOwvWWSVFQT8 pzYSvC4cfzs1OIuKW++aBW6SIqqWy44= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=o5rEfG7aB6VAs4bnjkgZIQtiuA8OYJfyMHGtZHye36Y=; b=3XrAraFOgtk5TXogf2pmNKaBftjIYeHm1WHBJhbOJMJnrSFBo5fD/kGBze1vHIXXzS4ZkP aEDugAsQMkNUhVAw== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id 8A577A3BAA; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 5FC751F2CBA; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 2/9] quota: Do not account space used by project quota file to quota Date: Wed, 16 Jun 2021 12:57:28 +0200 Message-Id: <20210616105735.5424-3-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Project quota files have high inode numbers but are not accounted in quota usage. Do not track them when computing quota usage. Signed-off-by: Jan Kara --- lib/support/mkquota.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/support/mkquota.c b/lib/support/mkquota.c index fbc3833aee98..21a5c34d6921 100644 --- a/lib/support/mkquota.c +++ b/lib/support/mkquota.c @@ -500,9 +500,11 @@ errcode_t quota_compute_usage(quota_ctx_t qctx) } if (ino == 0) break; - if (inode->i_links_count && - (ino == EXT2_ROOT_INO || - ino >= EXT2_FIRST_INODE(fs->super))) { + if (!inode->i_links_count) + continue; + if (ino == EXT2_ROOT_INO || + (ino >= EXT2_FIRST_INODE(fs->super) && + ino != quota_type2inum(PRJQUOTA, fs->super))) { space = ext2fs_get_stat_i_blocks(fs, EXT2_INODE(inode)) << 9; quota_data_add(qctx, inode, ino, space); From patchwork Wed Jun 16 10:57:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492881 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=ZlLzdity; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=HHe81ALt; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwr439Qz9sf8 for ; Wed, 16 Jun 2021 20:57:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231618AbhFPK7x (ORCPT ); Wed, 16 Jun 2021 06:59:53 -0400 Received: from smtp-out1.suse.de ([195.135.220.28]:40686 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231311AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id A87A7219E4; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uO8dUp84n6yNDrm8gJ+4XYzi8C4FmWVx7RQ+DqaFXY0=; b=ZlLzdityhxvSQbMHzPtv8x+YRFKP6QJwQ5SZiH8KU3ABc0Sdywjs0gInJSUOlfo+J1bl40 MjrT8DMfcvrH8PKKaOLZMQHlT3VPWwHwunaUeAK+kmVpZtZmCnaC0tBaWFaE6x755AeTSh Rib8r8r5oXcsvR0bPMwAzsut0lex5ko= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uO8dUp84n6yNDrm8gJ+4XYzi8C4FmWVx7RQ+DqaFXY0=; b=HHe81ALtElFoC4Nwl3DYuZ+zkGhAkK9RN+nJMuHGIMazN22WY9jMsu5zosi7u+tpm/fjL3 IZ/1M2JbIgHn0LCg== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id 8A4D1A3BA9; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 62D4D1F2CBB; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 3/9] e2image: Dump quota files Date: Wed, 16 Jun 2021 12:57:29 +0200 Message-Id: <20210616105735.5424-4-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Dump quota files to resulting filesystem image. They are fs metadata. Signed-off-by: Jan Kara --- misc/e2image.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/misc/e2image.c b/misc/e2image.c index 90a34bebc36d..ac00827e4628 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -52,6 +52,7 @@ extern int optind; #include "support/nls-enable.h" #include "support/plausible.h" +#include "support/quotaio.h" #include "../version.h" #define QCOW_OFLAG_COPIED (1ULL << 63) @@ -1364,9 +1365,11 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags, pb.ino = ino; pb.is_dir = LINUX_S_ISDIR(inode.i_mode); if (LINUX_S_ISDIR(inode.i_mode) || - (LINUX_S_ISLNK(inode.i_mode) && - ext2fs_inode_has_valid_blocks2(fs, &inode)) || - ino == fs->super->s_journal_inum) { + LINUX_S_ISLNK(inode.i_mode) || + ino == fs->super->s_journal_inum || + ino == quota_type2inum(USRQUOTA, fs->super) || + ino == quota_type2inum(GRPQUOTA, fs->super) || + ino == quota_type2inum(PRJQUOTA, fs->super)) { retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, process_dir_block, &pb); From patchwork Wed Jun 16 10:57:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492884 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=hR8qGDOh; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=hvrTsa5r; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwt2lVcz9sf9 for ; Wed, 16 Jun 2021 20:57:50 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231698AbhFPK7y (ORCPT ); Wed, 16 Jun 2021 06:59:54 -0400 Received: from smtp-out1.suse.de ([195.135.220.28]:40694 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231326AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id AD98121A4E; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Zs3eFdvrR/1ZmbFo0Ij2w6Oqe8l4cpvAONaHyU0TsDI=; b=hR8qGDOhsaLhBEBx4b4R0O9IoHiiMLL6LyQrO9WvNFul00PNVVALbUf0GVh6inTirPKFrC YNW+c2JosOxAQEXwOY9McXXh1kawK5Tz4d4aGy4bze2FUs8UC8iCm3ovUhutH/85dkFsWO i5+sZ8xTqNM7ZJnQ6Wrww1BnZ2KpFTQ= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Zs3eFdvrR/1ZmbFo0Ij2w6Oqe8l4cpvAONaHyU0TsDI=; b=hvrTsa5rjMvKCYSDuaN2BLVUH8MQzj1MIdGzqykP+Wbwf0TrnvaVs3kfON/2+QcTIaaKI3 jGzEPssOVIUp0mCw== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id 896CDA3BA8; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 678801F2CBC; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 4/9] libext2fs: Support for orphan file feature Date: Wed, 16 Jun 2021 12:57:30 +0200 Message-Id: <20210616105735.5424-5-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Add support for creating and deleting orphan file and a couple of utility functions that will be used in other tools. Signed-off-by: Jan Kara --- lib/e2p/feature.c | 4 + lib/ext2fs/Makefile.in | 2 + lib/ext2fs/ext2_fs.h | 16 ++- lib/ext2fs/ext2fs.h | 32 ++++- lib/ext2fs/orphan.c | 252 ++++++++++++++++++++++++++++++++++++ lib/ext2fs/swapfs.c | 3 +- lib/ext2fs/tst_super_size.c | 3 +- lib/support/mkquota.c | 3 +- 8 files changed, 307 insertions(+), 8 deletions(-) create mode 100644 lib/ext2fs/orphan.c diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c index 2291060214ff..29b7b1512400 100644 --- a/lib/e2p/feature.c +++ b/lib/e2p/feature.c @@ -49,6 +49,8 @@ static struct feature feature_list[] = { "fast_commit" }, { E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_STABLE_INODES, "stable_inodes" }, + { E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE, + "orphan_file" }, { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, "sparse_super" }, @@ -80,6 +82,8 @@ static struct feature feature_list[] = { "shared_blocks"}, { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_VERITY, "verity"}, + { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT, + "orphan_present" }, { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION, "compression" }, diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in index 5d9af86e520b..ffbfd7a7fc33 100644 --- a/lib/ext2fs/Makefile.in +++ b/lib/ext2fs/Makefile.in @@ -115,6 +115,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \ newdir.o \ nls_utf8.o \ openfs.o \ + orphan.o \ progress.o \ punch.o \ qcow2.o \ @@ -198,6 +199,7 @@ SRCS= ext2_err.c \ $(srcdir)/newdir.c \ $(srcdir)/nls_utf8.c \ $(srcdir)/openfs.c \ + $(srcdir)/orphan.c \ $(srcdir)/progress.c \ $(srcdir)/punch.c \ $(srcdir)/qcow2.c \ diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 6f1d5db4b482..00809e7b92be 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -761,7 +761,8 @@ struct ext2_super_block { __u8 s_last_error_errcode; /*27c*/ __le16 s_encoding; /* Filename charset encoding */ __le16 s_encoding_flags; /* Filename charset encoding flags */ - __le32 s_reserved[95]; /* Padding to the end of the block */ + __le32 s_orphan_file_inum; /* Inode for tracking orphan inodes */ + __le32 s_reserved[94]; /* Padding to the end of the block */ /*3fc*/ __u32 s_checksum; /* crc32c(superblock) */ }; @@ -816,7 +817,7 @@ struct ext2_super_block { #define EXT4_FEATURE_COMPAT_SPARSE_SUPER2 0x0200 #define EXT4_FEATURE_COMPAT_FAST_COMMIT 0x0400 #define EXT4_FEATURE_COMPAT_STABLE_INODES 0x0800 - +#define EXT4_FEATURE_COMPAT_ORPHAN_FILE 0x1000 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 @@ -825,6 +826,7 @@ struct ext2_super_block { #define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 +#define EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT 0x0080 #define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 #define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 /* @@ -918,6 +920,7 @@ EXT4_FEATURE_COMPAT_FUNCS(exclude_bitmap, 2, EXCLUDE_BITMAP) EXT4_FEATURE_COMPAT_FUNCS(sparse_super2, 4, SPARSE_SUPER2) EXT4_FEATURE_COMPAT_FUNCS(fast_commit, 4, FAST_COMMIT) EXT4_FEATURE_COMPAT_FUNCS(stable_inodes, 4, STABLE_INODES) +EXT4_FEATURE_COMPAT_FUNCS(orphan_file, 4, ORPHAN_FILE) EXT4_FEATURE_RO_COMPAT_FUNCS(sparse_super, 2, SPARSE_SUPER) EXT4_FEATURE_RO_COMPAT_FUNCS(large_file, 2, LARGE_FILE) @@ -933,6 +936,7 @@ EXT4_FEATURE_RO_COMPAT_FUNCS(readonly, 4, READONLY) EXT4_FEATURE_RO_COMPAT_FUNCS(project, 4, PROJECT) EXT4_FEATURE_RO_COMPAT_FUNCS(shared_blocks, 4, SHARED_BLOCKS) EXT4_FEATURE_RO_COMPAT_FUNCS(verity, 4, VERITY) +EXT4_FEATURE_RO_COMPAT_FUNCS(orphan_present, 4, ORPHAN_PRESENT) EXT4_FEATURE_INCOMPAT_FUNCS(compression, 2, COMPRESSION) EXT4_FEATURE_INCOMPAT_FUNCS(filetype, 2, FILETYPE) @@ -1100,6 +1104,14 @@ static inline unsigned int ext2fs_dir_rec_len(__u8 name_len, return rec_len; } +#define EXT4_ORPHAN_BLOCK_MAGIC 0x0b10ca04 + +/* Structure at the tail of orphan block */ +struct ext4_orphan_block_tail { + __u32 ob_magic; + __u32 ob_checksum; +}; + /* * Constants for ext4's extended time encoding */ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index df150f0003f2..886e12793620 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -620,7 +620,8 @@ typedef struct ext2_icount *ext2_icount_t; EXT2_FEATURE_COMPAT_EXT_ATTR|\ EXT4_FEATURE_COMPAT_SPARSE_SUPER2|\ EXT4_FEATURE_COMPAT_FAST_COMMIT|\ - EXT4_FEATURE_COMPAT_STABLE_INODES) + EXT4_FEATURE_COMPAT_STABLE_INODES|\ + EXT4_FEATURE_COMPAT_ORPHAN_FILE) #ifdef CONFIG_MMP #define EXT4_LIB_INCOMPAT_MMP EXT4_FEATURE_INCOMPAT_MMP @@ -655,7 +656,8 @@ typedef struct ext2_icount *ext2_icount_t; EXT4_FEATURE_RO_COMPAT_READONLY |\ EXT4_FEATURE_RO_COMPAT_PROJECT |\ EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS |\ - EXT4_FEATURE_RO_COMPAT_VERITY) + EXT4_FEATURE_RO_COMPAT_VERITY |\ + EXT4_FEATURE_RO_COMPAT_ORPHAN_PRESENT) /* * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed @@ -1687,6 +1689,15 @@ errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io); errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io); errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io); +/* orphan.c */ +extern errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks); +extern errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs); +extern e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs); +extern errcode_t ext2fs_orphan_file_block_csum_set(ext2_filsys fs, + ext2_ino_t ino, char *buf); +extern int ext2fs_orphan_file_block_csum_verify(ext2_filsys fs, ext2_ino_t ino, + char *buf); + /* get_pathname.c */ extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino, char **name); @@ -1840,7 +1851,9 @@ extern int ext2fs_dirent_file_type(const struct ext2_dir_entry *entry); extern void ext2fs_dirent_set_file_type(struct ext2_dir_entry *entry, int type); extern struct ext2_inode *ext2fs_inode(struct ext2_inode_large * large_inode); extern const struct ext2_inode *ext2fs_const_inode(const struct ext2_inode_large * large_inode); - +extern int ext2fs_inodes_per_orphan_block(ext2_filsys fs); +extern struct ext4_orphan_block_tail *ext2fs_orphan_block_tail(ext2_filsys fs, + char *buf); #endif /* @@ -2150,6 +2163,19 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode) return (const struct ext2_inode *) large_inode; } +_INLINE_ int ext2fs_inodes_per_orphan_block(ext2_filsys fs) +{ + return (fs->blocksize - sizeof(struct ext4_orphan_block_tail)) / + sizeof(__u32); +} + +_INLINE_ struct ext4_orphan_block_tail * +ext2fs_orphan_block_tail(ext2_filsys fs, char *buf) +{ + return (struct ext4_orphan_block_tail *)(buf + fs->blocksize - + sizeof(struct ext4_orphan_block_tail)); +} + #undef _INLINE_ #endif diff --git a/lib/ext2fs/orphan.c b/lib/ext2fs/orphan.c new file mode 100644 index 000000000000..71e8674ce601 --- /dev/null +++ b/lib/ext2fs/orphan.c @@ -0,0 +1,252 @@ +/* + * orphan.c --- utility function to handle orphan file + * + * Copyright (C) 2015 Jan Kara. + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Library + * General Public License, version 2. + * %End-Header% + */ + +#include "config.h" +#include + +#include "ext2_fs.h" +#include "ext2fsP.h" + +errcode_t ext2fs_truncate_orphan_file(ext2_filsys fs) +{ + struct ext2_inode inode; + errcode_t err; + ext2_ino_t ino = fs->super->s_orphan_file_inum; + + err = ext2fs_read_inode(fs, ino, &inode); + if (err) + return err; + + err = ext2fs_punch(fs, ino, &inode, NULL, 0, ~0ULL); + if (err) + return err; + + fs->flags &= ~EXT2_FLAG_SUPER_ONLY; + memset(&inode, 0, sizeof(struct ext2_inode)); + err = ext2fs_write_inode(fs, ino, &inode); + + ext2fs_clear_feature_orphan_file(fs->super); + ext2fs_clear_feature_orphan_present(fs->super); + ext2fs_mark_super_dirty(fs); + /* Need to update group descriptors as well */ + fs->flags &= ~EXT2_FLAG_SUPER_ONLY; + + return err; +} + +struct mkorphan_info { + char *buf; + char *zerobuf; + blk_t num_blocks; + blk_t alloc_blocks; + blk64_t last_blk; + errcode_t err; +}; + +static int mkorphan_proc(ext2_filsys fs, + blk64_t *blocknr, + e2_blkcnt_t blockcnt, + blk64_t ref_block EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct mkorphan_info *oi = (struct mkorphan_info *)priv_data; + blk64_t new_blk; + errcode_t err; + + /* Can we just continue in currently allocated cluster? */ + if (blockcnt && + EXT2FS_B2C(fs, oi->last_blk) == EXT2FS_B2C(fs, oi->last_blk + 1)) { + new_blk = oi->last_blk + 1; + } else { + err = ext2fs_new_block2(fs, oi->last_blk, 0, &new_blk); + if (err) { + oi->err = err; + return BLOCK_ABORT; + } + ext2fs_block_alloc_stats2(fs, new_blk, +1); + oi->alloc_blocks++; + } + if (blockcnt >= 0) + err = io_channel_write_blk64(fs->io, new_blk, 1, oi->buf); + else /* zerobuf is used to initialize new indirect blocks... */ + err = io_channel_write_blk64(fs->io, new_blk, 1, oi->zerobuf); + if (err) { + oi->err = err; + return BLOCK_ABORT; + } + oi->last_blk = new_blk; + *blocknr = new_blk; + if (blockcnt >= 0 && --oi->num_blocks == 0) + return BLOCK_CHANGED | BLOCK_ABORT; + return BLOCK_CHANGED; +} + +errcode_t ext2fs_create_orphan_file(ext2_filsys fs, blk_t num_blocks) +{ + struct ext2_inode inode; + ext2_ino_t ino = fs->super->s_orphan_file_inum; + errcode_t err; + char *buf = NULL, *zerobuf = NULL; + struct mkorphan_info oi; + struct ext4_orphan_block_tail *ob_tail; + + if (!ino) { + err = ext2fs_new_inode(fs, EXT2_ROOT_INO, LINUX_S_IFREG | 0600, + 0, &ino); + if (err) + return err; + ext2fs_inode_alloc_stats2(fs, ino, +1, 0); + ext2fs_mark_ib_dirty(fs); + } + + err = ext2fs_read_inode(fs, ino, &inode); + if (err) + return err; + if (EXT2_I_SIZE(&inode)) { + err = ext2fs_truncate_orphan_file(fs); + if (err) + return err; + } + + memset(&inode, 0, sizeof(struct ext2_inode)); + if (ext2fs_has_feature_extents(fs->super)) { + inode.i_flags |= EXT4_EXTENTS_FL; + err = ext2fs_write_inode(fs, ino, &inode); + if (err) + return err; + } + + err = ext2fs_get_mem(fs->blocksize, &buf); + if (err) + return err; + err = ext2fs_get_mem(fs->blocksize, &zerobuf); + if (err) + goto out; + memset(buf, 0, fs->blocksize); + memset(zerobuf, 0, fs->blocksize); + ob_tail = ext2fs_orphan_block_tail(fs, buf); + ob_tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC); + err = ext2fs_orphan_file_block_csum_set(fs, ino, buf); + if (err) + goto out; + oi.num_blocks = num_blocks; + oi.alloc_blocks = 0; + oi.last_blk = 0; + oi.buf = buf; + oi.zerobuf = zerobuf; + oi.err = 0; + err = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_APPEND, + 0, mkorphan_proc, &oi); + if (err) + goto out; + if (oi.err) { + err = oi.err; + goto out; + } + + /* Reread inode after blocks were allocated */ + err = ext2fs_read_inode(fs, ino, &inode); + if (err) + goto out; + ext2fs_iblk_set(fs, &inode, 0); + inode.i_atime = inode.i_mtime = + inode.i_ctime = fs->now ? fs->now : time(0); + inode.i_links_count = 1; + inode.i_mode = LINUX_S_IFREG | 0600; + ext2fs_iblk_add_blocks(fs, &inode, oi.alloc_blocks); + err = ext2fs_inode_size_set(fs, &inode, + (unsigned long long)fs->blocksize * num_blocks); + if (err) + goto out; + err = ext2fs_write_new_inode(fs, ino, &inode); + if (err) + goto out; + + fs->super->s_orphan_file_inum = ino; + ext2fs_set_feature_orphan_file(fs->super); + ext2fs_mark_super_dirty(fs); + /* Need to update group descriptors as well */ + fs->flags &= ~EXT2_FLAG_SUPER_ONLY; +out: + if (buf) + ext2fs_free_mem(&buf); + if (zerobuf) + ext2fs_free_mem(&zerobuf); + return err; +} + +/* + * Find reasonable size for orphan file. We choose orphan file size to be + * between 32 and 512 filesystem blocks and not more than 1/4096 of the + * filesystem unless it is really small. + */ +e2_blkcnt_t ext2fs_default_orphan_file_blocks(ext2_filsys fs) +{ + __u64 num_blocks = ext2fs_blocks_count(fs->super); + e2_blkcnt_t blks = 512; + + if (num_blocks < 128 * 1024) + blks = 32; + else if (num_blocks < 2 * 1024 * 1024) + blks = num_blocks / 4096; + return (blks + EXT2FS_CLUSTER_MASK(fs)) & ~EXT2FS_CLUSTER_MASK(fs); +} + +static errcode_t ext2fs_orphan_file_block_csum(ext2_filsys fs, ext2_ino_t ino, + char *buf, __u32 *crcp) +{ + int inodes_per_ob = ext2fs_inodes_per_orphan_block(fs); + __u32 gen, crc; + struct ext2_inode inode; + errcode_t retval; + + retval = ext2fs_read_inode(fs, ino, &inode); + if (retval) + return retval; + ino = ext2fs_cpu_to_le32(ino); + gen = ext2fs_cpu_to_le32(inode.i_generation); + crc = ext2fs_crc32c_le(fs->csum_seed, (unsigned char *)&ino, + sizeof(ino)); + crc = ext2fs_crc32c_le(crc, (unsigned char *)&gen, sizeof(gen)); + crc = ext2fs_crc32c_le(crc, buf, inodes_per_ob * sizeof(__u32)); + *crcp = ext2fs_cpu_to_le32(crc); + + return 0; +} + +errcode_t ext2fs_orphan_file_block_csum_set(ext2_filsys fs, ext2_ino_t ino, + char *buf) +{ + struct ext4_orphan_block_tail *tail; + + if (!ext2fs_has_feature_metadata_csum(fs->super)) + return 0; + + tail = ext2fs_orphan_block_tail(fs, buf); + return ext2fs_orphan_file_block_csum(fs, ino, buf, &tail->ob_checksum); +} + +int ext2fs_orphan_file_block_csum_verify(ext2_filsys fs, ext2_ino_t ino, + char *buf) +{ + struct ext4_orphan_block_tail *tail; + __u32 crc; + errcode_t retval; + + if (!ext2fs_has_feature_metadata_csum(fs->super)) + return 1; + retval = ext2fs_orphan_file_block_csum(fs, ino, buf, &crc); + if (retval) + return 0; + tail = ext2fs_orphan_block_tail(fs, buf); + return ext2fs_le32_to_cpu(tail->ob_checksum) == crc; +} diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index 1006b2d2bd52..b844e7665999 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -131,8 +131,9 @@ void ext2fs_swap_super(struct ext2_super_block * sb) /* s_*_time_hi are __u8 and does not need swabbing */ sb->s_encoding = ext2fs_swab16(sb->s_encoding); sb->s_encoding_flags = ext2fs_swab16(sb->s_encoding_flags); + sb->s_orphan_file_inum = ext2fs_swab32(sb->s_orphan_file_inum); /* catch when new fields are used from s_reserved */ - EXT2FS_BUILD_BUG_ON(sizeof(sb->s_reserved) != 95 * sizeof(__le32)); + EXT2FS_BUILD_BUG_ON(sizeof(sb->s_reserved) != 94 * sizeof(__le32)); sb->s_checksum = ext2fs_swab32(sb->s_checksum); } diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c index 80a5269bceb7..ad452dee8eb3 100644 --- a/lib/ext2fs/tst_super_size.c +++ b/lib/ext2fs/tst_super_size.c @@ -152,7 +152,8 @@ int main(int argc, char **argv) check_field(s_last_error_errcode, 1); check_field(s_encoding, 2); check_field(s_encoding_flags, 2); - check_field(s_reserved, 95 * 4); + check_field(s_orphan_file_inum, 4); + check_field(s_reserved, 94 * 4); check_field(s_checksum, 4); do_field("Superblock end", 0, 0, cur_offset, 1024); #endif diff --git a/lib/support/mkquota.c b/lib/support/mkquota.c index 21a5c34d6921..b790b93f52c2 100644 --- a/lib/support/mkquota.c +++ b/lib/support/mkquota.c @@ -504,7 +504,8 @@ errcode_t quota_compute_usage(quota_ctx_t qctx) continue; if (ino == EXT2_ROOT_INO || (ino >= EXT2_FIRST_INODE(fs->super) && - ino != quota_type2inum(PRJQUOTA, fs->super))) { + ino != quota_type2inum(PRJQUOTA, fs->super) && + ino != fs->super->s_orphan_file_inum)) { space = ext2fs_get_stat_i_blocks(fs, EXT2_INODE(inode)) << 9; quota_data_add(qctx, inode, ino, space); From patchwork Wed Jun 16 10:57:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492887 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=n6naESjj; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=UH2HXk37; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hww0lF5z9sf8 for ; Wed, 16 Jun 2021 20:57:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231447AbhFPK75 (ORCPT ); Wed, 16 Jun 2021 06:59:57 -0400 Received: from smtp-out2.suse.de ([195.135.220.29]:35826 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231294AbhFPK7x (ORCPT ); Wed, 16 Jun 2021 06:59:53 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id ECA311FD83; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=whp0qX1mVlnCabp4mvghIfzu6AhzRtxMM9JEx7Yp6N8=; b=n6naESjjmtw9UYjTG9VkL/aRtZQWeiV3izjhXZeKEf3upX7dc13S8Mbzb114KTlhdR25zc oWL+qwY9GT/Syj2SymxrbHVtCaYpSlPoSYgUyohCgPKIpm68BHW4eVrxiB37kF3wQSQIZG JqsdlmGVhFQnye30pdbnnuIKKfFGqxo= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=whp0qX1mVlnCabp4mvghIfzu6AhzRtxMM9JEx7Yp6N8=; b=UH2HXk37yenkH6gTFcuGezzBBPpZdTrn6s194P0VeEgTWK5F1XyyUAlU7GlFjw/Ggg2GJJ QLdLSnI7YBn/x1Ag== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id B34ABA3B81; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 6B7EA1F2CBD; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 5/9] mke2fs: Add support for orphan_file feature Date: Wed, 16 Jun 2021 12:57:31 +0200 Message-Id: <20210616105735.5424-6-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Signed-off-by: Jan Kara --- misc/mke2fs.8.in | 5 +++++ misc/mke2fs.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in index 84248ffc9e1d..3747c93a02bf 100644 --- a/misc/mke2fs.8.in +++ b/misc/mke2fs.8.in @@ -403,6 +403,11 @@ filesystem to change based on the user running \fBmke2fs\fR. Set a flag in the filesystem superblock indicating that it may be mounted using experimental kernel code, such as the ext4dev filesystem. .TP +.BI orphan_file_size= size +Set size of the file for tracking unlinked but still open inodes and inodes +with truncate in progress. Larger file allows for better scalability, reserving +a few blocks per cpu is ideal. +.TP .B discard Attempt to discard blocks at mkfs time (discarding blocks initially is useful on solid state devices and sparse / thin-provisioned storage). When the device diff --git a/misc/mke2fs.c b/misc/mke2fs.c index afbcf486bad2..8a5cf9b920e6 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -94,6 +94,7 @@ static gid_t root_gid; int journal_size; int journal_flags; int journal_fc_size; +static e2_blkcnt_t orphan_file_blocks; static int lazy_itable_init; static int packed_meta_blocks; int no_copy_xattrs; @@ -1087,6 +1088,21 @@ static void parse_extended_opts(struct ext2_super_block *param, continue; } encoding_flags = arg; + } else if (!strcmp(token, "orphan_file_size")) { + if (!arg) { + r_usage++; + badopt = token; + continue; + } + orphan_file_blocks = parse_num_blocks2(arg, + fs_param.s_log_block_size); + if (orphan_file_blocks == 0) { + fprintf(stderr, + _("Invalid size of orphan file %s\n"), + arg); + r_usage++; + continue; + } } else { r_usage++; badopt = token; @@ -1154,7 +1170,8 @@ static __u32 ok_features[3] = { EXT2_FEATURE_COMPAT_EXT_ATTR | EXT4_FEATURE_COMPAT_SPARSE_SUPER2 | EXT4_FEATURE_COMPAT_FAST_COMMIT | - EXT4_FEATURE_COMPAT_STABLE_INODES, + EXT4_FEATURE_COMPAT_STABLE_INODES | + EXT4_FEATURE_COMPAT_ORPHAN_FILE, /* Incompat */ EXT2_FEATURE_INCOMPAT_FILETYPE| EXT3_FEATURE_INCOMPAT_EXTENTS| @@ -3438,6 +3455,23 @@ no_journal: fix_cluster_bg_counts(fs); if (ext2fs_has_feature_quota(&fs_param)) create_quota_inodes(fs); + if (ext2fs_has_feature_orphan_file(&fs_param)) { + if (!ext2fs_has_feature_journal(&fs_param)) { + com_err(program_name, 0, _("cannot set orphan_file " + "flag without a journal.")); + exit(1); + } + if (!orphan_file_blocks) { + orphan_file_blocks = + ext2fs_default_orphan_file_blocks(fs); + } + retval = ext2fs_create_orphan_file(fs, orphan_file_blocks); + if (retval) { + com_err(program_name, retval, + _("while creating orphan file")); + exit(1); + } + } retval = mk_hugefiles(fs, device_name); if (retval) From patchwork Wed Jun 16 10:57:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492886 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=mCffGjXA; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=ykMH0c9G; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwv4xctz9sf9 for ; Wed, 16 Jun 2021 20:57:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231719AbhFPK74 (ORCPT ); Wed, 16 Jun 2021 06:59:56 -0400 Received: from smtp-out1.suse.de ([195.135.220.28]:40702 "EHLO smtp-out1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231447AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out1.suse.de (Postfix) with ESMTP id ECF5D21A57; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S7+K10RkTcTSCerXPiCpvUlTDILHLcGnieLtOmWqNq8=; b=mCffGjXA6dv+HutNN/eC0oXu/jd+WSNq2yiv35WBKGFXF4TTmxNRsTVC0900d95Ef2Kkvj UXdblfJzqxS9dZgORdz325lBm+RIW2A/75FFQVuaVfLNUWzVi3NE8U5ZR3uhp5Io5CITKp nYZ5J8I/hleDGm2h/ITyI6CA+Ala8lc= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S7+K10RkTcTSCerXPiCpvUlTDILHLcGnieLtOmWqNq8=; b=ykMH0c9GccVahBljFMZE2qdV4XNCNYxuktG/MLE7jQ+GsC9LnYT9cI6uzF6k9tQM9dL1GQ 46oiZUf2jirj9lCQ== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id B399CA3B98; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 6F7FD1F2CBF; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 6/9] e2fsck: Add support for handling orphan file Date: Wed, 16 Jun 2021 12:57:32 +0200 Message-Id: <20210616105735.5424-7-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Signed-off-by: Jan Kara --- e2fsck/e2fsck.h | 1 + e2fsck/pass1.c | 27 ++++ e2fsck/pass4.c | 2 +- e2fsck/problem.c | 80 +++++++++++ e2fsck/problem.h | 50 +++++++ e2fsck/super.c | 347 +++++++++++++++++++++++++++++++++++++++++------ e2fsck/unix.c | 73 +++++++++- 7 files changed, 536 insertions(+), 44 deletions(-) diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 15d043ee4692..979cdfcb2740 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -649,6 +649,7 @@ void sigcatcher_setup(void); void check_super_block(e2fsck_t ctx); int check_backup_super_block(e2fsck_t ctx); void check_resize_inode(e2fsck_t ctx); +int check_init_orphan_file(e2fsck_t ctx); /* util.c */ extern void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size, diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 9d4308956773..b8d8dd109096 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -1778,6 +1778,32 @@ void e2fsck_pass1(e2fsck_t ctx) inode_size, "pass1"); failed_csum = 0; } + } else if (ino == fs->super->s_orphan_file_inum) { + ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino); + if (ext2fs_has_feature_orphan_file(fs->super)) { + if (!LINUX_S_ISREG(inode->i_mode) && + fix_problem(ctx, PR_1_ORPHAN_FILE_BAD_MODE, + &pctx)) { + inode->i_mode = LINUX_S_IFREG; + e2fsck_write_inode(ctx, ino, inode, + "pass1"); + failed_csum = 0; + } + check_blocks(ctx, &pctx, block_buf, NULL); + FINISH_INODE_LOOP(ctx, ino, &pctx, failed_csum); + continue; + } + if ((inode->i_links_count || + inode->i_blocks || inode->i_block[0]) && + fix_problem(ctx, PR_1_ORPHAN_FILE_NOT_CLEAR, + &pctx)) { + memset(inode, 0, inode_size); + ext2fs_icount_store(ctx->inode_link_info, ino, + 0); + e2fsck_write_inode_full(ctx, ino, inode, + inode_size, "pass1"); + failed_csum = 0; + } } else if (ino < EXT2_FIRST_INODE(fs->super)) { problem_t problem = 0; @@ -3484,6 +3510,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, } if (ino != quota_type2inum(PRJQUOTA, fs->super) && + ino != fs->super->s_orphan_file_inum && (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) && !(inode->i_flags & EXT4_EA_INODE_FL)) { quota_data_add(ctx->qctx, (struct ext2_inode_large *) inode, diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index 8c2d2f1fca12..f41eb849e567 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -192,7 +192,7 @@ void e2fsck_pass4(e2fsck_t ctx) goto errout; } if (i == quota_type2inum(PRJQUOTA, ctx->fs->super) || - i == EXT2_BAD_INO || + i == fs->super->s_orphan_file_inum || i == EXT2_BAD_INO || (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super))) continue; if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, i)) || diff --git a/e2fsck/problem.c b/e2fsck/problem.c index eb2824f31684..0935fe30fc5b 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -526,6 +526,26 @@ static struct e2fsck_problem problem_table[] = { "not compatible. Resize @i should be disabled. "), PROMPT_FIX, 0, 0, 0, 0 }, + /* Orphan file contains holes */ + { PR_0_ORPHAN_FILE_HOLE, + N_("Orphan file (@i %i) contains hole at @b %b. Terminating orphan file recovery.\n"), + PROMPT_NONE, 0 }, + + /* Orphan file block has wrong magic */ + { PR_0_ORPHAN_FILE_BAD_MAGIC, + N_("Orphan file (@i %i) @b %b contains wrong magic. Terminating orphan file recovery.\n"), + PROMPT_NONE, 0 }, + + /* Orphan file block has wrong checksum */ + { PR_0_ORPHAN_FILE_BAD_CHECKSUM, + N_("Orphan file (@i %i) @b %b contains wrong checksum. Terminating orphan file recovery.\n"), + PROMPT_NONE, 0 }, + + /* Orphan file size isn't multiple of blocks size */ + { PR_0_ORPHAN_FILE_WRONG_SIZE, + N_("Orphan file (@i %i) size is not multiple of block size. Terminating orphan file recovery.\n"), + PROMPT_NONE, 0 }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ @@ -1280,6 +1300,16 @@ static struct e2fsck_problem problem_table[] = { PROMPT_CLEAR_HTREE, PR_PREEN_OK, 0, 0, 0 }, + /* Orphan file has bad mode */ + { PR_1_ORPHAN_FILE_BAD_MODE, + N_("Orphan file @i %i is not regular file. "), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* Orphan file inode is not in use, but contains data */ + { PR_1_ORPHAN_FILE_NOT_CLEAR, + N_("Orphan file @i %i is not in use, but contains data. "), + PROMPT_CLEAR, PR_PREEN_OK }, + /* Pass 1b errors */ /* Pass 1B: Rescan for duplicate/bad blocks */ @@ -2259,6 +2289,56 @@ static struct e2fsck_problem problem_table[] = { N_("Error writing quota info for quota type %N: %m\n"), PROMPT_NULL, 0, 0, 0, 0 }, + /* Orphan file without a journal */ + { PR_6_ORPHAN_FILE_WITHOUT_JOURNAL, + N_("@S has orphan file without @j.\n"), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* Orphan file truncation failed */ + { PR_6_ORPHAN_FILE_TRUNC_FAILED, + N_("Failed to truncate orphan file.\n"), + PROMPT_NONE, 0 }, + + /* Failed to initialize orphan file */ + { PR_6_ORPHAN_FILE_CORRUPTED, + N_("Failed to initialize orphan file.\n"), + PROMPT_RECREATE, PR_PREEN_OK }, + + /* Cannot fix corrupted orphan file with invalid bitmaps */ + { PR_6_ORPHAN_FILE_BITMAP_INVALID, + N_("Cannot fix corrupted orphan file with invalid bitmaps.\n"), + PROMPT_NONE, 0 }, + + /* Orphan file creation failed */ + { PR_6_ORPHAN_FILE_CREATE_FAILED, + N_("Failed to truncate orphan file (@i %i).\n"), + PROMPT_NONE, 0 }, + + /* Orphan file block contains data */ + { PR_6_ORPHAN_BLOCK_DIRTY, + N_("Orphan file (@i %i) @b %b is not clean.\n"), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* orphan_present set but orphan file is empty */ + { PR_6_ORPHAN_PRESENT_CLEAN_FILE, + N_("Flag orphan_present is set but orphan file is clean.\n"), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* orphan_present set but orphan_file is not */ + { PR_6_ORPHAN_PRESENT_NO_FILE, + N_("Flag orphan_present is set but flag orphan_file is not.\n"), + PROMPT_CLEAR, PR_PREEN_OK }, + + /* Orphan file size isn't multiple of blocks size */ + { PR_6_ORPHAN_FILE_WRONG_SIZE, + N_("Orphan file (@i %i) size is not multiple of block size.\n"), + PROMPT_NONE, 0 }, + + /* Orphan file contains holes */ + { PR_6_ORPHAN_FILE_HOLE, + N_("Orphan file (@i %i) contains hole at @b %b.\n"), + PROMPT_NONE, 0 }, + { 0 } }; diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 24cdcf9b90f7..0611d71f9e03 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -288,6 +288,18 @@ struct problem_context { /* Meta_bg and resize_inode are not compatible, remove resize_inode*/ #define PR_0_DISABLE_RESIZE_INODE 0x000051 +/* Orphan file contains holes */ +#define PR_0_ORPHAN_FILE_HOLE 0x000052 + +/* Orphan file block has wrong magic */ +#define PR_0_ORPHAN_FILE_BAD_MAGIC 0x000053 + +/* Orphan file block has wrong checksum */ +#define PR_0_ORPHAN_FILE_BAD_CHECKSUM 0x000054 + +/* Orphan file size isn't multiple of blocks size */ +#define PR_0_ORPHAN_FILE_WRONG_SIZE 0x000055 + /* * Pass 1 errors */ @@ -717,6 +729,15 @@ struct problem_context { #define PR_1_HTREE_CANNOT_SIPHASH 0x01008E +/* Orphan file inode is not a regular file */ +#define PR_1_ORPHAN_FILE_BAD_MODE 0x01007F + +/* Orphan file inode is not in use, but contains data */ +#define PR_1_ORPHAN_FILE_NOT_CLEAR 0x010080 + +/* Orphan file inode is not clear */ +#define PR_1_ORPHAN_INODE_NOT_CLEAR 0x01007F + /* * Pass 1b errors */ @@ -1293,6 +1314,35 @@ struct problem_context { /* Error updating quota information */ #define PR_6_WRITE_QUOTAS 0x060006 +/* Orphan file without a journal */ +#define PR_6_ORPHAN_FILE_WITHOUT_JOURNAL 0x060007 + +/* Orphan file truncation failed */ +#define PR_6_ORPHAN_FILE_TRUNC_FAILED 0x060008 + +/* Failed to initialize orphan file */ +#define PR_6_ORPHAN_FILE_CORRUPTED 0x060009 + +/* Cannot fix corrupted orphan file with invalid bitmaps */ +#define PR_6_ORPHAN_FILE_BITMAP_INVALID 0x06000A + +/* Orphan file creation failed */ +#define PR_6_ORPHAN_FILE_CREATE_FAILED 0x06000B + +/* Orphan file block contains data */ +#define PR_6_ORPHAN_BLOCK_DIRTY 0x06000C + +/* orphan_present set but orphan file is empty */ +#define PR_6_ORPHAN_PRESENT_CLEAN_FILE 0x06000D + +/* orphan_present set but orphan_file is not */ +#define PR_6_ORPHAN_PRESENT_NO_FILE 0x06000E + +/* Orphan file size isn't multiple of blocks size */ +#define PR_6_ORPHAN_FILE_WRONG_SIZE 0x06000F + +/* Orphan file contains holes */ +#define PR_6_ORPHAN_FILE_HOLE 0x060010 /* * Function declarations diff --git a/e2fsck/super.c b/e2fsck/super.c index e1c3f93572f4..963e286ed582 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -313,6 +313,178 @@ static errcode_t e2fsck_write_all_quotas(e2fsck_t ctx) return pctx.errcode; } +static int release_orphan_inode(e2fsck_t ctx, ext2_ino_t *ino, char *block_buf) +{ + ext2_filsys fs = ctx->fs; + struct problem_context pctx; + struct ext2_inode_large inode; + ext2_ino_t next_ino; + + e2fsck_read_inode_full(ctx, *ino, EXT2_INODE(&inode), + sizeof(inode), "release_orphan_inode"); + clear_problem_context(&pctx); + pctx.ino = *ino; + pctx.inode = EXT2_INODE(&inode); + pctx.str = inode.i_links_count ? _("Truncating") : _("Clearing"); + + fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx); + + next_ino = inode.i_dtime; + if (next_ino && + ((next_ino < EXT2_FIRST_INODE(fs->super)) || + (next_ino > fs->super->s_inodes_count))) { + pctx.ino = next_ino; + fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx); + return 1; + } + + if (release_inode_blocks(ctx, *ino, &inode, block_buf, &pctx)) + return 1; + + if (!inode.i_links_count) { + if (ctx->qctx) + quota_data_inodes(ctx->qctx, &inode, *ino, -1); + ext2fs_inode_alloc_stats2(fs, *ino, -1, + LINUX_S_ISDIR(inode.i_mode)); + ctx->free_inodes++; + inode.i_dtime = ctx->now; + } else { + inode.i_dtime = 0; + } + e2fsck_write_inode_full(ctx, *ino, EXT2_INODE(&inode), + sizeof(inode), "delete_file"); + *ino = next_ino; + return 0; +} + +struct process_orphan_block_data { + e2fsck_t ctx; + char *buf; + char *block_buf; + e2_blkcnt_t blocks; + int abort; + int clear; + errcode_t errcode; +}; + +static int process_orphan_block(ext2_filsys fs, + blk64_t *block_nr, + e2_blkcnt_t blockcnt, + blk64_t ref_blk EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct process_orphan_block_data *pd; + e2fsck_t ctx; + struct problem_context pctx; + blk64_t blk = *block_nr; + struct ext4_orphan_block_tail *tail; + int j; + int inodes_per_ob; + __u32 *bdata; + ext2_ino_t ino; + + pd = priv_data; + ctx = pd->ctx; + clear_problem_context(&pctx); + pctx.ino = fs->super->s_orphan_file_inum; + pctx.blk = blockcnt; + + /* Orphan file must not have holes */ + if (!blk) { + if (blockcnt == pd->blocks) + return BLOCK_ABORT; + fix_problem(ctx, PR_0_ORPHAN_FILE_HOLE, &pctx); +return_abort: + pd->abort = 1; + return BLOCK_ABORT; + } + inodes_per_ob = ext2fs_inodes_per_orphan_block(fs); + pd->errcode = io_channel_read_blk64(fs->io, blk, 1, pd->buf); + if (pd->errcode) + goto return_abort; + tail = ext2fs_orphan_block_tail(fs, pd->buf); + if (ext2fs_le32_to_cpu(tail->ob_magic) != + EXT4_ORPHAN_BLOCK_MAGIC) { + fix_problem(ctx, PR_0_ORPHAN_FILE_BAD_MAGIC, &pctx); + goto return_abort; + } + if (!ext2fs_orphan_file_block_csum_verify(fs, + fs->super->s_orphan_file_inum, pd->buf)) { + fix_problem(ctx, PR_0_ORPHAN_FILE_BAD_CHECKSUM, &pctx); + goto return_abort; + } + bdata = (__u32 *)pd->buf; + for (j = 0; j < inodes_per_ob; j++) { + if (!bdata[j]) + continue; + ino = ext2fs_le32_to_cpu(bdata[j]); + if (release_orphan_inode(ctx, &ino, pd->block_buf)) + goto return_abort; + } + return 0; +} + +static int process_orphan_file(e2fsck_t ctx, char *block_buf) +{ + ext2_filsys fs = ctx->fs; + char *orphan_buf; + struct process_orphan_block_data pd; + int ret = 0; + ext2_ino_t orphan_inum = fs->super->s_orphan_file_inum; + struct ext2_inode orphan_inode; + struct problem_context pctx; + errcode_t retval; + + if (!ext2fs_has_feature_orphan_file(fs->super)) + return 0; + + clear_problem_context(&pctx); + pctx.ino = orphan_inum; + + orphan_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, + "orphan block buffer"); + retval = ext2fs_read_inode(fs, orphan_inum, &orphan_inode); + if (retval < 0) { + com_err("process_orphan_file", retval, + _("while reading inode %d"), orphan_inum); + ret = 1; + goto out; + } + if (EXT2_I_SIZE(&orphan_inode) & (fs->blocksize - 1)) { + fix_problem(ctx, PR_0_ORPHAN_FILE_WRONG_SIZE, &pctx); + ret = 1; + goto out; + } + pd.buf = orphan_buf + 3 * fs->blocksize; + pd.block_buf = block_buf; + pd.blocks = EXT2_I_SIZE(&orphan_inode) / fs->blocksize; + pd.ctx = ctx; + pd.abort = 0; + pd.errcode = 0; + retval = ext2fs_block_iterate3(fs, orphan_inum, + BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE, + orphan_buf, process_orphan_block, &pd); + if (retval) { + com_err("process_orphan_block", retval, + _("while calling ext2fs_block_iterate for inode %d"), + orphan_inum); + ret = 1; + goto out; + } + if (pd.abort) { + if (pd.errcode) { + com_err("process_orphan_block", pd.errcode, + _("while reading blocks of inode %d"), + orphan_inum); + } + ret = 1; + } +out: + ext2fs_free_mem(&orphan_buf); + return ret; +} + /* * This function releases all of the orphan inodes. It returns 1 if * it hit some error, and 0 on success. @@ -325,10 +497,13 @@ static int release_orphan_inodes(e2fsck_t ctx) struct problem_context pctx; char *block_buf; - if ((ino = fs->super->s_last_orphan) == 0) + if (fs->super->s_last_orphan == 0 && + !ext2fs_has_feature_orphan_present(fs->super)) return 0; clear_problem_context(&pctx); + ino = fs->super->s_last_orphan; + pctx.ino = ino; pctx.errcode = e2fsck_read_all_quotas(ctx); if (pctx.errcode) { fix_problem(ctx, PR_0_QUOTA_INIT_CTX, &pctx); @@ -343,9 +518,10 @@ static int release_orphan_inodes(e2fsck_t ctx) ext2fs_mark_super_dirty(fs); /* - * If the filesystem contains errors, don't run the orphan - * list, since the orphan list can't be trusted; and we're - * going to be running a full e2fsck run anyway... + * If the filesystem contains errors, don't process the orphan list + * or orphan file, since neither can be trusted; and we're going to + * be running a full e2fsck run anyway... We clear orphan file contents + * after filesystem is checked to avoid clearing someone else's data. */ if (fs->super->s_state & EXT2_ERROR_FS) { if (ctx->qctx) @@ -353,10 +529,8 @@ static int release_orphan_inodes(e2fsck_t ctx) return 0; } - if ((ino < EXT2_FIRST_INODE(fs->super)) || - (ino > fs->super->s_inodes_count)) { - clear_problem_context(&pctx); - pctx.ino = ino; + if (ino && ((ino < EXT2_FIRST_INODE(fs->super)) || + (ino > fs->super->s_inodes_count))) { fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx); goto err_qctx; } @@ -365,43 +539,19 @@ static int release_orphan_inodes(e2fsck_t ctx) "block iterate buffer"); e2fsck_read_bitmaps(ctx); + /* First process orphan list */ while (ino) { - e2fsck_read_inode_full(ctx, ino, EXT2_INODE(&inode), - sizeof(inode), "release_orphan_inodes"); - clear_problem_context(&pctx); - pctx.ino = ino; - pctx.inode = EXT2_INODE(&inode); - pctx.str = inode.i_links_count ? _("Truncating") : - _("Clearing"); - - fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx); - - next_ino = inode.i_dtime; - if (next_ino && - ((next_ino < EXT2_FIRST_INODE(fs->super)) || - (next_ino > fs->super->s_inodes_count))) { - pctx.ino = next_ino; - fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx); + if (release_orphan_inode(ctx, &ino, block_buf)) goto err_buf; - } + } - if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx)) - goto err_buf; + /* Next process orphan file */ + if (ext2fs_has_feature_orphan_present(fs->super) && + !ext2fs_has_feature_orphan_file(fs->super)) + goto err_buf; + if (process_orphan_file(ctx, block_buf)) + goto err_buf; - if (!inode.i_links_count) { - if (ctx->qctx) - quota_data_inodes(ctx->qctx, &inode, ino, -1); - ext2fs_inode_alloc_stats2(fs, ino, -1, - LINUX_S_ISDIR(inode.i_mode)); - ctx->free_inodes++; - inode.i_dtime = ctx->now; - } else { - inode.i_dtime = 0; - } - e2fsck_write_inode_full(ctx, ino, EXT2_INODE(&inode), - sizeof(inode), "delete_file"); - ino = next_ino; - } ext2fs_free_mem(&block_buf); pctx.errcode = e2fsck_write_all_quotas(ctx); if (pctx.errcode) @@ -416,6 +566,121 @@ err: return 1; } +static int reinit_orphan_block(ext2_filsys fs, + blk64_t *block_nr, + e2_blkcnt_t blockcnt, + blk64_t ref_blk EXT2FS_ATTR((unused)), + int ref_offset EXT2FS_ATTR((unused)), + void *priv_data) +{ + struct process_orphan_block_data *pd; + e2fsck_t ctx; + blk64_t blk = *block_nr; + struct problem_context pctx; + + pd = priv_data; + ctx = pd->ctx; + + /* Orphan file must not have holes */ + if (!blk) { + if (blockcnt == pd->blocks) + return BLOCK_ABORT; + + clear_problem_context(&pctx); + pctx.ino = fs->super->s_orphan_file_inum; + pctx.blk = blockcnt; + fix_problem(ctx, PR_6_ORPHAN_FILE_HOLE, &pctx); +return_abort: + pd->abort = 1; + return BLOCK_ABORT; + } + if (!pd->clear) { + pd->errcode = io_channel_read_blk64(fs->io, blk, 1, + pd->block_buf); + /* Block is already cleanly initialized? */ + if (!memcmp(pd->block_buf, pd->buf, fs->blocksize)) + return 0; + + clear_problem_context(&pctx); + pctx.ino = fs->super->s_orphan_file_inum; + pctx.blk = blockcnt; + if (!fix_problem(ctx, PR_6_ORPHAN_BLOCK_DIRTY, &pctx)) + goto return_abort; + pd->clear = 1; + } + pd->errcode = io_channel_write_blk64(fs->io, blk, 1, pd->buf); + if (pd->errcode) + goto return_abort; + return 0; +} + +/* + * Check and clear orphan file. We just return non-zero if we hit some + * inconsistency. Caller will truncate & recreate new orphan file. + */ +int check_init_orphan_file(e2fsck_t ctx) +{ + ext2_filsys fs = ctx->fs; + char *orphan_buf; + struct process_orphan_block_data pd; + struct ext4_orphan_block_tail *tail; + ext2_ino_t orphan_inum = fs->super->s_orphan_file_inum; + struct ext2_inode orphan_inode; + int ret = 0; + errcode_t retval; + + orphan_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 5, + "orphan block buffer"); + e2fsck_read_inode(ctx, orphan_inum, &orphan_inode, "orphan inode"); + if (EXT2_I_SIZE(&orphan_inode) & (fs->blocksize - 1)) { + struct problem_context pctx; + + clear_problem_context(&pctx); + pctx.ino = orphan_inum; + fix_problem(ctx, PR_6_ORPHAN_FILE_WRONG_SIZE, &pctx); + ret = 1; + goto out; + } + pd.buf = orphan_buf + 3 * fs->blocksize; + pd.block_buf = orphan_buf + 4 * fs->blocksize; + pd.blocks = EXT2_I_SIZE(&orphan_inode) / fs->blocksize; + pd.ctx = ctx; + pd.abort = 0; + pd.clear = 0; + pd.errcode = 0; + /* Initialize buffer to write */ + memset(pd.buf, 0, fs->blocksize); + tail = ext2fs_orphan_block_tail(fs, pd.buf); + tail->ob_magic = ext2fs_cpu_to_le32(EXT4_ORPHAN_BLOCK_MAGIC); + ext2fs_orphan_file_block_csum_set(fs, orphan_inum, pd.buf); + + retval = ext2fs_block_iterate3(fs, orphan_inum, + BLOCK_FLAG_DATA_ONLY | BLOCK_FLAG_HOLE, + orphan_buf, reinit_orphan_block, &pd); + if (retval) { + com_err("reinit_orphan_block", retval, + _("while calling ext2fs_block_iterate for inode %d"), + orphan_inum); + ret = 1; + goto out; + } + if (pd.abort) { + if (pd.errcode) { + com_err("process_orphan_block", pd.errcode, + _("while reading blocks of inode %d"), + orphan_inum); + } + ret = 1; + } + + /* We had to clear some blocks. Report it up. */ + if (ret == 0 && pd.clear) + ret = 2; +out: + ext2fs_free_mem(&orphan_buf); + return ret; +} + /* * Check the resize inode to make sure it is sane. We check both for * the case where on-line resizing is not enabled (in which case the diff --git a/e2fsck/unix.c b/e2fsck/unix.c index c5f9e4415f8f..99347367e210 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -1945,15 +1945,83 @@ print_unsupp_features: _("\n*** journal has been regenerated ***\n")); } } -no_journal: +no_journal: if (run_result & E2F_FLAG_ABORT) { fatal_error(ctx, _("aborted")); } else if (run_result & E2F_FLAG_CANCEL) { log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ? ctx->device_name : ctx->filesystem_name); exit_value |= FSCK_CANCELED; - } else if (ctx->qctx && !ctx->invalid_bitmaps) { + goto cleanup; + } + + /* If there isn't journal, no point in creating orphan file... */ + if (ext2fs_has_feature_orphan_file(fs->super)) { + int ret; + + /* No point in orphan file without a journal... */ + if (!ext2fs_has_feature_journal(fs->super) && + fix_problem(ctx, PR_6_ORPHAN_FILE_WITHOUT_JOURNAL, &pctx)) { + retval = ext2fs_truncate_orphan_file(fs); + if (retval) { + /* Huh, failed to delete file */ + fix_problem(ctx, PR_6_ORPHAN_FILE_TRUNC_FAILED, + &pctx); + goto check_quotas; + } + ext2fs_clear_feature_orphan_file(fs->super); + ext2fs_mark_super_dirty(fs); + goto check_quotas; + } + ret = check_init_orphan_file(ctx); + if (ret == 2 || + (ret == 0 && ext2fs_has_feature_orphan_present(fs->super) && + fix_problem(ctx, PR_6_ORPHAN_PRESENT_CLEAN_FILE, &pctx))) { + ext2fs_clear_feature_orphan_present(fs->super); + ext2fs_mark_super_dirty(fs); + } else if (ret == 1 && + fix_problem(ctx, PR_6_ORPHAN_FILE_CORRUPTED, &pctx)) { + int orphan_file_blocks; + + if (ctx->invalid_bitmaps) { + fix_problem(ctx, + PR_6_ORPHAN_FILE_BITMAP_INVALID, + &pctx); + goto check_quotas; + } + + retval = ext2fs_truncate_orphan_file(fs); + if (retval) { + /* Huh, failed to truncate file */ + fix_problem(ctx, PR_6_ORPHAN_FILE_TRUNC_FAILED, + &pctx); + goto check_quotas; + } + + orphan_file_blocks = + ext2fs_default_orphan_file_blocks(fs); + log_out(ctx, _("Creating orphan file (%d blocks): "), + orphan_file_blocks); + fflush(stdout); + retval = ext2fs_create_orphan_file(fs, + orphan_file_blocks); + if (retval) { + log_out(ctx, "%s: while trying to create " + "orphan file\n", error_message(retval)); + fix_problem(ctx, PR_6_ORPHAN_FILE_CREATE_FAILED, + &pctx); + goto check_quotas; + } + log_out(ctx, "%s", _(" Done.\n")); + } + } else if (ext2fs_has_feature_orphan_present(fs->super) && + fix_problem(ctx, PR_6_ORPHAN_PRESENT_NO_FILE, &pctx)) { + ext2fs_clear_feature_orphan_present(fs->super); + ext2fs_mark_super_dirty(fs); + } +check_quotas: + if (ctx->qctx && !ctx->invalid_bitmaps) { int needs_writeout; for (qtype = 0; qtype < MAXQUOTAS; qtype++) { @@ -1988,6 +2056,7 @@ no_journal: goto restart; } +cleanup: #ifdef MTRACE mtrace_print("Cleanup"); #endif From patchwork Wed Jun 16 10:57:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492883 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=bsAZVVBH; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=zMetrdtu; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hws1TXVz9sWl for ; Wed, 16 Jun 2021 20:57:49 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231672AbhFPK7y (ORCPT ); Wed, 16 Jun 2021 06:59:54 -0400 Received: from smtp-out2.suse.de ([195.135.220.29]:35810 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231391AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id D69EC1FD70; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9//VL3jBOGhKr9yJAsWh0HMkNbxa5TY9gnH+hhZMqX4=; b=bsAZVVBHxMsfIAqBnnB9OJJUpwlwy0I3Z0HoybD0ppSEb57/561vFKQD5kTT479CHoflwv tzVq7nANn6ULJvaQjYUZcsGmTsgeR3Bram8d6gkrTh2eYAt3BlLJxUNfKOjrSNEZe0kXw8 BrPusAmSTSwXhwJGbecS4GCJbID9O4w= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9//VL3jBOGhKr9yJAsWh0HMkNbxa5TY9gnH+hhZMqX4=; b=zMetrdtuxtWZeyxz172GcAhRjstQkrsug0Dq9+AvFcSm3SSYBQ1ZdOb6L5UVv9P7TAI6/6 NcniPBpF5YCQFFCw== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id B66FBA3BA1; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 72C461F2CC0; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 7/9] tune2fs: Add support for orphan_file feature Date: Wed, 16 Jun 2021 12:57:33 +0200 Message-Id: <20210616105735.5424-8-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Signed-off-by: Jan Kara --- misc/tune2fs.8.in | 5 +++ misc/tune2fs.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/misc/tune2fs.8.in b/misc/tune2fs.8.in index b963f30edef3..849f94b68d6e 100644 --- a/misc/tune2fs.8.in +++ b/misc/tune2fs.8.in @@ -257,6 +257,11 @@ program. This superblock setting is only honored in 2.6.35+ kernels; and not at all by the ext2 and ext3 file system drivers. .TP +.BI orphan_file_size= size +Set size of the file for tracking unlinked but still open inodes and inodes +with truncate in progress. Larger file allows for better scalability, reserving +a few blocks per cpu is ideal. +.TP .B force_fsck Set a flag in the filesystem superblock indicating that errors have been found. This will force fsck to run at the next mount. diff --git a/misc/tune2fs.c b/misc/tune2fs.c index f739f16cd62b..4d4cf5a13384 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -106,6 +106,7 @@ int enabling_casefold; int journal_size, journal_fc_size, journal_flags; char *journal_device; static blk64_t journal_location = ~0LL; +static e2_blkcnt_t orphan_file_blocks; static struct list_head blk_move_list; @@ -152,7 +153,8 @@ static __u32 ok_features[3] = { EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_DIR_INDEX | EXT4_FEATURE_COMPAT_FAST_COMMIT | - EXT4_FEATURE_COMPAT_STABLE_INODES, + EXT4_FEATURE_COMPAT_STABLE_INODES | + EXT4_FEATURE_COMPAT_ORPHAN_FILE, /* Incompat */ EXT2_FEATURE_INCOMPAT_FILETYPE | EXT3_FEATURE_INCOMPAT_EXTENTS | @@ -183,7 +185,8 @@ static __u32 clear_ok_features[3] = { EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_RESIZE_INODE | EXT2_FEATURE_COMPAT_DIR_INDEX | - EXT4_FEATURE_COMPAT_FAST_COMMIT, + EXT4_FEATURE_COMPAT_FAST_COMMIT | + EXT4_FEATURE_COMPAT_ORPHAN_FILE, /* Incompat */ EXT2_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_FLEX_BG | @@ -1143,6 +1146,55 @@ static int update_feature_set(ext2_filsys fs, char *features) } } + if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE)) { + ext2_ino_t ino; + + if (mount_flags & EXT2_MF_MOUNTED) { + fputs(_("The orphan_file feature may only be cleared " + "when the filesystem is unmounted.\n"), stderr); + return 1; + } + if (ext2fs_has_feature_orphan_present(sb) && f_flag < 2) { + fputs(_("The orphan_present flag is set. Please run " + "e2fsck before clearing orphan_file flag.\n"), + stderr); + return 1; + } + err = ext2fs_read_bitmaps(fs); + if (err) { + com_err(program_name, err, "%s", + _("while loading bitmaps")); + return 1; + } + err = ext2fs_truncate_orphan_file(fs); + if (err) { + com_err(program_name, err, + _("\n\twhile trying to delete orphan file\n")); + return 1; + } + ino = sb->s_orphan_file_inum; + sb->s_orphan_file_inum = 0; + ext2fs_inode_alloc_stats2(fs, ino, -1, 0); + ext2fs_clear_feature_orphan_file(sb); + ext2fs_clear_feature_orphan_present(sb); + ext2fs_mark_super_dirty(fs); + } + + if (FEATURE_ON(E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_ORPHAN_FILE)) { + if (!ext2fs_has_feature_journal(sb)) { + fputs(_("orphan_file flag can be set only for " + "filesystems with journal.\n"), stderr); + return 1; + } + /* + * If adding an orphan file, let the create orphan file + * code below handle setting the flag and creating it. + * We supply a default size if necessary. + */ + orphan_file_blocks = ext2fs_default_orphan_file_blocks(fs); + ext2fs_set_feature_orphan_file(sb); + } + if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) { if (ext2fs_has_feature_meta_bg(sb)) { @@ -2262,6 +2314,21 @@ static int parse_extended_opts(ext2_filsys fs, const char *opts) continue; } encoding_flags = arg; + } else if (!strcmp(token, "orphan_file_size")) { + if (!arg) { + r_usage++; + continue; + } + orphan_file_blocks = parse_num_blocks2(arg, + fs->super->s_log_block_size); + + if (orphan_file_blocks < 1) { + fprintf(stderr, + _("Invalid size of orphan file %s\n"), + arg); + r_usage++; + continue; + } } else r_usage++; } @@ -3247,6 +3314,24 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n" if (rc) goto closefs; } + if (orphan_file_blocks) { + errcode_t err; + + err = ext2fs_read_bitmaps(fs); + if (err) { + com_err(program_name, err, "%s", + _("while loading bitmaps")); + rc = 1; + goto closefs; + } + err = ext2fs_create_orphan_file(fs, orphan_file_blocks); + if (err) { + com_err(program_name, err, "%s", + _("while creating orphan file")); + rc = 1; + goto closefs; + } + } if (Q_flag) { if (mount_flags & EXT2_MF_MOUNTED) { From patchwork Wed Jun 16 10:57:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492882 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=1dokGFEk; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=tNYLMhCw; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwr6ssNz9sW8 for ; Wed, 16 Jun 2021 20:57:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231666AbhFPK7x (ORCPT ); Wed, 16 Jun 2021 06:59:53 -0400 Received: from smtp-out2.suse.de ([195.135.220.29]:35808 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231373AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id D64271FD6F; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bzNcke28CCdvhGi1On7m4Wh58678UhE+mdrTdbKpFgs=; b=1dokGFEk73BE3pKVh1mS+cnPGLnw10NzRhgIN8vNnTZEB+j65FembphlfOeb6dReJLTZrH taZq9Yek0whIOgatlqF7zgQ9MO8BjMcOZ7tsYC8rwhAskoIxVBpMQN83SgvsZ1jm/W8xBS PPMOCC1j8ks0TTE+Hb2pxFBr7O3xLOY= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bzNcke28CCdvhGi1On7m4Wh58678UhE+mdrTdbKpFgs=; b=tNYLMhCw4uWU+NtmVn5x0CvakLDhJGAqchYlpyiGEurpTKkFBHm8VTt4FFbaSrWaVqQGdo t0ZrfVO7V/+MnfAQ== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id B6748A3BAB; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 75BCD1F2CC1; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 8/9] mke2fs: Add orphan_file feature into mke2fs.conf Date: Wed, 16 Jun 2021 12:57:34 +0200 Message-Id: <20210616105735.5424-9-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Enable orphan_file feature by default in larger filesystems. Since the feature is COMPAT, older kernels will just ignore it and happily work with the filesystem as well. Signed-off-by: Jan Kara --- misc/mke2fs.conf.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/misc/mke2fs.conf.in b/misc/mke2fs.conf.in index 01e35cf83150..d97d8d643d1d 100644 --- a/misc/mke2fs.conf.in +++ b/misc/mke2fs.conf.in @@ -11,15 +11,17 @@ features = has_journal } ext4 = { - features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize + features = has_journal,extent,huge_file,flex_bg,metadata_csum,64bit,dir_nlink,extra_isize,orphan_file inode_size = 256 } small = { + default_features = ^orphan_file blocksize = 1024 inode_size = 128 inode_ratio = 4096 } floppy = { + default_features = ^orphan_file blocksize = 1024 inode_size = 128 inode_ratio = 8192 From patchwork Wed Jun 16 10:57:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kara X-Patchwork-Id: 1492885 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=suse.cz header.i=@suse.cz header.a=rsa-sha256 header.s=susede2_rsa header.b=uokbQCqw; dkim=pass header.d=suse.cz header.i=@suse.cz header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=zoHg8ux+; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4G4hwv1MRZz9sWX for ; Wed, 16 Jun 2021 20:57:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231699AbhFPK7z (ORCPT ); Wed, 16 Jun 2021 06:59:55 -0400 Received: from smtp-out2.suse.de ([195.135.220.29]:35824 "EHLO smtp-out2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231441AbhFPK7w (ORCPT ); Wed, 16 Jun 2021 06:59:52 -0400 Received: from relay2.suse.de (relay2.suse.de [149.44.160.134]) by smtp-out2.suse.de (Postfix) with ESMTP id DE53C1FD7C; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0Pb/2tVFedocS+FH0D59jy+87lCOXbgCfd1rnKsgzts=; b=uokbQCqwa15nH9LModYQAayd8LaVk2t+EMH+ETog+L09iZMmJOsLMkhPsblK/lrlhwE898 hlPvUdE9j9orNwcOtxJhGw1P9086xhfG/SBK/DpaK+kgvUlOwqihElZC/eN8WOYiYC5EDA fv4zskYrmyLcMcfOPvv6uJ8mg4pPjaM= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1623841065; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0Pb/2tVFedocS+FH0D59jy+87lCOXbgCfd1rnKsgzts=; b=zoHg8ux+0y4/l//CIsAu3+TueG6NkCLFBDz/P3ZAXD3LdI/+pyA5sI1BDpG5XHnjcpvAbs C9edMBxEUH68AFBQ== Received: from quack2.suse.cz (unknown [10.100.200.198]) by relay2.suse.de (Postfix) with ESMTP id B8E40A3BAC; Wed, 16 Jun 2021 10:57:45 +0000 (UTC) Received: by quack2.suse.cz (Postfix, from userid 1000) id 79D751F2CC2; Wed, 16 Jun 2021 12:57:45 +0200 (CEST) From: Jan Kara To: Ted Tso Cc: , Jan Kara Subject: [PATCH 9/9] dumpe2fs, debugfs, e2image: Add support for orphan file Date: Wed, 16 Jun 2021 12:57:35 +0200 Message-Id: <20210616105735.5424-10-jack@suse.cz> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210616105735.5424-1-jack@suse.cz> References: <20210616105735.5424-1-jack@suse.cz> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Print inode number of orphan file in outputs, dump e2image file to filesystem image. Signed-off-by: Jan Kara --- debugfs/set_fields.c | 1 + lib/e2p/ls.c | 3 +++ misc/e2image.c | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c index b00157940774..f916deab8cea 100644 --- a/debugfs/set_fields.c +++ b/debugfs/set_fields.c @@ -183,6 +183,7 @@ static struct field_set_info super_fields[] = { { "lpf_ino", &set_sb.s_lpf_ino, NULL, 4, parse_uint }, { "checksum_seed", &set_sb.s_checksum_seed, NULL, 4, parse_uint }, { "encoding", &set_sb.s_encoding, NULL, 2, parse_encoding }, + { "orphan_file_inum", &set_sb.s_orphan_file_inum, NULL, 4, parse_uint }, { 0, 0, 0, 0 } }; diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c index 176bee0fd19f..1762bc44cac4 100644 --- a/lib/e2p/ls.c +++ b/lib/e2p/ls.c @@ -482,6 +482,9 @@ void list_super2(struct ext2_super_block * sb, FILE *f) if (ext2fs_has_feature_casefold(sb)) fprintf(f, "Character encoding: %s\n", e2p_encoding2str(sb->s_encoding)); + if (ext2fs_has_feature_orphan_file(sb)) + fprintf(f, "Orphan file inode: %u\n", + sb->s_orphan_file_inum); } void list_super (struct ext2_super_block * s) diff --git a/misc/e2image.c b/misc/e2image.c index ac00827e4628..a9c64506d7cc 100644 --- a/misc/e2image.c +++ b/misc/e2image.c @@ -1369,7 +1369,8 @@ static void write_raw_image_file(ext2_filsys fs, int fd, int type, int flags, ino == fs->super->s_journal_inum || ino == quota_type2inum(USRQUOTA, fs->super) || ino == quota_type2inum(GRPQUOTA, fs->super) || - ino == quota_type2inum(PRJQUOTA, fs->super)) { + ino == quota_type2inum(PRJQUOTA, fs->super) || + ino == fs->super->s_orphan_file_inum) { retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_READ_ONLY, block_buf, process_dir_block, &pb);