From patchwork Fri Aug 21 07:38:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Omar Sandoval X-Patchwork-Id: 11728451 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 955C61392 for ; Fri, 21 Aug 2020 07:39:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7ABEB21775 for ; Fri, 21 Aug 2020 07:39:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=osandov-com.20150623.gappssmtp.com header.i=@osandov-com.20150623.gappssmtp.com header.b="JEJATJnT" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728123AbgHUHjm (ORCPT ); Fri, 21 Aug 2020 03:39:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728036AbgHUHjJ (ORCPT ); Fri, 21 Aug 2020 03:39:09 -0400 Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D3F2C06134B for ; Fri, 21 Aug 2020 00:39:06 -0700 (PDT) Received: by mail-pl1-x644.google.com with SMTP id y10so504355plr.11 for ; Fri, 21 Aug 2020 00:39:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=osandov-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=reb1cFIlvC8AHbYRUQvz0dOYFqG+X8Ib/9wa8g4PRW0=; b=JEJATJnTis8ttC7gmMyPmDRS9ihTtYCc69cq2xwc2M6H05AvUjid1ENsnzAhjl2CVL 19wL1cPXNl0nsvMfiWwwFTjwbYxdyuBUEt/2Ypmrp7BCgLrEnXQYEf3G0WEiEGICkvVg FpMKYtT5QWiLymZS3zpiOXW8I73JoGXtFpNvghr/727HmeRsLp/wizve4NVsRP68bus8 DOkQFqndEZn/eHbqGxu9kMeXm9tNgbMXp4+dD7Uc7ug3mIEAWTyJFH/oDAVPIhP+ndTP SjTIBjVIzWbwuB1068E5Kvg73FvKpVChypPJ4CwNZglBgxz8Kt3/WJ4J3Zs+V+3LgV/a rh9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=reb1cFIlvC8AHbYRUQvz0dOYFqG+X8Ib/9wa8g4PRW0=; b=ac/Do1Nzk1qbe1UjtsliIFOdvFKoR+Usr7AtR2qtT8NP8KBxprH5ccZfcdwSl0LlDu B+wZ9W/YRQDJ5N0Tz90v7kyYGQ3Tj8PmaZTvBd/f3AJgvk0xYj3uDdQfBUIqawNKDxl7 so19z6zpObpk1i7WxDvBq2u1njZiPjfx7FVZYW/YwLF2fbns0kVtqIK4YyPHH0PCuqIB 4nm5cFtmqTRtO2HW9OPi+fd3rQ+w5UDBaQwpj3Ou3yARwg4gQyLz06a2djHM2rW/UUi5 aPKWsN7VaH9c3jcLXddifFSMwd0UH2Gx1wKso5ok8+J/7drOu2pLwYjm2Mse2jWEYATS UGrQ== X-Gm-Message-State: AOAM530x2HWUG1XWAJf7NZXRnIGP4uXX7VvOAbbWyYa9a6mjYb77KY0P RsnAJuSPbPWUAlIThXTzI3Mxib9RAMKfag== X-Google-Smtp-Source: ABdhPJzdV2Py/H7JSvdHazVL/eGihjwSD+jTaymC/W1d8DuR7oj3DAhHcBNru4j9j07dHU1Ndzf83A== X-Received: by 2002:a17:902:fe0d:: with SMTP id g13mr1343458plj.287.1597995545240; Fri, 21 Aug 2020 00:39:05 -0700 (PDT) Received: from exodia.tfbnw.net ([2620:10d:c090:400::5:f2a4]) by smtp.gmail.com with ESMTPSA id t10sm1220867pgp.15.2020.08.21.00.39.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Aug 2020 00:39:04 -0700 (PDT) From: Omar Sandoval To: linux-fsdevel@vger.kernel.org, linux-btrfs@vger.kernel.org, Al Viro , Christoph Hellwig Cc: Dave Chinner , Jann Horn , Amir Goldstein , Aleksa Sarai , linux-api@vger.kernel.org, kernel-team@fb.com Subject: [PATCH v5 6/9] btrfs: support different disk extent size for delalloc Date: Fri, 21 Aug 2020 00:38:37 -0700 Message-Id: <61dd1001b124fc1b09e43e27b804c5f8d597640a.1597993855.git.osandov@osandov.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org From: Omar Sandoval Currently, we always reserve the same extent size in the file and extent size on disk for delalloc because the former is the worst case for the latter. For RWF_ENCODED writes, we know the exact size of the extent on disk, which may be less than or greater than (for bookends) the size in the file. Add a disk_num_bytes parameter to btrfs_delalloc_reserve_metadata() so that we can reserve the correct amount of csum bytes. No functional change. Reviewed-by: Nikolay Borisov Signed-off-by: Omar Sandoval Reviewed-by: Josef Bacik --- fs/btrfs/ctree.h | 3 ++- fs/btrfs/delalloc-space.c | 18 ++++++++++-------- fs/btrfs/file.c | 3 ++- fs/btrfs/inode.c | 3 ++- fs/btrfs/relocation.c | 4 ++-- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index cbbfaedd6e3c..47581706a132 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2626,7 +2626,8 @@ void btrfs_subvolume_release_metadata(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *rsv); void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes); -int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes); +int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, + u64 disk_num_bytes); u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo); int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info, u64 start, u64 end); diff --git a/fs/btrfs/delalloc-space.c b/fs/btrfs/delalloc-space.c index bacee09b7bfd..948b78f03f63 100644 --- a/fs/btrfs/delalloc-space.c +++ b/fs/btrfs/delalloc-space.c @@ -265,11 +265,11 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info, } static void calc_inode_reservations(struct btrfs_fs_info *fs_info, - u64 num_bytes, u64 *meta_reserve, - u64 *qgroup_reserve) + u64 num_bytes, u64 disk_num_bytes, + u64 *meta_reserve, u64 *qgroup_reserve) { u64 nr_extents = count_max_extents(num_bytes); - u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, num_bytes); + u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes); u64 inode_update = btrfs_calc_metadata_size(fs_info, 1); *meta_reserve = btrfs_calc_insert_metadata_size(fs_info, @@ -283,7 +283,8 @@ static void calc_inode_reservations(struct btrfs_fs_info *fs_info, *qgroup_reserve = nr_extents * fs_info->nodesize; } -int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) +int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes, + u64 disk_num_bytes) { struct btrfs_root *root = inode->root; struct btrfs_fs_info *fs_info = root->fs_info; @@ -313,6 +314,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) } num_bytes = ALIGN(num_bytes, fs_info->sectorsize); + disk_num_bytes = ALIGN(disk_num_bytes, fs_info->sectorsize); /* * We always want to do it this way, every other way is wrong and ends @@ -324,8 +326,8 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) * everything out and try again, which is bad. This way we just * over-reserve slightly, and clean up the mess when we are done. */ - calc_inode_reservations(fs_info, num_bytes, &meta_reserve, - &qgroup_reserve); + calc_inode_reservations(fs_info, num_bytes, disk_num_bytes, + &meta_reserve, &qgroup_reserve); ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true); if (ret) return ret; @@ -344,7 +346,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes) spin_lock(&inode->lock); nr_extents = count_max_extents(num_bytes); btrfs_mod_outstanding_extents(inode, nr_extents); - inode->csum_bytes += num_bytes; + inode->csum_bytes += disk_num_bytes; btrfs_calculate_inode_block_rsv_size(fs_info, inode); spin_unlock(&inode->lock); @@ -448,7 +450,7 @@ int btrfs_delalloc_reserve_space(struct btrfs_inode *inode, ret = btrfs_check_data_free_space(inode, reserved, start, len); if (ret < 0) return ret; - ret = btrfs_delalloc_reserve_metadata(inode, len); + ret = btrfs_delalloc_reserve_metadata(inode, len, len); if (ret < 0) btrfs_free_reserved_data_space(inode, *reserved, start, len); return ret; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 5a818ebcb01f..ed236cbe8adb 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1706,7 +1706,8 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, WARN_ON(reserve_bytes == 0); ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), - reserve_bytes); + reserve_bytes, + reserve_bytes); if (ret) { if (!only_release_metadata) btrfs_free_reserved_data_space(BTRFS_I(inode), diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e71fb848838d..e607c6a14faf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4546,7 +4546,8 @@ int btrfs_truncate_block(struct inode *inode, loff_t from, loff_t len, goto out; } } - ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), blocksize); + ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), blocksize, + blocksize); if (ret < 0) { if (!only_release_metadata) btrfs_free_reserved_data_space(BTRFS_I(inode), diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 4ba1ab9cc76d..d8e922469721 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2705,8 +2705,8 @@ static int relocate_file_extent_cluster(struct inode *inode, index = (cluster->start - offset) >> PAGE_SHIFT; last_index = (cluster->end - offset) >> PAGE_SHIFT; while (index <= last_index) { - ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), - PAGE_SIZE); + ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), PAGE_SIZE, + PAGE_SIZE); if (ret) goto out;