From: Dave Chinner Date: Fri, 4 Sep 2020 19:58:20 +0000 (-0400) Subject: xfs: attach inodes to the cluster buffer when dirtied X-Git-Tag: v5.9.0-rc0~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2efa10f35fbbc52a8c1ae19f0da84b39589170f9;p=thirdparty%2Fxfsprogs-dev.git xfs: attach inodes to the cluster buffer when dirtied Source kernel commit: 48d55e2ae3ce837598c073995bbbac5d24a35fe1 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 Reviewed-by: Darrick J. Wong Reviewed-by: Brian Foster Signed-off-by: Darrick J. Wong Signed-off-by: Eric Sandeen --- diff --git a/include/xfs_trans.h b/include/xfs_trans.h index 84f29418c..1f087672a 100644 --- a/include/xfs_trans.h +++ b/include/xfs_trans.h @@ -23,6 +23,7 @@ typedef struct xfs_log_item { uint li_type; /* item type */ unsigned long li_flags; /* misc flags */ struct xfs_buf *li_buf; /* real buffer pointer */ + struct list_head li_bio_list; /* buffer item list */ } xfs_log_item_t; #define XFS_LI_DIRTY 3 /* log item dirty in transaction */ diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h index 8b67a57df..e7ec754f6 100644 --- a/libxfs/libxfs_io.h +++ b/libxfs/libxfs_io.h @@ -69,6 +69,7 @@ typedef struct xfs_buf { pthread_t b_holder; unsigned int b_recur; void *b_log_item; + struct list_head b_li_list; /* Log items list head */ void *b_transp; void *b_addr; int b_error; diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 5688284de..4356fa432 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -410,6 +410,11 @@ howmany_64(uint64_t x, uint32_t y) #define xfs_buf_stale(bp) ((bp)->b_flags |= LIBXFS_B_STALE) #define XFS_BUF_UNDELAYWRITE(bp) ((bp)->b_flags &= ~LIBXFS_B_DIRTY) +/* buffer type flags for write callbacks */ +#define _XBF_INODES 0 /* inode buffer */ +#define _XBF_DQUOTS 0 /* dquot buffer */ +#define _XBF_LOGRECOVERY 0 /* log recovery buffer */ + static inline struct xfs_buf *xfs_buf_incore(struct xfs_buftarg *target, xfs_daddr_t blkno, size_t numblks, xfs_buf_flags_t flags) { diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index bf238c380..5167c58e3 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -376,6 +376,7 @@ __initbuf(xfs_buf_t *bp, struct xfs_buftarg *btp, xfs_daddr_t bno, bp->b_holder = 0; bp->b_recur = 0; bp->b_ops = NULL; + INIT_LIST_HEAD(&bp->b_li_list); if (!bp->b_maps) { bp->b_nmaps = 1; diff --git a/libxfs/trans.c b/libxfs/trans.c index 5b6e59467..af3342755 100644 --- a/libxfs/trans.c +++ b/libxfs/trans.c @@ -783,6 +783,8 @@ xfs_inode_item_put( ASSERT(iip->ili_item.li_buf == NULL); ip->i_itemp = NULL; + + list_del_init(&iip->ili_item.li_bio_list); kmem_cache_free(xfs_ili_zone, iip); } diff --git a/libxfs/util.c b/libxfs/util.c index 7fb0a9959..85907d163 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -683,6 +683,7 @@ xfs_log_item_init( item->li_type = type; INIT_LIST_HEAD(&item->li_trans); + INIT_LIST_HEAD(&item->li_bio_list); } static struct xfs_buftarg * diff --git a/libxfs/xfs_trans_inode.c b/libxfs/xfs_trans_inode.c index 4387660b9..034eef9c7 100644 --- a/libxfs/xfs_trans_inode.c +++ b/libxfs/xfs_trans_inode.c @@ -160,13 +160,16 @@ xfs_trans_log_inode( /* * We need an explicit buffer reference for the log item but * don't want the buffer to remain attached to the transaction. - * Hold the buffer but release the transaction reference. + * Hold the buffer but release the transaction reference once + * we've attached the inode log item to the buffer log item + * list. */ xfs_buf_hold(bp); - xfs_trans_brelse(tp, bp); - spin_lock(&iip->ili_lock); iip->ili_item.li_buf = bp; + bp->b_flags |= _XBF_INODES; + list_add_tail(&iip->ili_item.li_bio_list, &bp->b_li_list); + xfs_trans_brelse(tp, bp); } /*