diff options
-rw-r--r-- | fs/xfs/xfs_mount.c | 49 |
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); |