From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A066EC61DC2 for ; Thu, 27 Aug 2026 09:24:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: Reply-To:From:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Subject:In-Reply-To:References:To:MIME-Version:Date: Message-ID:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=OgBk4SM7QSvakH06r2f3Xk5OLnqL9vD8xfw7yqo5iPc=; b=EwBPkvIZnFmHjeV52ZyK1V0LSx NOpyb+3tBlVO6iJAzfrM2rnaY/YWQ1iaUhO8RXYRwINn92RUVdAnG2WKk3ZDyBolDS1UyYnDAHdMm uXdd/P+FuVb+mn7UJLgRayCm1gnXoTCMg1361MvBKSG85vM/EAxVlLIYYBDAVPXHgbco=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzWLS-0000Oc-4K; Thu, 27 Aug 2026 09:24:26 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzWLI-0000OQ-3e for linux-f2fs-devel@lists.sourceforge.net; Thu, 27 Aug 2026 09:24:16 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: From:References:To:Subject:Cc:MIME-Version:Date:Message-ID:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=hOkytZV0Gmu3k8FlxDUznDi0+0beZnhW5bCwVj5T1M8=; b=HzR7N2mfDRmWPMEQGjyhtHwhAq O8qh1nhBvMbMaOCK4zf9qS+OwzCIRX6TEi9Z2rJ3fwg+6wRe4p69K1yUz9V9KVQ3yI6hR1zsJIw/o EeJzLUL0weYepHdhO+9BiNknPWCyK6a07pnh0yZcmM9T6aVP+zuOFG2bGosSakTQEf2k=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:From:References:To: Subject:Cc:MIME-Version:Date:Message-ID:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=hOkytZV0Gmu3k8FlxDUznDi0+0beZnhW5bCwVj5T1M8=; b=AG1TovcO2XCXbpKOryidPQPMMb f6VMVKVgOu5o/28lC23Ty15m/QNrPtejK8z5njexqjoBROnRsLdtEyHSxciG/PfoJuaypflIwqAiT /ejNRFasSImgM+8bXorV6bwelMXiZ/Y+jEjyKBRZxijJ/px1Pl7BSeMCtvJgiyrL9F3M=; Received: from sea.source.kernel.org ([172.234.252.31]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzWLI-0001rU-2d for linux-f2fs-devel@lists.sourceforge.net; Thu, 27 Aug 2026 09:24:16 +0000 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id B1EB443942; Thu, 27 Aug 2026 09:24:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 95C031F00A3A; Thu, 27 Aug 2026 09:24:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1787822650; bh=hOkytZV0Gmu3k8FlxDUznDi0+0beZnhW5bCwVj5T1M8=; h=Date:Cc:Subject:To:References:From:In-Reply-To; b=enbT/nO0/4dO16FcQ4Nz8RezCHgVYKqKhKw+PFcv4AwINaeysKuPqPY/zYEe5L/py sZqIA6olQEKFqd/YW0Wr6Tm40f5kqi1u65f9+WCiRyqu56ww/leeCXR/8Fb01+pgeK 9Mf3MX7lq4PX2pJc/b+2jXnah7Y5mdoYxZsZOjnvHS2IyNHi8/UnsUAD8s+DKmrv4E eMVcJCls5rTEjuhy1ur5+mHTV9Q61kGTuy9UfprVFPkeeLTtoLjnEH8d1cwjTriZZU 3SQl8TqC2+hi4G8kbwkdmta6a9V7W85LJ22YwO5IWMOpXbNZHvbRh6PTjtTqyaemnn KhEX5WLqM0M/A== Message-ID: <9a00f46d-1fc6-454d-9c77-89ae51266c01@kernel.org> Date: Thu, 27 Aug 2026 17:24:06 +0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: Nanzhe Zhao , linux-f2fs-devel@lists.sourceforge.net, Jaegeuk Kim References: <20260826082641.2007658-1-zhaonanzhe@xiaomi.com> <20260826082641.2007658-5-zhaonanzhe@xiaomi.com> Content-Language: en-US In-Reply-To: <20260826082641.2007658-5-zhaonanzhe@xiaomi.com> X-Headers-End: 1wzWLI-0001rU-2d Subject: Re: [f2fs-dev] [PATCH 04/14] f2fs: support atomic file large folios buffered write X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Chao Yu via Linux-f2fs-devel Reply-To: Chao Yu Cc: Barry Song , Juan Yescas , Dev Jain , linux-kernel@vger.kernel.org, David Hildenbrand , Bo Zhang , Kalesh Singh , Nanzhe Zhao , Pengfei Li , Ryan Roberts Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net On 8/26/26 16:26, Nanzhe Zhao wrote: > ioctl can convert an inode with large folio support into an atomic > file. Support large folio buffered writes for atomic files as well. > > Add a large folio atomic write_begin helper that reserves COW mappings > for the write range. For partial head and tail subpages, read the > existing data from either the COW inode or the original inode before > marking the subpage uptodate. > > Signed-off-by: Nanzhe Zhao > --- > fs/f2fs/data.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 121 insertions(+), 2 deletions(-) > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index 7ce96ae02cfc..dff802725544 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -4211,6 +4211,117 @@ static int prepare_large_folio_write_begin(struct inode *inode, > return 0; > } > > +static int prepare_large_folio_atomic_write_begin(struct inode *inode, > + struct address_space *mapping, struct folio *folio, loff_t pos, > + unsigned int len) > +{ > + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > + struct inode *cow_inode = F2FS_I(inode)->cow_inode; > + size_t ori_off = offset_in_folio(folio, pos); > + size_t need_off = ori_off; > + pgoff_t index; > + int err = 0; > + unsigned int orig_order; > + bool need_balance = false; > + > + len = min_t(unsigned int, len, folio_size(folio) - ori_off); > + > + f2fs_ffs_find_or_alloc(folio); > + > + /* Inline data must have been converted before reaching here. */ > + f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); > + > + /* Reserve COW blocks for all covered 4K subpages first. */ > + pgoff_t start_index = folio->index + (ori_off >> PAGE_SHIFT); > + pgoff_t end_index = folio->index + > + ((ori_off + len - 1) >> PAGE_SHIFT); > + > + for (index = start_index; index <= end_index; index++) { > + block_t cow_blkaddr = NULL_ADDR; > + bool node_changed = false; > + int ret; > + > + ret = __find_data_block(cow_inode, index, &cow_blkaddr); > + if (ret) > + return ret; > + if (cow_blkaddr != NULL_ADDR) > + continue; > + > + ret = __reserve_data_block(cow_inode, index, &cow_blkaddr, > + &node_changed); > + if (ret) > + return ret; > + > + inc_atomic_write_cnt(inode); In order to not miss any logic in prepare_atomic_write_begin(), can you reuse prepare_atomic_write_begin() as much as possible? needs to change parameters a bit there. for (...) { err = prepare_atomic_write_begin(sbi, inode, index, pos, len, ...); ... } > + need_balance |= node_changed; > + } > + > + if (need_balance && !IS_NOQUOTA(inode) && > + has_not_enough_free_secs(sbi, 0, 0)) { > + orig_order = folio_order(folio); > + folio_unlock(folio); > + f2fs_balance_fs(sbi, true); > + folio_lock(folio); > + if (unlikely(folio->mapping != mapping || > + folio_order(folio) != orig_order)) > + return -EAGAIN; > + } > + > + if (folio_test_uptodate(folio) || len == folio_size(folio)) > + return 0; > + > + /* Then read partial 4K subpages. */ > + while (find_next_valid_block(folio, ori_off, &need_off, len)) { Can we record first and last blkaddr in first loop of prepare_large_folio_atomic_write_begin(), and then we can avoid lot of complexity below to find target blkaddr? We really don't want to miss any corner case of atomic write + large folio, please consider that. Thanks, > + size_t off; > + block_t cow_blkaddr = NULL_ADDR; > + block_t ori_blkaddr = NULL_ADDR; > + struct inode *read_inode = NULL; > + block_t read_blkaddr = NULL_ADDR; > + > + index = folio->index + (need_off >> PAGE_SHIFT); > + off = offset_in_folio(folio, index << PAGE_SHIFT); > + > + err = __find_data_block(cow_inode, index, &cow_blkaddr); > + if (err) > + return err; > + > + if (__is_valid_data_blkaddr(cow_blkaddr)) { > + if (!f2fs_is_valid_blkaddr(sbi, cow_blkaddr, > + DATA_GENERIC_ENHANCE_READ)) > + return -EFSCORRUPTED; > + read_inode = cow_inode; > + read_blkaddr = cow_blkaddr; > + } else if (is_inode_flag_set(inode, FI_ATOMIC_REPLACE)) { > + folio_zero_segment(folio, off, off + PAGE_SIZE); > + f2fs_ffs_mark_subrange_uptodate(folio, off, PAGE_SIZE); > + continue; > + } else { > + err = __find_data_block(inode, index, &ori_blkaddr); > + if (err) > + return err; > + > + if (!__is_valid_data_blkaddr(ori_blkaddr)) { > + folio_zero_segment(folio, off, off + PAGE_SIZE); > + f2fs_ffs_mark_subrange_uptodate(folio, off, PAGE_SIZE); > + continue; > + } > + > + if (!f2fs_is_valid_blkaddr(sbi, ori_blkaddr, > + DATA_GENERIC_ENHANCE_READ)) > + return -EFSCORRUPTED; > + read_inode = inode; > + read_blkaddr = ori_blkaddr; > + } > + > + err = f2fs_submit_page_read_sync(read_inode, folio, > + index, read_blkaddr); > + if (err) > + return err; > + } > + > + return 0; > +} > + > static int f2fs_write_begin(const struct kiocb *iocb, > struct address_space *mapping, > loff_t pos, unsigned len, struct folio **foliop, > @@ -4282,7 +4393,7 @@ static int f2fs_write_begin(const struct kiocb *iocb, > > *foliop = folio; > > - if (f2fs_is_atomic_file(inode)) > + if (f2fs_is_atomic_file(inode) && !folio_test_large(folio)) > err = prepare_atomic_write_begin(sbi, folio, pos, len, > &blkaddr, &need_balance); > else if (!folio_test_large(folio)) > @@ -4307,10 +4418,18 @@ static int f2fs_write_begin(const struct kiocb *iocb, > f2fs_folio_wait_writeback(folio, DATA, false, true); > > if (folio_test_large(folio)) { > - err = prepare_large_folio_write_begin(inode, > + if (f2fs_is_atomic_file(inode)) > + err = prepare_large_folio_atomic_write_begin(inode, > + mapping, folio, pos, len); > + else > + err = prepare_large_folio_write_begin(inode, > folio, pos, len); > if (!err) > return 0; > + if (err == -EAGAIN) { > + f2fs_folio_put(folio, true); > + goto repeat; > + } > goto put_folio; > } > _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel