diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index b901eedf3bb81bf41a9b9f223c670f7e293e1ab2..95bfe89651add0e260964d756fb295f9a9872d04 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -543,6 +543,13 @@ xfs_alloc_fixup_trees( nfbno2 = rbno + rlen; nflen2 = (fbno + flen) - nfbno2; } + + /* + * Record the potential maximum free length in advance. + */ + if (nfbno1 != NULLAGBLOCK || nfbno2 != NULLAGBLOCK) + cnt_cur->bc_free_longest = max_t(xfs_extlen_t, nflen1, nflen2); + /* * Delete the entry from the by-size btree. */ @@ -2039,6 +2046,13 @@ xfs_free_ag_extent( * Now allocate and initialize a cursor for the by-size tree. */ cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_CNT); + /* + * Record the potential maximum free length in advance. + */ + if (haveleft) + cnt_cur->bc_free_longest = ltlen; + if (haveright) + cnt_cur->bc_free_longest = gtlen; /* * Have both left and right contiguous neighbors. * Merge all three into a single free block. diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 613a1743fdd596b152579d9eaaadfe1e7791dcfe..8282a171131e811f71e872997ef2701e164b2545 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -141,13 +141,20 @@ xfs_allocbt_update_lastrec( return; ASSERT(ptr == numrecs + 1); + /* + * Update in advance to prevent file creation failure + * for concurrent processes even though there is no + * numrec currently. + * And there's no need to worry as the value that not + * less than bc_free_longest will be inserted later. + */ + len = cpu_to_be32(cur->bc_free_longest); if (numrecs) { xfs_alloc_rec_t *rrp; rrp = XFS_ALLOC_REC_ADDR(cur->bc_mp, block, numrecs); - len = rrp->ar_blockcount; - } else { - len = 0; + len = cpu_to_be32(max_t(xfs_extlen_t, cur->bc_free_longest, + be32_to_cpu(rrp->ar_blockcount))); } break; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index d172046ae833fca8cb02c6163ff47d048e6c4eba..1d89b897c056d170d880ca551345ce9d5de0fac4 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -235,6 +235,7 @@ typedef struct xfs_btree_cur struct xfs_btree_cur_ag bc_ag; struct xfs_btree_cur_ino bc_ino; }; + xfs_extlen_t bc_free_longest; /* the actual longest free extent */ } xfs_btree_cur_t; /* cursor flags */