mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-09 16:12:21 +00:00
xfs: update ag iterator to support wait on new inodes
The AG inode iterator currently skips new inodes as such inodes are inserted into the inode radix tree before they are fully constructed. Certain contexts require the ability to wait on the construction of new inodes, however. The fs-wide dquot release from the quotaoff sequence is an example of this. Update the AG inode iterator to support the ability to wait on inodes flagged with XFS_INEW upon request. Create a new xfs_inode_ag_iterator_flags() interface and support a set of iteration flags to modify the iteration behavior. When the XFS_AGITER_INEW_WAIT flag is set, include XFS_INEW flags in the radix tree inode lookup and wait on them before the callback is executed. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
756baca27f
commit
ae2c4ac2dd
2 changed files with 53 additions and 8 deletions
|
@ -262,6 +262,22 @@ xfs_inode_clear_reclaim_tag(
|
|||
xfs_perag_clear_reclaim_tag(pag);
|
||||
}
|
||||
|
||||
static void
|
||||
xfs_inew_wait(
|
||||
struct xfs_inode *ip)
|
||||
{
|
||||
wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_INEW_BIT);
|
||||
DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_INEW_BIT);
|
||||
|
||||
do {
|
||||
prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
|
||||
if (!xfs_iflags_test(ip, XFS_INEW))
|
||||
break;
|
||||
schedule();
|
||||
} while (true);
|
||||
finish_wait(wq, &wait.wait);
|
||||
}
|
||||
|
||||
/*
|
||||
* When we recycle a reclaimable inode, we need to re-initialise the VFS inode
|
||||
* part of the structure. This is made more complex by the fact we store
|
||||
|
@ -626,9 +642,11 @@ out_error_or_again:
|
|||
|
||||
STATIC int
|
||||
xfs_inode_ag_walk_grab(
|
||||
struct xfs_inode *ip)
|
||||
struct xfs_inode *ip,
|
||||
int flags)
|
||||
{
|
||||
struct inode *inode = VFS_I(ip);
|
||||
bool newinos = !!(flags & XFS_AGITER_INEW_WAIT);
|
||||
|
||||
ASSERT(rcu_read_lock_held());
|
||||
|
||||
|
@ -646,7 +664,8 @@ xfs_inode_ag_walk_grab(
|
|||
goto out_unlock_noent;
|
||||
|
||||
/* avoid new or reclaimable inodes. Leave for reclaim code to flush */
|
||||
if (__xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM))
|
||||
if ((!newinos && __xfs_iflags_test(ip, XFS_INEW)) ||
|
||||
__xfs_iflags_test(ip, XFS_IRECLAIMABLE | XFS_IRECLAIM))
|
||||
goto out_unlock_noent;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
|
@ -674,7 +693,8 @@ xfs_inode_ag_walk(
|
|||
void *args),
|
||||
int flags,
|
||||
void *args,
|
||||
int tag)
|
||||
int tag,
|
||||
int iter_flags)
|
||||
{
|
||||
uint32_t first_index;
|
||||
int last_error = 0;
|
||||
|
@ -716,7 +736,7 @@ restart:
|
|||
for (i = 0; i < nr_found; i++) {
|
||||
struct xfs_inode *ip = batch[i];
|
||||
|
||||
if (done || xfs_inode_ag_walk_grab(ip))
|
||||
if (done || xfs_inode_ag_walk_grab(ip, iter_flags))
|
||||
batch[i] = NULL;
|
||||
|
||||
/*
|
||||
|
@ -744,6 +764,9 @@ restart:
|
|||
for (i = 0; i < nr_found; i++) {
|
||||
if (!batch[i])
|
||||
continue;
|
||||
if ((iter_flags & XFS_AGITER_INEW_WAIT) &&
|
||||
xfs_iflags_test(batch[i], XFS_INEW))
|
||||
xfs_inew_wait(batch[i]);
|
||||
error = execute(batch[i], flags, args);
|
||||
IRELE(batch[i]);
|
||||
if (error == -EAGAIN) {
|
||||
|
@ -823,12 +846,13 @@ xfs_cowblocks_worker(
|
|||
}
|
||||
|
||||
int
|
||||
xfs_inode_ag_iterator(
|
||||
xfs_inode_ag_iterator_flags(
|
||||
struct xfs_mount *mp,
|
||||
int (*execute)(struct xfs_inode *ip, int flags,
|
||||
void *args),
|
||||
int flags,
|
||||
void *args)
|
||||
void *args,
|
||||
int iter_flags)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
int error = 0;
|
||||
|
@ -838,7 +862,8 @@ xfs_inode_ag_iterator(
|
|||
ag = 0;
|
||||
while ((pag = xfs_perag_get(mp, ag))) {
|
||||
ag = pag->pag_agno + 1;
|
||||
error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1);
|
||||
error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1,
|
||||
iter_flags);
|
||||
xfs_perag_put(pag);
|
||||
if (error) {
|
||||
last_error = error;
|
||||
|
@ -849,6 +874,17 @@ xfs_inode_ag_iterator(
|
|||
return last_error;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_inode_ag_iterator(
|
||||
struct xfs_mount *mp,
|
||||
int (*execute)(struct xfs_inode *ip, int flags,
|
||||
void *args),
|
||||
int flags,
|
||||
void *args)
|
||||
{
|
||||
return xfs_inode_ag_iterator_flags(mp, execute, flags, args, 0);
|
||||
}
|
||||
|
||||
int
|
||||
xfs_inode_ag_iterator_tag(
|
||||
struct xfs_mount *mp,
|
||||
|
@ -866,7 +902,8 @@ xfs_inode_ag_iterator_tag(
|
|||
ag = 0;
|
||||
while ((pag = xfs_perag_get_tag(mp, ag, tag))) {
|
||||
ag = pag->pag_agno + 1;
|
||||
error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag);
|
||||
error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag,
|
||||
0);
|
||||
xfs_perag_put(pag);
|
||||
if (error) {
|
||||
last_error = error;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue