diff options
Diffstat (limited to 'fs/xfs/xfs_icache.c')
| -rw-r--r-- | fs/xfs/xfs_icache.c | 46 | 
1 files changed, 37 insertions, 9 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0f60e301eb1f..453890942d9f 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -454,6 +454,27 @@ xfs_inodegc_queue_all(  	return ret;  } +/* Wait for all queued work and collect errors */ +static int +xfs_inodegc_wait_all( +	struct xfs_mount	*mp) +{ +	int			cpu; +	int			error = 0; + +	flush_workqueue(mp->m_inodegc_wq); +	for_each_online_cpu(cpu) { +		struct xfs_inodegc	*gc; + +		gc = per_cpu_ptr(mp->m_inodegc, cpu); +		if (gc->error && !error) +			error = gc->error; +		gc->error = 0; +	} + +	return error; +} +  /*   * Check the validity of the inode we just found it the cache   */ @@ -1491,15 +1512,14 @@ xfs_blockgc_free_space(  	if (error)  		return error; -	xfs_inodegc_flush(mp); -	return 0; +	return xfs_inodegc_flush(mp);  }  /*   * Reclaim all the free space that we can by scheduling the background blockgc   * and inodegc workers immediately and waiting for them all to clear.   */ -void +int  xfs_blockgc_flush_all(  	struct xfs_mount	*mp)  { @@ -1520,7 +1540,7 @@ xfs_blockgc_flush_all(  	for_each_perag_tag(mp, agno, pag, XFS_ICI_BLOCKGC_TAG)  		flush_delayed_work(&pag->pag_blockgc_work); -	xfs_inodegc_flush(mp); +	return xfs_inodegc_flush(mp);  }  /* @@ -1842,13 +1862,17 @@ xfs_inodegc_set_reclaimable(   * This is the last chance to make changes to an otherwise unreferenced file   * before incore reclamation happens.   */ -static void +static int  xfs_inodegc_inactivate(  	struct xfs_inode	*ip)  { +	int			error; +  	trace_xfs_inode_inactivating(ip); -	xfs_inactive(ip); +	error = xfs_inactive(ip);  	xfs_inodegc_set_reclaimable(ip); +	return error; +  }  void @@ -1880,8 +1904,12 @@ xfs_inodegc_worker(  	WRITE_ONCE(gc->shrinker_hits, 0);  	llist_for_each_entry_safe(ip, n, node, i_gclist) { +		int	error; +  		xfs_iflags_set(ip, XFS_INACTIVATING); -		xfs_inodegc_inactivate(ip); +		error = xfs_inodegc_inactivate(ip); +		if (error && !gc->error) +			gc->error = error;  	}  	memalloc_nofs_restore(nofs_flag); @@ -1905,13 +1933,13 @@ xfs_inodegc_push(   * Force all currently queued inode inactivation work to run immediately and   * wait for the work to finish.   */ -void +int  xfs_inodegc_flush(  	struct xfs_mount	*mp)  {  	xfs_inodegc_push(mp);  	trace_xfs_inodegc_flush(mp, __return_address); -	flush_workqueue(mp->m_inodegc_wq); +	return xfs_inodegc_wait_all(mp);  }  /*  |