diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e39c9e83670e78e18893383e19be6922b595fdc1..b8e97fd0bac13a529ff620548809be727decc4b8 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4158,8 +4158,7 @@ xfs_bmapi_reserve_delalloc( ASSERT(indlen > 0); if (rt) { - error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - -((int64_t)extsz), 0); + error = xfs_mod_frextents(mp, -((int64_t)extsz)); } else { error = xfs_mod_fdblocks(mp, -((int64_t)alen), false); } @@ -4194,7 +4193,7 @@ xfs_bmapi_reserve_delalloc( out_unreserve_blocks: if (rt) - xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0); + xfs_mod_frextents(mp, extsz); else xfs_mod_fdblocks(mp, alen, false); out_unreserve_quota: @@ -5278,8 +5277,7 @@ xfs_bunmapi( rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); do_div(rtexts, mp->m_sb.sb_rextsize); - xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, - (int64_t)rtexts, 0); + xfs_mod_frextents(mp, (int64_t)rtexts); (void)xfs_trans_reserve_quota_nblks(NULL, ip, -((long)del.br_blockcount), 0, XFS_QMOPT_RES_RTBLKS); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 05b392e35e358d34d3b2d9b27b11f7d8b92d9549..df4c32fdc706948b6366bb07c3143c7d6fec85db 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1198,6 +1198,24 @@ xfs_mod_fdblocks( return -ENOSPC; } +int +xfs_mod_frextents( + struct xfs_mount *mp, + int64_t delta) +{ + int64_t lcounter; + int ret = 0; + + spin_lock(&mp->m_sb_lock); + lcounter = mp->m_sb.sb_frextents + delta; + if (lcounter < 0) + ret = -ENOSPC; + else + mp->m_sb.sb_frextents = lcounter; + spin_unlock(&mp->m_sb_lock); + return ret; +} + /* * xfs_mod_incore_sb_unlocked() is a utility routine commonly used to apply * a delta to a specified field in the in-core superblock. Simply @@ -1227,16 +1245,9 @@ xfs_mod_incore_sb_unlocked( case XFS_SBS_ICOUNT: case XFS_SBS_IFREE: case XFS_SBS_FDBLOCKS: + case XFS_SBS_FREXTENTS: ASSERT(0); return -EINVAL; - case XFS_SBS_FREXTENTS: - lcounter = (long long)mp->m_sb.sb_frextents; - lcounter += delta; - if (lcounter < 0) { - return -ENOSPC; - } - mp->m_sb.sb_frextents = lcounter; - return 0; case XFS_SBS_DBLOCKS: lcounter = (long long)mp->m_sb.sb_dblocks; lcounter += delta; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 205f23a240a7e94dde2c971a62b8865d55433629..d65e0f23b84724f556ed9d9d6d7446fbf4788c4f 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -331,6 +331,8 @@ extern int xfs_mod_icount(struct xfs_mount *mp, int64_t delta); extern int xfs_mod_ifree(struct xfs_mount *mp, int64_t delta); extern int xfs_mod_fdblocks(struct xfs_mount *mp, int64_t delta, bool reserved); +extern int xfs_mod_frextents(struct xfs_mount *mp, int64_t delta); + extern int xfs_mount_log_sb(xfs_mount_t *); extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); extern int xfs_readsb(xfs_mount_t *, int); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index e99f5e552c64038fefc2cd716b4d113e9fb5958e..4e4bc5aed6b6006a22661b75057312731ef047a8 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -235,8 +235,7 @@ xfs_trans_reserve( * fail if the count would go below zero. */ if (rtextents > 0) { - error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FREXTENTS, - -((int64_t)rtextents), rsvd); + error = xfs_mod_frextents(tp->t_mountp, -((int64_t)rtextents)); if (error) { error = -ENOSPC; goto undo_log; @@ -562,10 +561,10 @@ xfs_trans_unreserve_and_mod_sb( } /* apply remaining deltas */ - if (rtxdelta != 0) { - msbp->msb_field = XFS_SBS_FREXTENTS; - msbp->msb_delta = rtxdelta; - msbp++; + if (rtxdelta) { + error = xfs_mod_frextents(mp, rtxdelta); + if (error) + goto out_undo_ifree; } if (tp->t_flags & XFS_TRANS_SB_DIRTY) { @@ -618,12 +617,15 @@ xfs_trans_unreserve_and_mod_sb( error = xfs_mod_incore_sb_batch(tp->t_mountp, msb, (uint)(msbp - msb), rsvd); if (error) - goto out_undo_ifreecount; + goto out_undo_frextents; } return; -out_undo_ifreecount: +out_undo_frextents: + if (rtxdelta) + xfs_mod_frextents(mp, -rtxdelta); +out_undo_ifree: if (ifreedelta) xfs_mod_ifree(mp, -ifreedelta); out_undo_icount: