* count. This is suboptimal, but the VFS flushed the dest range
* before we started. That should have removed all the delalloc
* reservations, but we code defensively.
+ *
+ * xfs_trans_alloc_inode above already tried to grab an even larger
+ * quota reservation, and kicked off a blockgc scan if it couldn't.
+ * If we can't get a potentially smaller quota reservation now, we're
+ * done.
*/
if (!quota_reserved && !smap_real && dmap_written) {
error = xfs_trans_reserve_quota_nblks(tp, ip,
#include "xfs_inode.h"
#include "xfs_dquot_item.h"
#include "xfs_dquot.h"
+#include "xfs_icache.h"
kmem_zone_t *xfs_trans_zone;
{
struct xfs_trans *tp;
struct xfs_mount *mp = ip->i_mount;
+ bool retried = false;
int error;
+retry:
error = xfs_trans_alloc(mp, resv, dblocks,
rblocks / mp->m_sb.sb_rextsize,
force ? XFS_TRANS_RESERVE : 0, &tp);
}
error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks, force);
+ if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
+ xfs_trans_cancel(tp);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ xfs_blockgc_free_quota(ip, 0);
+ retried = true;
+ goto retry;
+ }
if (error)
goto out_cancel;