diff options
author | David Chinner <dgc@sgi.com> | 2008-04-09 22:21:18 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-17 21:58:17 -0400 |
commit | e5720eec0548c08943d759e39db0388d8fe59287 (patch) | |
tree | e38b474f0dbac30aee7141878953223a2a588c69 /fs/xfs/xfs_inode.c | |
parent | 3c1e2bbe5bcdcd435510a05eb121fa74b848e24f (diff) |
[XFS] Propagate errors from xfs_trans_commit().
xfs_trans_commit() can return errors when there are problems in the
transaction subsystem. They are indicative that the entire transaction may
be incomplete, and hence the error should be propagated as there is a good
possibility that there is something fatally wrong in the filesystem. Catch
and propagate or warn about commit errors in the places where they are
currently ignored.
SGI-PV: 980084
SGI-Modid: xfs-linux-melb:xfs-kern:30795a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index d7514f8317df..63e66890f063 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1699,33 +1699,16 @@ xfs_itruncate_finish( | |||
1699 | * blocks in the file system, but oh well. | 1699 | * blocks in the file system, but oh well. |
1700 | */ | 1700 | */ |
1701 | xfs_bmap_cancel(&free_list); | 1701 | xfs_bmap_cancel(&free_list); |
1702 | if (committed) { | 1702 | if (committed) |
1703 | /* | 1703 | goto error_join; |
1704 | * If the passed in transaction committed | ||
1705 | * in xfs_bmap_finish(), then we want to | ||
1706 | * add the inode to this one before returning. | ||
1707 | * This keeps things simple for the higher | ||
1708 | * level code, because it always knows that | ||
1709 | * the inode is locked and held in the | ||
1710 | * transaction that returns to it whether | ||
1711 | * errors occur or not. We don't mark the | ||
1712 | * inode dirty so that this transaction can | ||
1713 | * be easily aborted if possible. | ||
1714 | */ | ||
1715 | xfs_trans_ijoin(ntp, ip, | ||
1716 | XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
1717 | xfs_trans_ihold(ntp, ip); | ||
1718 | } | ||
1719 | return error; | 1704 | return error; |
1720 | } | 1705 | } |
1721 | 1706 | ||
1722 | if (committed) { | 1707 | if (committed) { |
1723 | /* | 1708 | /* |
1724 | * The first xact was committed, | 1709 | * The first xact was committed, so add the inode to |
1725 | * so add the inode to the new one. | 1710 | * the new one. Mark it dirty so it will be logged and |
1726 | * Mark it dirty so it will be logged | 1711 | * moved forward in the log as part of every commit. |
1727 | * and moved forward in the log as | ||
1728 | * part of every commit. | ||
1729 | */ | 1712 | */ |
1730 | xfs_trans_ijoin(ntp, ip, | 1713 | xfs_trans_ijoin(ntp, ip, |
1731 | XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1714 | XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
@@ -1733,19 +1716,16 @@ xfs_itruncate_finish( | |||
1733 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); | 1716 | xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); |
1734 | } | 1717 | } |
1735 | ntp = xfs_trans_dup(ntp); | 1718 | ntp = xfs_trans_dup(ntp); |
1736 | (void) xfs_trans_commit(*tp, 0); | 1719 | error = xfs_trans_commit(*tp, 0); |
1737 | *tp = ntp; | 1720 | *tp = ntp; |
1721 | if (error) | ||
1722 | goto error_join; | ||
1738 | error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, | 1723 | error = xfs_trans_reserve(ntp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, |
1739 | XFS_TRANS_PERM_LOG_RES, | 1724 | XFS_TRANS_PERM_LOG_RES, |
1740 | XFS_ITRUNCATE_LOG_COUNT); | 1725 | XFS_ITRUNCATE_LOG_COUNT); |
1741 | /* | ||
1742 | * Add the inode being truncated to the next chained | ||
1743 | * transaction. | ||
1744 | */ | ||
1745 | xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
1746 | xfs_trans_ihold(ntp, ip); | ||
1747 | if (error) | 1726 | if (error) |
1748 | return (error); | 1727 | goto error_join; |
1728 | |||
1749 | } | 1729 | } |
1750 | /* | 1730 | /* |
1751 | * Only update the size in the case of the data fork, but | 1731 | * Only update the size in the case of the data fork, but |
@@ -1777,6 +1757,18 @@ xfs_itruncate_finish( | |||
1777 | (ip->i_d.di_nextents == 0)); | 1757 | (ip->i_d.di_nextents == 0)); |
1778 | xfs_itrunc_trace(XFS_ITRUNC_FINISH2, ip, 0, new_size, 0, 0); | 1758 | xfs_itrunc_trace(XFS_ITRUNC_FINISH2, ip, 0, new_size, 0, 0); |
1779 | return 0; | 1759 | return 0; |
1760 | |||
1761 | error_join: | ||
1762 | /* | ||
1763 | * Add the inode being truncated to the next chained transaction. This | ||
1764 | * keeps things simple for the higher level code, because it always | ||
1765 | * knows that the inode is locked and held in the transaction that | ||
1766 | * returns to it whether errors occur or not. We don't mark the inode | ||
1767 | * dirty so that this transaction can be easily aborted if possible. | ||
1768 | */ | ||
1769 | xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
1770 | xfs_trans_ihold(ntp, ip); | ||
1771 | return error; | ||
1780 | } | 1772 | } |
1781 | 1773 | ||
1782 | 1774 | ||