xfs: improve handling of busy extents in the low-level allocator
Currently we force the log and simply try again if we hit a busy extent, but especially with online discard enabled it might take a while after the log force for the busy extents to disappear, and we might have already completed our second pass. So instead we add a new waitqueue and a generation counter to the pag structure so that we can do wakeups once we've removed busy extents, and we replace the single retry with an unconditional one - after all we hold the AGF buffer lock, so no other allocations or frees can be racing with us in this AG. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:

committed by
Darrick J. Wong

parent
5e30c23d13
commit
ebf5587261
@@ -45,6 +45,7 @@
|
||||
#include "xfs_rmap_btree.h"
|
||||
#include "xfs_refcount_btree.h"
|
||||
#include "xfs_reflink.h"
|
||||
#include "xfs_extent_busy.h"
|
||||
|
||||
|
||||
static DEFINE_MUTEX(xfs_uuid_table_mutex);
|
||||
@@ -213,6 +214,7 @@ xfs_initialize_perag(
|
||||
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
|
||||
if (xfs_buf_hash_init(pag))
|
||||
goto out_free_pag;
|
||||
init_waitqueue_head(&pag->pagb_wait);
|
||||
|
||||
if (radix_tree_preload(GFP_NOFS))
|
||||
goto out_hash_destroy;
|
||||
@@ -1078,6 +1080,12 @@ xfs_unmountfs(
|
||||
*/
|
||||
xfs_log_force(mp, XFS_LOG_SYNC);
|
||||
|
||||
/*
|
||||
* Wait for all busy extents to be freed, including completion of
|
||||
* any discard operation.
|
||||
*/
|
||||
xfs_extent_busy_wait_all(mp);
|
||||
|
||||
/*
|
||||
* We now need to tell the world we are unmounting. This will allow
|
||||
* us to detect that the filesystem is going away and we should error
|
||||
|
Reference in New Issue
Block a user