diff options
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r-- | fs/xfs/xfs_trans.c | 305 |
1 files changed, 189 insertions, 116 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 28547dfce037..f6d956b7711e 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 |
@@ -24,16 +25,12 @@ | |||
24 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
25 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
26 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
27 | #include "xfs_dir2.h" | ||
28 | #include "xfs_dmapi.h" | ||
29 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
30 | #include "xfs_error.h" | 29 | #include "xfs_error.h" |
31 | #include "xfs_da_btree.h" | 30 | #include "xfs_da_btree.h" |
32 | #include "xfs_bmap_btree.h" | 31 | #include "xfs_bmap_btree.h" |
33 | #include "xfs_alloc_btree.h" | 32 | #include "xfs_alloc_btree.h" |
34 | #include "xfs_ialloc_btree.h" | 33 | #include "xfs_ialloc_btree.h" |
35 | #include "xfs_dir2_sf.h" | ||
36 | #include "xfs_attr_sf.h" | ||
37 | #include "xfs_dinode.h" | 34 | #include "xfs_dinode.h" |
38 | #include "xfs_inode.h" | 35 | #include "xfs_inode.h" |
39 | #include "xfs_btree.h" | 36 | #include "xfs_btree.h" |
@@ -47,6 +44,7 @@ | |||
47 | #include "xfs_trace.h" | 44 | #include "xfs_trace.h" |
48 | 45 | ||
49 | kmem_zone_t *xfs_trans_zone; | 46 | kmem_zone_t *xfs_trans_zone; |
47 | kmem_zone_t *xfs_log_item_desc_zone; | ||
50 | 48 | ||
51 | 49 | ||
52 | /* | 50 | /* |
@@ -597,8 +595,7 @@ _xfs_trans_alloc( | |||
597 | tp->t_magic = XFS_TRANS_MAGIC; | 595 | tp->t_magic = XFS_TRANS_MAGIC; |
598 | tp->t_type = type; | 596 | tp->t_type = type; |
599 | tp->t_mountp = mp; | 597 | tp->t_mountp = mp; |
600 | tp->t_items_free = XFS_LIC_NUM_SLOTS; | 598 | INIT_LIST_HEAD(&tp->t_items); |
601 | xfs_lic_init(&(tp->t_items)); | ||
602 | INIT_LIST_HEAD(&tp->t_busy); | 599 | INIT_LIST_HEAD(&tp->t_busy); |
603 | return tp; | 600 | return tp; |
604 | } | 601 | } |
@@ -643,8 +640,7 @@ xfs_trans_dup( | |||
643 | ntp->t_magic = XFS_TRANS_MAGIC; | 640 | ntp->t_magic = XFS_TRANS_MAGIC; |
644 | ntp->t_type = tp->t_type; | 641 | ntp->t_type = tp->t_type; |
645 | ntp->t_mountp = tp->t_mountp; | 642 | ntp->t_mountp = tp->t_mountp; |
646 | ntp->t_items_free = XFS_LIC_NUM_SLOTS; | 643 | INIT_LIST_HEAD(&ntp->t_items); |
647 | xfs_lic_init(&(ntp->t_items)); | ||
648 | INIT_LIST_HEAD(&ntp->t_busy); | 644 | INIT_LIST_HEAD(&ntp->t_busy); |
649 | 645 | ||
650 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); | 646 | ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); |
@@ -700,7 +696,7 @@ xfs_trans_reserve( | |||
700 | * fail if the count would go below zero. | 696 | * fail if the count would go below zero. |
701 | */ | 697 | */ |
702 | if (blocks > 0) { | 698 | if (blocks > 0) { |
703 | error = xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, | 699 | error = xfs_icsb_modify_counters(tp->t_mountp, XFS_SBS_FDBLOCKS, |
704 | -((int64_t)blocks), rsvd); | 700 | -((int64_t)blocks), rsvd); |
705 | if (error != 0) { | 701 | if (error != 0) { |
706 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 702 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
@@ -771,7 +767,7 @@ undo_log: | |||
771 | 767 | ||
772 | undo_blocks: | 768 | undo_blocks: |
773 | if (blocks > 0) { | 769 | if (blocks > 0) { |
774 | (void) xfs_mod_incore_sb(tp->t_mountp, XFS_SBS_FDBLOCKS, | 770 | xfs_icsb_modify_counters(tp->t_mountp, XFS_SBS_FDBLOCKS, |
775 | (int64_t)blocks, rsvd); | 771 | (int64_t)blocks, rsvd); |
776 | tp->t_blk_res = 0; | 772 | tp->t_blk_res = 0; |
777 | } | 773 | } |
@@ -1013,7 +1009,7 @@ void | |||
1013 | xfs_trans_unreserve_and_mod_sb( | 1009 | xfs_trans_unreserve_and_mod_sb( |
1014 | xfs_trans_t *tp) | 1010 | xfs_trans_t *tp) |
1015 | { | 1011 | { |
1016 | xfs_mod_sb_t msb[14]; /* If you add cases, add entries */ | 1012 | xfs_mod_sb_t msb[9]; /* If you add cases, add entries */ |
1017 | xfs_mod_sb_t *msbp; | 1013 | xfs_mod_sb_t *msbp; |
1018 | xfs_mount_t *mp = tp->t_mountp; | 1014 | xfs_mount_t *mp = tp->t_mountp; |
1019 | /* REFERENCED */ | 1015 | /* REFERENCED */ |
@@ -1021,55 +1017,61 @@ xfs_trans_unreserve_and_mod_sb( | |||
1021 | int rsvd; | 1017 | int rsvd; |
1022 | int64_t blkdelta = 0; | 1018 | int64_t blkdelta = 0; |
1023 | int64_t rtxdelta = 0; | 1019 | int64_t rtxdelta = 0; |
1020 | int64_t idelta = 0; | ||
1021 | int64_t ifreedelta = 0; | ||
1024 | 1022 | ||
1025 | msbp = msb; | 1023 | msbp = msb; |
1026 | rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; | 1024 | rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0; |
1027 | 1025 | ||
1028 | /* calculate free blocks delta */ | 1026 | /* calculate deltas */ |
1029 | if (tp->t_blk_res > 0) | 1027 | if (tp->t_blk_res > 0) |
1030 | blkdelta = tp->t_blk_res; | 1028 | blkdelta = tp->t_blk_res; |
1031 | |||
1032 | if ((tp->t_fdblocks_delta != 0) && | 1029 | if ((tp->t_fdblocks_delta != 0) && |
1033 | (xfs_sb_version_haslazysbcount(&mp->m_sb) || | 1030 | (xfs_sb_version_haslazysbcount(&mp->m_sb) || |
1034 | (tp->t_flags & XFS_TRANS_SB_DIRTY))) | 1031 | (tp->t_flags & XFS_TRANS_SB_DIRTY))) |
1035 | blkdelta += tp->t_fdblocks_delta; | 1032 | blkdelta += tp->t_fdblocks_delta; |
1036 | 1033 | ||
1037 | if (blkdelta != 0) { | ||
1038 | msbp->msb_field = XFS_SBS_FDBLOCKS; | ||
1039 | msbp->msb_delta = blkdelta; | ||
1040 | msbp++; | ||
1041 | } | ||
1042 | |||
1043 | /* calculate free realtime extents delta */ | ||
1044 | if (tp->t_rtx_res > 0) | 1034 | if (tp->t_rtx_res > 0) |
1045 | rtxdelta = tp->t_rtx_res; | 1035 | rtxdelta = tp->t_rtx_res; |
1046 | |||
1047 | if ((tp->t_frextents_delta != 0) && | 1036 | if ((tp->t_frextents_delta != 0) && |
1048 | (tp->t_flags & XFS_TRANS_SB_DIRTY)) | 1037 | (tp->t_flags & XFS_TRANS_SB_DIRTY)) |
1049 | rtxdelta += tp->t_frextents_delta; | 1038 | rtxdelta += tp->t_frextents_delta; |
1050 | 1039 | ||
1040 | if (xfs_sb_version_haslazysbcount(&mp->m_sb) || | ||
1041 | (tp->t_flags & XFS_TRANS_SB_DIRTY)) { | ||
1042 | idelta = tp->t_icount_delta; | ||
1043 | ifreedelta = tp->t_ifree_delta; | ||
1044 | } | ||
1045 | |||
1046 | /* apply the per-cpu counters */ | ||
1047 | if (blkdelta) { | ||
1048 | error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | ||
1049 | blkdelta, rsvd); | ||
1050 | if (error) | ||
1051 | goto out; | ||
1052 | } | ||
1053 | |||
1054 | if (idelta) { | ||
1055 | error = xfs_icsb_modify_counters(mp, XFS_SBS_ICOUNT, | ||
1056 | idelta, rsvd); | ||
1057 | if (error) | ||
1058 | goto out_undo_fdblocks; | ||
1059 | } | ||
1060 | |||
1061 | if (ifreedelta) { | ||
1062 | error = xfs_icsb_modify_counters(mp, XFS_SBS_IFREE, | ||
1063 | ifreedelta, rsvd); | ||
1064 | if (error) | ||
1065 | goto out_undo_icount; | ||
1066 | } | ||
1067 | |||
1068 | /* apply remaining deltas */ | ||
1051 | if (rtxdelta != 0) { | 1069 | if (rtxdelta != 0) { |
1052 | msbp->msb_field = XFS_SBS_FREXTENTS; | 1070 | msbp->msb_field = XFS_SBS_FREXTENTS; |
1053 | msbp->msb_delta = rtxdelta; | 1071 | msbp->msb_delta = rtxdelta; |
1054 | msbp++; | 1072 | msbp++; |
1055 | } | 1073 | } |
1056 | 1074 | ||
1057 | /* apply remaining deltas */ | ||
1058 | |||
1059 | if (xfs_sb_version_haslazysbcount(&mp->m_sb) || | ||
1060 | (tp->t_flags & XFS_TRANS_SB_DIRTY)) { | ||
1061 | if (tp->t_icount_delta != 0) { | ||
1062 | msbp->msb_field = XFS_SBS_ICOUNT; | ||
1063 | msbp->msb_delta = tp->t_icount_delta; | ||
1064 | msbp++; | ||
1065 | } | ||
1066 | if (tp->t_ifree_delta != 0) { | ||
1067 | msbp->msb_field = XFS_SBS_IFREE; | ||
1068 | msbp->msb_delta = tp->t_ifree_delta; | ||
1069 | msbp++; | ||
1070 | } | ||
1071 | } | ||
1072 | |||
1073 | if (tp->t_flags & XFS_TRANS_SB_DIRTY) { | 1075 | if (tp->t_flags & XFS_TRANS_SB_DIRTY) { |
1074 | if (tp->t_dblocks_delta != 0) { | 1076 | if (tp->t_dblocks_delta != 0) { |
1075 | msbp->msb_field = XFS_SBS_DBLOCKS; | 1077 | msbp->msb_field = XFS_SBS_DBLOCKS; |
@@ -1119,7 +1121,125 @@ xfs_trans_unreserve_and_mod_sb( | |||
1119 | if (msbp > msb) { | 1121 | if (msbp > msb) { |
1120 | error = xfs_mod_incore_sb_batch(tp->t_mountp, msb, | 1122 | error = xfs_mod_incore_sb_batch(tp->t_mountp, msb, |
1121 | (uint)(msbp - msb), rsvd); | 1123 | (uint)(msbp - msb), rsvd); |
1122 | ASSERT(error == 0); | 1124 | if (error) |
1125 | goto out_undo_ifreecount; | ||
1126 | } | ||
1127 | |||
1128 | return; | ||
1129 | |||
1130 | out_undo_ifreecount: | ||
1131 | if (ifreedelta) | ||
1132 | xfs_icsb_modify_counters(mp, XFS_SBS_IFREE, -ifreedelta, rsvd); | ||
1133 | out_undo_icount: | ||
1134 | if (idelta) | ||
1135 | xfs_icsb_modify_counters(mp, XFS_SBS_ICOUNT, -idelta, rsvd); | ||
1136 | out_undo_fdblocks: | ||
1137 | if (blkdelta) | ||
1138 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, -blkdelta, rsvd); | ||
1139 | out: | ||
1140 | ASSERT(error = 0); | ||
1141 | return; | ||
1142 | } | ||
1143 | |||
1144 | /* | ||
1145 | * Add the given log item to the transaction's list of log items. | ||
1146 | * | ||
1147 | * The log item will now point to its new descriptor with its li_desc field. | ||
1148 | */ | ||
1149 | void | ||
1150 | xfs_trans_add_item( | ||
1151 | struct xfs_trans *tp, | ||
1152 | struct xfs_log_item *lip) | ||
1153 | { | ||
1154 | struct xfs_log_item_desc *lidp; | ||
1155 | |||
1156 | ASSERT(lip->li_mountp = tp->t_mountp); | ||
1157 | ASSERT(lip->li_ailp = tp->t_mountp->m_ail); | ||
1158 | |||
1159 | lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS); | ||
1160 | |||
1161 | lidp->lid_item = lip; | ||
1162 | lidp->lid_flags = 0; | ||
1163 | lidp->lid_size = 0; | ||
1164 | list_add_tail(&lidp->lid_trans, &tp->t_items); | ||
1165 | |||
1166 | lip->li_desc = lidp; | ||
1167 | } | ||
1168 | |||
1169 | STATIC void | ||
1170 | xfs_trans_free_item_desc( | ||
1171 | struct xfs_log_item_desc *lidp) | ||
1172 | { | ||
1173 | list_del_init(&lidp->lid_trans); | ||
1174 | kmem_zone_free(xfs_log_item_desc_zone, lidp); | ||
1175 | } | ||
1176 | |||
1177 | /* | ||
1178 | * Unlink and free the given descriptor. | ||
1179 | */ | ||
1180 | void | ||
1181 | xfs_trans_del_item( | ||
1182 | struct xfs_log_item *lip) | ||
1183 | { | ||
1184 | xfs_trans_free_item_desc(lip->li_desc); | ||
1185 | lip->li_desc = NULL; | ||
1186 | } | ||
1187 | |||
1188 | /* | ||
1189 | * Unlock all of the items of a transaction and free all the descriptors | ||
1190 | * of that transaction. | ||
1191 | */ | ||
1192 | void | ||
1193 | xfs_trans_free_items( | ||
1194 | struct xfs_trans *tp, | ||
1195 | xfs_lsn_t commit_lsn, | ||
1196 | int flags) | ||
1197 | { | ||
1198 | struct xfs_log_item_desc *lidp, *next; | ||
1199 | |||
1200 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { | ||
1201 | struct xfs_log_item *lip = lidp->lid_item; | ||
1202 | |||
1203 | lip->li_desc = NULL; | ||
1204 | |||
1205 | if (commit_lsn != NULLCOMMITLSN) | ||
1206 | IOP_COMMITTING(lip, commit_lsn); | ||
1207 | if (flags & XFS_TRANS_ABORT) | ||
1208 | lip->li_flags |= XFS_LI_ABORTED; | ||
1209 | IOP_UNLOCK(lip); | ||
1210 | |||
1211 | xfs_trans_free_item_desc(lidp); | ||
1212 | } | ||
1213 | } | ||
1214 | |||
1215 | /* | ||
1216 | * Unlock the items associated with a transaction. | ||
1217 | * | ||
1218 | * Items which were not logged should be freed. Those which were logged must | ||
1219 | * still be tracked so they can be unpinned when the transaction commits. | ||
1220 | */ | ||
1221 | STATIC void | ||
1222 | xfs_trans_unlock_items( | ||
1223 | struct xfs_trans *tp, | ||
1224 | xfs_lsn_t commit_lsn) | ||
1225 | { | ||
1226 | struct xfs_log_item_desc *lidp, *next; | ||
1227 | |||
1228 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { | ||
1229 | struct xfs_log_item *lip = lidp->lid_item; | ||
1230 | |||
1231 | lip->li_desc = NULL; | ||
1232 | |||
1233 | if (commit_lsn != NULLCOMMITLSN) | ||
1234 | IOP_COMMITTING(lip, commit_lsn); | ||
1235 | IOP_UNLOCK(lip); | ||
1236 | |||
1237 | /* | ||
1238 | * Free the descriptor if the item is not dirty | ||
1239 | * within this transaction. | ||
1240 | */ | ||
1241 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) | ||
1242 | xfs_trans_free_item_desc(lidp); | ||
1123 | } | 1243 | } |
1124 | } | 1244 | } |
1125 | 1245 | ||
@@ -1134,30 +1254,27 @@ xfs_trans_count_vecs( | |||
1134 | struct xfs_trans *tp) | 1254 | struct xfs_trans *tp) |
1135 | { | 1255 | { |
1136 | int nvecs; | 1256 | int nvecs; |
1137 | xfs_log_item_desc_t *lidp; | 1257 | struct xfs_log_item_desc *lidp; |
1138 | 1258 | ||
1139 | nvecs = 1; | 1259 | nvecs = 1; |
1140 | lidp = xfs_trans_first_item(tp); | ||
1141 | ASSERT(lidp != NULL); | ||
1142 | 1260 | ||
1143 | /* In the non-debug case we need to start bailing out if we | 1261 | /* In the non-debug case we need to start bailing out if we |
1144 | * didn't find a log_item here, return zero and let trans_commit | 1262 | * didn't find a log_item here, return zero and let trans_commit |
1145 | * deal with it. | 1263 | * deal with it. |
1146 | */ | 1264 | */ |
1147 | if (lidp == NULL) | 1265 | if (list_empty(&tp->t_items)) { |
1266 | ASSERT(0); | ||
1148 | return 0; | 1267 | return 0; |
1268 | } | ||
1149 | 1269 | ||
1150 | while (lidp != NULL) { | 1270 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1151 | /* | 1271 | /* |
1152 | * Skip items which aren't dirty in this transaction. | 1272 | * Skip items which aren't dirty in this transaction. |
1153 | */ | 1273 | */ |
1154 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1274 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) |
1155 | lidp = xfs_trans_next_item(tp, lidp); | ||
1156 | continue; | 1275 | continue; |
1157 | } | ||
1158 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | 1276 | lidp->lid_size = IOP_SIZE(lidp->lid_item); |
1159 | nvecs += lidp->lid_size; | 1277 | nvecs += lidp->lid_size; |
1160 | lidp = xfs_trans_next_item(tp, lidp); | ||
1161 | } | 1278 | } |
1162 | 1279 | ||
1163 | return nvecs; | 1280 | return nvecs; |
@@ -1177,7 +1294,7 @@ xfs_trans_fill_vecs( | |||
1177 | struct xfs_trans *tp, | 1294 | struct xfs_trans *tp, |
1178 | struct xfs_log_iovec *log_vector) | 1295 | struct xfs_log_iovec *log_vector) |
1179 | { | 1296 | { |
1180 | xfs_log_item_desc_t *lidp; | 1297 | struct xfs_log_item_desc *lidp; |
1181 | struct xfs_log_iovec *vecp; | 1298 | struct xfs_log_iovec *vecp; |
1182 | uint nitems; | 1299 | uint nitems; |
1183 | 1300 | ||
@@ -1188,14 +1305,11 @@ xfs_trans_fill_vecs( | |||
1188 | vecp = log_vector + 1; | 1305 | vecp = log_vector + 1; |
1189 | 1306 | ||
1190 | nitems = 0; | 1307 | nitems = 0; |
1191 | lidp = xfs_trans_first_item(tp); | 1308 | ASSERT(!list_empty(&tp->t_items)); |
1192 | ASSERT(lidp); | 1309 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1193 | while (lidp) { | ||
1194 | /* Skip items which aren't dirty in this transaction. */ | 1310 | /* Skip items which aren't dirty in this transaction. */ |
1195 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1311 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) |
1196 | lidp = xfs_trans_next_item(tp, lidp); | ||
1197 | continue; | 1312 | continue; |
1198 | } | ||
1199 | 1313 | ||
1200 | /* | 1314 | /* |
1201 | * The item may be marked dirty but not log anything. This can | 1315 | * The item may be marked dirty but not log anything. This can |
@@ -1206,7 +1320,6 @@ xfs_trans_fill_vecs( | |||
1206 | IOP_FORMAT(lidp->lid_item, vecp); | 1320 | IOP_FORMAT(lidp->lid_item, vecp); |
1207 | vecp += lidp->lid_size; | 1321 | vecp += lidp->lid_size; |
1208 | IOP_PIN(lidp->lid_item); | 1322 | IOP_PIN(lidp->lid_item); |
1209 | lidp = xfs_trans_next_item(tp, lidp); | ||
1210 | } | 1323 | } |
1211 | 1324 | ||
1212 | /* | 1325 | /* |
@@ -1284,7 +1397,7 @@ xfs_trans_item_committed( | |||
1284 | * log item flags, if anyone else stales the buffer we do not want to | 1397 | * log item flags, if anyone else stales the buffer we do not want to |
1285 | * pay any attention to it. | 1398 | * pay any attention to it. |
1286 | */ | 1399 | */ |
1287 | IOP_UNPIN(lip); | 1400 | IOP_UNPIN(lip, 0); |
1288 | } | 1401 | } |
1289 | 1402 | ||
1290 | /* | 1403 | /* |
@@ -1298,27 +1411,15 @@ xfs_trans_item_committed( | |||
1298 | */ | 1411 | */ |
1299 | STATIC void | 1412 | STATIC void |
1300 | xfs_trans_committed( | 1413 | xfs_trans_committed( |
1301 | struct xfs_trans *tp, | 1414 | void *arg, |
1302 | int abortflag) | 1415 | int abortflag) |
1303 | { | 1416 | { |
1304 | xfs_log_item_desc_t *lidp; | 1417 | struct xfs_trans *tp = arg; |
1305 | xfs_log_item_chunk_t *licp; | 1418 | struct xfs_log_item_desc *lidp, *next; |
1306 | xfs_log_item_chunk_t *next_licp; | ||
1307 | |||
1308 | /* Call the transaction's completion callback if there is one. */ | ||
1309 | if (tp->t_callback != NULL) | ||
1310 | tp->t_callback(tp, tp->t_callarg); | ||
1311 | 1419 | ||
1312 | for (lidp = xfs_trans_first_item(tp); | 1420 | list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) { |
1313 | lidp != NULL; | ||
1314 | lidp = xfs_trans_next_item(tp, lidp)) { | ||
1315 | xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag); | 1421 | xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag); |
1316 | } | 1422 | xfs_trans_free_item_desc(lidp); |
1317 | |||
1318 | /* free the item chunks, ignoring the embedded chunk */ | ||
1319 | for (licp = tp->t_items.lic_next; licp != NULL; licp = next_licp) { | ||
1320 | next_licp = licp->lic_next; | ||
1321 | kmem_free(licp); | ||
1322 | } | 1423 | } |
1323 | 1424 | ||
1324 | xfs_trans_free(tp); | 1425 | xfs_trans_free(tp); |
@@ -1333,16 +1434,14 @@ xfs_trans_uncommit( | |||
1333 | struct xfs_trans *tp, | 1434 | struct xfs_trans *tp, |
1334 | uint flags) | 1435 | uint flags) |
1335 | { | 1436 | { |
1336 | xfs_log_item_desc_t *lidp; | 1437 | struct xfs_log_item_desc *lidp; |
1337 | 1438 | ||
1338 | for (lidp = xfs_trans_first_item(tp); | 1439 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1339 | lidp != NULL; | ||
1340 | lidp = xfs_trans_next_item(tp, lidp)) { | ||
1341 | /* | 1440 | /* |
1342 | * Unpin all but those that aren't dirty. | 1441 | * Unpin all but those that aren't dirty. |
1343 | */ | 1442 | */ |
1344 | if (lidp->lid_flags & XFS_LID_DIRTY) | 1443 | if (lidp->lid_flags & XFS_LID_DIRTY) |
1345 | IOP_UNPIN_REMOVE(lidp->lid_item, tp); | 1444 | IOP_UNPIN(lidp->lid_item, 1); |
1346 | } | 1445 | } |
1347 | 1446 | ||
1348 | xfs_trans_unreserve_and_mod_sb(tp); | 1447 | xfs_trans_unreserve_and_mod_sb(tp); |
@@ -1445,7 +1544,7 @@ xfs_trans_commit_iclog( | |||
1445 | * running in simulation mode (the log is explicitly turned | 1544 | * running in simulation mode (the log is explicitly turned |
1446 | * off). | 1545 | * off). |
1447 | */ | 1546 | */ |
1448 | tp->t_logcb.cb_func = (void(*)(void*, int))xfs_trans_committed; | 1547 | tp->t_logcb.cb_func = xfs_trans_committed; |
1449 | tp->t_logcb.cb_arg = tp; | 1548 | tp->t_logcb.cb_arg = tp; |
1450 | 1549 | ||
1451 | /* | 1550 | /* |
@@ -1508,33 +1607,28 @@ STATIC struct xfs_log_vec * | |||
1508 | xfs_trans_alloc_log_vecs( | 1607 | xfs_trans_alloc_log_vecs( |
1509 | xfs_trans_t *tp) | 1608 | xfs_trans_t *tp) |
1510 | { | 1609 | { |
1511 | xfs_log_item_desc_t *lidp; | 1610 | struct xfs_log_item_desc *lidp; |
1512 | struct xfs_log_vec *lv = NULL; | 1611 | struct xfs_log_vec *lv = NULL; |
1513 | struct xfs_log_vec *ret_lv = NULL; | 1612 | struct xfs_log_vec *ret_lv = NULL; |
1514 | 1613 | ||
1515 | lidp = xfs_trans_first_item(tp); | ||
1516 | 1614 | ||
1517 | /* Bail out if we didn't find a log item. */ | 1615 | /* Bail out if we didn't find a log item. */ |
1518 | if (!lidp) { | 1616 | if (list_empty(&tp->t_items)) { |
1519 | ASSERT(0); | 1617 | ASSERT(0); |
1520 | return NULL; | 1618 | return NULL; |
1521 | } | 1619 | } |
1522 | 1620 | ||
1523 | while (lidp != NULL) { | 1621 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { |
1524 | struct xfs_log_vec *new_lv; | 1622 | struct xfs_log_vec *new_lv; |
1525 | 1623 | ||
1526 | /* Skip items which aren't dirty in this transaction. */ | 1624 | /* Skip items which aren't dirty in this transaction. */ |
1527 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) { | 1625 | if (!(lidp->lid_flags & XFS_LID_DIRTY)) |
1528 | lidp = xfs_trans_next_item(tp, lidp); | ||
1529 | continue; | 1626 | continue; |
1530 | } | ||
1531 | 1627 | ||
1532 | /* Skip items that do not have any vectors for writing */ | 1628 | /* Skip items that do not have any vectors for writing */ |
1533 | lidp->lid_size = IOP_SIZE(lidp->lid_item); | 1629 | lidp->lid_size = IOP_SIZE(lidp->lid_item); |
1534 | if (!lidp->lid_size) { | 1630 | if (!lidp->lid_size) |
1535 | lidp = xfs_trans_next_item(tp, lidp); | ||
1536 | continue; | 1631 | continue; |
1537 | } | ||
1538 | 1632 | ||
1539 | new_lv = kmem_zalloc(sizeof(*new_lv) + | 1633 | new_lv = kmem_zalloc(sizeof(*new_lv) + |
1540 | lidp->lid_size * sizeof(struct xfs_log_iovec), | 1634 | lidp->lid_size * sizeof(struct xfs_log_iovec), |
@@ -1549,7 +1643,6 @@ xfs_trans_alloc_log_vecs( | |||
1549 | else | 1643 | else |
1550 | lv->lv_next = new_lv; | 1644 | lv->lv_next = new_lv; |
1551 | lv = new_lv; | 1645 | lv = new_lv; |
1552 | lidp = xfs_trans_next_item(tp, lidp); | ||
1553 | } | 1646 | } |
1554 | 1647 | ||
1555 | return ret_lv; | 1648 | return ret_lv; |
@@ -1579,9 +1672,6 @@ xfs_trans_commit_cil( | |||
1579 | return error; | 1672 | return error; |
1580 | 1673 | ||
1581 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1674 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1582 | |||
1583 | /* xfs_trans_free_items() unlocks them first */ | ||
1584 | xfs_trans_free_items(tp, *commit_lsn, 0); | ||
1585 | xfs_trans_free(tp); | 1675 | xfs_trans_free(tp); |
1586 | return 0; | 1676 | return 0; |
1587 | } | 1677 | } |
@@ -1708,12 +1798,6 @@ xfs_trans_cancel( | |||
1708 | int flags) | 1798 | int flags) |
1709 | { | 1799 | { |
1710 | int log_flags; | 1800 | int log_flags; |
1711 | #ifdef DEBUG | ||
1712 | xfs_log_item_chunk_t *licp; | ||
1713 | xfs_log_item_desc_t *lidp; | ||
1714 | xfs_log_item_t *lip; | ||
1715 | int i; | ||
1716 | #endif | ||
1717 | xfs_mount_t *mp = tp->t_mountp; | 1801 | xfs_mount_t *mp = tp->t_mountp; |
1718 | 1802 | ||
1719 | /* | 1803 | /* |
@@ -1732,21 +1816,11 @@ xfs_trans_cancel( | |||
1732 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); | 1816 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
1733 | } | 1817 | } |
1734 | #ifdef DEBUG | 1818 | #ifdef DEBUG |
1735 | if (!(flags & XFS_TRANS_ABORT)) { | 1819 | if (!(flags & XFS_TRANS_ABORT) && !XFS_FORCED_SHUTDOWN(mp)) { |
1736 | licp = &(tp->t_items); | 1820 | struct xfs_log_item_desc *lidp; |
1737 | while (licp != NULL) { | 1821 | |
1738 | lidp = licp->lic_descs; | 1822 | list_for_each_entry(lidp, &tp->t_items, lid_trans) |
1739 | for (i = 0; i < licp->lic_unused; i++, lidp++) { | 1823 | ASSERT(!(lidp->lid_item->li_type == XFS_LI_EFD)); |
1740 | if (xfs_lic_isfree(licp, i)) { | ||
1741 | continue; | ||
1742 | } | ||
1743 | |||
1744 | lip = lidp->lid_item; | ||
1745 | if (!XFS_FORCED_SHUTDOWN(mp)) | ||
1746 | ASSERT(!(lip->li_type == XFS_LI_EFD)); | ||
1747 | } | ||
1748 | licp = licp->lic_next; | ||
1749 | } | ||
1750 | } | 1824 | } |
1751 | #endif | 1825 | #endif |
1752 | xfs_trans_unreserve_and_mod_sb(tp); | 1826 | xfs_trans_unreserve_and_mod_sb(tp); |
@@ -1834,7 +1908,6 @@ xfs_trans_roll( | |||
1834 | if (error) | 1908 | if (error) |
1835 | return error; | 1909 | return error; |
1836 | 1910 | ||
1837 | xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL); | 1911 | xfs_trans_ijoin(trans, dp); |
1838 | xfs_trans_ihold(trans, dp); | ||
1839 | return 0; | 1912 | return 0; |
1840 | } | 1913 | } |