aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_mount.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index c207fef6770b..e79b56b4bca6 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1097,13 +1097,15 @@ xfs_default_resblks(xfs_mount_t *mp)
1097 __uint64_t resblks; 1097 __uint64_t resblks;
1098 1098
1099 /* 1099 /*
1100 * We default to 5% or 1024 fsbs of space reserved, whichever is smaller. 1100 * We default to 5% or 8192 fsbs of space reserved, whichever is
1101 * This may drive us straight to ENOSPC on mount, but that implies 1101 * smaller. This is intended to cover concurrent allocation
1102 * we were already there on the last unmount. Warn if this occurs. 1102 * transactions when we initially hit enospc. These each require a 4
1103 * block reservation. Hence by default we cover roughly 2000 concurrent
1104 * allocation reservations.
1103 */ 1105 */
1104 resblks = mp->m_sb.sb_dblocks; 1106 resblks = mp->m_sb.sb_dblocks;
1105 do_div(resblks, 20); 1107 do_div(resblks, 20);
1106 resblks = min_t(__uint64_t, resblks, 1024); 1108 resblks = min_t(__uint64_t, resblks, 8192);
1107 return resblks; 1109 return resblks;
1108} 1110}
1109 1111
@@ -1417,6 +1419,9 @@ xfs_mountfs(
1417 * when at ENOSPC. This is needed for operations like create with 1419 * when at ENOSPC. This is needed for operations like create with
1418 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations 1420 * attr, unwritten extent conversion at ENOSPC, etc. Data allocations
1419 * are not allowed to use this reserved space. 1421 * are not allowed to use this reserved space.
1422 *
1423 * This may drive us straight to ENOSPC on mount, but that implies
1424 * we were already there on the last unmount. Warn if this occurs.
1420 */ 1425 */
1421 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { 1426 if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
1422 resblks = xfs_default_resblks(mp); 1427 resblks = xfs_default_resblks(mp);
@@ -1725,26 +1730,30 @@ xfs_mod_incore_sb_unlocked(
1725 lcounter += rem; 1730 lcounter += rem;
1726 } 1731 }
1727 } else { /* Taking blocks away */ 1732 } else { /* Taking blocks away */
1728
1729 lcounter += delta; 1733 lcounter += delta;
1734 if (lcounter >= 0) {
1735 mp->m_sb.sb_fdblocks = lcounter +
1736 XFS_ALLOC_SET_ASIDE(mp);
1737 return 0;
1738 }
1730 1739
1731 /* 1740 /*
1732 * If were out of blocks, use any available reserved blocks if 1741 * We are out of blocks, use any available reserved
1733 * were allowed to. 1742 * blocks if were allowed to.
1734 */ 1743 */
1744 if (!rsvd)
1745 return XFS_ERROR(ENOSPC);
1735 1746
1736 if (lcounter < 0) { 1747 lcounter = (long long)mp->m_resblks_avail + delta;
1737 if (rsvd) { 1748 if (lcounter >= 0) {
1738 lcounter = (long long)mp->m_resblks_avail + delta; 1749 mp->m_resblks_avail = lcounter;
1739 if (lcounter < 0) { 1750 return 0;
1740 return XFS_ERROR(ENOSPC);
1741 }
1742 mp->m_resblks_avail = lcounter;
1743 return 0;
1744 } else { /* not reserved */
1745 return XFS_ERROR(ENOSPC);
1746 }
1747 } 1751 }
1752 printk_once(KERN_WARNING
1753 "Filesystem \"%s\": reserve blocks depleted! "
1754 "Consider increasing reserve pool size.",
1755 mp->m_fsname);
1756 return XFS_ERROR(ENOSPC);
1748 } 1757 }
1749 1758
1750 mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp); 1759 mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);