diff options
author | Dave Chinner <dchinner@redhat.com> | 2020-06-29 14:49:18 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2020-07-07 07:15:08 -0700 |
commit | 48d55e2ae3ce837598c073995bbbac5d24a35fe1 (patch) | |
tree | b5d1923900858dd3e77b725bae8d4a0f666fcc5f /fs/xfs/xfs_inode.c | |
parent | 71e3e35646861f2f9b8d36e00720904ed3ca31cb (diff) | |
download | linux-stable-48d55e2ae3ce837598c073995bbbac5d24a35fe1.tar.gz linux-stable-48d55e2ae3ce837598c073995bbbac5d24a35fe1.tar.bz2 linux-stable-48d55e2ae3ce837598c073995bbbac5d24a35fe1.zip |
xfs: attach inodes to the cluster buffer when dirtied
Rather than attach inodes to the cluster buffer just when we are
doing IO, attach the inodes to the cluster buffer when they are
dirtied. The means the buffer always carries a list of dirty inodes
that reference it, and we can use that list to make more fundamental
changes to inode writeback that aren't otherwise possible.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 24 |
1 files changed, 5 insertions, 19 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 1c3a8bed4875..c4586ac3656a 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2584,27 +2584,24 @@ retry: ASSERT(iip->ili_last_fields); goto out_iunlock; } - ASSERT(!iip || list_empty(&iip->ili_item.li_bio_list)); /* - * Clean inodes can be released immediately. Everything else has to go - * through xfs_iflush_abort() on journal commit as the flock - * synchronises removal of the inode from the cluster buffer against - * inode reclaim. + * Inodes not attached to the buffer can be released immediately. + * Everything else has to go through xfs_iflush_abort() on journal + * commit as the flock synchronises removal of the inode from the + * cluster buffer against inode reclaim. */ - if (xfs_inode_clean(ip)) { + if (!iip || list_empty(&iip->ili_item.li_bio_list)) { xfs_ifunlock(ip); goto out_iunlock; } /* we have a dirty inode in memory that has not yet been flushed. */ - ASSERT(iip->ili_fields); spin_lock(&iip->ili_lock); iip->ili_last_fields = iip->ili_fields; iip->ili_fields = 0; iip->ili_fsync_fields = 0; spin_unlock(&iip->ili_lock); - list_add_tail(&iip->ili_item.li_bio_list, &bp->b_li_list); ASSERT(iip->ili_last_fields); out_iunlock: @@ -3818,19 +3815,8 @@ flush_out: xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, &iip->ili_item.li_lsn); - /* - * Attach the inode item callback to the buffer whether the flush - * succeeded or not. If not, the caller will shut down and fail I/O - * completion on the buffer to remove the inode from the AIL and release - * the flush lock. - */ - bp->b_flags |= _XBF_INODES; - list_add_tail(&iip->ili_item.li_bio_list, &bp->b_li_list); - /* generate the checksum. */ xfs_dinode_calc_crc(mp, dip); - - ASSERT(!list_empty(&bp->b_li_list)); return error; } |