diff options
author | Christoph Hellwig <hch@lst.de> | 2017-04-21 14:24:42 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2017-04-25 12:40:42 -0400 |
commit | 27af1bbf524459962d1477a38ac6e0b7f79aaecc (patch) | |
tree | 8421b1c164281b38deaf5aa7421847344b9abae1 | |
parent | 3f88a15ae0f15f8dec3b10a55d02d1c1defa73c6 (diff) |
xfs: remove xfs_trans_ail_delete_bulk
xfs_iflush_done uses an on-stack variable length array to pass the log
items to be deleted to xfs_trans_ail_delete_bulk. On-stack VLAs are a
nasty gcc extension that can lead to unbounded stack allocations, but
fortunately we can easily avoid them by simply open coding
xfs_trans_ail_delete_bulk in xfs_iflush_done, which is the only caller
of it except for the single-item xfs_trans_ail_delete.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 29 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_ail.c | 71 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_priv.h | 15 |
3 files changed, 55 insertions, 60 deletions
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index d90e7811ccdd..08cb7d1a4a3a 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -731,22 +731,27 @@ xfs_iflush_done( | |||
731 | * holding the lock before removing the inode from the AIL. | 731 | * holding the lock before removing the inode from the AIL. |
732 | */ | 732 | */ |
733 | if (need_ail) { | 733 | if (need_ail) { |
734 | struct xfs_log_item *log_items[need_ail]; | 734 | bool mlip_changed = false; |
735 | int i = 0; | 735 | |
736 | /* this is an opencoded batch version of xfs_trans_ail_delete */ | ||
736 | spin_lock(&ailp->xa_lock); | 737 | spin_lock(&ailp->xa_lock); |
737 | for (blip = lip; blip; blip = blip->li_bio_list) { | 738 | for (blip = lip; blip; blip = blip->li_bio_list) { |
738 | iip = INODE_ITEM(blip); | 739 | if (INODE_ITEM(blip)->ili_logged && |
739 | if (iip->ili_logged && | 740 | blip->li_lsn == INODE_ITEM(blip)->ili_flush_lsn) |
740 | blip->li_lsn == iip->ili_flush_lsn) { | 741 | mlip_changed |= xfs_ail_delete_one(ailp, blip); |
741 | log_items[i++] = blip; | ||
742 | } | ||
743 | ASSERT(i <= need_ail); | ||
744 | } | 742 | } |
745 | /* xfs_trans_ail_delete_bulk() drops the AIL lock. */ | ||
746 | xfs_trans_ail_delete_bulk(ailp, log_items, i, | ||
747 | SHUTDOWN_CORRUPT_INCORE); | ||
748 | } | ||
749 | 743 | ||
744 | if (mlip_changed) { | ||
745 | if (!XFS_FORCED_SHUTDOWN(ailp->xa_mount)) | ||
746 | xlog_assign_tail_lsn_locked(ailp->xa_mount); | ||
747 | if (list_empty(&ailp->xa_ail)) | ||
748 | wake_up_all(&ailp->xa_empty); | ||
749 | } | ||
750 | spin_unlock(&ailp->xa_lock); | ||
751 | |||
752 | if (mlip_changed) | ||
753 | xfs_log_space_wake(ailp->xa_mount); | ||
754 | } | ||
750 | 755 | ||
751 | /* | 756 | /* |
752 | * clean up and unlock the flush lock now we are done. We can clear the | 757 | * clean up and unlock the flush lock now we are done. We can clear the |
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index d6c9c3e9e02b..9056c0f34a3c 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c | |||
@@ -684,8 +684,23 @@ xfs_trans_ail_update_bulk( | |||
684 | } | 684 | } |
685 | } | 685 | } |
686 | 686 | ||
687 | /* | 687 | bool |
688 | * xfs_trans_ail_delete_bulk - remove multiple log items from the AIL | 688 | xfs_ail_delete_one( |
689 | struct xfs_ail *ailp, | ||
690 | struct xfs_log_item *lip) | ||
691 | { | ||
692 | struct xfs_log_item *mlip = xfs_ail_min(ailp); | ||
693 | |||
694 | trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn); | ||
695 | xfs_ail_delete(ailp, lip); | ||
696 | lip->li_flags &= ~XFS_LI_IN_AIL; | ||
697 | lip->li_lsn = 0; | ||
698 | |||
699 | return mlip == lip; | ||
700 | } | ||
701 | |||
702 | /** | ||
703 | * Remove a log items from the AIL | ||
689 | * | 704 | * |
690 | * @xfs_trans_ail_delete_bulk takes an array of log items that all need to | 705 | * @xfs_trans_ail_delete_bulk takes an array of log items that all need to |
691 | * removed from the AIL. The caller is already holding the AIL lock, and done | 706 | * removed from the AIL. The caller is already holding the AIL lock, and done |
@@ -706,52 +721,36 @@ xfs_trans_ail_update_bulk( | |||
706 | * before returning. | 721 | * before returning. |
707 | */ | 722 | */ |
708 | void | 723 | void |
709 | xfs_trans_ail_delete_bulk( | 724 | xfs_trans_ail_delete( |
710 | struct xfs_ail *ailp, | 725 | struct xfs_ail *ailp, |
711 | struct xfs_log_item **log_items, | 726 | struct xfs_log_item *lip, |
712 | int nr_items, | ||
713 | int shutdown_type) __releases(ailp->xa_lock) | 727 | int shutdown_type) __releases(ailp->xa_lock) |
714 | { | 728 | { |
715 | xfs_log_item_t *mlip; | 729 | struct xfs_mount *mp = ailp->xa_mount; |
716 | int mlip_changed = 0; | 730 | bool mlip_changed; |
717 | int i; | ||
718 | 731 | ||
719 | mlip = xfs_ail_min(ailp); | 732 | if (!(lip->li_flags & XFS_LI_IN_AIL)) { |
720 | 733 | spin_unlock(&ailp->xa_lock); | |
721 | for (i = 0; i < nr_items; i++) { | 734 | if (!XFS_FORCED_SHUTDOWN(mp)) { |
722 | struct xfs_log_item *lip = log_items[i]; | 735 | xfs_alert_tag(mp, XFS_PTAG_AILDELETE, |
723 | if (!(lip->li_flags & XFS_LI_IN_AIL)) { | 736 | "%s: attempting to delete a log item that is not in the AIL", |
724 | struct xfs_mount *mp = ailp->xa_mount; | 737 | __func__); |
725 | 738 | xfs_force_shutdown(mp, shutdown_type); | |
726 | spin_unlock(&ailp->xa_lock); | ||
727 | if (!XFS_FORCED_SHUTDOWN(mp)) { | ||
728 | xfs_alert_tag(mp, XFS_PTAG_AILDELETE, | ||
729 | "%s: attempting to delete a log item that is not in the AIL", | ||
730 | __func__); | ||
731 | xfs_force_shutdown(mp, shutdown_type); | ||
732 | } | ||
733 | return; | ||
734 | } | 739 | } |
735 | 740 | return; | |
736 | trace_xfs_ail_delete(lip, mlip->li_lsn, lip->li_lsn); | ||
737 | xfs_ail_delete(ailp, lip); | ||
738 | lip->li_flags &= ~XFS_LI_IN_AIL; | ||
739 | lip->li_lsn = 0; | ||
740 | if (mlip == lip) | ||
741 | mlip_changed = 1; | ||
742 | } | 741 | } |
743 | 742 | ||
743 | mlip_changed = xfs_ail_delete_one(ailp, lip); | ||
744 | if (mlip_changed) { | 744 | if (mlip_changed) { |
745 | if (!XFS_FORCED_SHUTDOWN(ailp->xa_mount)) | 745 | if (!XFS_FORCED_SHUTDOWN(mp)) |
746 | xlog_assign_tail_lsn_locked(ailp->xa_mount); | 746 | xlog_assign_tail_lsn_locked(mp); |
747 | if (list_empty(&ailp->xa_ail)) | 747 | if (list_empty(&ailp->xa_ail)) |
748 | wake_up_all(&ailp->xa_empty); | 748 | wake_up_all(&ailp->xa_empty); |
749 | spin_unlock(&ailp->xa_lock); | 749 | } |
750 | 750 | ||
751 | spin_unlock(&ailp->xa_lock); | ||
752 | if (mlip_changed) | ||
751 | xfs_log_space_wake(ailp->xa_mount); | 753 | xfs_log_space_wake(ailp->xa_mount); |
752 | } else { | ||
753 | spin_unlock(&ailp->xa_lock); | ||
754 | } | ||
755 | } | 754 | } |
756 | 755 | ||
757 | int | 756 | int |
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 49931b72da8a..d91706c56c63 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -106,18 +106,9 @@ xfs_trans_ail_update( | |||
106 | xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn); | 106 | xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn); |
107 | } | 107 | } |
108 | 108 | ||
109 | void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp, | 109 | bool xfs_ail_delete_one(struct xfs_ail *ailp, struct xfs_log_item *lip); |
110 | struct xfs_log_item **log_items, int nr_items, | 110 | void xfs_trans_ail_delete(struct xfs_ail *ailp, struct xfs_log_item *lip, |
111 | int shutdown_type) | 111 | int shutdown_type) __releases(ailp->xa_lock); |
112 | __releases(ailp->xa_lock); | ||
113 | static inline void | ||
114 | xfs_trans_ail_delete( | ||
115 | struct xfs_ail *ailp, | ||
116 | xfs_log_item_t *lip, | ||
117 | int shutdown_type) __releases(ailp->xa_lock) | ||
118 | { | ||
119 | xfs_trans_ail_delete_bulk(ailp, &lip, 1, shutdown_type); | ||
120 | } | ||
121 | 112 | ||
122 | static inline void | 113 | static inline void |
123 | xfs_trans_ail_remove( | 114 | xfs_trans_ail_remove( |