From patchwork Wed Sep 9 08:19:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 11765063 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 1AD42746 for ; Wed, 9 Sep 2020 08:19:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 09ED6208FE for ; Wed, 9 Sep 2020 08:19:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726169AbgIIITR (ORCPT ); Wed, 9 Sep 2020 04:19:17 -0400 Received: from mail104.syd.optusnet.com.au ([211.29.132.246]:38962 "EHLO mail104.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbgIIITR (ORCPT ); Wed, 9 Sep 2020 04:19:17 -0400 Received: from dread.disaster.area (pa49-195-191-192.pa.nsw.optusnet.com.au [49.195.191.192]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id A68458243E2 for ; Wed, 9 Sep 2020 18:19:14 +1000 (AEST) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1kFvJx-00005K-FP for linux-xfs@vger.kernel.org; Wed, 09 Sep 2020 18:19:13 +1000 Received: from dave by discord.disaster.area with local (Exim 4.93) (envelope-from ) id 1kFvJx-004yO0-2F for linux-xfs@vger.kernel.org; Wed, 09 Sep 2020 18:19:13 +1000 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 1/3] xfs: EFI recovery needs it's own transaction reservation Date: Wed, 9 Sep 2020 18:19:10 +1000 Message-Id: <20200909081912.1185392-2-david@fromorbit.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200909081912.1185392-1-david@fromorbit.com> References: <20200909081912.1185392-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.3 cv=KcmsTjQD c=1 sm=1 tr=0 cx=a_idp_d a=vvDRHhr1aDYKXl+H6jx2TA==:117 a=vvDRHhr1aDYKXl+H6jx2TA==:17 a=reM5J-MqmosA:10 a=20KFwNOVAAAA:8 a=JTkEanIKHGTgUDm-kJgA:9 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Recovering an EFI currently uses a itruncate reservation, which is designed for a rolling transaction that modifies the BMBT and logs the EFI in one commit, then frees the space and logs the EFD in the second commit. Recovering the EFI only requires the second transaction in this pair, and hence has a smaller log space requirement than a truncate operation. Hence when the extent free is being processed at runtime, the log reservation that is held by the filesystem is only enough to complete the extent free, not the entire truncate operation. Hence if the EFI pins the tail of the log and the log fills up while the extent is being freed, the amount of reserved free space in the log is not enough to start another entire truncate operation. Hence if we crash at this point, log recovery will deadlock with the EFI pinning the tail of the log and the log not having enough free space to reserve an itruncate transaction. As such, EFI recovery needs it's own log space reservation separate to the itruncate reservation. We only need what is required free the extent, and this matches the space we have reserved at runtime for this operation and hence should prevent the recovery deadlock from occurring. This patch adds the new reservation in a way that minimises the change such that it should be back-portable to older kernels easily. Follow up patches will factor and rework the reservations to be more correct and more tightly defined. Note: this would appear to be a generic problem with intent recovery; we use the entire operation reservation for recovery, not the reservation that was held at runtime after the intent was logged. I suspect all intents are going to require their own reservation as a result. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_trans_resv.c | 10 ++++++++++ fs/xfs/libxfs/xfs_trans_resv.h | 2 ++ fs/xfs/xfs_extfree_item.c | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index d1a0848cb52e..da2ec052ac0a 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -916,6 +916,16 @@ xfs_trans_resv_calc( resp->tr_qm_dqalloc.tr_logcount = XFS_WRITE_LOG_COUNT; resp->tr_qm_dqalloc.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + /* + * Log recovery reservations for intent replay + * + * EFI recovery is itruncate minus the initial transaction that logs + * logs the EFI. + */ + resp->tr_efi.tr_logres = resp->tr_itruncate.tr_logres; + resp->tr_efi.tr_logcount = resp->tr_itruncate.tr_logcount - 1; + resp->tr_efi.tr_logflags |= XFS_TRANS_PERM_LOG_RES; + /* * The following transactions are logged in logical format with * a default log count. diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h index 7241ab28cf84..13173b3eaac9 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.h +++ b/fs/xfs/libxfs/xfs_trans_resv.h @@ -50,6 +50,8 @@ struct xfs_trans_resv { struct xfs_trans_res tr_qm_equotaoff;/* end of turn quota off */ struct xfs_trans_res tr_sb; /* modify superblock */ struct xfs_trans_res tr_fsyncts; /* update timestamps on fsync */ + struct xfs_trans_res tr_efi; /* EFI log item recovery */ + }; /* shorthand way of accessing reservation structure */ diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 6cb8cd11072a..1ea9ab4cd44e 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -618,7 +618,7 @@ xfs_efi_item_recover( } } - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_efi, 0, 0, 0, &tp); if (error) return error; efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); From patchwork Wed Sep 9 08:19:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 11765067 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 EF6C1746 for ; Wed, 9 Sep 2020 08:19:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D2FBD21D7D for ; Wed, 9 Sep 2020 08:19:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725975AbgIIITS (ORCPT ); Wed, 9 Sep 2020 04:19:18 -0400 Received: from mail104.syd.optusnet.com.au ([211.29.132.246]:38961 "EHLO mail104.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726060AbgIIITR (ORCPT ); Wed, 9 Sep 2020 04:19:17 -0400 Received: from dread.disaster.area (pa49-195-191-192.pa.nsw.optusnet.com.au [49.195.191.192]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id A767A824414 for ; Wed, 9 Sep 2020 18:19:14 +1000 (AEST) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1kFvJx-00005N-JW for linux-xfs@vger.kernel.org; Wed, 09 Sep 2020 18:19:13 +1000 Received: from dave by discord.disaster.area with local (Exim 4.93) (envelope-from ) id 1kFvJx-004yO5-4J for linux-xfs@vger.kernel.org; Wed, 09 Sep 2020 18:19:13 +1000 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 2/3] xfs: add a free space extent change reservation Date: Wed, 9 Sep 2020 18:19:11 +1000 Message-Id: <20200909081912.1185392-3-david@fromorbit.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200909081912.1185392-1-david@fromorbit.com> References: <20200909081912.1185392-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.3 cv=XJ9OtjpE c=1 sm=1 tr=0 cx=a_idp_d a=vvDRHhr1aDYKXl+H6jx2TA==:117 a=vvDRHhr1aDYKXl+H6jx2TA==:17 a=reM5J-MqmosA:10 a=20KFwNOVAAAA:8 a=NvrPUYSSg0wYV7KhmsoA:9 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Lots of the transaction reservation code reserves space for an extent allocation. It is inconsistently implemented, and many of them get it wrong. Introduce a new function to calculate the log space reservation for adding or removing an extent from the free space btrees. This function reserves space for logging the AGF, the AGFL and the free space btrees, avoiding the need to account for them seperately in every reservation that manipulates free space. Convert the EFI recovery reservation to use this transaction reservation as EFI recovery only needs to manipulate the free space index. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_trans_resv.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index da2ec052ac0a..621ddb277dfa 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -79,6 +79,23 @@ xfs_allocfree_log_count( return blocks; } +/* + * Log reservation required to add or remove a single extent to the free space + * btrees. This requires modifying: + * + * the agf header: 1 sector + * the agfl header: 1 sector + * the allocation btrees: 2 trees * (max depth - 1) * block size + */ +uint +xfs_allocfree_extent_res( + struct xfs_mount *mp) +{ + return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), + XFS_FSB_TO_B(mp, 1)); +} + /* * Logging inodes is really tricksy. They are logged in memory format, * which means that what we write into the log doesn't directly translate into @@ -922,7 +939,7 @@ xfs_trans_resv_calc( * EFI recovery is itruncate minus the initial transaction that logs * logs the EFI. */ - resp->tr_efi.tr_logres = resp->tr_itruncate.tr_logres; + resp->tr_efi.tr_logres = xfs_allocfree_extent_res(mp); resp->tr_efi.tr_logcount = resp->tr_itruncate.tr_logcount - 1; resp->tr_efi.tr_logflags |= XFS_TRANS_PERM_LOG_RES; From patchwork Wed Sep 9 08:19:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 11765069 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 613CC138E for ; Wed, 9 Sep 2020 08:19:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4208021D7A for ; Wed, 9 Sep 2020 08:19:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725984AbgIIIT1 (ORCPT ); Wed, 9 Sep 2020 04:19:27 -0400 Received: from mail104.syd.optusnet.com.au ([211.29.132.246]:39285 "EHLO mail104.syd.optusnet.com.au" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725826AbgIIITX (ORCPT ); Wed, 9 Sep 2020 04:19:23 -0400 Received: from dread.disaster.area (pa49-195-191-192.pa.nsw.optusnet.com.au [49.195.191.192]) by mail104.syd.optusnet.com.au (Postfix) with ESMTPS id A8CB6824447 for ; Wed, 9 Sep 2020 18:19:14 +1000 (AEST) Received: from discord.disaster.area ([192.168.253.110]) by dread.disaster.area with esmtp (Exim 4.92.3) (envelope-from ) id 1kFvJx-00005P-OV for linux-xfs@vger.kernel.org; Wed, 09 Sep 2020 18:19:13 +1000 Received: from dave by discord.disaster.area with local (Exim 4.93) (envelope-from ) id 1kFvJx-004yOC-6S for linux-xfs@vger.kernel.org; Wed, 09 Sep 2020 18:19:13 +1000 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH 3/3] xfs: factor free space tree transaciton reservations Date: Wed, 9 Sep 2020 18:19:12 +1000 Message-Id: <20200909081912.1185392-4-david@fromorbit.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200909081912.1185392-1-david@fromorbit.com> References: <20200909081912.1185392-1-david@fromorbit.com> MIME-Version: 1.0 X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.3 cv=XJ9OtjpE c=1 sm=1 tr=0 cx=a_idp_d a=vvDRHhr1aDYKXl+H6jx2TA==:117 a=vvDRHhr1aDYKXl+H6jx2TA==:17 a=reM5J-MqmosA:10 a=20KFwNOVAAAA:8 a=bxfpV1sUp7d6p-NBOosA:9 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Convert all the open coded free space tree modification reservations to use the new xfs_allocfree_extent_res() function. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_trans_resv.c | 116 +++++++++++++-------------------- 1 file changed, 44 insertions(+), 72 deletions(-) diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 621ddb277dfa..cb3cddb84d75 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -143,18 +143,16 @@ xfs_calc_inode_res( * reservation: * * the inode btree: max depth * blocksize - * the allocation btrees: 2 trees * (max depth - 1) * block size + * one extent for the AG free space trees * - * The caller must account for SB and AG header modifications, etc. */ STATIC uint xfs_calc_inobt_res( struct xfs_mount *mp) { return xfs_calc_buf_res(M_IGEO(mp)->inobt_maxlevels, - XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), - XFS_FSB_TO_B(mp, 1)); + XFS_FSB_TO_B(mp, 1)) + + xfs_allocfree_extent_res(mp); } /* @@ -200,8 +198,7 @@ xfs_calc_inode_chunk_res( { uint res, size = 0; - res = xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), - XFS_FSB_TO_B(mp, 1)); + res = xfs_allocfree_extent_res(mp); if (alloc) { /* icreate tx uses ordered buffers */ if (xfs_sb_version_has_v3inode(&mp->m_sb)) @@ -256,22 +253,19 @@ xfs_rtalloc_log_count( * extents. This gives (t1): * the inode getting the new extents: inode size * the inode's bmap btree: max depth * block size - * the agfs of the ags from which the extents are allocated: 2 * sector * the superblock free block counter: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + * two extents for the AG free space trees * Or, if we're writing to a realtime file (t2): * the inode getting the new extents: inode size * the inode's bmap btree: max depth * block size - * the agfs of the ags from which the extents are allocated: 2 * sector + * one extent for the AG free space trees * the superblock free block counter: sector size * the realtime bitmap: ((MAXEXTLEN / rtextsize) / NBBY) bytes * the realtime summary: 1 block - * the allocation btrees: 2 trees * (2 * max depth - 1) * block size * And the bmap_finish transaction can free bmap blocks in a join (t3): - * the agfs of the ags containing the blocks: 2 * sector size * the agfls of the ags containing the blocks: 2 * sector size * the super block free block counter: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + * two extents for the AG free space trees */ STATIC uint xfs_calc_write_reservation( @@ -282,8 +276,8 @@ xfs_calc_write_reservation( t1 = xfs_calc_inode_res(mp, 1) + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), blksz) + - xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz); + xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 2; if (xfs_sb_version_hasrealtime(&mp->m_sb)) { t2 = xfs_calc_inode_res(mp, 1) + @@ -291,13 +285,13 @@ xfs_calc_write_reservation( blksz) + xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + xfs_calc_buf_res(xfs_rtalloc_log_count(mp, 1), blksz) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), blksz); + xfs_allocfree_extent_res(mp); } else { t2 = 0; } - t3 = xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz); + t3 = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 2; return XFS_DQUOT_LOGRES(mp) + max3(t1, t2, t3); } @@ -307,19 +301,13 @@ xfs_calc_write_reservation( * the inode being truncated: inode size * the inode's bmap btree: (max depth + 1) * block size * And the bmap_finish transaction can free the blocks and bmap blocks (t2): - * the agf for each of the ags: 4 * sector size - * the agfl for each of the ags: 4 * sector size * the super block to reflect the freed blocks: sector size - * worst case split in allocation btrees per extent assuming 4 extents: - * 4 exts * 2 trees * (2 * max depth - 1) * block size + * four (XXX: one?) extents for the AG free space trees * Or, if it's a realtime file (t3): - * the agf for each of the ags: 2 * sector size - * the agfl for each of the ags: 2 * sector size * the super block to reflect the freed blocks: sector size * the realtime bitmap: 2 exts * ((MAXEXTLEN / rtextsize) / NBBY) bytes * the realtime summary: 2 exts * 1 block - * worst case split in allocation btrees per extent assuming 2 extents: - * 2 exts * 2 trees * (2 * max depth - 1) * block size + * two extents for the AG free space trees */ STATIC uint xfs_calc_itruncate_reservation( @@ -331,13 +319,13 @@ xfs_calc_itruncate_reservation( t1 = xfs_calc_inode_res(mp, 1) + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, blksz); - t2 = xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), blksz); + t2 = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 4; if (xfs_sb_version_hasrealtime(&mp->m_sb)) { - t3 = xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + + t3 = xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + xfs_calc_buf_res(xfs_rtalloc_log_count(mp, 2), blksz) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), blksz); + xfs_allocfree_extent_res(mp) * 2; } else { t3 = 0; } @@ -352,10 +340,8 @@ xfs_calc_itruncate_reservation( * the two directory bmap btrees: 2 * max depth * block size * And the bmap_finish transaction can free dir and bmap blocks (two sets * of bmap blocks) giving: - * the agf for the ags in which the blocks live: 3 * sector size - * the agfl for the ags in which the blocks live: 3 * sector size * the superblock for the free block count: sector size - * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size + * three extents for the AG free space trees */ STATIC uint xfs_calc_rename_reservation( @@ -365,9 +351,8 @@ xfs_calc_rename_reservation( max((xfs_calc_inode_res(mp, 4) + xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 3), - XFS_FSB_TO_B(mp, 1)))); + (xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 3)); } /* @@ -381,20 +366,19 @@ xfs_calc_iunlink_remove_reservation( struct xfs_mount *mp) { return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + - 2 * M_IGEO(mp)->inode_cluster_size; + xfs_calc_buf_res(2, M_IGEO(mp)->inode_cluster_size); } /* * For creating a link to an inode: + * the inode is removed from the iunlink list (O_TMPFILE) * the parent directory inode: inode size * the linked inode: inode size * the directory btree could split: (max depth + v2) * dir block size * the directory bmap btree could join or split: (max depth + v2) * blocksize * And the bmap_finish transaction can free some bmap blocks giving: - * the agf for the ag in which the blocks live: sector size - * the agfl for the ag in which the blocks live: sector size * the superblock for the free block count: sector size - * the allocation btrees: 2 trees * (2 * max depth - 1) * block size + * one extent for the AG free space trees */ STATIC uint xfs_calc_link_reservation( @@ -405,9 +389,8 @@ xfs_calc_link_reservation( max((xfs_calc_inode_res(mp, 2) + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), - XFS_FSB_TO_B(mp, 1)))); + (xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp))); } /* @@ -419,20 +402,19 @@ STATIC uint xfs_calc_iunlink_add_reservation(xfs_mount_t *mp) { return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + - M_IGEO(mp)->inode_cluster_size; + xfs_calc_buf_res(1, M_IGEO(mp)->inode_cluster_size); } /* * For removing a directory entry we can modify: + * the inode is added to the agi unlinked list * the parent directory inode: inode size * the removed inode: inode size * the directory btree could join: (max depth + v2) * dir block size * the directory bmap btree could join or split: (max depth + v2) * blocksize * And the bmap_finish transaction can free the dir and bmap blocks giving: - * the agf for the ag in which the blocks live: 2 * sector size - * the agfl for the ag in which the blocks live: 2 * sector size * the superblock for the free block count: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + * two extents for the AG free space trees */ STATIC uint xfs_calc_remove_reservation( @@ -443,9 +425,8 @@ xfs_calc_remove_reservation( max((xfs_calc_inode_res(mp, 1) + xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), - XFS_FSB_TO_B(mp, 1)))); + (xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 2)); } /* @@ -582,15 +563,14 @@ xfs_calc_ichange_reservation( * Growing the data section of the filesystem. * superblock * agi and agf - * allocation btrees + * growing the last AG requires freeing one extent */ STATIC uint xfs_calc_growdata_reservation( struct xfs_mount *mp) { - return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), - XFS_FSB_TO_B(mp, 1)); + return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp); } /* @@ -598,10 +578,9 @@ xfs_calc_growdata_reservation( * In the first set of transactions (ALLOC) we allocate space to the * bitmap or summary files. * superblock: sector size - * agf of the ag from which the extent is allocated: sector size * bmap btree for bitmap/summary inode: max depth * blocksize * bitmap/summary inode: inode size - * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize + * one extent for the AG free space trees */ STATIC uint xfs_calc_growrtalloc_reservation( @@ -611,8 +590,7 @@ xfs_calc_growrtalloc_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), XFS_FSB_TO_B(mp, 1)) + xfs_calc_inode_res(mp, 1) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), - XFS_FSB_TO_B(mp, 1)); + xfs_allocfree_extent_res(mp); } /* @@ -675,7 +653,7 @@ xfs_calc_writeid_reservation( * agf block and superblock (for block allocation) * the new block (directory sized) * bmap blocks for the new directory block - * allocation btrees + * one extent for the AG free space trees */ STATIC uint xfs_calc_addafork_reservation( @@ -687,8 +665,7 @@ xfs_calc_addafork_reservation( xfs_calc_buf_res(1, mp->m_dir_geo->blksize) + xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), - XFS_FSB_TO_B(mp, 1)); + xfs_allocfree_extent_res(mp); } /* @@ -696,11 +673,8 @@ xfs_calc_addafork_reservation( * the inode being truncated: inode size * the inode's bmap btree: max depth * block size * And the bmap_finish transaction can free the blocks and bmap blocks: - * the agf for each of the ags: 4 * sector size - * the agfl for each of the ags: 4 * sector size * the super block to reflect the freed blocks: sector size - * worst case split in allocation btrees per extent assuming 4 extents: - * 4 exts * 2 trees * (2 * max depth - 1) * block size + * four (XXX: really? should be one?) extents for the AG free space trees */ STATIC uint xfs_calc_attrinval_reservation( @@ -709,9 +683,8 @@ xfs_calc_attrinval_reservation( return max((xfs_calc_inode_res(mp, 1) + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), XFS_FSB_TO_B(mp, 1))), - (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), - XFS_FSB_TO_B(mp, 1)))); + (xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 4)); } /* @@ -763,7 +736,7 @@ xfs_calc_attrsetrt_reservation( * the agf for the ag in which the blocks live: 2 * sector size * the agfl for the ag in which the blocks live: 2 * sector size * the superblock for the free block count: sector size - * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size + * two extents for the AG free space trees */ STATIC uint xfs_calc_attrrm_reservation( @@ -776,9 +749,8 @@ xfs_calc_attrrm_reservation( (uint)XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), - (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), - XFS_FSB_TO_B(mp, 1)))); + (xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) + + xfs_allocfree_extent_res(mp) * 2)); } /*