]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: attach inodes to the cluster buffer when dirtied
authorDave Chinner <dchinner@redhat.com>
Fri, 4 Sep 2020 19:58:20 +0000 (15:58 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Fri, 4 Sep 2020 19:58:20 +0000 (15:58 -0400)
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 <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>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/xfs_trans.h
libxfs/libxfs_io.h
libxfs/libxfs_priv.h
libxfs/rdwr.c
libxfs/trans.c
libxfs/util.c
libxfs/xfs_trans_inode.c

index 84f29418c40c757497743b8834bc7d7fd0189fdc..1f087672a2a8e5440785f3f16c5ccf8a7224f7f8 100644 (file)
@@ -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 */
index 8b67a57df9f760980473a57e2e8cf295c4d615d7..e7ec754f6b86ddcb3e6874ed934d2a33ffdf3984 100644 (file)
@@ -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;
index 5688284deb4eeec6eec25bf4ce82e25e11dcb9e6..4356fa4322d762d6e6baf67c0807fb9cbefc6d83 100644 (file)
@@ -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)
 {
index bf238c380e5b02f87d35b2b193d28c3deed5d273..5167c58e337a4e7d3e3614da6dce0e31eeb12edc 100644 (file)
@@ -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;
index 5b6e5946709a310314239bbd68a91622aa3fde58..af3342755c6dd56ec128d2d5690571a94c2fd816 100644 (file)
@@ -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);
 }
 
index 7fb0a99596f4ee4a9a573daf090ec045b7226f39..85907d16372bdb0453f61ecf17c004436a221869 100644 (file)
@@ -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 *
index 4387660b9e075dd8c455f3972b8c93bb9c7dfdcb..034eef9c74b1d9ddc64756648acc2d47cbe06422 100644 (file)
@@ -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);
        }
 
        /*