__xfs_iunpin_wait() is nearly an open-coded version of wait_var_event(). The bit XFS_IPINNED in ->i_flags is never used (not set, cleared, or tested). Its only role is in choosing a wait_queue. The code is more transparent if we discard that flag bit and use wait_var_event() to wait for the pincount to reach zero, which is signalled by wake_up_var() - or more specifically atomic_dec_and_wake_up_var() In order to use io_schedule(), we actually use ___wait_var_event(). Signed-off-by: NeilBrown <neilb@xxxxxxx> --- fs/xfs/xfs_inode.c | 24 +++++------------------- fs/xfs/xfs_inode.h | 2 -- fs/xfs/xfs_inode_item.c | 3 +-- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7dc6f326936c..a855295363b5 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1899,29 +1899,15 @@ xfs_iunpin( } -static void -__xfs_iunpin_wait( - struct xfs_inode *ip) -{ - wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_IPINNED_BIT); - DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_IPINNED_BIT); - - xfs_iunpin(ip); - - do { - prepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE); - if (xfs_ipincount(ip)) - io_schedule(); - } while (xfs_ipincount(ip)); - finish_wait(wq, &wait.wq_entry); -} - void xfs_iunpin_wait( struct xfs_inode *ip) { - if (xfs_ipincount(ip)) - __xfs_iunpin_wait(ip); + if (xfs_ipincount(ip)) { + xfs_iunpin(ip); + ___wait_var_event(&ip->i_pincount, xfs_ipincount(ip) == 0, + TASK_UNINTERRUPTIBLE, 0, 0, io_schedule()); + } } /* diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 51defdebef30..5062580034ec 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -337,8 +337,6 @@ static inline bool xfs_inode_has_bigrtalloc(struct xfs_inode *ip) #define XFS_ITRUNCATED (1 << 5) /* truncated down so flush-on-close */ #define XFS_IDIRTY_RELEASE (1 << 6) /* dirty release already seen */ #define XFS_IFLUSHING (1 << 7) /* inode is being flushed */ -#define __XFS_IPINNED_BIT 8 /* wakeup key for zero pin count */ -#define XFS_IPINNED (1 << __XFS_IPINNED_BIT) #define XFS_IEOFBLOCKS (1 << 9) /* has the preallocblocks tag set */ #define XFS_NEED_INACTIVE (1 << 10) /* see XFS_INACTIVATING below */ /* diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index b509cbd191f4..7fee751c7dfd 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -712,8 +712,7 @@ xfs_inode_item_unpin( trace_xfs_inode_unpin(ip, _RET_IP_); ASSERT(lip->li_buf || xfs_iflags_test(ip, XFS_ISTALE)); ASSERT(atomic_read(&ip->i_pincount) > 0); - if (atomic_dec_and_test(&ip->i_pincount)) - wake_up_bit(&ip->i_flags, __XFS_IPINNED_BIT); + atomic_dec_and_wake_up_var(&ip->i_pincount); } STATIC uint -- 2.44.0