|
@@ -1097,13 +1097,15 @@ xfs_default_resblks(xfs_mount_t *mp)
|
|
|
__uint64_t resblks;
|
|
|
|
|
|
/*
|
|
|
- * We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
|
|
|
- * This may drive us straight to ENOSPC on mount, but that implies
|
|
|
- * we were already there on the last unmount. Warn if this occurs.
|
|
|
+ * We default to 5% or 8192 fsbs of space reserved, whichever is
|
|
|
+ * smaller. This is intended to cover concurrent allocation
|
|
|
+ * transactions when we initially hit enospc. These each require a 4
|
|
|
+ * block reservation. Hence by default we cover roughly 2000 concurrent
|
|
|
+ * allocation reservations.
|
|
|
*/
|
|
|
resblks = mp->m_sb.sb_dblocks;
|
|
|
do_div(resblks, 20);
|
|
|
- resblks = min_t(__uint64_t, resblks, 1024);
|
|
|
+ resblks = min_t(__uint64_t, resblks, 8192);
|
|
|
return resblks;
|
|
|
}
|
|
|
|
|
@@ -1417,6 +1419,9 @@ xfs_mountfs(
|
|
|
* when at ENOSPC. This is needed for operations like create with
|
|
|
* attr, unwritten extent conversion at ENOSPC, etc. Data allocations
|
|
|
* are not allowed to use this reserved space.
|
|
|
+ *
|
|
|
+ * This may drive us straight to ENOSPC on mount, but that implies
|
|
|
+ * we were already there on the last unmount. Warn if this occurs.
|
|
|
*/
|
|
|
if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
|
|
|
resblks = xfs_default_resblks(mp);
|
|
@@ -1725,26 +1730,30 @@ xfs_mod_incore_sb_unlocked(
|
|
|
lcounter += rem;
|
|
|
}
|
|
|
} else { /* Taking blocks away */
|
|
|
-
|
|
|
lcounter += delta;
|
|
|
+ if (lcounter >= 0) {
|
|
|
+ mp->m_sb.sb_fdblocks = lcounter +
|
|
|
+ XFS_ALLOC_SET_ASIDE(mp);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- /*
|
|
|
- * If were out of blocks, use any available reserved blocks if
|
|
|
- * were allowed to.
|
|
|
- */
|
|
|
+ /*
|
|
|
+ * We are out of blocks, use any available reserved
|
|
|
+ * blocks if were allowed to.
|
|
|
+ */
|
|
|
+ if (!rsvd)
|
|
|
+ return XFS_ERROR(ENOSPC);
|
|
|
|
|
|
- if (lcounter < 0) {
|
|
|
- if (rsvd) {
|
|
|
- lcounter = (long long)mp->m_resblks_avail + delta;
|
|
|
- if (lcounter < 0) {
|
|
|
- return XFS_ERROR(ENOSPC);
|
|
|
- }
|
|
|
- mp->m_resblks_avail = lcounter;
|
|
|
- return 0;
|
|
|
- } else { /* not reserved */
|
|
|
- return XFS_ERROR(ENOSPC);
|
|
|
- }
|
|
|
+ lcounter = (long long)mp->m_resblks_avail + delta;
|
|
|
+ if (lcounter >= 0) {
|
|
|
+ mp->m_resblks_avail = lcounter;
|
|
|
+ return 0;
|
|
|
}
|
|
|
+ printk_once(KERN_WARNING
|
|
|
+ "Filesystem \"%s\": reserve blocks depleted! "
|
|
|
+ "Consider increasing reserve pool size.",
|
|
|
+ mp->m_fsname);
|
|
|
+ return XFS_ERROR(ENOSPC);
|
|
|
}
|
|
|
|
|
|
mp->m_sb.sb_fdblocks = lcounter + XFS_ALLOC_SET_ASIDE(mp);
|