From 2c8f6265397642bb150d933fa46b1f7c294f4ffe Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Mon, 8 Jan 2018 10:41:35 -0800 Subject: xfs: print transaction log reservation on overrun The transaction dump code displays the content and reservation consumption of a particular transaction in the event of an overrun. It currently displays the reservation associated with the transaction ticket, but not the original reservation attached to the transaction. The latter value reflects the original transaction reservation calculation before additional reservation overhead is assigned, such as for the CIL context header and potential split region headers. Update xlog_print_trans() to also print the original transaction reservation in the event of overrun. This provides a reference point to identify how much reservation overhead was added to a particular ticket by xfs_log_calc_unit_res(). Signed-off-by: Brian Foster Reviewed-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_log.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/xfs/xfs_log.c') diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a503af96d780..047df85528b0 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2117,7 +2117,9 @@ xlog_print_trans( /* dump core transaction and ticket info */ xfs_warn(mp, "transaction summary:"); - xfs_warn(mp, " flags = 0x%x", tp->t_flags); + xfs_warn(mp, " log res = %d", tp->t_log_res); + xfs_warn(mp, " log count = %d", tp->t_log_count); + xfs_warn(mp, " flags = 0x%x", tp->t_flags); xlog_print_tic_res(mp, tp->t_ticket); -- cgit v1.2.3-55-g7522 From 3d170aa24283568b1ed92a09daa0e05a8788c6a4 Mon Sep 17 00:00:00 2001 From: Darrick J. Wong Date: Tue, 9 Jan 2018 11:43:36 -0800 Subject: xfs: change 0x%p -> %p in print messages Since %p prepends "0x" to the outputted string, we can drop the prefix. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/xfs_fsops.c | 2 +- fs/xfs/xfs_inode.c | 10 +++++----- fs/xfs/xfs_log.c | 4 ++-- fs/xfs/xfs_log_recover.c | 24 ++++++++++++------------ fs/xfs/xfs_trace.h | 14 +++++++------- 6 files changed, 28 insertions(+), 28 deletions(-) (limited to 'fs/xfs/xfs_log.c') diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 915c4fe5e4c3..e900dbcb0de9 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1919,7 +1919,7 @@ xfs_dir2_node_addname_int( (unsigned long long)ifbno, lastfbno); if (fblk) { xfs_alert(mp, - " fblk 0x%p blkno %llu index %d magic 0x%x", + " fblk %p blkno %llu index %d magic 0x%x", fblk, (unsigned long long)fblk->blkno, fblk->index, diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 84d73835c614..cc86b2b34243 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -878,7 +878,7 @@ xfs_do_force_shutdown( if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { xfs_notice(mp, - "%s(0x%x) called from line %d of file %s. Return address = 0x%p", + "%s(0x%x) called from line %d of file %s. Return address = %p", __func__, flags, lnnum, fname, __return_address); } /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 663b546f2bcd..e93fb885bbc5 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3529,7 +3529,7 @@ xfs_iflush_int( if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC), mp, XFS_ERRTAG_IFLUSH_1)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad inode %Lu magic number 0x%x, ptr 0x%p", + "%s: Bad inode %Lu magic number 0x%x, ptr %p", __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); goto corrupt_out; } @@ -3539,7 +3539,7 @@ xfs_iflush_int( (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), mp, XFS_ERRTAG_IFLUSH_3)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad regular inode %Lu, ptr 0x%p", + "%s: Bad regular inode %Lu, ptr %p", __func__, ip->i_ino, ip); goto corrupt_out; } @@ -3550,7 +3550,7 @@ xfs_iflush_int( (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), mp, XFS_ERRTAG_IFLUSH_4)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad directory inode %Lu, ptr 0x%p", + "%s: Bad directory inode %Lu, ptr %p", __func__, ip->i_ino, ip); goto corrupt_out; } @@ -3559,7 +3559,7 @@ xfs_iflush_int( ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, "%s: detected corrupt incore inode %Lu, " - "total extents = %d, nblocks = %Ld, ptr 0x%p", + "total extents = %d, nblocks = %Ld, ptr %p", __func__, ip->i_ino, ip->i_d.di_nextents + ip->i_d.di_anextents, ip->i_d.di_nblocks, ip); @@ -3568,7 +3568,7 @@ xfs_iflush_int( if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize, mp, XFS_ERRTAG_IFLUSH_6)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: bad inode %Lu, forkoff 0x%x, ptr 0x%p", + "%s: bad inode %Lu, forkoff 0x%x, ptr %p", __func__, ip->i_ino, ip->i_d.di_forkoff, ip); goto corrupt_out; } diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 047df85528b0..922e5a9764ca 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2244,7 +2244,7 @@ xlog_write_setup_ophdr( break; default: xfs_warn(log->l_mp, - "Bad XFS transaction clientid 0x%x in ticket 0x%p", + "Bad XFS transaction clientid 0x%x in ticket %p", ophdr->oh_clientid, ticket); return NULL; } @@ -3926,7 +3926,7 @@ xlog_verify_iclog( } if (clientid != XFS_TRANSACTION && clientid != XFS_LOG) xfs_warn(log->l_mp, - "%s: invalid clientid %d op 0x%p offset 0x%lx", + "%s: invalid clientid %d op %p offset 0x%lx", __func__, clientid, ophead, (unsigned long)field_offset); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 7864a298f7eb..205bace41832 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2218,7 +2218,7 @@ xlog_recover_do_inode_buffer( next_unlinked_offset - reg_buf_offset; if (unlikely(*logged_nextp == 0)) { xfs_alert(mp, - "Bad inode buffer log record (ptr = 0x%p, bp = 0x%p). " + "Bad inode buffer log record (ptr = %p, bp = %p). " "Trying to replay bad (0) inode di_next_unlinked field.", item, bp); XFS_ERROR_REPORT("xlog_recover_do_inode_buf", @@ -3049,7 +3049,7 @@ xlog_recover_inode_pass2( */ if (unlikely(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))) { xfs_alert(mp, - "%s: Bad inode magic number, dip = 0x%p, dino bp = 0x%p, ino = %Ld", + "%s: Bad inode magic number, dip = %p, dino bp = %p, ino = %Ld", __func__, dip, bp, in_f->ilf_ino); XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)", XFS_ERRLEVEL_LOW, mp); @@ -3059,7 +3059,7 @@ xlog_recover_inode_pass2( ldip = item->ri_buf[1].i_addr; if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) { xfs_alert(mp, - "%s: Bad inode log record, rec ptr 0x%p, ino %Ld", + "%s: Bad inode log record, rec ptr %p, ino %Ld", __func__, item, in_f->ilf_ino); XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)", XFS_ERRLEVEL_LOW, mp); @@ -3117,8 +3117,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad regular inode log record, rec ptr 0x%p, " - "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", + "%s: Bad regular inode log record, rec ptr %p, " + "ino ptr = %p, ino bp = %p, ino %Ld", __func__, item, dip, bp, in_f->ilf_ino); error = -EFSCORRUPTED; goto out_release; @@ -3130,8 +3130,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad dir inode log record, rec ptr 0x%p, " - "ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", + "%s: Bad dir inode log record, rec ptr %p, " + "ino ptr = %p, ino bp = %p, ino %Ld", __func__, item, dip, bp, in_f->ilf_ino); error = -EFSCORRUPTED; goto out_release; @@ -3141,8 +3141,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " - "dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld", + "%s: Bad inode log record, rec ptr %p, dino ptr %p, " + "dino bp %p, ino %Ld, total extents = %d, nblocks = %Ld", __func__, item, dip, bp, in_f->ilf_ino, ldip->di_nextents + ldip->di_anextents, ldip->di_nblocks); @@ -3153,8 +3153,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, " - "dino bp 0x%p, ino %Ld, forkoff 0x%x", __func__, + "%s: Bad inode log record, rec ptr %p, dino ptr %p, " + "dino bp %p, ino %Ld, forkoff 0x%x", __func__, item, dip, bp, in_f->ilf_ino, ldip->di_forkoff); error = -EFSCORRUPTED; goto out_release; @@ -3164,7 +3164,7 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad inode log record length %d, rec ptr 0x%p", + "%s: Bad inode log record length %d, rec ptr %p", __func__, item->ri_buf[1].i_len, item); error = -EFSCORRUPTED; goto out_release; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index b6251f8d66a0..560545f1a0d7 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -72,7 +72,7 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class, __entry->flags = ctx->flags; ), TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u " - "alist 0x%p size %u count %u firstu %u flags %d %s", + "alist %p size %u count %u firstu %u flags %d %s", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, __entry->hashval, @@ -200,7 +200,7 @@ TRACE_EVENT(xfs_attr_list_node_descend, __entry->bt_before = be32_to_cpu(btree->before); ), TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u " - "alist 0x%p size %u count %u firstu %u flags %d %s " + "alist %p size %u count %u firstu %u flags %d %s " "node hashval %u, node before %u", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, @@ -251,7 +251,7 @@ DECLARE_EVENT_CLASS(xfs_bmap_class, __entry->bmap_state = state; __entry->caller_ip = caller_ip; ), - TP_printk("dev %d:%d ino 0x%llx state %s cur 0x%p/%d " + TP_printk("dev %d:%d ino 0x%llx state %s cur %p/%d " "offset %lld block %lld count %lld flag %d caller %ps", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, @@ -460,7 +460,7 @@ DECLARE_EVENT_CLASS(xfs_buf_item_class, ), TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " "lock %d flags %s recur %d refcount %d bliflags %s " - "lidesc 0x%p liflags %s", + "lidesc %p liflags %s", MAJOR(__entry->dev), MINOR(__entry->dev), (unsigned long long)__entry->buf_bno, __entry->buf_len, @@ -1028,7 +1028,7 @@ DECLARE_EVENT_CLASS(xfs_log_item_class, __entry->flags = lip->li_flags; __entry->lsn = lip->li_lsn; ), - TP_printk("dev %d:%d lip 0x%p lsn %d/%d type %s flags %s", + TP_printk("dev %d:%d lip %p lsn %d/%d type %s flags %s", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->lip, CYCLE_LSN(__entry->lsn), BLOCK_LSN(__entry->lsn), @@ -1082,7 +1082,7 @@ DECLARE_EVENT_CLASS(xfs_ail_class, __entry->old_lsn = old_lsn; __entry->new_lsn = new_lsn; ), - TP_printk("dev %d:%d lip 0x%p old lsn %d/%d new lsn %d/%d type %s flags %s", + TP_printk("dev %d:%d lip %p old lsn %d/%d new lsn %d/%d type %s flags %s", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->lip, CYCLE_LSN(__entry->old_lsn), BLOCK_LSN(__entry->old_lsn), @@ -2014,7 +2014,7 @@ DECLARE_EVENT_CLASS(xfs_log_recover_item_class, __entry->count = item->ri_cnt; __entry->total = item->ri_total; ), - TP_printk("dev %d:%d tid 0x%x lsn 0x%llx, pass %d, item 0x%p, " + TP_printk("dev %d:%d tid 0x%x lsn 0x%llx, pass %d, item %p, " "item type %s item region count/total %d/%d", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->tid, -- cgit v1.2.3-55-g7522 From c96900435fa9fdfd9702a60cd765bd85e380303e Mon Sep 17 00:00:00 2001 From: Darrick J. Wong Date: Tue, 9 Jan 2018 12:02:55 -0800 Subject: xfs: use %px for data pointers when debugging Starting with commit 57e734423ad ("vsprintf: refactor %pK code out of pointer"), the behavior of the raw '%p' printk format specifier was changed to print a 32-bit hash of the pointer value to avoid leaking kernel pointers into dmesg. For most situations that's good. This is /undesirable/ behavior when we're trying to debug XFS, however, so define a PTR_FMT that prints the actual pointer when we're in debug mode. Note that %p for tracepoints still prints the raw pointer, so in the long run we could consider rewriting some of these messages as tracepoints. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/xfs_aops.c | 2 +- fs/xfs/xfs_dquot_item.c | 2 +- fs/xfs/xfs_fsops.c | 2 +- fs/xfs/xfs_inode.c | 10 +++++----- fs/xfs/xfs_linux.h | 12 ++++++++++++ fs/xfs/xfs_log.c | 4 ++-- fs/xfs/xfs_log_recover.c | 24 ++++++++++++------------ fs/xfs/xfs_qm.c | 4 ++-- 9 files changed, 37 insertions(+), 25 deletions(-) (limited to 'fs/xfs/xfs_log.c') diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index e900dbcb0de9..bb893ae02696 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -1919,7 +1919,7 @@ xfs_dir2_node_addname_int( (unsigned long long)ifbno, lastfbno); if (fblk) { xfs_alert(mp, - " fblk %p blkno %llu index %d magic 0x%x", + " fblk "PTR_FMT" blkno %llu index %d magic 0x%x", fblk, (unsigned long long)fblk->blkno, fblk->index, diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 4fc526a27a94..2e094c76bd45 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -791,7 +791,7 @@ xfs_aops_discard_page( goto out_invalidate; xfs_alert(ip->i_mount, - "page discard on page %p, inode 0x%llx, offset %llu.", + "page discard on page "PTR_FMT", inode 0x%llx, offset %llu.", page, ip->i_ino, offset); xfs_ilock(ip, XFS_ILOCK_EXCL); diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 664dea105e76..e564f11d83f3 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -212,7 +212,7 @@ xfs_qm_dquot_logitem_push( error = xfs_qm_dqflush(dqp, &bp); if (error) { - xfs_warn(dqp->q_mount, "%s: push error %d on dqp %p", + xfs_warn(dqp->q_mount, "%s: push error %d on dqp "PTR_FMT, __func__, error, dqp); } else { if (!xfs_buf_delwri_queue(bp, buffer_list)) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index cc86b2b34243..8b4545623e25 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -878,7 +878,7 @@ xfs_do_force_shutdown( if (!(flags & SHUTDOWN_FORCE_UMOUNT)) { xfs_notice(mp, - "%s(0x%x) called from line %d of file %s. Return address = %p", + "%s(0x%x) called from line %d of file %s. Return address = "PTR_FMT, __func__, flags, lnnum, fname, __return_address); } /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 29c47da383e0..c9e40d4fc939 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3529,7 +3529,7 @@ xfs_iflush_int( if (XFS_TEST_ERROR(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC), mp, XFS_ERRTAG_IFLUSH_1)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad inode %Lu magic number 0x%x, ptr %p", + "%s: Bad inode %Lu magic number 0x%x, ptr "PTR_FMT, __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); goto corrupt_out; } @@ -3539,7 +3539,7 @@ xfs_iflush_int( (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), mp, XFS_ERRTAG_IFLUSH_3)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad regular inode %Lu, ptr %p", + "%s: Bad regular inode %Lu, ptr "PTR_FMT, __func__, ip->i_ino, ip); goto corrupt_out; } @@ -3550,7 +3550,7 @@ xfs_iflush_int( (ip->i_d.di_format != XFS_DINODE_FMT_LOCAL), mp, XFS_ERRTAG_IFLUSH_4)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: Bad directory inode %Lu, ptr %p", + "%s: Bad directory inode %Lu, ptr "PTR_FMT, __func__, ip->i_ino, ip); goto corrupt_out; } @@ -3559,7 +3559,7 @@ xfs_iflush_int( ip->i_d.di_nblocks, mp, XFS_ERRTAG_IFLUSH_5)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, "%s: detected corrupt incore inode %Lu, " - "total extents = %d, nblocks = %Ld, ptr %p", + "total extents = %d, nblocks = %Ld, ptr "PTR_FMT, __func__, ip->i_ino, ip->i_d.di_nextents + ip->i_d.di_anextents, ip->i_d.di_nblocks, ip); @@ -3568,7 +3568,7 @@ xfs_iflush_int( if (XFS_TEST_ERROR(ip->i_d.di_forkoff > mp->m_sb.sb_inodesize, mp, XFS_ERRTAG_IFLUSH_6)) { xfs_alert_tag(mp, XFS_PTAG_IFLUSH, - "%s: bad inode %Lu, forkoff 0x%x, ptr %p", + "%s: bad inode %Lu, forkoff 0x%x, ptr "PTR_FMT, __func__, ip->i_ino, ip->i_d.di_forkoff, ip); goto corrupt_out; } diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 74d3576c8043..bee51a14a906 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -291,4 +291,16 @@ static inline uint64_t howmany_64(uint64_t x, uint32_t y) #define XFS_IS_REALTIME_MOUNT(mp) (0) #endif +/* + * Starting in Linux 4.15, the %p (raw pointer value) printk modifier + * prints a hashed version of the pointer to avoid leaking kernel + * pointers into dmesg. If we're trying to debug the kernel we want the + * raw values, so override this behavior as best we can. + */ +#ifdef DEBUG +# define PTR_FMT "%px" +#else +# define PTR_FMT "%p" +#endif + #endif /* __XFS_LINUX__ */ diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 922e5a9764ca..c1f266c34af7 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2244,7 +2244,7 @@ xlog_write_setup_ophdr( break; default: xfs_warn(log->l_mp, - "Bad XFS transaction clientid 0x%x in ticket %p", + "Bad XFS transaction clientid 0x%x in ticket "PTR_FMT, ophdr->oh_clientid, ticket); return NULL; } @@ -3926,7 +3926,7 @@ xlog_verify_iclog( } if (clientid != XFS_TRANSACTION && clientid != XFS_LOG) xfs_warn(log->l_mp, - "%s: invalid clientid %d op %p offset 0x%lx", + "%s: invalid clientid %d op "PTR_FMT" offset 0x%lx", __func__, clientid, ophead, (unsigned long)field_offset); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 205bace41832..d864380b6575 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2218,7 +2218,7 @@ xlog_recover_do_inode_buffer( next_unlinked_offset - reg_buf_offset; if (unlikely(*logged_nextp == 0)) { xfs_alert(mp, - "Bad inode buffer log record (ptr = %p, bp = %p). " + "Bad inode buffer log record (ptr = "PTR_FMT", bp = "PTR_FMT"). " "Trying to replay bad (0) inode di_next_unlinked field.", item, bp); XFS_ERROR_REPORT("xlog_recover_do_inode_buf", @@ -3049,7 +3049,7 @@ xlog_recover_inode_pass2( */ if (unlikely(dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))) { xfs_alert(mp, - "%s: Bad inode magic number, dip = %p, dino bp = %p, ino = %Ld", + "%s: Bad inode magic number, dip = "PTR_FMT", dino bp = "PTR_FMT", ino = %Ld", __func__, dip, bp, in_f->ilf_ino); XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)", XFS_ERRLEVEL_LOW, mp); @@ -3059,7 +3059,7 @@ xlog_recover_inode_pass2( ldip = item->ri_buf[1].i_addr; if (unlikely(ldip->di_magic != XFS_DINODE_MAGIC)) { xfs_alert(mp, - "%s: Bad inode log record, rec ptr %p, ino %Ld", + "%s: Bad inode log record, rec ptr "PTR_FMT", ino %Ld", __func__, item, in_f->ilf_ino); XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)", XFS_ERRLEVEL_LOW, mp); @@ -3117,8 +3117,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad regular inode log record, rec ptr %p, " - "ino ptr = %p, ino bp = %p, ino %Ld", + "%s: Bad regular inode log record, rec ptr "PTR_FMT", " + "ino ptr = "PTR_FMT", ino bp = "PTR_FMT", ino %Ld", __func__, item, dip, bp, in_f->ilf_ino); error = -EFSCORRUPTED; goto out_release; @@ -3130,8 +3130,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad dir inode log record, rec ptr %p, " - "ino ptr = %p, ino bp = %p, ino %Ld", + "%s: Bad dir inode log record, rec ptr "PTR_FMT", " + "ino ptr = "PTR_FMT", ino bp = "PTR_FMT", ino %Ld", __func__, item, dip, bp, in_f->ilf_ino); error = -EFSCORRUPTED; goto out_release; @@ -3141,8 +3141,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad inode log record, rec ptr %p, dino ptr %p, " - "dino bp %p, ino %Ld, total extents = %d, nblocks = %Ld", + "%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", " + "dino bp "PTR_FMT", ino %Ld, total extents = %d, nblocks = %Ld", __func__, item, dip, bp, in_f->ilf_ino, ldip->di_nextents + ldip->di_anextents, ldip->di_nblocks); @@ -3153,8 +3153,8 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad inode log record, rec ptr %p, dino ptr %p, " - "dino bp %p, ino %Ld, forkoff 0x%x", __func__, + "%s: Bad inode log record, rec ptr "PTR_FMT", dino ptr "PTR_FMT", " + "dino bp "PTR_FMT", ino %Ld, forkoff 0x%x", __func__, item, dip, bp, in_f->ilf_ino, ldip->di_forkoff); error = -EFSCORRUPTED; goto out_release; @@ -3164,7 +3164,7 @@ xlog_recover_inode_pass2( XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", XFS_ERRLEVEL_LOW, mp, ldip); xfs_alert(mp, - "%s: Bad inode log record length %d, rec ptr %p", + "%s: Bad inode log record length %d, rec ptr "PTR_FMT, __func__, item->ri_buf[1].i_len, item); error = -EFSCORRUPTED; goto out_release; diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 6b9f44df7918..5b848f4b637f 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -162,7 +162,7 @@ xfs_qm_dqpurge( */ error = xfs_qm_dqflush(dqp, &bp); if (error) { - xfs_warn(mp, "%s: dquot %p flush failed", + xfs_warn(mp, "%s: dquot "PTR_FMT" flush failed", __func__, dqp); } else { error = xfs_bwrite(bp); @@ -480,7 +480,7 @@ xfs_qm_dquot_isolate( error = xfs_qm_dqflush(dqp, &bp); if (error) { - xfs_warn(dqp->q_mount, "%s: dquot %p flush failed", + xfs_warn(dqp->q_mount, "%s: dquot "PTR_FMT" flush failed", __func__, dqp); goto out_unlock_dirty; } -- cgit v1.2.3-55-g7522 From fb1755a645972ed096047583600838f6cf414e2b Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Wed, 24 Jan 2018 13:38:48 -0800 Subject: Split buffer's b_fspriv field By splitting the b_fspriv field into two different fields (b_log_item and b_li_list). It's possible to get rid of an old ABI workaround, by using the new b_log_item field to store xfs_buf_log_item separated from the log items attached to the buffer, which will be linked in the new b_li_list field. This way, there is no more need to reorder the log items list to place the buf_log_item at the beginning of the list, simplifying a bit the logic to handle buffer IO. This also opens the possibility to change buffer's log items list into a proper list_head. b_log_item field is still defined as a void *, because it is still used by the log buffers to store xlog_in_core structures, and there is no need to add an extra field on xfs_buf just for xlog_in_core. Signed-off-by: Carlos Maiolino Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong [darrick: minor style changes] Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 8 ++-- fs/xfs/libxfs/xfs_attr_leaf.c | 2 +- fs/xfs/libxfs/xfs_btree.c | 4 +- fs/xfs/libxfs/xfs_da_btree.c | 2 +- fs/xfs/libxfs/xfs_dir2_block.c | 2 +- fs/xfs/libxfs/xfs_dir2_data.c | 2 +- fs/xfs/libxfs/xfs_dir2_leaf.c | 2 +- fs/xfs/libxfs/xfs_dir2_node.c | 2 +- fs/xfs/libxfs/xfs_ialloc.c | 4 +- fs/xfs/libxfs/xfs_sb.c | 2 +- fs/xfs/libxfs/xfs_symlink_remote.c | 2 +- fs/xfs/xfs_buf.h | 3 +- fs/xfs/xfs_buf_item.c | 85 +++++++++++++++++++++++--------------- fs/xfs/xfs_inode.c | 4 +- fs/xfs/xfs_inode_item.c | 4 +- fs/xfs/xfs_log.c | 8 ++-- fs/xfs/xfs_log_recover.c | 6 +-- fs/xfs/xfs_trans_buf.c | 48 ++++++++++----------- 18 files changed, 104 insertions(+), 86 deletions(-) (limited to 'fs/xfs/xfs_log.c') diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 6883a7668de6..c02781a4c091 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -590,8 +590,8 @@ static void xfs_agfl_write_verify( struct xfs_buf *bp) { - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_log_item; xfs_failaddr_t fa; /* no verification of non-crc AGFLs */ @@ -2487,8 +2487,8 @@ static void xfs_agf_write_verify( struct xfs_buf *bp) { - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_log_item; xfs_failaddr_t fa; fa = xfs_agf_verify(bp); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index efe5f8acbd45..2135b8e67dcc 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -309,7 +309,7 @@ xfs_attr3_leaf_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 567cff5ed511..79ee4a1951d1 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -273,7 +273,7 @@ xfs_btree_lblock_calc_crc( struct xfs_buf *bp) { struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) return; @@ -311,7 +311,7 @@ xfs_btree_sblock_calc_crc( struct xfs_buf *bp) { struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; if (!xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) return; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index cf07585b9d83..ea187b4a7991 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -182,7 +182,7 @@ xfs_da3_node_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; struct xfs_da3_node_hdr *hdr3 = bp->b_addr; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index fe951fa1a583..2da86a394bcf 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -103,7 +103,7 @@ xfs_dir3_block_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index a1e30c751c00..920279485275 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -320,7 +320,7 @@ xfs_dir3_data_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index a7ad649398c7..d7e630f41f9c 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -208,7 +208,7 @@ __write_verify( uint16_t magic) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index bb893ae02696..239d97a64296 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -141,7 +141,7 @@ xfs_dir3_free_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; xfs_failaddr_t fa; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 3625d1da7462..0e2cf5f0be1f 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2557,8 +2557,8 @@ static void xfs_agi_write_verify( struct xfs_buf *bp) { - struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_buf_log_item *bip = bp->b_log_item; xfs_failaddr_t fa; fa = xfs_agi_verify(bp); diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index e0c826403c6a..46af6aa60a8e 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -688,7 +688,7 @@ xfs_sb_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; int error; error = xfs_sb_verify(bp, false); diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c index 091e3cf0868f..5ef5f354587e 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.c +++ b/fs/xfs/libxfs/xfs_symlink_remote.c @@ -149,7 +149,7 @@ xfs_symlink_write_verify( struct xfs_buf *bp) { struct xfs_mount *mp = bp->b_target->bt_mount; - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; xfs_failaddr_t fa; /* no verification of non-crc buffers */ diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 5b5b4861c729..6fcba7536d7e 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -176,7 +176,8 @@ typedef struct xfs_buf { struct workqueue_struct *b_ioend_wq; /* I/O completion wq */ xfs_buf_iodone_t b_iodone; /* I/O completion function */ struct completion b_iowait; /* queue for I/O waiters */ - void *b_fspriv; + void *b_log_item; + struct xfs_log_item *b_li_list; struct xfs_trans *b_transp; struct page **b_pages; /* array of page pointers */ struct page *b_page_array[XB_PAGES]; /* inline pages */ diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 8afcfa3ed976..8354fab9796e 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -411,7 +411,7 @@ xfs_buf_item_unpin( int stale = bip->bli_flags & XFS_BLI_STALE; int freed; - ASSERT(bp->b_fspriv == bip); + ASSERT(bp->b_log_item == bip); ASSERT(atomic_read(&bip->bli_refcount) > 0); trace_xfs_buf_item_unpin(bip); @@ -456,13 +456,14 @@ xfs_buf_item_unpin( */ if (bip->bli_flags & XFS_BLI_STALE_INODE) { xfs_buf_do_callbacks(bp); - bp->b_fspriv = NULL; + bp->b_log_item = NULL; + bp->b_li_list = NULL; bp->b_iodone = NULL; } else { spin_lock(&ailp->xa_lock); xfs_trans_ail_delete(ailp, lip, SHUTDOWN_LOG_IO_ERROR); xfs_buf_item_relse(bp); - ASSERT(bp->b_fspriv == NULL); + ASSERT(bp->b_log_item == NULL); } xfs_buf_relse(bp); } else if (freed && remove) { @@ -722,18 +723,15 @@ xfs_buf_item_free_format( /* * Allocate a new buf log item to go with the given buffer. - * Set the buffer's b_fsprivate field to point to the new - * buf log item. If there are other item's attached to the - * buffer (see xfs_buf_attach_iodone() below), then put the - * buf log item at the front. + * Set the buffer's b_log_item field to point to the new + * buf log item. */ int xfs_buf_item_init( struct xfs_buf *bp, struct xfs_mount *mp) { - struct xfs_log_item *lip = bp->b_fspriv; - struct xfs_buf_log_item *bip; + struct xfs_buf_log_item *bip = bp->b_log_item; int chunks; int map_size; int error; @@ -741,13 +739,14 @@ xfs_buf_item_init( /* * Check to see if there is already a buf log item for - * this buffer. If there is, it is guaranteed to be - * the first. If we do already have one, there is + * this buffer. If we do already have one, there is * nothing to do here so return. */ ASSERT(bp->b_target->bt_mount == mp); - if (lip != NULL && lip->li_type == XFS_LI_BUF) + if (bip != NULL) { + ASSERT(bip->bli_item.li_type == XFS_LI_BUF); return 0; + } bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP); xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops); @@ -781,13 +780,7 @@ xfs_buf_item_init( bip->bli_formats[i].blf_map_size = map_size; } - /* - * Put the buf item into the list of items attached to the - * buffer at the front. - */ - if (bp->b_fspriv) - bip->bli_item.li_bio_list = bp->b_fspriv; - bp->b_fspriv = bip; + bp->b_log_item = bip; xfs_buf_hold(bp); return 0; } @@ -961,13 +954,14 @@ void xfs_buf_item_relse( xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; + struct xfs_log_item *lip = bp->b_li_list; trace_xfs_buf_item_relse(bp, _RET_IP_); ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); - bp->b_fspriv = bip->bli_item.li_bio_list; - if (bp->b_fspriv == NULL) + bp->b_log_item = NULL; + if (lip == NULL) bp->b_iodone = NULL; xfs_buf_rele(bp); @@ -980,9 +974,7 @@ xfs_buf_item_relse( * to be called when the buffer's I/O completes. If it is not set * already, set the buffer's b_iodone() routine to be * xfs_buf_iodone_callbacks() and link the log item into the list of - * items rooted at b_fsprivate. Items are always added as the second - * entry in the list if there is a first, because the buf item code - * assumes that the buf log item is first. + * items rooted at b_li_list. */ void xfs_buf_attach_iodone( @@ -995,12 +987,12 @@ xfs_buf_attach_iodone( ASSERT(xfs_buf_islocked(bp)); lip->li_cb = cb; - head_lip = bp->b_fspriv; + head_lip = bp->b_li_list; if (head_lip) { lip->li_bio_list = head_lip->li_bio_list; head_lip->li_bio_list = lip; } else { - bp->b_fspriv = lip; + bp->b_li_list = lip; } ASSERT(bp->b_iodone == NULL || @@ -1024,10 +1016,17 @@ STATIC void xfs_buf_do_callbacks( struct xfs_buf *bp) { + struct xfs_buf_log_item *blip = bp->b_log_item; struct xfs_log_item *lip; - while ((lip = bp->b_fspriv) != NULL) { - bp->b_fspriv = lip->li_bio_list; + /* If there is a buf_log_item attached, run its callback */ + if (blip) { + lip = &blip->bli_item; + lip->li_cb(bp, lip); + } + + while ((lip = bp->b_li_list) != NULL) { + bp->b_li_list = lip->li_bio_list; ASSERT(lip->li_cb != NULL); /* * Clear the next pointer so we don't have any @@ -1052,10 +1051,19 @@ STATIC void xfs_buf_do_callbacks_fail( struct xfs_buf *bp) { + struct xfs_log_item *lip = bp->b_li_list; struct xfs_log_item *next; - struct xfs_log_item *lip = bp->b_fspriv; - struct xfs_ail *ailp = lip->li_ailp; + struct xfs_ail *ailp; + /* + * Buffer log item errors are handled directly by xfs_buf_item_push() + * and xfs_buf_iodone_callback_error, and they have no IO error + * callbacks. Check only for items in b_li_list. + */ + if (lip == NULL) + return; + + ailp = lip->li_ailp; spin_lock(&ailp->xa_lock); for (; lip; lip = next) { next = lip->li_bio_list; @@ -1069,12 +1077,20 @@ static bool xfs_buf_iodone_callback_error( struct xfs_buf *bp) { - struct xfs_log_item *lip = bp->b_fspriv; - struct xfs_mount *mp = lip->li_mountp; + struct xfs_buf_log_item *bip = bp->b_log_item; + struct xfs_log_item *lip = bp->b_li_list; + struct xfs_mount *mp; static ulong lasttime; static xfs_buftarg_t *lasttarg; struct xfs_error_cfg *cfg; + /* + * The failed buffer might not have a buf_log_item attached or the + * log_item list might be empty. Get the mp from the available + * xfs_log_item + */ + mp = bip ? bip->bli_item.li_mountp : lip->li_mountp; + /* * If we've already decided to shutdown the filesystem because of * I/O errors, there's no point in giving this a retry. @@ -1183,7 +1199,8 @@ xfs_buf_iodone_callbacks( bp->b_first_retry_time = 0; xfs_buf_do_callbacks(bp); - bp->b_fspriv = NULL; + bp->b_log_item = NULL; + bp->b_li_list = NULL; bp->b_iodone = NULL; xfs_buf_ioend(bp); } diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c9e40d4fc939..8a3ff6343d91 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2272,7 +2272,7 @@ xfs_ifree_cluster( * stale first, we will not attempt to lock them in the loop * below as the XFS_ISTALE flag will be set. */ - lip = bp->b_fspriv; + lip = bp->b_li_list; while (lip) { if (lip->li_type == XFS_LI_INODE) { iip = (xfs_inode_log_item_t *)lip; @@ -3649,7 +3649,7 @@ xfs_iflush_int( /* generate the checksum. */ xfs_dinode_calc_crc(mp, dip); - ASSERT(bp->b_fspriv != NULL); + ASSERT(bp->b_li_list != NULL); ASSERT(bp->b_iodone != NULL); return 0; diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 6ee5c3bf19ad..993736032b4b 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -722,7 +722,7 @@ xfs_iflush_done( * Scan the buffer IO completions for other inodes being completed and * attach them to the current inode log item. */ - blip = bp->b_fspriv; + blip = bp->b_li_list; prev = NULL; while (blip != NULL) { if (blip->li_cb != xfs_iflush_done) { @@ -734,7 +734,7 @@ xfs_iflush_done( /* remove from list */ next = blip->li_bio_list; if (!prev) { - bp->b_fspriv = next; + bp->b_li_list = next; } else { prev->li_bio_list = next; } diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index c1f266c34af7..20483b654ef1 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1242,7 +1242,7 @@ xlog_space_left( static void xlog_iodone(xfs_buf_t *bp) { - struct xlog_in_core *iclog = bp->b_fspriv; + struct xlog_in_core *iclog = bp->b_log_item; struct xlog *l = iclog->ic_log; int aborted = 0; @@ -1773,7 +1773,7 @@ STATIC int xlog_bdstrat( struct xfs_buf *bp) { - struct xlog_in_core *iclog = bp->b_fspriv; + struct xlog_in_core *iclog = bp->b_log_item; xfs_buf_lock(bp); if (iclog->ic_state & XLOG_STATE_IOERROR) { @@ -1919,7 +1919,7 @@ xlog_sync( } bp->b_io_length = BTOBB(count); - bp->b_fspriv = iclog; + bp->b_log_item = iclog; bp->b_flags &= ~XBF_FLUSH; bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE | XBF_FUA); @@ -1958,7 +1958,7 @@ xlog_sync( XFS_BUF_SET_ADDR(bp, 0); /* logical 0 */ xfs_buf_associate_memory(bp, (char *)&iclog->ic_header + count, split); - bp->b_fspriv = iclog; + bp->b_log_item = iclog; bp->b_flags &= ~XBF_FLUSH; bp->b_flags |= (XBF_ASYNC | XBF_SYNCIO | XBF_WRITE | XBF_FUA); diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index d864380b6575..00240c9ee72e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -400,9 +400,9 @@ xlog_recover_iodone( * On v5 supers, a bli could be attached to update the metadata LSN. * Clean it up. */ - if (bp->b_fspriv) + if (bp->b_log_item) xfs_buf_item_relse(bp); - ASSERT(bp->b_fspriv == NULL); + ASSERT(bp->b_log_item == NULL); bp->b_iodone = NULL; xfs_buf_ioend(bp); @@ -2630,7 +2630,7 @@ xlog_recover_validate_buf_type( ASSERT(!bp->b_iodone || bp->b_iodone == xlog_recover_iodone); bp->b_iodone = xlog_recover_iodone; xfs_buf_item_init(bp, mp); - bip = bp->b_fspriv; + bip = bp->b_log_item; bip->bli_item.li_lsn = current_lsn; } } diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index 74563cd2970c..653ce379d36b 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c @@ -82,12 +82,12 @@ _xfs_trans_bjoin( ASSERT(bp->b_transp == NULL); /* - * The xfs_buf_log_item pointer is stored in b_fsprivate. If + * The xfs_buf_log_item pointer is stored in b_log_item. If * it doesn't have one yet, then allocate one and initialize it. * The checks to see if one is there are in xfs_buf_item_init(). */ xfs_buf_item_init(bp, tp->t_mountp); - bip = bp->b_fspriv; + bip = bp->b_log_item; ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL)); ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); @@ -118,7 +118,7 @@ xfs_trans_bjoin( struct xfs_buf *bp) { _xfs_trans_bjoin(tp, bp, 0); - trace_xfs_trans_bjoin(bp->b_fspriv); + trace_xfs_trans_bjoin(bp->b_log_item); } /* @@ -159,7 +159,7 @@ xfs_trans_get_buf_map( } ASSERT(bp->b_transp == tp); - bip = bp->b_fspriv; + bip = bp->b_log_item; ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); bip->bli_recur++; @@ -175,7 +175,7 @@ xfs_trans_get_buf_map( ASSERT(!bp->b_error); _xfs_trans_bjoin(tp, bp, 1); - trace_xfs_trans_get_buf(bp->b_fspriv); + trace_xfs_trans_get_buf(bp->b_log_item); return bp; } @@ -211,7 +211,7 @@ xfs_trans_getsb( */ bp = mp->m_sb_bp; if (bp->b_transp == tp) { - bip = bp->b_fspriv; + bip = bp->b_log_item; ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); bip->bli_recur++; @@ -224,7 +224,7 @@ xfs_trans_getsb( return NULL; _xfs_trans_bjoin(tp, bp, 1); - trace_xfs_trans_getsb(bp->b_fspriv); + trace_xfs_trans_getsb(bp->b_log_item); return bp; } @@ -267,7 +267,7 @@ xfs_trans_read_buf_map( if (bp) { ASSERT(xfs_buf_islocked(bp)); ASSERT(bp->b_transp == tp); - ASSERT(bp->b_fspriv != NULL); + ASSERT(bp->b_log_item != NULL); ASSERT(!bp->b_error); ASSERT(bp->b_flags & XBF_DONE); @@ -280,7 +280,7 @@ xfs_trans_read_buf_map( return -EIO; } - bip = bp->b_fspriv; + bip = bp->b_log_item; bip->bli_recur++; ASSERT(atomic_read(&bip->bli_refcount) > 0); @@ -330,7 +330,7 @@ xfs_trans_read_buf_map( if (tp) { _xfs_trans_bjoin(tp, bp, 1); - trace_xfs_trans_read_buf(bp->b_fspriv); + trace_xfs_trans_read_buf(bp->b_log_item); } *bpp = bp; return 0; @@ -370,7 +370,7 @@ xfs_trans_brelse( } ASSERT(bp->b_transp == tp); - bip = bp->b_fspriv; + bip = bp->b_log_item; ASSERT(bip->bli_item.li_type == XFS_LI_BUF); ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL)); @@ -462,7 +462,7 @@ xfs_trans_bhold( xfs_trans_t *tp, xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -483,7 +483,7 @@ xfs_trans_bhold_release( xfs_trans_t *tp, xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -504,7 +504,7 @@ xfs_trans_dirty_buf( struct xfs_trans *tp, struct xfs_buf *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -561,7 +561,7 @@ xfs_trans_log_buf( uint first, uint last) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(first <= last && last < BBTOB(bp->b_length)); ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED)); @@ -607,7 +607,7 @@ xfs_trans_binval( xfs_trans_t *tp, xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; int i; ASSERT(bp->b_transp == tp); @@ -662,7 +662,7 @@ xfs_trans_inode_buf( xfs_trans_t *tp, xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -686,7 +686,7 @@ xfs_trans_stale_inode_buf( xfs_trans_t *tp, xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -711,7 +711,7 @@ xfs_trans_inode_alloc_buf( xfs_trans_t *tp, xfs_buf_t *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -733,7 +733,7 @@ xfs_trans_ordered_buf( struct xfs_trans *tp, struct xfs_buf *bp) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); @@ -763,7 +763,7 @@ xfs_trans_buf_set_type( struct xfs_buf *bp, enum xfs_blft type) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; if (!tp) return; @@ -780,8 +780,8 @@ xfs_trans_buf_copy_type( struct xfs_buf *dst_bp, struct xfs_buf *src_bp) { - struct xfs_buf_log_item *sbip = src_bp->b_fspriv; - struct xfs_buf_log_item *dbip = dst_bp->b_fspriv; + struct xfs_buf_log_item *sbip = src_bp->b_log_item; + struct xfs_buf_log_item *dbip = dst_bp->b_log_item; enum xfs_blft type; type = xfs_blft_from_flags(&sbip->__bli_format); @@ -805,7 +805,7 @@ xfs_trans_dquot_buf( xfs_buf_t *bp, uint type) { - struct xfs_buf_log_item *bip = bp->b_fspriv; + struct xfs_buf_log_item *bip = bp->b_log_item; ASSERT(type == XFS_BLF_UDQUOT_BUF || type == XFS_BLF_PDQUOT_BUF || -- cgit v1.2.3-55-g7522 From 643c8c05e75d978c55ceb584f21a16de5431c17d Mon Sep 17 00:00:00 2001 From: Carlos Maiolino Date: Wed, 24 Jan 2018 13:38:49 -0800 Subject: Use list_head infra-structure for buffer's log items list Now that buffer's b_fspriv has been split, just replace the current singly linked list of xfs_log_items, by the list_head infrastructure. Also, remove the xfs_log_item argument from xfs_buf_resubmit_failed_buffers(), there is no need for this argument, once the log items can be walked through the list_head in the buffer. Signed-off-by: Carlos Maiolino Reviewed-by: Bill O'Donnell Reviewed-by: Darrick J. Wong [darrick: minor style cleanups] Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_buf.c | 1 + fs/xfs/xfs_buf.h | 2 +- fs/xfs/xfs_buf_item.c | 57 +++++++++++++++++++++---------------------------- fs/xfs/xfs_buf_item.h | 1 - fs/xfs/xfs_dquot_item.c | 2 +- fs/xfs/xfs_inode.c | 8 +++---- fs/xfs/xfs_inode_item.c | 41 +++++++++++------------------------ fs/xfs/xfs_log.c | 1 + fs/xfs/xfs_trans.h | 2 +- 9 files changed, 44 insertions(+), 71 deletions(-) (limited to 'fs/xfs/xfs_log.c') diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 0820c1ccf97c..d1da2ee9e6db 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -236,6 +236,7 @@ _xfs_buf_alloc( init_completion(&bp->b_iowait); INIT_LIST_HEAD(&bp->b_lru); INIT_LIST_HEAD(&bp->b_list); + INIT_LIST_HEAD(&bp->b_li_list); sema_init(&bp->b_sema, 0); /* held, no waiters */ spin_lock_init(&bp->b_lock); XB_SET_OWNER(bp); diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index 6fcba7536d7e..2f4c91452861 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -177,7 +177,7 @@ typedef struct xfs_buf { xfs_buf_iodone_t b_iodone; /* I/O completion function */ struct completion b_iowait; /* queue for I/O waiters */ void *b_log_item; - struct xfs_log_item *b_li_list; + struct list_head b_li_list; /* Log items list head */ struct xfs_trans *b_transp; struct page **b_pages; /* array of page pointers */ struct page *b_page_array[XB_PAGES]; /* inline pages */ diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 8354fab9796e..270ddb4d2313 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -457,7 +457,7 @@ xfs_buf_item_unpin( if (bip->bli_flags & XFS_BLI_STALE_INODE) { xfs_buf_do_callbacks(bp); bp->b_log_item = NULL; - bp->b_li_list = NULL; + list_del_init(&bp->b_li_list); bp->b_iodone = NULL; } else { spin_lock(&ailp->xa_lock); @@ -955,13 +955,12 @@ xfs_buf_item_relse( xfs_buf_t *bp) { struct xfs_buf_log_item *bip = bp->b_log_item; - struct xfs_log_item *lip = bp->b_li_list; trace_xfs_buf_item_relse(bp, _RET_IP_); ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); bp->b_log_item = NULL; - if (lip == NULL) + if (list_empty(&bp->b_li_list)) bp->b_iodone = NULL; xfs_buf_rele(bp); @@ -982,18 +981,10 @@ xfs_buf_attach_iodone( void (*cb)(xfs_buf_t *, xfs_log_item_t *), xfs_log_item_t *lip) { - xfs_log_item_t *head_lip; - ASSERT(xfs_buf_islocked(bp)); lip->li_cb = cb; - head_lip = bp->b_li_list; - if (head_lip) { - lip->li_bio_list = head_lip->li_bio_list; - head_lip->li_bio_list = lip; - } else { - bp->b_li_list = lip; - } + list_add_tail(&lip->li_bio_list, &bp->b_li_list); ASSERT(bp->b_iodone == NULL || bp->b_iodone == xfs_buf_iodone_callbacks); @@ -1003,12 +994,12 @@ xfs_buf_attach_iodone( /* * We can have many callbacks on a buffer. Running the callbacks individually * can cause a lot of contention on the AIL lock, so we allow for a single - * callback to be able to scan the remaining lip->li_bio_list for other items - * of the same type and callback to be processed in the first call. + * callback to be able to scan the remaining items in bp->b_li_list for other + * items of the same type and callback to be processed in the first call. * * As a result, the loop walking the callback list below will also modify the * list. it removes the first item from the list and then runs the callback. - * The loop then restarts from the new head of the list. This allows the + * The loop then restarts from the new first item int the list. This allows the * callback to scan and modify the list attached to the buffer and we don't * have to care about maintaining a next item pointer. */ @@ -1025,16 +1016,17 @@ xfs_buf_do_callbacks( lip->li_cb(bp, lip); } - while ((lip = bp->b_li_list) != NULL) { - bp->b_li_list = lip->li_bio_list; - ASSERT(lip->li_cb != NULL); + while (!list_empty(&bp->b_li_list)) { + lip = list_first_entry(&bp->b_li_list, struct xfs_log_item, + li_bio_list); + /* - * Clear the next pointer so we don't have any + * Remove the item from the list, so we don't have any * confusion if the item is added to another buf. * Don't touch the log item after calling its * callback, because it could have freed itself. */ - lip->li_bio_list = NULL; + list_del_init(&lip->li_bio_list); lip->li_cb(bp, lip); } } @@ -1051,8 +1043,7 @@ STATIC void xfs_buf_do_callbacks_fail( struct xfs_buf *bp) { - struct xfs_log_item *lip = bp->b_li_list; - struct xfs_log_item *next; + struct xfs_log_item *lip; struct xfs_ail *ailp; /* @@ -1060,13 +1051,14 @@ xfs_buf_do_callbacks_fail( * and xfs_buf_iodone_callback_error, and they have no IO error * callbacks. Check only for items in b_li_list. */ - if (lip == NULL) + if (list_empty(&bp->b_li_list)) return; + lip = list_first_entry(&bp->b_li_list, struct xfs_log_item, + li_bio_list); ailp = lip->li_ailp; spin_lock(&ailp->xa_lock); - for (; lip; lip = next) { - next = lip->li_bio_list; + list_for_each_entry(lip, &bp->b_li_list, li_bio_list) { if (lip->li_ops->iop_error) lip->li_ops->iop_error(lip, bp); } @@ -1078,7 +1070,7 @@ xfs_buf_iodone_callback_error( struct xfs_buf *bp) { struct xfs_buf_log_item *bip = bp->b_log_item; - struct xfs_log_item *lip = bp->b_li_list; + struct xfs_log_item *lip; struct xfs_mount *mp; static ulong lasttime; static xfs_buftarg_t *lasttarg; @@ -1089,7 +1081,9 @@ xfs_buf_iodone_callback_error( * log_item list might be empty. Get the mp from the available * xfs_log_item */ - mp = bip ? bip->bli_item.li_mountp : lip->li_mountp; + lip = list_first_entry_or_null(&bp->b_li_list, struct xfs_log_item, + li_bio_list); + mp = lip ? lip->li_mountp : bip->bli_item.li_mountp; /* * If we've already decided to shutdown the filesystem because of @@ -1200,7 +1194,7 @@ xfs_buf_iodone_callbacks( xfs_buf_do_callbacks(bp); bp->b_log_item = NULL; - bp->b_li_list = NULL; + list_del_init(&bp->b_li_list); bp->b_iodone = NULL; xfs_buf_ioend(bp); } @@ -1245,10 +1239,9 @@ xfs_buf_iodone( bool xfs_buf_resubmit_failed_buffers( struct xfs_buf *bp, - struct xfs_log_item *lip, struct list_head *buffer_list) { - struct xfs_log_item *next; + struct xfs_log_item *lip; /* * Clear XFS_LI_FAILED flag from all items before resubmit @@ -1256,10 +1249,8 @@ xfs_buf_resubmit_failed_buffers( * XFS_LI_FAILED set/clear is protected by xa_lock, caller this * function already have it acquired */ - for (; lip; lip = next) { - next = lip->li_bio_list; + list_for_each_entry(lip, &bp->b_li_list, li_bio_list) xfs_clear_li_failed(lip); - } /* Add this buffer back to the delayed write list */ return xfs_buf_delwri_queue(bp, buffer_list); diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 0febfbbf6ba9..643f53dcfe51 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h @@ -71,7 +71,6 @@ void xfs_buf_attach_iodone(struct xfs_buf *, void xfs_buf_iodone_callbacks(struct xfs_buf *); void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *); bool xfs_buf_resubmit_failed_buffers(struct xfs_buf *, - struct xfs_log_item *, struct list_head *); extern kmem_zone_t *xfs_buf_item_zone; diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 51ee848a550e..96eaa6933709 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -176,7 +176,7 @@ xfs_qm_dquot_logitem_push( if (!xfs_buf_trylock(bp)) return XFS_ITEM_LOCKED; - if (!xfs_buf_resubmit_failed_buffers(bp, lip, buffer_list)) + if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list)) rval = XFS_ITEM_FLUSHING; xfs_buf_unlock(bp); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8a3ff6343d91..c66effc8e7dd 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2214,7 +2214,7 @@ xfs_ifree_cluster( xfs_buf_t *bp; xfs_inode_t *ip; xfs_inode_log_item_t *iip; - xfs_log_item_t *lip; + struct xfs_log_item *lip; struct xfs_perag *pag; xfs_ino_t inum; @@ -2272,8 +2272,7 @@ xfs_ifree_cluster( * stale first, we will not attempt to lock them in the loop * below as the XFS_ISTALE flag will be set. */ - lip = bp->b_li_list; - while (lip) { + list_for_each_entry(lip, &bp->b_li_list, li_bio_list) { if (lip->li_type == XFS_LI_INODE) { iip = (xfs_inode_log_item_t *)lip; ASSERT(iip->ili_logged == 1); @@ -2283,7 +2282,6 @@ xfs_ifree_cluster( &iip->ili_item.li_lsn); xfs_iflags_set(iip->ili_inode, XFS_ISTALE); } - lip = lip->li_bio_list; } @@ -3649,7 +3647,7 @@ xfs_iflush_int( /* generate the checksum. */ xfs_dinode_calc_crc(mp, dip); - ASSERT(bp->b_li_list != NULL); + ASSERT(!list_empty(&bp->b_li_list)); ASSERT(bp->b_iodone != NULL); return 0; diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 993736032b4b..ddfc2c80af5e 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -521,7 +521,7 @@ xfs_inode_item_push( if (!xfs_buf_trylock(bp)) return XFS_ITEM_LOCKED; - if (!xfs_buf_resubmit_failed_buffers(bp, lip, buffer_list)) + if (!xfs_buf_resubmit_failed_buffers(bp, buffer_list)) rval = XFS_ITEM_FLUSHING; xfs_buf_unlock(bp); @@ -712,37 +712,23 @@ xfs_iflush_done( struct xfs_log_item *lip) { struct xfs_inode_log_item *iip; - struct xfs_log_item *blip; - struct xfs_log_item *next; - struct xfs_log_item *prev; + struct xfs_log_item *blip, *n; struct xfs_ail *ailp = lip->li_ailp; int need_ail = 0; + LIST_HEAD(tmp); /* * Scan the buffer IO completions for other inodes being completed and * attach them to the current inode log item. */ - blip = bp->b_li_list; - prev = NULL; - while (blip != NULL) { - if (blip->li_cb != xfs_iflush_done) { - prev = blip; - blip = blip->li_bio_list; - continue; - } - /* remove from list */ - next = blip->li_bio_list; - if (!prev) { - bp->b_li_list = next; - } else { - prev->li_bio_list = next; - } + list_add_tail(&lip->li_bio_list, &tmp); - /* add to current list */ - blip->li_bio_list = lip->li_bio_list; - lip->li_bio_list = blip; + list_for_each_entry_safe(blip, n, &bp->b_li_list, li_bio_list) { + if (lip->li_cb != xfs_iflush_done) + continue; + list_move_tail(&blip->li_bio_list, &tmp); /* * while we have the item, do the unlocked check for needing * the AIL lock. @@ -751,8 +737,6 @@ xfs_iflush_done( if ((iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) || (blip->li_flags & XFS_LI_FAILED)) need_ail++; - - blip = next; } /* make sure we capture the state of the initial inode. */ @@ -775,7 +759,7 @@ xfs_iflush_done( /* this is an opencoded batch version of xfs_trans_ail_delete */ spin_lock(&ailp->xa_lock); - for (blip = lip; blip; blip = blip->li_bio_list) { + list_for_each_entry(blip, &tmp, li_bio_list) { if (INODE_ITEM(blip)->ili_logged && blip->li_lsn == INODE_ITEM(blip)->ili_flush_lsn) mlip_changed |= xfs_ail_delete_one(ailp, blip); @@ -801,15 +785,14 @@ xfs_iflush_done( * ili_last_fields bits now that we know that the data corresponding to * them is safely on disk. */ - for (blip = lip; blip; blip = next) { - next = blip->li_bio_list; - blip->li_bio_list = NULL; - + list_for_each_entry_safe(blip, n, &tmp, li_bio_list) { + list_del_init(&blip->li_bio_list); iip = INODE_ITEM(blip); iip->ili_logged = 0; iip->ili_last_fields = 0; xfs_ifunlock(iip->ili_inode); } + list_del(&tmp); } /* diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 20483b654ef1..3e5ba1ecc080 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1047,6 +1047,7 @@ xfs_log_item_init( INIT_LIST_HEAD(&item->li_ail); INIT_LIST_HEAD(&item->li_cil); + INIT_LIST_HEAD(&item->li_bio_list); } /* diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 815b53d20e26..9d542dfe0052 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -50,7 +50,7 @@ typedef struct xfs_log_item { uint li_type; /* item type */ uint li_flags; /* misc flags */ struct xfs_buf *li_buf; /* real buffer pointer */ - struct xfs_log_item *li_bio_list; /* buffer item list */ + struct list_head li_bio_list; /* buffer item list */ void (*li_cb)(struct xfs_buf *, struct xfs_log_item *); /* buffer item iodone */ -- cgit v1.2.3-55-g7522