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); |
