struct xfs_inode *ip, int whichfork,
struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp,
struct xfs_bmbt_irec *new, int *logflagsp);
+xfs_extlen_t xfs_bmapi_minleft(struct xfs_trans *tp, struct xfs_inode *ip,
+ int fork);
enum xfs_bmap_intent_type {
XFS_BMAP_MAP = 1,
if (args.fsbno == NULLFSBLOCK) {
args.fsbno = be64_to_cpu(start->l);
args.type = XFS_ALLOCTYPE_START_BNO;
+
/*
- * Make sure there is sufficient room left in the AG to
- * complete a full tree split for an extent insert. If
- * we are converting the middle part of an extent then
- * we may need space for two tree splits.
- *
- * We are relying on the caller to make the correct block
- * reservation for this operation to succeed. If the
- * reservation amount is insufficient then we may fail a
- * block allocation here and corrupt the filesystem.
+ * If we are coming here from something like unwritten extent
+ * conversion, there has been no data extent allocation already
+ * done, so we have to ensure that we attempt to locate the
+ * entire set of bmbt allocations in the same AG, as
+ * xfs_bmapi_write() would have reserved.
*/
- args.minleft = args.tp->t_blk_res;
+ args.minleft = xfs_bmapi_minleft(cur->bc_tp, cur->bc_ino.ip,
+ cur->bc_ino.whichfork);
} else if (cur->bc_tp->t_flags & XFS_TRANS_LOWMODE) {
args.type = XFS_ALLOCTYPE_START_BNO;
} else {
* successful activate the lowspace algorithm.
*/
args.fsbno = 0;
+ args.minleft = 0;
args.type = XFS_ALLOCTYPE_FIRST_AG;
error = xfs_alloc_vextent(&args);
if (error)