diff options
-rw-r--r-- | fs/xfs/Makefile | 1 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 11 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_trans_dquot.c | 25 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 45 | ||||
-rw-r--r-- | fs/xfs/xfs_buf_item.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_extfree_item.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 200 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 105 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 64 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_extfree.c | 22 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_inode.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_item.c | 440 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_priv.h | 18 |
13 files changed, 194 insertions, 759 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a5239b1713b..0dce969d6ca 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -87,7 +87,6 @@ xfs-y += xfs_alloc.o \ | |||
87 | xfs_trans_buf.o \ | 87 | xfs_trans_buf.o \ |
88 | xfs_trans_extfree.o \ | 88 | xfs_trans_extfree.o \ |
89 | xfs_trans_inode.o \ | 89 | xfs_trans_inode.o \ |
90 | xfs_trans_item.o \ | ||
91 | xfs_utils.o \ | 90 | xfs_utils.o \ |
92 | xfs_vnodeops.o \ | 91 | xfs_vnodeops.o \ |
93 | xfs_rw.o | 92 | xfs_rw.o |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 5593066d497..4b90e4b531b 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -1703,6 +1703,12 @@ xfs_init_zones(void) | |||
1703 | if (!xfs_trans_zone) | 1703 | if (!xfs_trans_zone) |
1704 | goto out_destroy_ifork_zone; | 1704 | goto out_destroy_ifork_zone; |
1705 | 1705 | ||
1706 | xfs_log_item_desc_zone = | ||
1707 | kmem_zone_init(sizeof(struct xfs_log_item_desc), | ||
1708 | "xfs_log_item_desc"); | ||
1709 | if (!xfs_log_item_desc_zone) | ||
1710 | goto out_destroy_trans_zone; | ||
1711 | |||
1706 | /* | 1712 | /* |
1707 | * The size of the zone allocated buf log item is the maximum | 1713 | * The size of the zone allocated buf log item is the maximum |
1708 | * size possible under XFS. This wastes a little bit of memory, | 1714 | * size possible under XFS. This wastes a little bit of memory, |
@@ -1712,7 +1718,7 @@ xfs_init_zones(void) | |||
1712 | (((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / | 1718 | (((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) / |
1713 | NBWORD) * sizeof(int))), "xfs_buf_item"); | 1719 | NBWORD) * sizeof(int))), "xfs_buf_item"); |
1714 | if (!xfs_buf_item_zone) | 1720 | if (!xfs_buf_item_zone) |
1715 | goto out_destroy_trans_zone; | 1721 | goto out_destroy_log_item_desc_zone; |
1716 | 1722 | ||
1717 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + | 1723 | xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) + |
1718 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * | 1724 | ((XFS_EFD_MAX_FAST_EXTENTS - 1) * |
@@ -1749,6 +1755,8 @@ xfs_init_zones(void) | |||
1749 | kmem_zone_destroy(xfs_efd_zone); | 1755 | kmem_zone_destroy(xfs_efd_zone); |
1750 | out_destroy_buf_item_zone: | 1756 | out_destroy_buf_item_zone: |
1751 | kmem_zone_destroy(xfs_buf_item_zone); | 1757 | kmem_zone_destroy(xfs_buf_item_zone); |
1758 | out_destroy_log_item_desc_zone: | ||
1759 | kmem_zone_destroy(xfs_log_item_desc_zone); | ||
1752 | out_destroy_trans_zone: | 1760 | out_destroy_trans_zone: |
1753 | kmem_zone_destroy(xfs_trans_zone); | 1761 | kmem_zone_destroy(xfs_trans_zone); |
1754 | out_destroy_ifork_zone: | 1762 | out_destroy_ifork_zone: |
@@ -1779,6 +1787,7 @@ xfs_destroy_zones(void) | |||
1779 | kmem_zone_destroy(xfs_efi_zone); | 1787 | kmem_zone_destroy(xfs_efi_zone); |
1780 | kmem_zone_destroy(xfs_efd_zone); | 1788 | kmem_zone_destroy(xfs_efd_zone); |
1781 | kmem_zone_destroy(xfs_buf_item_zone); | 1789 | kmem_zone_destroy(xfs_buf_item_zone); |
1790 | kmem_zone_destroy(xfs_log_item_desc_zone); | ||
1782 | kmem_zone_destroy(xfs_trans_zone); | 1791 | kmem_zone_destroy(xfs_trans_zone); |
1783 | kmem_zone_destroy(xfs_ifork_zone); | 1792 | kmem_zone_destroy(xfs_ifork_zone); |
1784 | kmem_zone_destroy(xfs_dabuf_zone); | 1793 | kmem_zone_destroy(xfs_dabuf_zone); |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 08f5604d092..7de91d1b75c 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -49,16 +49,14 @@ xfs_trans_dqjoin( | |||
49 | xfs_trans_t *tp, | 49 | xfs_trans_t *tp, |
50 | xfs_dquot_t *dqp) | 50 | xfs_dquot_t *dqp) |
51 | { | 51 | { |
52 | xfs_dq_logitem_t *lp = &dqp->q_logitem; | ||
53 | |||
54 | ASSERT(dqp->q_transp != tp); | 52 | ASSERT(dqp->q_transp != tp); |
55 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 53 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
56 | ASSERT(lp->qli_dquot == dqp); | 54 | ASSERT(dqp->q_logitem.qli_dquot == dqp); |
57 | 55 | ||
58 | /* | 56 | /* |
59 | * Get a log_item_desc to point at the new item. | 57 | * Get a log_item_desc to point at the new item. |
60 | */ | 58 | */ |
61 | (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(lp)); | 59 | xfs_trans_add_item(tp, &dqp->q_logitem.qli_item); |
62 | 60 | ||
63 | /* | 61 | /* |
64 | * Initialize i_transp so we can later determine if this dquot is | 62 | * Initialize i_transp so we can later determine if this dquot is |
@@ -83,16 +81,11 @@ xfs_trans_log_dquot( | |||
83 | xfs_trans_t *tp, | 81 | xfs_trans_t *tp, |
84 | xfs_dquot_t *dqp) | 82 | xfs_dquot_t *dqp) |
85 | { | 83 | { |
86 | xfs_log_item_desc_t *lidp; | ||
87 | |||
88 | ASSERT(dqp->q_transp == tp); | 84 | ASSERT(dqp->q_transp == tp); |
89 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 85 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
90 | 86 | ||
91 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(&dqp->q_logitem)); | ||
92 | ASSERT(lidp != NULL); | ||
93 | |||
94 | tp->t_flags |= XFS_TRANS_DIRTY; | 87 | tp->t_flags |= XFS_TRANS_DIRTY; |
95 | lidp->lid_flags |= XFS_LID_DIRTY; | 88 | dqp->q_logitem.qli_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
96 | } | 89 | } |
97 | 90 | ||
98 | /* | 91 | /* |
@@ -864,9 +857,8 @@ xfs_trans_get_qoff_item( | |||
864 | /* | 857 | /* |
865 | * Get a log_item_desc to point at the new item. | 858 | * Get a log_item_desc to point at the new item. |
866 | */ | 859 | */ |
867 | (void) xfs_trans_add_item(tp, (xfs_log_item_t*)q); | 860 | xfs_trans_add_item(tp, &q->qql_item); |
868 | 861 | return q; | |
869 | return (q); | ||
870 | } | 862 | } |
871 | 863 | ||
872 | 864 | ||
@@ -880,13 +872,8 @@ xfs_trans_log_quotaoff_item( | |||
880 | xfs_trans_t *tp, | 872 | xfs_trans_t *tp, |
881 | xfs_qoff_logitem_t *qlp) | 873 | xfs_qoff_logitem_t *qlp) |
882 | { | 874 | { |
883 | xfs_log_item_desc_t *lidp; | ||
884 | |||
885 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t *)qlp); | ||
886 | ASSERT(lidp != NULL); | ||
887 | |||
888 | tp->t_flags |= XFS_TRANS_DIRTY; | 875 | tp->t_flags |= XFS_TRANS_DIRTY; |
889 | lidp->lid_flags |= XFS_LID_DIRTY; | 876 | qlp->qql_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
890 | } | 877 | } |
891 | 878 | ||
892 | STATIC void | 879 | STATIC void |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index ed4e3ae2c1d..ff8675b4197 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -5857,43 +5857,18 @@ xfs_bmap_get_bp( | |||
5857 | bp = NULL; | 5857 | bp = NULL; |
5858 | 5858 | ||
5859 | if (!bp) { /* Chase down all the log items to see if the bp is there */ | 5859 | if (!bp) { /* Chase down all the log items to see if the bp is there */ |
5860 | xfs_log_item_chunk_t *licp; | 5860 | struct xfs_log_item_desc *lidp; |
5861 | xfs_trans_t *tp; | 5861 | struct xfs_buf_log_item *bip; |
5862 | 5862 | ||
5863 | tp = cur->bc_tp; | 5863 | list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) { |
5864 | licp = &tp->t_items; | 5864 | bip = (struct xfs_buf_log_item *)lidp->lid_item; |
5865 | while (!bp && licp != NULL) { | 5865 | if (bip->bli_item.li_type == XFS_LI_BUF && |
5866 | if (xfs_lic_are_all_free(licp)) { | 5866 | XFS_BUF_ADDR(bip->bli_buf) == bno) |
5867 | licp = licp->lic_next; | 5867 | return bip->bli_buf; |
5868 | continue; | ||
5869 | } | ||
5870 | for (i = 0; i < licp->lic_unused; i++) { | ||
5871 | xfs_log_item_desc_t *lidp; | ||
5872 | xfs_log_item_t *lip; | ||
5873 | xfs_buf_log_item_t *bip; | ||
5874 | xfs_buf_t *lbp; | ||
5875 | |||
5876 | if (xfs_lic_isfree(licp, i)) { | ||
5877 | continue; | ||
5878 | } | ||
5879 | |||
5880 | lidp = xfs_lic_slot(licp, i); | ||
5881 | lip = lidp->lid_item; | ||
5882 | if (lip->li_type != XFS_LI_BUF) | ||
5883 | continue; | ||
5884 | |||
5885 | bip = (xfs_buf_log_item_t *)lip; | ||
5886 | lbp = bip->bli_buf; | ||
5887 | |||
5888 | if (XFS_BUF_ADDR(lbp) == bno) { | ||
5889 | bp = lbp; | ||
5890 | break; /* Found it */ | ||
5891 | } | ||
5892 | } | ||
5893 | licp = licp->lic_next; | ||
5894 | } | 5868 | } |
5895 | } | 5869 | } |
5896 | return(bp); | 5870 | |
5871 | return bp; | ||
5897 | } | 5872 | } |
5898 | 5873 | ||
5899 | STATIC void | 5874 | STATIC void |
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 91ad92e83bc..711f69abbbe 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c | |||
@@ -460,13 +460,10 @@ xfs_buf_item_unpin_remove( | |||
460 | * occurs later in the xfs_trans_uncommit() will try to | 460 | * occurs later in the xfs_trans_uncommit() will try to |
461 | * reference the buffer which we no longer have a hold on. | 461 | * reference the buffer which we no longer have a hold on. |
462 | */ | 462 | */ |
463 | struct xfs_log_item_desc *lidp; | ||
464 | |||
465 | ASSERT(XFS_BUF_VALUSEMA(bip->bli_buf) <= 0); | 463 | ASSERT(XFS_BUF_VALUSEMA(bip->bli_buf) <= 0); |
466 | trace_xfs_buf_item_unpin_stale(bip); | 464 | trace_xfs_buf_item_unpin_stale(bip); |
467 | 465 | ||
468 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t *)bip); | 466 | xfs_trans_del_item(&bip->bli_item); |
469 | xfs_trans_free_item(tp, lidp); | ||
470 | 467 | ||
471 | /* | 468 | /* |
472 | * Since the transaction no longer refers to the buffer, the | 469 | * Since the transaction no longer refers to the buffer, the |
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 1023b1fadfe..8d0e543ca3c 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c | |||
@@ -131,18 +131,18 @@ STATIC void | |||
131 | xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) | 131 | xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp) |
132 | { | 132 | { |
133 | struct xfs_ail *ailp = efip->efi_item.li_ailp; | 133 | struct xfs_ail *ailp = efip->efi_item.li_ailp; |
134 | xfs_log_item_desc_t *lidp; | ||
135 | 134 | ||
136 | spin_lock(&ailp->xa_lock); | 135 | spin_lock(&ailp->xa_lock); |
137 | if (efip->efi_flags & XFS_EFI_CANCELED) { | 136 | if (efip->efi_flags & XFS_EFI_CANCELED) { |
137 | struct xfs_log_item *lip = &efip->efi_item; | ||
138 | |||
138 | /* | 139 | /* |
139 | * free the xaction descriptor pointing to this item | 140 | * free the xaction descriptor pointing to this item |
140 | */ | 141 | */ |
141 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) efip); | 142 | xfs_trans_del_item(lip); |
142 | xfs_trans_free_item(tp, lidp); | ||
143 | 143 | ||
144 | /* xfs_trans_ail_delete() drops the AIL lock. */ | 144 | /* xfs_trans_ail_delete() drops the AIL lock. */ |
145 | xfs_trans_ail_delete(ailp, (xfs_log_item_t *)efip); | 145 | xfs_trans_ail_delete(ailp, lip); |
146 | xfs_efi_item_free(efip); | 146 | xfs_efi_item_free(efip); |
147 | } else { | 147 | } else { |
148 | efip->efi_flags |= XFS_EFI_COMMITTED; | 148 | efip->efi_flags |= XFS_EFI_COMMITTED; |
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 57c53f7ad2c..9c41efccf72 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. |
3 | * Copyright (C) 2010 Red Hat, Inc. | ||
3 | * All Rights Reserved. | 4 | * All Rights Reserved. |
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
@@ -43,6 +44,7 @@ | |||
43 | #include "xfs_trace.h" | 44 | #include "xfs_trace.h" |
44 | 45 | ||
45 | kmem_zone_t *xfs_trans_zone; | 46 | kmem_zone_t *xfs_trans_zone; |
47 | kmem_zone_t *xfs_log_item_desc_zone; | ||
46 | 48 | ||
47 | 49 | ||
48 | /* | 50 | /* |
@@ -593,8 +595,7 @@ _xfs_trans_alloc( | |||
593 | tp->t_magic = XFS_TRANS_MAGIC; | 595 | tp->t_magic = XFS_TRANS_MAGIC; |
594 | tp->t_type = type; | 596 | tp->t_type = type; |
595 | tp->t_mountp = mp; | 597 | tp->t_mountp = mp; |
596 | tp->t_items_free = XFS_LIC_NUM_SLOTS; | 598 | INIT_LIST_HEAD(&tp->t_items); |
597 | xfs_lic_init(&(tp->t_items)); | ||
598 | INIT_LIST_HEAD(&tp->t_busy); | 599 | INIT_LIST_HEAD(&tp->t_busy); |
599 | return tp; | 600 | return tp; |
600 | } | 601 | } |
@@ -639,8 +640,7 @@ xfs_trans_dup( | |||
639 | ntp->t_magic = XFS_TRANS_MAGIC; | 640 | ntp->t_magic = XFS_TRANS_MAGIC; |
640 | ntp->t_type = tp->t_type; | 641 | ntp->t_type = tp->t_type; |
641 | ntp->t_mountp = tp->t_mountp; | 642 | ntp->t_mountp = tp->t_mountp; |
642 | ntp->t_items_free = XFS_LIC_NUM_SLOTS; | 643 | INIT_LIST_HEAD(&ntp->t_items); |
643 | xfs_lic_init(&(ntp->t_items)); | ||
644 | INIT_LIST_HEAD(&ntp->t_busy); | 644 | INIT_LIST_HEAD(&ntp->t_busy); |
645 | 645 | ||
646 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 646 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); |
@@ -1120,6 +1120,108 @@ xfs_trans_unreserve_and_mod_sb( | |||
1120 | } | 1120 | } |
1121 | 1121 | ||
1122 | /* | 1122 | /* |
1123 | * Add the given log item to the transaction's list of log items. | ||
1124 | * | ||
1125 | * The log item will now point to its new descriptor with its li_desc field. | ||
1126 | */ | ||
1127 | void | ||
1128 | xfs_trans_add_item( | ||
1129 | struct xfs_trans *tp, | ||
1130 | struct xfs_log_item *lip) | ||
1131 | { | ||
1132 | struct xfs_log_item_desc *lidp; | ||
1133 | |||
1134 | ASSERT(lip->li_mountp = tp->t_mountp); | ||
1135 | ASSERT(lip->li_ailp = tp->t_mountp->m_ail); | ||
1136 | |||
1137 | lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP); | ||
1138 | |||
1139 | lidp->lid_item = lip; | ||
1140 | lidp->lid_flags = 0; | ||
1141 | lidp->lid_size = 0; | ||
1142 | list_add_tail(&lidp->lid_trans, &tp->t_items); | ||
1143 | |||
1144 | lip->li_desc = lidp; | ||
1145 | } | ||
1146 | |||
1147 | STATIC void | ||
1148 | xfs_trans_free_item_desc( | ||
1149 | struct xfs_log_item_desc *lidp) | ||
1150 | { | ||
1151 | list_del_init(&lidp->lid_trans); | ||
1152 | kmem_zone_free(xfs_log_item_desc_zone, lidp); | ||
1153 | } | ||
1154 | |||
1155 | /* | ||
1156 | * Unlink and free the given descriptor. | ||
1157 | */ | ||
1158 | void | ||
1159 | xfs_trans_del_item( | ||
1160 | struct xfs_log_item *lip) | ||
1161 | { | ||
1162 | xfs_trans_free_item_desc(lip->li_desc); | ||
1163 | lip->li_desc = NULL; | ||
1164 | } | ||
1165 | |||
1166 | /* | ||
1167 | * Unlock all of the items of a transaction and free all the descriptors | ||
1168 | * of that transaction. | ||
1169 | */ | ||
1170 | STATIC void | ||
1171 | xfs_trans_free_items( | ||
1172 | struct xfs_trans *tp, | ||
1173 | xfs_lsn_t commit_lsn, | ||
1174 | int flags) | ||
1175 | { | ||
1176 | struct xfs_log_item_desc *lidp, *next; | ||
1177 | |||
1178 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { | ||
1179 | struct xfs_log_item *lip = lidp->lid_item; | ||
1180 | |||
1181 | lip->li_desc = NULL; | ||
1182 | |||
1183 | if (commit_lsn != NULLCOMMITLSN) | ||
1184 | IOP_COMMITTING(lip, commit_lsn); | ||
1185 | if (flags & XFS_TRANS_ABORT) | ||
1186 | lip->li_flags |= XFS_LI_ABORTED; | ||
1187 | IOP_UNLOCK(lip); | ||
1188 | |||
1189 | xfs_trans_free_item_desc(lidp); | ||
1190 | } | ||
1191 | } | ||
1192 | |||
1193 | /* | ||
1194 | * Unlock the items associated with a transaction. | ||
1195 | * | ||
1196 | * Items which were not logged should be freed. Those which were logged must | ||
1197 | * still be tracked so they can be unpinned when the transaction commits. | ||
1198 | */ | ||
1199 | STATIC void | ||
1200 | xfs_trans_unlock_items( | ||
1201 | struct xfs_trans *tp, | ||
1202 | xfs_lsn_t commit_lsn) | ||
1203 | { | ||
1204 | struct xfs_log_item_desc *lidp, *next; | ||
1205 | |||
1206 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { | ||
1207 | struct xfs_log_item *lip = lidp->lid_item; | ||
1208 | |||
1209 | lip->li_desc = NULL; | ||
1210 | |||
1211 | if (commit_lsn != NULLCOMMITLSN) | ||
1212 | IOP_COMMITTING(lip, commit_lsn); | ||
1213 | IOP_UNLOCK(lip); | ||
1214 | |||
1215 | /* | ||
1216 | * Free the descriptor if the item is not dirty | ||
1217 | * within this transaction. | ||
1218 | */ | ||
1219 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) | ||
1220 | xfs_trans_free_item_desc(lidp); | ||
1221 | } | ||
1222 | } | ||
1223 | |||
1224 | /* | ||
1123 | * Total up the number of log iovecs needed to commit this | 1225 | * Total up the number of log iovecs needed to commit this |
1124 | * transaction. The transaction itself needs one for the | 1226 | * transaction. The transaction itself needs one for the |
1125 | * transaction header. Ask each dirty item in turn how many | 1227 | * transaction header. Ask each dirty item in turn how many |
@@ -1130,30 +1232,27 @@ xfs_trans_count_vecs( | |||
1130 | struct xfs_trans *tp) | 1232 | struct xfs_trans *tp) |
1131 | { | 1233 | { |
1132 | int nvecs; | 1234 | int nvecs; |
1133 | xfs_log_item_desc_t *lidp; | 1235 | struct xfs_log_item_desc *lidp; |
1134 | 1236 | ||
1135 | nvecs = 1; | 1237 | nvecs = 1; |
1136 | lidp = xfs_trans_first_item(tp); | ||
1137 | ASSERT(lidp != NULL); | ||
1138 | 1238 | ||
1139 | /* In the non-debug case we need to start bailing out if we | 1239 | /* In the non-debug case we need to start bailing out if we |
1140 | * didn't find a log_item here, return zero and let trans_commit | 1240 | * didn't find a log_item here, return zero and let trans_commit |
1141 | * deal with it. | 1241 | * deal with it. |
1142 | */ | 1242 | */ |
1143 | if (lidp == NULL) | 1243 | if (list_empty(&tp->t_items)) { |
1244 | ASSERT(0); | ||
1144 | return 0; | 1245 | return 0; |
1246 | } | ||
1145 | 1247 | ||
1146 | while (lidp != NULL) { | 1248 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1147 | /* | 1249 | /* |
1148 | * Skip items which aren't dirty in this transaction. | 1250 | * Skip items which aren't dirty in this transaction. |
1149 | */ | 1251 | */ |
1150 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1252 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) |
1151 | lidp = xfs_trans_next_item(tp, lidp); | ||
1152 | continue; | 1253 | continue; |
1153 | } | ||
1154 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | 1254 | lidp->lid_size = IOP_SIZE(lidp->lid_item); |
1155 | nvecs += lidp->lid_size; | 1255 | nvecs += lidp->lid_size; |
1156 | lidp = xfs_trans_next_item(tp, lidp); | ||
1157 | } | 1256 | } |
1158 | 1257 | ||
1159 | return nvecs; | 1258 | return nvecs; |
@@ -1173,7 +1272,7 @@ xfs_trans_fill_vecs( | |||
1173 | struct xfs_trans *tp, | 1272 | struct xfs_trans *tp, |
1174 | struct xfs_log_iovec *log_vector) | 1273 | struct xfs_log_iovec *log_vector) |
1175 | { | 1274 | { |
1176 | xfs_log_item_desc_t *lidp; | 1275 | struct xfs_log_item_desc *lidp; |
1177 | struct xfs_log_iovec *vecp; | 1276 | struct xfs_log_iovec *vecp; |
1178 | uint nitems; | 1277 | uint nitems; |
1179 | 1278 | ||
@@ -1184,14 +1283,11 @@ xfs_trans_fill_vecs( | |||
1184 | vecp = log_vector + 1; | 1283 | vecp = log_vector + 1; |
1185 | 1284 | ||
1186 | nitems = 0; | 1285 | nitems = 0; |
1187 | lidp = xfs_trans_first_item(tp); | 1286 | ASSERT(!list_empty(&tp->t_items)); |
1188 | ASSERT(lidp); | 1287 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1189 | while (lidp) { | ||
1190 | /* Skip items which aren't dirty in this transaction. */ | 1288 | /* Skip items which aren't dirty in this transaction. */ |
1191 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1289 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) |
1192 | lidp = xfs_trans_next_item(tp, lidp); | ||
1193 | continue; | 1290 | continue; |
1194 | } | ||
1195 | 1291 | ||
1196 | /* | 1292 | /* |
1197 | * The item may be marked dirty but not log anything. This can | 1293 | * The item may be marked dirty but not log anything. This can |
@@ -1202,7 +1298,6 @@ xfs_trans_fill_vecs( | |||
1202 | IOP_FORMAT(lidp->lid_item, vecp); | 1298 | IOP_FORMAT(lidp->lid_item, vecp); |
1203 | vecp += lidp->lid_size; | 1299 | vecp += lidp->lid_size; |
1204 | IOP_PIN(lidp->lid_item); | 1300 | IOP_PIN(lidp->lid_item); |
1205 | lidp = xfs_trans_next_item(tp, lidp); | ||
1206 | } | 1301 | } |
1207 | 1302 | ||
1208 | /* | 1303 | /* |
@@ -1297,24 +1392,15 @@ xfs_trans_committed( | |||
1297 | struct xfs_trans *tp, | 1392 | struct xfs_trans *tp, |
1298 | int abortflag) | 1393 | int abortflag) |
1299 | { | 1394 | { |
1300 | xfs_log_item_desc_t *lidp; | 1395 | struct xfs_log_item_desc *lidp, *next; |
1301 | xfs_log_item_chunk_t *licp; | ||
1302 | xfs_log_item_chunk_t *next_licp; | ||
1303 | 1396 | ||
1304 | /* Call the transaction's completion callback if there is one. */ | 1397 | /* Call the transaction's completion callback if there is one. */ |
1305 | if (tp->t_callback != NULL) | 1398 | if (tp->t_callback != NULL) |
1306 | tp->t_callback(tp, tp->t_callarg); | 1399 | tp->t_callback(tp, tp->t_callarg); |
1307 | 1400 | ||
1308 | for (lidp = xfs_trans_first_item(tp); | 1401 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { |
1309 | lidp != NULL; | ||
1310 | lidp = xfs_trans_next_item(tp, lidp)) { | ||
1311 | xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag); | 1402 | xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag); |
1312 | } | 1403 | xfs_trans_free_item_desc(lidp); |
1313 | |||
1314 | /* free the item chunks, ignoring the embedded chunk */ | ||
1315 | for (licp = tp->t_items.lic_next; licp != NULL; licp = next_licp) { | ||
1316 | next_licp = licp->lic_next; | ||
1317 | kmem_free(licp); | ||
1318 | } | 1404 | } |
1319 | 1405 | ||
1320 | xfs_trans_free(tp); | 1406 | xfs_trans_free(tp); |
@@ -1329,11 +1415,9 @@ xfs_trans_uncommit( | |||
1329 | struct xfs_trans *tp, | 1415 | struct xfs_trans *tp, |
1330 | uint flags) | 1416 | uint flags) |
1331 | { | 1417 | { |
1332 | xfs_log_item_desc_t *lidp; | 1418 | struct xfs_log_item_desc *lidp; |
1333 | 1419 | ||
1334 | for (lidp = xfs_trans_first_item(tp); | 1420 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1335 | lidp != NULL; | ||
1336 | lidp = xfs_trans_next_item(tp, lidp)) { | ||
1337 | /* | 1421 | /* |
1338 | * Unpin all but those that aren't dirty. | 1422 | * Unpin all but those that aren't dirty. |
1339 | */ | 1423 | */ |
@@ -1504,33 +1588,28 @@ STATIC struct xfs_log_vec * | |||
1504 | xfs_trans_alloc_log_vecs( | 1588 | xfs_trans_alloc_log_vecs( |
1505 | xfs_trans_t *tp) | 1589 | xfs_trans_t *tp) |
1506 | { | 1590 | { |
1507 | xfs_log_item_desc_t *lidp; | 1591 | struct xfs_log_item_desc *lidp; |
1508 | struct xfs_log_vec *lv = NULL; | 1592 | struct xfs_log_vec *lv = NULL; |
1509 | struct xfs_log_vec *ret_lv = NULL; | 1593 | struct xfs_log_vec *ret_lv = NULL; |
1510 | 1594 | ||
1511 | lidp = xfs_trans_first_item(tp); | ||
1512 | 1595 | ||
1513 | /* Bail out if we didn't find a log item. */ | 1596 | /* Bail out if we didn't find a log item. */ |
1514 | if (!lidp) { | 1597 | if (list_empty(&tp->t_items)) { |
1515 | ASSERT(0); | 1598 | ASSERT(0); |
1516 | return NULL; | 1599 | return NULL; |
1517 | } | 1600 | } |
1518 | 1601 | ||
1519 | while (lidp != NULL) { | 1602 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1520 | struct xfs_log_vec *new_lv; | 1603 | struct xfs_log_vec *new_lv; |
1521 | 1604 | ||
1522 | /* Skip items which aren't dirty in this transaction. */ | 1605 | /* Skip items which aren't dirty in this transaction. */ |
1523 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1606 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) |
1524 | lidp = xfs_trans_next_item(tp, lidp); | ||
1525 | continue; | 1607 | continue; |
1526 | } | ||
1527 | 1608 | ||
1528 | /* Skip items that do not have any vectors for writing */ | 1609 | /* Skip items that do not have any vectors for writing */ |
1529 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | 1610 | lidp->lid_size = IOP_SIZE(lidp->lid_item); |
1530 | if (!lidp->lid_size) { | 1611 | if (!lidp->lid_size) |
1531 | lidp = xfs_trans_next_item(tp, lidp); | ||
1532 | continue; | 1612 | continue; |
1533 | } | ||
1534 | 1613 | ||
1535 | new_lv = kmem_zalloc(sizeof(*new_lv) + | 1614 | new_lv = kmem_zalloc(sizeof(*new_lv) + |
1536 | lidp->lid_size * sizeof(struct xfs_log_iovec), | 1615 | lidp->lid_size * sizeof(struct xfs_log_iovec), |
@@ -1545,7 +1624,6 @@ xfs_trans_alloc_log_vecs( | |||
1545 | else | 1624 | else |
1546 | lv->lv_next = new_lv; | 1625 | lv->lv_next = new_lv; |
1547 | lv = new_lv; | 1626 | lv = new_lv; |
1548 | lidp = xfs_trans_next_item(tp, lidp); | ||
1549 | } | 1627 | } |
1550 | 1628 | ||
1551 | return ret_lv; | 1629 | return ret_lv; |
@@ -1704,12 +1782,6 @@ xfs_trans_cancel( | |||
1704 | int flags) | 1782 | int flags) |
1705 | { | 1783 | { |
1706 | int log_flags; | 1784 | int log_flags; |
1707 | #ifdef DEBUG | ||
1708 | xfs_log_item_chunk_t *licp; | ||
1709 | xfs_log_item_desc_t *lidp; | ||
1710 | xfs_log_item_t *lip; | ||
1711 | int i; | ||
1712 | #endif | ||
1713 | xfs_mount_t *mp = tp->t_mountp; | 1785 | xfs_mount_t *mp = tp->t_mountp; |
1714 | 1786 | ||
1715 | /* | 1787 | /* |
@@ -1728,21 +1800,11 @@ xfs_trans_cancel( | |||
1728 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 1800 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
1729 | } | 1801 | } |
1730 | #ifdef DEBUG | 1802 | #ifdef DEBUG |
1731 | if (!(flags & XFS_TRANS_ABORT)) { | 1803 | if (!(flags & XFS_TRANS_ABORT) && !XFS_FORCED_SHUTDOWN(mp)) { |
1732 | licp = &(tp->t_items); | 1804 | struct xfs_log_item_desc *lidp; |
1733 | while (licp != NULL) { | 1805 | |
1734 | lidp = licp->lic_descs; | 1806 | list_for_each_entry(lidp, &tp->t_items, lid_trans) |
1735 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | 1807 | ASSERT(!(lidp->lid_item->li_type == XFS_LI_EFD)); |
1736 | if (xfs_lic_isfree(licp, i)) { | ||
1737 | continue; | ||
1738 | } | ||
1739 | |||
1740 | lip = lidp->lid_item; | ||
1741 | if (!XFS_FORCED_SHUTDOWN(mp)) | ||
1742 | ASSERT(!(lip->li_type == XFS_LI_EFD)); | ||
1743 | } | ||
1744 | licp = licp->lic_next; | ||
1745 | } | ||
1746 | } | 1808 | } |
1747 | #endif | 1809 | #endif |
1748 | xfs_trans_unreserve_and_mod_sb(tp); | 1810 | xfs_trans_unreserve_and_mod_sb(tp); |
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index e639e8e9a2a..0c903eb8bbe 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -161,105 +161,14 @@ typedef struct xfs_trans_header { | |||
161 | * the amount of space needed to log the item it describes | 161 | * the amount of space needed to log the item it describes |
162 | * once we get to commit processing (see xfs_trans_commit()). | 162 | * once we get to commit processing (see xfs_trans_commit()). |
163 | */ | 163 | */ |
164 | typedef struct xfs_log_item_desc { | 164 | struct xfs_log_item_desc { |
165 | struct xfs_log_item *lid_item; | 165 | struct xfs_log_item *lid_item; |
166 | ushort lid_size; | 166 | ushort lid_size; |
167 | unsigned char lid_flags; | 167 | unsigned char lid_flags; |
168 | unsigned char lid_index; | 168 | struct list_head lid_trans; |
169 | } xfs_log_item_desc_t; | 169 | }; |
170 | 170 | ||
171 | #define XFS_LID_DIRTY 0x1 | 171 | #define XFS_LID_DIRTY 0x1 |
172 | #define XFS_LID_PINNED 0x2 | ||
173 | |||
174 | /* | ||
175 | * This structure is used to maintain a chunk list of log_item_desc | ||
176 | * structures. The free field is a bitmask indicating which descriptors | ||
177 | * in this chunk's array are free. The unused field is the first value | ||
178 | * not used since this chunk was allocated. | ||
179 | */ | ||
180 | #define XFS_LIC_NUM_SLOTS 15 | ||
181 | typedef struct xfs_log_item_chunk { | ||
182 | struct xfs_log_item_chunk *lic_next; | ||
183 | ushort lic_free; | ||
184 | ushort lic_unused; | ||
185 | xfs_log_item_desc_t lic_descs[XFS_LIC_NUM_SLOTS]; | ||
186 | } xfs_log_item_chunk_t; | ||
187 | |||
188 | #define XFS_LIC_MAX_SLOT (XFS_LIC_NUM_SLOTS - 1) | ||
189 | #define XFS_LIC_FREEMASK ((1 << XFS_LIC_NUM_SLOTS) - 1) | ||
190 | |||
191 | |||
192 | /* | ||
193 | * Initialize the given chunk. Set the chunk's free descriptor mask | ||
194 | * to indicate that all descriptors are free. The caller gets to set | ||
195 | * lic_unused to the right value (0 matches all free). The | ||
196 | * lic_descs.lid_index values are set up as each desc is allocated. | ||
197 | */ | ||
198 | static inline void xfs_lic_init(xfs_log_item_chunk_t *cp) | ||
199 | { | ||
200 | cp->lic_free = XFS_LIC_FREEMASK; | ||
201 | } | ||
202 | |||
203 | static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot) | ||
204 | { | ||
205 | cp->lic_descs[slot].lid_index = (unsigned char)(slot); | ||
206 | } | ||
207 | |||
208 | static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp) | ||
209 | { | ||
210 | return cp->lic_free & XFS_LIC_FREEMASK; | ||
211 | } | ||
212 | |||
213 | static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp) | ||
214 | { | ||
215 | cp->lic_free = XFS_LIC_FREEMASK; | ||
216 | } | ||
217 | |||
218 | static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp) | ||
219 | { | ||
220 | return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK); | ||
221 | } | ||
222 | |||
223 | static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot) | ||
224 | { | ||
225 | return (cp->lic_free & (1 << slot)); | ||
226 | } | ||
227 | |||
228 | static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot) | ||
229 | { | ||
230 | cp->lic_free &= ~(1 << slot); | ||
231 | } | ||
232 | |||
233 | static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot) | ||
234 | { | ||
235 | cp->lic_free |= 1 << slot; | ||
236 | } | ||
237 | |||
238 | static inline xfs_log_item_desc_t * | ||
239 | xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot) | ||
240 | { | ||
241 | return &(cp->lic_descs[slot]); | ||
242 | } | ||
243 | |||
244 | static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp) | ||
245 | { | ||
246 | return (uint)dp->lid_index; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Calculate the address of a chunk given a descriptor pointer: | ||
251 | * dp - dp->lid_index give the address of the start of the lic_descs array. | ||
252 | * From this we subtract the offset of the lic_descs field in a chunk. | ||
253 | * All of this yields the address of the chunk, which is | ||
254 | * cast to a chunk pointer. | ||
255 | */ | ||
256 | static inline xfs_log_item_chunk_t * | ||
257 | xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp) | ||
258 | { | ||
259 | return (xfs_log_item_chunk_t*) \ | ||
260 | (((xfs_caddr_t)((dp) - (dp)->lid_index)) - \ | ||
261 | (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs)); | ||
262 | } | ||
263 | 172 | ||
264 | #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ | 173 | #define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */ |
265 | /* | 174 | /* |
@@ -516,8 +425,7 @@ typedef struct xfs_trans { | |||
516 | int64_t t_rblocks_delta;/* superblock rblocks change */ | 425 | int64_t t_rblocks_delta;/* superblock rblocks change */ |
517 | int64_t t_rextents_delta;/* superblocks rextents chg */ | 426 | int64_t t_rextents_delta;/* superblocks rextents chg */ |
518 | int64_t t_rextslog_delta;/* superblocks rextslog chg */ | 427 | int64_t t_rextslog_delta;/* superblocks rextslog chg */ |
519 | unsigned int t_items_free; /* log item descs free */ | 428 | struct list_head t_items; /* log item descriptors */ |
520 | xfs_log_item_chunk_t t_items; /* first log item desc chunk */ | ||
521 | xfs_trans_header_t t_header; /* header for in-log trans */ | 429 | xfs_trans_header_t t_header; /* header for in-log trans */ |
522 | struct list_head t_busy; /* list of busy extents */ | 430 | struct list_head t_busy; /* list of busy extents */ |
523 | unsigned long t_pflags; /* saved process flags state */ | 431 | unsigned long t_pflags; /* saved process flags state */ |
@@ -595,6 +503,7 @@ int xfs_trans_ail_init(struct xfs_mount *); | |||
595 | void xfs_trans_ail_destroy(struct xfs_mount *); | 503 | void xfs_trans_ail_destroy(struct xfs_mount *); |
596 | 504 | ||
597 | extern kmem_zone_t *xfs_trans_zone; | 505 | extern kmem_zone_t *xfs_trans_zone; |
506 | extern kmem_zone_t *xfs_log_item_desc_zone; | ||
598 | 507 | ||
599 | #endif /* __KERNEL__ */ | 508 | #endif /* __KERNEL__ */ |
600 | 509 | ||
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c index d1d08aa404b..74a1c33e409 100644 --- a/fs/xfs/xfs_trans_buf.c +++ b/fs/xfs/xfs_trans_buf.c | |||
@@ -47,36 +47,17 @@ xfs_trans_buf_item_match( | |||
47 | xfs_daddr_t blkno, | 47 | xfs_daddr_t blkno, |
48 | int len) | 48 | int len) |
49 | { | 49 | { |
50 | xfs_log_item_chunk_t *licp; | 50 | struct xfs_log_item_desc *lidp; |
51 | xfs_log_item_desc_t *lidp; | 51 | struct xfs_buf_log_item *blip; |
52 | xfs_buf_log_item_t *blip; | ||
53 | int i; | ||
54 | 52 | ||
55 | len = BBTOB(len); | 53 | len = BBTOB(len); |
56 | for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) { | 54 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
57 | if (xfs_lic_are_all_free(licp)) { | 55 | blip = (struct xfs_buf_log_item *)lidp->lid_item; |
58 | ASSERT(licp == &tp->t_items); | 56 | if (blip->bli_item.li_type == XFS_LI_BUF && |
59 | ASSERT(licp->lic_next == NULL); | 57 | XFS_BUF_TARGET(blip->bli_buf) == target && |
60 | return NULL; | 58 | XFS_BUF_ADDR(blip->bli_buf) == blkno && |
61 | } | 59 | XFS_BUF_COUNT(blip->bli_buf) == len) |
62 | 60 | return blip->bli_buf; | |
63 | for (i = 0; i < licp->lic_unused; i++) { | ||
64 | /* | ||
65 | * Skip unoccupied slots. | ||
66 | */ | ||
67 | if (xfs_lic_isfree(licp, i)) | ||
68 | continue; | ||
69 | |||
70 | lidp = xfs_lic_slot(licp, i); | ||
71 | blip = (xfs_buf_log_item_t *)lidp->lid_item; | ||
72 | if (blip->bli_item.li_type != XFS_LI_BUF) | ||
73 | continue; | ||
74 | |||
75 | if (XFS_BUF_TARGET(blip->bli_buf) == target && | ||
76 | XFS_BUF_ADDR(blip->bli_buf) == blkno && | ||
77 | XFS_BUF_COUNT(blip->bli_buf) == len) | ||
78 | return blip->bli_buf; | ||
79 | } | ||
80 | } | 61 | } |
81 | 62 | ||
82 | return NULL; | 63 | return NULL; |
@@ -123,7 +104,7 @@ _xfs_trans_bjoin( | |||
123 | /* | 104 | /* |
124 | * Get a log_item_desc to point at the new item. | 105 | * Get a log_item_desc to point at the new item. |
125 | */ | 106 | */ |
126 | (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip); | 107 | xfs_trans_add_item(tp, &bip->bli_item); |
127 | 108 | ||
128 | /* | 109 | /* |
129 | * Initialize b_fsprivate2 so we can find it with incore_match() | 110 | * Initialize b_fsprivate2 so we can find it with incore_match() |
@@ -479,7 +460,6 @@ xfs_trans_brelse(xfs_trans_t *tp, | |||
479 | { | 460 | { |
480 | xfs_buf_log_item_t *bip; | 461 | xfs_buf_log_item_t *bip; |
481 | xfs_log_item_t *lip; | 462 | xfs_log_item_t *lip; |
482 | xfs_log_item_desc_t *lidp; | ||
483 | 463 | ||
484 | /* | 464 | /* |
485 | * Default to a normal brelse() call if the tp is NULL. | 465 | * Default to a normal brelse() call if the tp is NULL. |
@@ -510,13 +490,6 @@ xfs_trans_brelse(xfs_trans_t *tp, | |||
510 | ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); | 490 | ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); |
511 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 491 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
512 | 492 | ||
513 | /* | ||
514 | * Find the item descriptor pointing to this buffer's | ||
515 | * log item. It must be there. | ||
516 | */ | ||
517 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip); | ||
518 | ASSERT(lidp != NULL); | ||
519 | |||
520 | trace_xfs_trans_brelse(bip); | 493 | trace_xfs_trans_brelse(bip); |
521 | 494 | ||
522 | /* | 495 | /* |
@@ -532,7 +505,7 @@ xfs_trans_brelse(xfs_trans_t *tp, | |||
532 | * If the buffer is dirty within this transaction, we can't | 505 | * If the buffer is dirty within this transaction, we can't |
533 | * release it until we commit. | 506 | * release it until we commit. |
534 | */ | 507 | */ |
535 | if (lidp->lid_flags & XFS_LID_DIRTY) | 508 | if (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY) |
536 | return; | 509 | return; |
537 | 510 | ||
538 | /* | 511 | /* |
@@ -549,7 +522,7 @@ xfs_trans_brelse(xfs_trans_t *tp, | |||
549 | /* | 522 | /* |
550 | * Free up the log item descriptor tracking the released item. | 523 | * Free up the log item descriptor tracking the released item. |
551 | */ | 524 | */ |
552 | xfs_trans_free_item(tp, lidp); | 525 | xfs_trans_del_item(&bip->bli_item); |
553 | 526 | ||
554 | /* | 527 | /* |
555 | * Clear the hold flag in the buf log item if it is set. | 528 | * Clear the hold flag in the buf log item if it is set. |
@@ -661,7 +634,6 @@ xfs_trans_log_buf(xfs_trans_t *tp, | |||
661 | uint last) | 634 | uint last) |
662 | { | 635 | { |
663 | xfs_buf_log_item_t *bip; | 636 | xfs_buf_log_item_t *bip; |
664 | xfs_log_item_desc_t *lidp; | ||
665 | 637 | ||
666 | ASSERT(XFS_BUF_ISBUSY(bp)); | 638 | ASSERT(XFS_BUF_ISBUSY(bp)); |
667 | ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); | 639 | ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); |
@@ -703,11 +675,8 @@ xfs_trans_log_buf(xfs_trans_t *tp, | |||
703 | bip->bli_format.blf_flags &= ~XFS_BLF_CANCEL; | 675 | bip->bli_format.blf_flags &= ~XFS_BLF_CANCEL; |
704 | } | 676 | } |
705 | 677 | ||
706 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip); | ||
707 | ASSERT(lidp != NULL); | ||
708 | |||
709 | tp->t_flags |= XFS_TRANS_DIRTY; | 678 | tp->t_flags |= XFS_TRANS_DIRTY; |
710 | lidp->lid_flags |= XFS_LID_DIRTY; | 679 | bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
711 | bip->bli_flags |= XFS_BLI_LOGGED; | 680 | bip->bli_flags |= XFS_BLI_LOGGED; |
712 | xfs_buf_item_log(bip, first, last); | 681 | xfs_buf_item_log(bip, first, last); |
713 | } | 682 | } |
@@ -736,7 +705,6 @@ xfs_trans_binval( | |||
736 | xfs_trans_t *tp, | 705 | xfs_trans_t *tp, |
737 | xfs_buf_t *bp) | 706 | xfs_buf_t *bp) |
738 | { | 707 | { |
739 | xfs_log_item_desc_t *lidp; | ||
740 | xfs_buf_log_item_t *bip; | 708 | xfs_buf_log_item_t *bip; |
741 | 709 | ||
742 | ASSERT(XFS_BUF_ISBUSY(bp)); | 710 | ASSERT(XFS_BUF_ISBUSY(bp)); |
@@ -744,8 +712,6 @@ xfs_trans_binval( | |||
744 | ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); | 712 | ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); |
745 | 713 | ||
746 | bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); | 714 | bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *); |
747 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip); | ||
748 | ASSERT(lidp != NULL); | ||
749 | ASSERT(atomic_read(&bip->bli_refcount) > 0); | 715 | ASSERT(atomic_read(&bip->bli_refcount) > 0); |
750 | 716 | ||
751 | trace_xfs_trans_binval(bip); | 717 | trace_xfs_trans_binval(bip); |
@@ -760,7 +726,7 @@ xfs_trans_binval( | |||
760 | ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY))); | 726 | ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY))); |
761 | ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_INODE_BUF)); | 727 | ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_INODE_BUF)); |
762 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); | 728 | ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); |
763 | ASSERT(lidp->lid_flags & XFS_LID_DIRTY); | 729 | ASSERT(bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY); |
764 | ASSERT(tp->t_flags & XFS_TRANS_DIRTY); | 730 | ASSERT(tp->t_flags & XFS_TRANS_DIRTY); |
765 | return; | 731 | return; |
766 | } | 732 | } |
@@ -793,7 +759,7 @@ xfs_trans_binval( | |||
793 | bip->bli_format.blf_flags |= XFS_BLF_CANCEL; | 759 | bip->bli_format.blf_flags |= XFS_BLF_CANCEL; |
794 | memset((char *)(bip->bli_format.blf_data_map), 0, | 760 | memset((char *)(bip->bli_format.blf_data_map), 0, |
795 | (bip->bli_format.blf_map_size * sizeof(uint))); | 761 | (bip->bli_format.blf_map_size * sizeof(uint))); |
796 | lidp->lid_flags |= XFS_LID_DIRTY; | 762 | bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
797 | tp->t_flags |= XFS_TRANS_DIRTY; | 763 | tp->t_flags |= XFS_TRANS_DIRTY; |
798 | } | 764 | } |
799 | 765 | ||
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index dfb6a0fdcf9..f783d5e9fa7 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c | |||
@@ -48,9 +48,8 @@ xfs_trans_get_efi(xfs_trans_t *tp, | |||
48 | /* | 48 | /* |
49 | * Get a log_item_desc to point at the new item. | 49 | * Get a log_item_desc to point at the new item. |
50 | */ | 50 | */ |
51 | (void) xfs_trans_add_item(tp, (xfs_log_item_t*)efip); | 51 | xfs_trans_add_item(tp, &efip->efi_item); |
52 | 52 | return efip; | |
53 | return (efip); | ||
54 | } | 53 | } |
55 | 54 | ||
56 | /* | 55 | /* |
@@ -64,15 +63,11 @@ xfs_trans_log_efi_extent(xfs_trans_t *tp, | |||
64 | xfs_fsblock_t start_block, | 63 | xfs_fsblock_t start_block, |
65 | xfs_extlen_t ext_len) | 64 | xfs_extlen_t ext_len) |
66 | { | 65 | { |
67 | xfs_log_item_desc_t *lidp; | ||
68 | uint next_extent; | 66 | uint next_extent; |
69 | xfs_extent_t *extp; | 67 | xfs_extent_t *extp; |
70 | 68 | ||
71 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)efip); | ||
72 | ASSERT(lidp != NULL); | ||
73 | |||
74 | tp->t_flags |= XFS_TRANS_DIRTY; | 69 | tp->t_flags |= XFS_TRANS_DIRTY; |
75 | lidp->lid_flags |= XFS_LID_DIRTY; | 70 | efip->efi_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
76 | 71 | ||
77 | next_extent = efip->efi_next_extent; | 72 | next_extent = efip->efi_next_extent; |
78 | ASSERT(next_extent < efip->efi_format.efi_nextents); | 73 | ASSERT(next_extent < efip->efi_format.efi_nextents); |
@@ -105,9 +100,8 @@ xfs_trans_get_efd(xfs_trans_t *tp, | |||
105 | /* | 100 | /* |
106 | * Get a log_item_desc to point at the new item. | 101 | * Get a log_item_desc to point at the new item. |
107 | */ | 102 | */ |
108 | (void) xfs_trans_add_item(tp, (xfs_log_item_t*)efdp); | 103 | xfs_trans_add_item(tp, &efdp->efd_item); |
109 | 104 | return efdp; | |
110 | return (efdp); | ||
111 | } | 105 | } |
112 | 106 | ||
113 | /* | 107 | /* |
@@ -121,15 +115,11 @@ xfs_trans_log_efd_extent(xfs_trans_t *tp, | |||
121 | xfs_fsblock_t start_block, | 115 | xfs_fsblock_t start_block, |
122 | xfs_extlen_t ext_len) | 116 | xfs_extlen_t ext_len) |
123 | { | 117 | { |
124 | xfs_log_item_desc_t *lidp; | ||
125 | uint next_extent; | 118 | uint next_extent; |
126 | xfs_extent_t *extp; | 119 | xfs_extent_t *extp; |
127 | 120 | ||
128 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)efdp); | ||
129 | ASSERT(lidp != NULL); | ||
130 | |||
131 | tp->t_flags |= XFS_TRANS_DIRTY; | 121 | tp->t_flags |= XFS_TRANS_DIRTY; |
132 | lidp->lid_flags |= XFS_LID_DIRTY; | 122 | efdp->efd_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
133 | 123 | ||
134 | next_extent = efdp->efd_next_extent; | 124 | next_extent = efdp->efd_next_extent; |
135 | ASSERT(next_extent < efdp->efd_format.efd_nextents); | 125 | ASSERT(next_extent < efdp->efd_format.efd_nextents); |
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 04cc08a1b66..865eeb63ce1 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c | |||
@@ -88,7 +88,7 @@ xfs_trans_ijoin( | |||
88 | /* | 88 | /* |
89 | * Get a log_item_desc to point at the new item. | 89 | * Get a log_item_desc to point at the new item. |
90 | */ | 90 | */ |
91 | (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(iip)); | 91 | xfs_trans_add_item(tp, &iip->ili_item); |
92 | 92 | ||
93 | xfs_trans_inode_broot_debug(ip); | 93 | xfs_trans_inode_broot_debug(ip); |
94 | 94 | ||
@@ -144,17 +144,12 @@ xfs_trans_log_inode( | |||
144 | xfs_inode_t *ip, | 144 | xfs_inode_t *ip, |
145 | uint flags) | 145 | uint flags) |
146 | { | 146 | { |
147 | xfs_log_item_desc_t *lidp; | ||
148 | |||
149 | ASSERT(ip->i_transp == tp); | 147 | ASSERT(ip->i_transp == tp); |
150 | ASSERT(ip->i_itemp != NULL); | 148 | ASSERT(ip->i_itemp != NULL); |
151 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 149 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
152 | 150 | ||
153 | lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(ip->i_itemp)); | ||
154 | ASSERT(lidp != NULL); | ||
155 | |||
156 | tp->t_flags |= XFS_TRANS_DIRTY; | 151 | tp->t_flags |= XFS_TRANS_DIRTY; |
157 | lidp->lid_flags |= XFS_LID_DIRTY; | 152 | ip->i_itemp->ili_item.li_desc->lid_flags |= XFS_LID_DIRTY; |
158 | 153 | ||
159 | /* | 154 | /* |
160 | * Always OR in the bits from the ili_last_fields field. | 155 | * Always OR in the bits from the ili_last_fields field. |
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c deleted file mode 100644 index 55035a7401c..00000000000 --- a/fs/xfs/xfs_trans_item.c +++ /dev/null | |||
@@ -1,440 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_types.h" | ||
21 | #include "xfs_log.h" | ||
22 | #include "xfs_inum.h" | ||
23 | #include "xfs_trans.h" | ||
24 | #include "xfs_trans_priv.h" | ||
25 | /* XXX: from here down needed until struct xfs_trans has its own ailp */ | ||
26 | #include "xfs_bit.h" | ||
27 | #include "xfs_buf_item.h" | ||
28 | #include "xfs_sb.h" | ||
29 | #include "xfs_ag.h" | ||
30 | #include "xfs_dir2.h" | ||
31 | #include "xfs_mount.h" | ||
32 | |||
33 | STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *, | ||
34 | int, int, xfs_lsn_t); | ||
35 | |||
36 | /* | ||
37 | * This is called to add the given log item to the transaction's | ||
38 | * list of log items. It must find a free log item descriptor | ||
39 | * or allocate a new one and add the item to that descriptor. | ||
40 | * The function returns a pointer to item descriptor used to point | ||
41 | * to the new item. The log item will now point to its new descriptor | ||
42 | * with its li_desc field. | ||
43 | */ | ||
44 | xfs_log_item_desc_t * | ||
45 | xfs_trans_add_item(xfs_trans_t *tp, xfs_log_item_t *lip) | ||
46 | { | ||
47 | xfs_log_item_desc_t *lidp; | ||
48 | xfs_log_item_chunk_t *licp; | ||
49 | int i=0; | ||
50 | |||
51 | /* | ||
52 | * If there are no free descriptors, allocate a new chunk | ||
53 | * of them and put it at the front of the chunk list. | ||
54 | */ | ||
55 | if (tp->t_items_free == 0) { | ||
56 | licp = (xfs_log_item_chunk_t*) | ||
57 | kmem_alloc(sizeof(xfs_log_item_chunk_t), KM_SLEEP); | ||
58 | ASSERT(licp != NULL); | ||
59 | /* | ||
60 | * Initialize the chunk, and then | ||
61 | * claim the first slot in the newly allocated chunk. | ||
62 | */ | ||
63 | xfs_lic_init(licp); | ||
64 | xfs_lic_claim(licp, 0); | ||
65 | licp->lic_unused = 1; | ||
66 | xfs_lic_init_slot(licp, 0); | ||
67 | lidp = xfs_lic_slot(licp, 0); | ||
68 | |||
69 | /* | ||
70 | * Link in the new chunk and update the free count. | ||
71 | */ | ||
72 | licp->lic_next = tp->t_items.lic_next; | ||
73 | tp->t_items.lic_next = licp; | ||
74 | tp->t_items_free = XFS_LIC_NUM_SLOTS - 1; | ||
75 | |||
76 | /* | ||
77 | * Initialize the descriptor and the generic portion | ||
78 | * of the log item. | ||
79 | * | ||
80 | * Point the new slot at this item and return it. | ||
81 | * Also point the log item at its currently active | ||
82 | * descriptor and set the item's mount pointer. | ||
83 | */ | ||
84 | lidp->lid_item = lip; | ||
85 | lidp->lid_flags = 0; | ||
86 | lidp->lid_size = 0; | ||
87 | lip->li_desc = lidp; | ||
88 | lip->li_mountp = tp->t_mountp; | ||
89 | lip->li_ailp = tp->t_mountp->m_ail; | ||
90 | return lidp; | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Find the free descriptor. It is somewhere in the chunklist | ||
95 | * of descriptors. | ||
96 | */ | ||
97 | licp = &tp->t_items; | ||
98 | while (licp != NULL) { | ||
99 | if (xfs_lic_vacancy(licp)) { | ||
100 | if (licp->lic_unused <= XFS_LIC_MAX_SLOT) { | ||
101 | i = licp->lic_unused; | ||
102 | ASSERT(xfs_lic_isfree(licp, i)); | ||
103 | break; | ||
104 | } | ||
105 | for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) { | ||
106 | if (xfs_lic_isfree(licp, i)) | ||
107 | break; | ||
108 | } | ||
109 | ASSERT(i <= XFS_LIC_MAX_SLOT); | ||
110 | break; | ||
111 | } | ||
112 | licp = licp->lic_next; | ||
113 | } | ||
114 | ASSERT(licp != NULL); | ||
115 | /* | ||
116 | * If we find a free descriptor, claim it, | ||
117 | * initialize it, and return it. | ||
118 | */ | ||
119 | xfs_lic_claim(licp, i); | ||
120 | if (licp->lic_unused <= i) { | ||
121 | licp->lic_unused = i + 1; | ||
122 | xfs_lic_init_slot(licp, i); | ||
123 | } | ||
124 | lidp = xfs_lic_slot(licp, i); | ||
125 | tp->t_items_free--; | ||
126 | lidp->lid_item = lip; | ||
127 | lidp->lid_flags = 0; | ||
128 | lidp->lid_size = 0; | ||
129 | lip->li_desc = lidp; | ||
130 | lip->li_mountp = tp->t_mountp; | ||
131 | lip->li_ailp = tp->t_mountp->m_ail; | ||
132 | return lidp; | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * Free the given descriptor. | ||
137 | * | ||
138 | * This requires setting the bit in the chunk's free mask corresponding | ||
139 | * to the given slot. | ||
140 | */ | ||
141 | void | ||
142 | xfs_trans_free_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp) | ||
143 | { | ||
144 | uint slot; | ||
145 | xfs_log_item_chunk_t *licp; | ||
146 | xfs_log_item_chunk_t **licpp; | ||
147 | |||
148 | slot = xfs_lic_desc_to_slot(lidp); | ||
149 | licp = xfs_lic_desc_to_chunk(lidp); | ||
150 | xfs_lic_relse(licp, slot); | ||
151 | lidp->lid_item->li_desc = NULL; | ||
152 | tp->t_items_free++; | ||
153 | |||
154 | /* | ||
155 | * If there are no more used items in the chunk and this is not | ||
156 | * the chunk embedded in the transaction structure, then free | ||
157 | * the chunk. First pull it from the chunk list and then | ||
158 | * free it back to the heap. We didn't bother with a doubly | ||
159 | * linked list here because the lists should be very short | ||
160 | * and this is not a performance path. It's better to save | ||
161 | * the memory of the extra pointer. | ||
162 | * | ||
163 | * Also decrement the transaction structure's count of free items | ||
164 | * by the number in a chunk since we are freeing an empty chunk. | ||
165 | */ | ||
166 | if (xfs_lic_are_all_free(licp) && (licp != &(tp->t_items))) { | ||
167 | licpp = &(tp->t_items.lic_next); | ||
168 | while (*licpp != licp) { | ||
169 | ASSERT(*licpp != NULL); | ||
170 | licpp = &((*licpp)->lic_next); | ||
171 | } | ||
172 | *licpp = licp->lic_next; | ||
173 | kmem_free(licp); | ||
174 | tp->t_items_free -= XFS_LIC_NUM_SLOTS; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * This is called to find the descriptor corresponding to the given | ||
180 | * log item. It returns a pointer to the descriptor. | ||
181 | * The log item MUST have a corresponding descriptor in the given | ||
182 | * transaction. This routine does not return NULL, it panics. | ||
183 | * | ||
184 | * The descriptor pointer is kept in the log item's li_desc field. | ||
185 | * Just return it. | ||
186 | */ | ||
187 | /*ARGSUSED*/ | ||
188 | xfs_log_item_desc_t * | ||
189 | xfs_trans_find_item(xfs_trans_t *tp, xfs_log_item_t *lip) | ||
190 | { | ||
191 | ASSERT(lip->li_desc != NULL); | ||
192 | |||
193 | return lip->li_desc; | ||
194 | } | ||
195 | |||
196 | |||
197 | /* | ||
198 | * Return a pointer to the first descriptor in the chunk list. | ||
199 | * This does not return NULL if there are none, it panics. | ||
200 | * | ||
201 | * The first descriptor must be in either the first or second chunk. | ||
202 | * This is because the only chunk allowed to be empty is the first. | ||
203 | * All others are freed when they become empty. | ||
204 | * | ||
205 | * At some point this and xfs_trans_next_item() should be optimized | ||
206 | * to quickly look at the mask to determine if there is anything to | ||
207 | * look at. | ||
208 | */ | ||
209 | xfs_log_item_desc_t * | ||
210 | xfs_trans_first_item(xfs_trans_t *tp) | ||
211 | { | ||
212 | xfs_log_item_chunk_t *licp; | ||
213 | int i; | ||
214 | |||
215 | licp = &tp->t_items; | ||
216 | /* | ||
217 | * If it's not in the first chunk, skip to the second. | ||
218 | */ | ||
219 | if (xfs_lic_are_all_free(licp)) { | ||
220 | licp = licp->lic_next; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * Return the first non-free descriptor in the chunk. | ||
225 | */ | ||
226 | ASSERT(!xfs_lic_are_all_free(licp)); | ||
227 | for (i = 0; i < licp->lic_unused; i++) { | ||
228 | if (xfs_lic_isfree(licp, i)) { | ||
229 | continue; | ||
230 | } | ||
231 | |||
232 | return xfs_lic_slot(licp, i); | ||
233 | } | ||
234 | cmn_err(CE_WARN, "xfs_trans_first_item() -- no first item"); | ||
235 | return NULL; | ||
236 | } | ||
237 | |||
238 | |||
239 | /* | ||
240 | * Given a descriptor, return the next descriptor in the chunk list. | ||
241 | * This returns NULL if there are no more used descriptors in the list. | ||
242 | * | ||
243 | * We do this by first locating the chunk in which the descriptor resides, | ||
244 | * and then scanning forward in the chunk and the list for the next | ||
245 | * used descriptor. | ||
246 | */ | ||
247 | /*ARGSUSED*/ | ||
248 | xfs_log_item_desc_t * | ||
249 | xfs_trans_next_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp) | ||
250 | { | ||
251 | xfs_log_item_chunk_t *licp; | ||
252 | int i; | ||
253 | |||
254 | licp = xfs_lic_desc_to_chunk(lidp); | ||
255 | |||
256 | /* | ||
257 | * First search the rest of the chunk. The for loop keeps us | ||
258 | * from referencing things beyond the end of the chunk. | ||
259 | */ | ||
260 | for (i = (int)xfs_lic_desc_to_slot(lidp) + 1; i < licp->lic_unused; i++) { | ||
261 | if (xfs_lic_isfree(licp, i)) { | ||
262 | continue; | ||
263 | } | ||
264 | |||
265 | return xfs_lic_slot(licp, i); | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * Now search the next chunk. It must be there, because the | ||
270 | * next chunk would have been freed if it were empty. | ||
271 | * If there is no next chunk, return NULL. | ||
272 | */ | ||
273 | if (licp->lic_next == NULL) { | ||
274 | return NULL; | ||
275 | } | ||
276 | |||
277 | licp = licp->lic_next; | ||
278 | ASSERT(!xfs_lic_are_all_free(licp)); | ||
279 | for (i = 0; i < licp->lic_unused; i++) { | ||
280 | if (xfs_lic_isfree(licp, i)) { | ||
281 | continue; | ||
282 | } | ||
283 | |||
284 | return xfs_lic_slot(licp, i); | ||
285 | } | ||
286 | ASSERT(0); | ||
287 | /* NOTREACHED */ | ||
288 | return NULL; /* keep gcc quite */ | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * This is called to unlock all of the items of a transaction and to free | ||
293 | * all the descriptors of that transaction. | ||
294 | * | ||
295 | * It walks the list of descriptors and unlocks each item. It frees | ||
296 | * each chunk except that embedded in the transaction as it goes along. | ||
297 | */ | ||
298 | void | ||
299 | xfs_trans_free_items( | ||
300 | xfs_trans_t *tp, | ||
301 | xfs_lsn_t commit_lsn, | ||
302 | int flags) | ||
303 | { | ||
304 | xfs_log_item_chunk_t *licp; | ||
305 | xfs_log_item_chunk_t *next_licp; | ||
306 | int abort; | ||
307 | |||
308 | abort = flags & XFS_TRANS_ABORT; | ||
309 | licp = &tp->t_items; | ||
310 | /* | ||
311 | * Special case the embedded chunk so we don't free it below. | ||
312 | */ | ||
313 | if (!xfs_lic_are_all_free(licp)) { | ||
314 | (void) xfs_trans_unlock_chunk(licp, 1, abort, commit_lsn); | ||
315 | xfs_lic_all_free(licp); | ||
316 | licp->lic_unused = 0; | ||
317 | } | ||
318 | licp = licp->lic_next; | ||
319 | |||
320 | /* | ||
321 | * Unlock each item in each chunk and free the chunks. | ||
322 | */ | ||
323 | while (licp != NULL) { | ||
324 | ASSERT(!xfs_lic_are_all_free(licp)); | ||
325 | (void) xfs_trans_unlock_chunk(licp, 1, abort, commit_lsn); | ||
326 | next_licp = licp->lic_next; | ||
327 | kmem_free(licp); | ||
328 | licp = next_licp; | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Reset the transaction structure's free item count. | ||
333 | */ | ||
334 | tp->t_items_free = XFS_LIC_NUM_SLOTS; | ||
335 | tp->t_items.lic_next = NULL; | ||
336 | } | ||
337 | |||
338 | |||
339 | |||
340 | /* | ||
341 | * This is called to unlock the items associated with a transaction. | ||
342 | * Items which were not logged should be freed. | ||
343 | * Those which were logged must still be tracked so they can be unpinned | ||
344 | * when the transaction commits. | ||
345 | */ | ||
346 | void | ||
347 | xfs_trans_unlock_items(xfs_trans_t *tp, xfs_lsn_t commit_lsn) | ||
348 | { | ||
349 | xfs_log_item_chunk_t *licp; | ||
350 | xfs_log_item_chunk_t *next_licp; | ||
351 | xfs_log_item_chunk_t **licpp; | ||
352 | int freed; | ||
353 | |||
354 | freed = 0; | ||
355 | licp = &tp->t_items; | ||
356 | |||
357 | /* | ||
358 | * Special case the embedded chunk so we don't free. | ||
359 | */ | ||
360 | if (!xfs_lic_are_all_free(licp)) { | ||
361 | freed = xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn); | ||
362 | } | ||
363 | licpp = &(tp->t_items.lic_next); | ||
364 | licp = licp->lic_next; | ||
365 | |||
366 | /* | ||
367 | * Unlock each item in each chunk, free non-dirty descriptors, | ||
368 | * and free empty chunks. | ||
369 | */ | ||
370 | while (licp != NULL) { | ||
371 | ASSERT(!xfs_lic_are_all_free(licp)); | ||
372 | freed += xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn); | ||
373 | next_licp = licp->lic_next; | ||
374 | if (xfs_lic_are_all_free(licp)) { | ||
375 | *licpp = next_licp; | ||
376 | kmem_free(licp); | ||
377 | freed -= XFS_LIC_NUM_SLOTS; | ||
378 | } else { | ||
379 | licpp = &(licp->lic_next); | ||
380 | } | ||
381 | ASSERT(*licpp == next_licp); | ||
382 | licp = next_licp; | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * Fix the free descriptor count in the transaction. | ||
387 | */ | ||
388 | tp->t_items_free += freed; | ||
389 | } | ||
390 | |||
391 | /* | ||
392 | * Unlock each item pointed to by a descriptor in the given chunk. | ||
393 | * Stamp the commit lsn into each item if necessary. | ||
394 | * Free descriptors pointing to items which are not dirty if freeing_chunk | ||
395 | * is zero. If freeing_chunk is non-zero, then we need to unlock all | ||
396 | * items in the chunk. | ||
397 | * | ||
398 | * Return the number of descriptors freed. | ||
399 | */ | ||
400 | STATIC int | ||
401 | xfs_trans_unlock_chunk( | ||
402 | xfs_log_item_chunk_t *licp, | ||
403 | int freeing_chunk, | ||
404 | int abort, | ||
405 | xfs_lsn_t commit_lsn) | ||
406 | { | ||
407 | xfs_log_item_desc_t *lidp; | ||
408 | xfs_log_item_t *lip; | ||
409 | int i; | ||
410 | int freed; | ||
411 | |||
412 | freed = 0; | ||
413 | lidp = licp->lic_descs; | ||
414 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | ||
415 | if (xfs_lic_isfree(licp, i)) { | ||
416 | continue; | ||
417 | } | ||
418 | lip = lidp->lid_item; | ||
419 | lip->li_desc = NULL; | ||
420 | |||
421 | if (commit_lsn != NULLCOMMITLSN) | ||
422 | IOP_COMMITTING(lip, commit_lsn); | ||
423 | if (abort) | ||
424 | lip->li_flags |= XFS_LI_ABORTED; | ||
425 | IOP_UNLOCK(lip); | ||
426 | |||
427 | /* | ||
428 | * Free the descriptor if the item is not dirty | ||
429 | * within this transaction and the caller is not | ||
430 | * going to just free the entire thing regardless. | ||
431 | */ | ||
432 | if (!(freeing_chunk) && | ||
433 | (!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) { | ||
434 | xfs_lic_relse(licp, i); | ||
435 | freed++; | ||
436 | } | ||
437 | } | ||
438 | |||
439 | return freed; | ||
440 | } | ||
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index c6e4f2c8de6..e2d93d8ead7 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h | |||
@@ -23,22 +23,8 @@ struct xfs_log_item_desc; | |||
23 | struct xfs_mount; | 23 | struct xfs_mount; |
24 | struct xfs_trans; | 24 | struct xfs_trans; |
25 | 25 | ||
26 | /* | 26 | void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); |
27 | * From xfs_trans_item.c | 27 | void xfs_trans_del_item(struct xfs_log_item *); |
28 | */ | ||
29 | struct xfs_log_item_desc *xfs_trans_add_item(struct xfs_trans *, | ||
30 | struct xfs_log_item *); | ||
31 | void xfs_trans_free_item(struct xfs_trans *, | ||
32 | struct xfs_log_item_desc *); | ||
33 | struct xfs_log_item_desc *xfs_trans_find_item(struct xfs_trans *, | ||
34 | struct xfs_log_item *); | ||
35 | struct xfs_log_item_desc *xfs_trans_first_item(struct xfs_trans *); | ||
36 | struct xfs_log_item_desc *xfs_trans_next_item(struct xfs_trans *, | ||
37 | struct xfs_log_item_desc *); | ||
38 | |||
39 | void xfs_trans_unlock_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn); | ||
40 | void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn, | ||
41 | int flags); | ||
42 | 28 | ||
43 | void xfs_trans_item_committed(struct xfs_log_item *lip, | 29 | void xfs_trans_item_committed(struct xfs_log_item *lip, |
44 | xfs_lsn_t commit_lsn, int aborted); | 30 | xfs_lsn_t commit_lsn, int aborted); |