diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h index 32a8ab3da18371a1889489cd5f9a58c1d054f0fa..27732685b8aebed0ae21157c3effd8e8d20ef70f 100644 --- a/fs/xfs/libxfs/xfs_log_recover.h +++ b/fs/xfs/libxfs/xfs_log_recover.h @@ -18,6 +18,7 @@ enum xlog_recover_reorder { XLOG_REORDER_ITEM_LIST, XLOG_REORDER_INODE_BUFFER_LIST, XLOG_REORDER_CANCEL_LIST, + XLOG_REORDER_SB_BUFFER_LIST, }; struct xlog_recover_item_ops { diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 368937745f809b7ec9e15cd8fc3fca3c9f5e7a65..9cb79a494d06bf002745b35c32bb31feba67ef49 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -162,6 +162,8 @@ xlog_recover_buf_reorder( return XLOG_REORDER_CANCEL_LIST; if (buf_f->blf_flags & XFS_BLF_INODE_BUF) return XLOG_REORDER_INODE_BUFFER_LIST; + if (buf_f->blf_blkno == XFS_SB_DADDR) + return XLOG_REORDER_SB_BUFFER_LIST; return XLOG_REORDER_BUFFER_LIST; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 7d2a788b3e7ebcbbd95f720535897b7e0126e697..8235a1e05ee848b36fca22140239cec3eef3b4d2 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1879,6 +1879,9 @@ xlog_recover_reorder_trans( case XLOG_REORDER_BUFFER_LIST: list_move_tail(&item->ri_list, &buffer_list); break; + case XLOG_REORDER_SB_BUFFER_LIST: + list_move(&item->ri_list, &buffer_list); + break; case XLOG_REORDER_CANCEL_LIST: trace_xfs_log_recover_item_reorder_head(log, trans, item, pass); @@ -1942,6 +1945,25 @@ xlog_recover_items_pass2( return error; } +#define XLOG_RECOVER_COMMIT_QUEUE_MAX 100 +static inline bool +xlog_recover_should_pass2( + struct xlog_recover_item *item, + int items_queued) +{ + struct xfs_buf_log_format *buf_f; + + if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) + return true; + if (ITEM_TYPE(item) == XFS_LI_BUF) { + buf_f = item->ri_buf[0].i_addr; + if (buf_f->blf_blkno == XFS_SB_DADDR) + return true; + } + + return false; +} + /* * Perform the transaction. * @@ -1962,8 +1984,6 @@ xlog_recover_commit_trans( LIST_HEAD (ra_list); LIST_HEAD (done_list); - #define XLOG_RECOVER_COMMIT_QUEUE_MAX 100 - hlist_del_init(&trans->r_list); error = xlog_recover_reorder_trans(log, trans, pass); @@ -1983,7 +2003,7 @@ xlog_recover_commit_trans( item->ri_ops->ra_pass2(log, item); list_move_tail(&item->ri_list, &ra_list); items_queued++; - if (items_queued >= XLOG_RECOVER_COMMIT_QUEUE_MAX) { + if (xlog_recover_should_pass2(item, items_queued)) { error = xlog_recover_items_pass2(log, trans, buffer_list, &ra_list); list_splice_tail_init(&ra_list, &done_list);