diff options
Diffstat (limited to 'fs/xfs/xfs_trans.c')
-rw-r--r-- | fs/xfs/xfs_trans.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 33dbc4e0ad62..76922793f64f 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1446,6 +1446,14 @@ xfs_log_item_batch_insert( | |||
1446 | * Bulk operation version of xfs_trans_committed that takes a log vector of | 1446 | * Bulk operation version of xfs_trans_committed that takes a log vector of |
1447 | * items to insert into the AIL. This uses bulk AIL insertion techniques to | 1447 | * items to insert into the AIL. This uses bulk AIL insertion techniques to |
1448 | * minimise lock traffic. | 1448 | * minimise lock traffic. |
1449 | * | ||
1450 | * If we are called with the aborted flag set, it is because a log write during | ||
1451 | * a CIL checkpoint commit has failed. In this case, all the items in the | ||
1452 | * checkpoint have already gone through IOP_COMMITED and IOP_UNLOCK, which | ||
1453 | * means that checkpoint commit abort handling is treated exactly the same | ||
1454 | * as an iclog write error even though we haven't started any IO yet. Hence in | ||
1455 | * this case all we need to do is IOP_COMMITTED processing, followed by an | ||
1456 | * IOP_UNPIN(aborted) call. | ||
1449 | */ | 1457 | */ |
1450 | void | 1458 | void |
1451 | xfs_trans_committed_bulk( | 1459 | xfs_trans_committed_bulk( |
@@ -1472,6 +1480,16 @@ xfs_trans_committed_bulk( | |||
1472 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1480 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1473 | continue; | 1481 | continue; |
1474 | 1482 | ||
1483 | /* | ||
1484 | * if we are aborting the operation, no point in inserting the | ||
1485 | * object into the AIL as we are in a shutdown situation. | ||
1486 | */ | ||
1487 | if (aborted) { | ||
1488 | ASSERT(XFS_FORCED_SHUTDOWN(ailp->xa_mount)); | ||
1489 | IOP_UNPIN(lip, 1); | ||
1490 | continue; | ||
1491 | } | ||
1492 | |||
1475 | if (item_lsn != commit_lsn) { | 1493 | if (item_lsn != commit_lsn) { |
1476 | 1494 | ||
1477 | /* | 1495 | /* |
@@ -1503,20 +1521,24 @@ xfs_trans_committed_bulk( | |||
1503 | } | 1521 | } |
1504 | 1522 | ||
1505 | /* | 1523 | /* |
1506 | * Called from the trans_commit code when we notice that | 1524 | * Called from the trans_commit code when we notice that the filesystem is in |
1507 | * the filesystem is in the middle of a forced shutdown. | 1525 | * the middle of a forced shutdown. |
1526 | * | ||
1527 | * When we are called here, we have already pinned all the items in the | ||
1528 | * transaction. However, neither IOP_COMMITTING or IOP_UNLOCK has been called | ||
1529 | * so we can simply walk the items in the transaction, unpin them with an abort | ||
1530 | * flag and then free the items. Note that unpinning the items can result in | ||
1531 | * them being freed immediately, so we need to use a safe list traversal method | ||
1532 | * here. | ||
1508 | */ | 1533 | */ |
1509 | STATIC void | 1534 | STATIC void |
1510 | xfs_trans_uncommit( | 1535 | xfs_trans_uncommit( |
1511 | struct xfs_trans *tp, | 1536 | struct xfs_trans *tp, |
1512 | uint flags) | 1537 | uint flags) |
1513 | { | 1538 | { |
1514 | struct xfs_log_item_desc *lidp; | 1539 | struct xfs_log_item_desc *lidp, *n; |
1515 | 1540 | ||
1516 | list_for_each_entry(lidp, &tp->t_items, lid_trans) { | 1541 | list_for_each_entry_safe(lidp, n, &tp->t_items, lid_trans) { |
1517 | /* | ||
1518 | * Unpin all but those that aren't dirty. | ||
1519 | */ | ||
1520 | if (lidp->lid_flags & XFS_LID_DIRTY) | 1542 | if (lidp->lid_flags & XFS_LID_DIRTY) |
1521 | IOP_UNPIN(lidp->lid_item, 1); | 1543 | IOP_UNPIN(lidp->lid_item, 1); |
1522 | } | 1544 | } |
@@ -1733,7 +1755,6 @@ xfs_trans_commit_cil( | |||
1733 | int flags) | 1755 | int flags) |
1734 | { | 1756 | { |
1735 | struct xfs_log_vec *log_vector; | 1757 | struct xfs_log_vec *log_vector; |
1736 | int error; | ||
1737 | 1758 | ||
1738 | /* | 1759 | /* |
1739 | * Get each log item to allocate a vector structure for | 1760 | * Get each log item to allocate a vector structure for |
@@ -1744,9 +1765,7 @@ xfs_trans_commit_cil( | |||
1744 | if (!log_vector) | 1765 | if (!log_vector) |
1745 | return ENOMEM; | 1766 | return ENOMEM; |
1746 | 1767 | ||
1747 | error = xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags); | 1768 | xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags); |
1748 | if (error) | ||
1749 | return error; | ||
1750 | 1769 | ||
1751 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); | 1770 | current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); |
1752 | xfs_trans_free(tp); | 1771 | xfs_trans_free(tp); |