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>
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 */
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;
#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)
{
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;
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);
}
item->li_type = type;
INIT_LIST_HEAD(&item->li_trans);
+ INIT_LIST_HEAD(&item->li_bio_list);
}
static struct xfs_buftarg *
/*
* 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);
}
/*