Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp1283038pxp; Thu, 10 Mar 2022 02:23:56 -0800 (PST) X-Google-Smtp-Source: ABdhPJzf+TCYN/mFprr16yXfY2Dcz0JjM8782JjYFOYTxlRdzdfJ/cis005cAtPszRYMihxGjEpM X-Received: by 2002:a17:90b:4a52:b0:1be:fb7c:9fef with SMTP id lb18-20020a17090b4a5200b001befb7c9fefmr15204352pjb.57.1646907836562; Thu, 10 Mar 2022 02:23:56 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1646907836; cv=none; d=google.com; s=arc-20160816; b=tYD39VXHqiAXAbS2SsKvZCyMr521/Ts1yN8jfrahIfDekmp9+vxDXQA01J+BZURLcp Sx2Az0UZJ2dCCuKLeThhOngJPd9GrwggxjcTuvWTHVvOgYgDA9zj1YjBDC+axDwTTlYT YBFEDtZrZF4G78YaJLt81noFtg7almFhryZDjrKs2mY2XRKz7jzNibJeQli+9MEL+2AS 6iZXm3uf3YI80PaGkDI/qbJFOshvVWLblEDk4FCe7DSGZMurT+rwfn1ist4Mc4pbi2D3 +ZHDnDieqdLXX8N1x37+nKvtC3Gm/Wkaw3fmgyZND9019LIJ7jswEJ6WvMgMLtzgI+4W LfLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:to:from:date:dkim-signature; bh=V1oeC4nusLmxbGSdtSvxcwfue4tToad/PIZRfqBjnVY=; b=sW/2k+96Y0DWUW/G5Ubblf6Fru/tN/RZd8gCRIP6BbifJMfOMtqY5s2HafbAhRrBrc T6aCGe7zu/sy8EeCBCj7/PfXZmz8SIK1no5wSeRy/EyYFyFO0zBxaxVKHgRnaTCYmzm2 etoSAY6vAUPzf+QU6Iv9aDXolanKsh/RtEp3jgU+G7IKunWjSC1Q4pKBUNKLZNGEDNFK YpebRaoR3a3vT8huJYwZxdJB1ugTn4aCrIyW4LO52dTDC3vjzyhn+9NknZIKNV0BS0Gg w4EFmWqbB5ecJtnFldtO3R6B1rv+/MEeaCCnUpC3nRAMW/KuR62D1igpwCKF7Q7R//KQ I7jQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=f4MWATkQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y184-20020a638ac1000000b00380b1d47aafsi4249285pgd.758.2022.03.10.02.23.41; Thu, 10 Mar 2022 02:23:56 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=f4MWATkQ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236913AbiCJCxi (ORCPT + 99 others); Wed, 9 Mar 2022 21:53:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236425AbiCJCxf (ORCPT ); Wed, 9 Mar 2022 21:53:35 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61C46E6C for ; Wed, 9 Mar 2022 18:52:33 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 966CDB81EA4 for ; Thu, 10 Mar 2022 02:52:32 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3AEBDC340E8; Thu, 10 Mar 2022 02:52:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1646880751; bh=HpVTTTr8PbusXmul2H66Jzw0dd3D6fNFf0OwnRc1hII=; h=Date:From:To:Subject:References:In-Reply-To:From; b=f4MWATkQ+7vf8dtfeA81v0X/sgvqFAu+mM4dunCMdO8EAU2Y4LotDp/fkVC0H9HeO aUPaIIEPx92v6JQd7DetqSe6bQQBKE19S0mUnQcs7nSpEVh4bhsW9Yi1tNZjwWIdmR 3CE728pFYvQ5y0l3GwP2iKSOVjIMEVXHi/RD1THzMRWHh0agFf4W5DOH6oIUz66mPr P4HgUoL+IeVvZ5zXdX80GHxUq6ayMUCRSPclsuJH9ZOIA10ec6X1l+dcSpQVFpgOie KOrjP9Q0VSmGoARLl5LhsBlIcDhOlsqpdLPCpvAZ9X+vMPncAK5WrKw/yiIV3TRCbd eSXe+HjxrYxwg== Date: Wed, 9 Mar 2022 18:52:29 -0800 From: Jaegeuk Kim To: linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net Subject: Re: [PATCH 1/2 v2] f2fs: do not expose unwritten blocks to user by DIO Message-ID: References: <20220309214834.3408741-1-jaegeuk@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220309214834.3408741-1-jaegeuk@kernel.org> X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org DIO preallocates physical blocks before writing data, but if an error occurrs or power-cut happens, we can see block contents from the disk. This patch tries to fix it by 1) turning to buffered writes for DIO into holes, 2) truncating unwritten blocks from error or power-cut. Signed-off-by: Jaegeuk Kim --- - log from v1: added documentation fs/f2fs/data.c | 5 ++++- fs/f2fs/f2fs.h | 5 +++++ fs/f2fs/file.c | 27 ++++++++++++++++++--------- fs/f2fs/inode.c | 8 ++++++++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 3db0f3049b90..9c867de1ec29 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1543,8 +1543,11 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, flag != F2FS_GET_BLOCK_DIO); err = __allocate_data_block(&dn, map->m_seg_type); - if (!err) + if (!err) { + if (flag == F2FS_GET_BLOCK_PRE_DIO) + file_need_truncate(inode); set_inode_flag(inode, FI_APPEND_WRITE); + } } if (err) goto sync_out; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 6f196621f772..d7435fcb9658 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -654,6 +654,7 @@ enum { #define FADVISE_KEEP_SIZE_BIT 0x10 #define FADVISE_HOT_BIT 0x20 #define FADVISE_VERITY_BIT 0x40 +#define FADVISE_TRUNC_BIT 0x80 #define FADVISE_MODIFIABLE_BITS (FADVISE_COLD_BIT | FADVISE_HOT_BIT) @@ -681,6 +682,10 @@ enum { #define file_is_verity(inode) is_file(inode, FADVISE_VERITY_BIT) #define file_set_verity(inode) set_file(inode, FADVISE_VERITY_BIT) +#define file_should_truncate(inode) is_file(inode, FADVISE_TRUNC_BIT) +#define file_need_truncate(inode) set_file(inode, FADVISE_TRUNC_BIT) +#define file_dont_truncate(inode) clear_file(inode, FADVISE_TRUNC_BIT) + #define DEF_DIR_LEVEL 0 enum { diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 808a7c24d993..e1445cf915ea 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1687,6 +1687,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset, map.m_seg_type = CURSEG_COLD_DATA_PINNED; err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO); + file_dont_truncate(inode); up_write(&sbi->pin_sem); @@ -4257,6 +4258,13 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter) /* If it will be an out-of-place direct write, don't bother. */ if (dio && f2fs_lfs_mode(sbi)) return 0; + /* + * Don't preallocate holes aligned to DIO_SKIP_HOLES which turns into + * buffered IO, if DIO meets any holes. + */ + if (dio && i_size_read(inode) && + (F2FS_BYTES_TO_BLK(pos) < F2FS_BLK_ALIGN(i_size_read(inode)))) + return 0; /* No-wait I/O can't allocate blocks. */ if (iocb->ki_flags & IOCB_NOWAIT) @@ -4292,8 +4300,8 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter) } ret = f2fs_map_blocks(inode, &map, 1, flag); - /* -ENOSPC is only a fatal error if no blocks could be allocated. */ - if (ret < 0 && !(ret == -ENOSPC && map.m_len > 0)) + /* -ENOSPC|-EDQUOT are fine to report the number of allocated blocks. */ + if (ret < 0 && !((ret == -ENOSPC || ret == -EDQUOT) && map.m_len > 0)) return ret; if (ret == 0) set_inode_flag(inode, FI_PREALLOCATED_ALL); @@ -4359,20 +4367,21 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) /* Possibly preallocate the blocks for the write. */ target_size = iocb->ki_pos + iov_iter_count(from); preallocated = f2fs_preallocate_blocks(iocb, from); - if (preallocated < 0) { + if (preallocated < 0) ret = preallocated; - goto out_unlock; - } - - ret = __generic_file_write_iter(iocb, from); + else + ret = __generic_file_write_iter(iocb, from); /* Don't leave any preallocated blocks around past i_size. */ - if (preallocated > 0 && i_size_read(inode) < target_size) { + if (preallocated && i_size_read(inode) < target_size) { down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping); - f2fs_truncate(inode); + if (!f2fs_truncate(inode)) + file_dont_truncate(inode); filemap_invalidate_unlock(inode->i_mapping); up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + } else { + file_dont_truncate(inode); } clear_inode_flag(inode, FI_PREALLOCATED_ALL); diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 0f8b2df3e1e0..6998eb1d6bdb 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -544,6 +544,14 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) goto bad_inode; } f2fs_set_inode_flags(inode); + + if (file_should_truncate(inode)) { + ret = f2fs_truncate(inode); + if (ret) + goto bad_inode; + file_dont_truncate(inode); + } + unlock_new_inode(inode); trace_f2fs_iget(inode); return inode; -- 2.34.1.400.ga245620fadb-goog