@@ -4912,6 +4912,30 @@ xfs_bmap_del_extent_delay(
WARN_ON_ONCE(!got_indlen || !new_indlen);
stolen = xfs_bmap_split_indlen(da_old, &got_indlen, &new_indlen,
del->br_blockcount);
+ if (isrt && stolen) {
+ /*
+ * Ugg, we can't just steal reservations from the data
+ * blocks as the data blocks come from a different pool.
+ *
+ * So we have to try to increase our reservations here,
+ * and if that fails we have to fail the unmap. To
+ * avoid that as much as possible dip into the reserve
+ * pool.
+ *
+ * Note that in theory the user/group/project could
+ * be over the quota limit in the meantime, thus we
+ * force the quota accounting even if it was over the
+ * limit.
+ */
+ error = xfs_dec_fdblocks(mp, stolen, true);
+ if (error) {
+ ip->i_delayed_blks += del->br_blockcount;
+ xfs_trans_reserve_quota_nblks(NULL, ip, 0,
+ del->br_blockcount, true);
+ return error;
+ }
+ xfs_mod_delalloc(ip, 0, stolen);
+ }
got->br_startblock = nullstartblock((int)got_indlen);
@@ -4924,7 +4948,8 @@ xfs_bmap_del_extent_delay(
xfs_iext_insert(ip, icur, &new, state);
da_new = got_indlen + new_indlen - stolen;
- del->br_blockcount -= stolen;
+ if (!isrt)
+ del->br_blockcount -= stolen;
break;
}