aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2007-06-18 02:50:27 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-07-14 01:35:19 -0400
commit84e1e99f112dead8f9ba036c02d24a9f5ce7f544 (patch)
treee903589be98c05b45586908171d795a1a466357d /fs/xfs/xfs_iomap.c
parent641c56fbfeae85d5ec87fee90a752f7b7224f236 (diff)
[XFS] Prevent ENOSPC from aborting transactions that need to succeed
During delayed allocation extent conversion or unwritten extent conversion, we need to reserve some blocks for transactions reservations. We need to reserve these blocks in case a btree split occurs and we need to allocate some blocks. Unfortunately, we've only ever reserved the number of data blocks we are allocating, so in both the unwritten and delalloc case we can get ENOSPC to the transaction reservation. This is bad because in both cases we cannot report the failure to the writing application. The fix is two-fold: 1 - leverage the reserved block infrastructure XFS already has to reserve a small pool of blocks by default to allow specially marked transactions to dip into when we are at ENOSPC. Default setting is min(5%, 1024 blocks). 2 - convert critical transaction reservations to be allowed to dip into this pool. Spots changed are delalloc conversion, unwritten extent conversion and growing a filesystem at ENOSPC. This also allows growing the filesytsem to succeed at ENOSPC. SGI-PV: 964468 SGI-Modid: xfs-linux-melb:xfs-kern:28865a Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c22
1 files changed, 8 insertions, 14 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 3f2b9f2a7b94..ab5062199f55 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -489,13 +489,13 @@ xfs_iomap_write_direct(
489 if (unlikely(rt)) { 489 if (unlikely(rt)) {
490 resrtextents = qblocks = resaligned; 490 resrtextents = qblocks = resaligned;
491 resrtextents /= mp->m_sb.sb_rextsize; 491 resrtextents /= mp->m_sb.sb_rextsize;
492 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); 492 resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0);
493 quota_flag = XFS_QMOPT_RES_RTBLKS; 493 quota_flag = XFS_QMOPT_RES_RTBLKS;
494 } else { 494 } else {
495 resrtextents = 0; 495 resrtextents = 0;
496 resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned); 496 resblks = qblocks = XFS_DIOSTRAT_SPACE_RES(mp, resaligned);
497 quota_flag = XFS_QMOPT_RES_REGBLKS; 497 quota_flag = XFS_QMOPT_RES_REGBLKS;
498 } 498 }
499 499
500 /* 500 /*
501 * Allocate and setup the transaction 501 * Allocate and setup the transaction
@@ -788,18 +788,12 @@ xfs_iomap_write_allocate(
788 nimaps = 0; 788 nimaps = 0;
789 while (nimaps == 0) { 789 while (nimaps == 0) {
790 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); 790 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
791 tp->t_flags |= XFS_TRANS_RESERVE;
791 nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); 792 nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK);
792 error = xfs_trans_reserve(tp, nres, 793 error = xfs_trans_reserve(tp, nres,
793 XFS_WRITE_LOG_RES(mp), 794 XFS_WRITE_LOG_RES(mp),
794 0, XFS_TRANS_PERM_LOG_RES, 795 0, XFS_TRANS_PERM_LOG_RES,
795 XFS_WRITE_LOG_COUNT); 796 XFS_WRITE_LOG_COUNT);
796 if (error == ENOSPC) {
797 error = xfs_trans_reserve(tp, 0,
798 XFS_WRITE_LOG_RES(mp),
799 0,
800 XFS_TRANS_PERM_LOG_RES,
801 XFS_WRITE_LOG_COUNT);
802 }
803 if (error) { 797 if (error) {
804 xfs_trans_cancel(tp, 0); 798 xfs_trans_cancel(tp, 0);
805 return XFS_ERROR(error); 799 return XFS_ERROR(error);
@@ -917,8 +911,8 @@ xfs_iomap_write_unwritten(
917 * from unwritten to real. Do allocations in a loop until 911 * from unwritten to real. Do allocations in a loop until
918 * we have covered the range passed in. 912 * we have covered the range passed in.
919 */ 913 */
920
921 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); 914 tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE);
915 tp->t_flags |= XFS_TRANS_RESERVE;
922 error = xfs_trans_reserve(tp, resblks, 916 error = xfs_trans_reserve(tp, resblks,
923 XFS_WRITE_LOG_RES(mp), 0, 917 XFS_WRITE_LOG_RES(mp), 0,
924 XFS_TRANS_PERM_LOG_RES, 918 XFS_TRANS_PERM_LOG_RES,