aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2013-09-20 11:06:10 -0400
committerBen Myers <bpm@sgi.com>2013-10-08 16:32:11 -0400
commitf7be2d7f594cbc7a00902b5427332a1ad519a528 (patch)
tree564355cd78bbe0a967437698b733c6f8fc868c31 /fs/xfs
parent36b21dde6e899d2f25077b7c239d2d6bcff17d73 (diff)
xfs: push down inactive transaction mgmt for truncate
Create the new xfs_inactive_truncate() function to handle the truncate portion of xfs_inactive(). Push the locking and transaction management into the new function. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_inode.c117
1 files changed, 68 insertions, 49 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c26990b50941..7b86f643046b 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1663,6 +1663,58 @@ xfs_release(
1663} 1663}
1664 1664
1665/* 1665/*
1666 * xfs_inactive_truncate
1667 *
1668 * Called to perform a truncate when an inode becomes unlinked.
1669 */
1670STATIC int
1671xfs_inactive_truncate(
1672 struct xfs_inode *ip)
1673{
1674 struct xfs_mount *mp = ip->i_mount;
1675 struct xfs_trans *tp;
1676 int error;
1677
1678 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1679 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
1680 if (error) {
1681 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1682 xfs_trans_cancel(tp, 0);
1683 return error;
1684 }
1685
1686 xfs_ilock(ip, XFS_ILOCK_EXCL);
1687 xfs_trans_ijoin(tp, ip, 0);
1688
1689 /*
1690 * Log the inode size first to prevent stale data exposure in the event
1691 * of a system crash before the truncate completes. See the related
1692 * comment in xfs_setattr_size() for details.
1693 */
1694 ip->i_d.di_size = 0;
1695 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1696
1697 error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
1698 if (error)
1699 goto error_trans_cancel;
1700
1701 ASSERT(ip->i_d.di_nextents == 0);
1702
1703 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1704 if (error)
1705 goto error_unlock;
1706
1707 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1708 return 0;
1709
1710error_trans_cancel:
1711 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
1712error_unlock:
1713 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1714 return error;
1715}
1716
1717/*
1666 * xfs_inactive 1718 * xfs_inactive
1667 * 1719 *
1668 * This is called when the vnode reference count for the vnode 1720 * This is called when the vnode reference count for the vnode
@@ -1679,7 +1731,6 @@ xfs_inactive(
1679 int committed; 1731 int committed;
1680 struct xfs_trans *tp; 1732 struct xfs_trans *tp;
1681 struct xfs_mount *mp; 1733 struct xfs_mount *mp;
1682 struct xfs_trans_res *resp;
1683 int error; 1734 int error;
1684 int truncate = 0; 1735 int truncate = 0;
1685 1736
@@ -1724,35 +1775,12 @@ xfs_inactive(
1724 if (error) 1775 if (error)
1725 return VN_INACTIVE_CACHE; 1776 return VN_INACTIVE_CACHE;
1726 1777
1727 if (S_ISLNK(ip->i_d.di_mode)) { 1778 if (S_ISLNK(ip->i_d.di_mode))
1728 error = xfs_inactive_symlink(ip); 1779 error = xfs_inactive_symlink(ip);
1729 if (error) 1780 else if (truncate)
1730 goto out; 1781 error = xfs_inactive_truncate(ip);
1731 } 1782 if (error)
1732 1783 goto out;
1733 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1734 resp = truncate ? &M_RES(mp)->tr_itruncate : &M_RES(mp)->tr_ifree;
1735
1736 error = xfs_trans_reserve(tp, resp, 0, 0);
1737 if (error) {
1738 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1739 xfs_trans_cancel(tp, 0);
1740 return VN_INACTIVE_CACHE;
1741 }
1742
1743 xfs_ilock(ip, XFS_ILOCK_EXCL);
1744 xfs_trans_ijoin(tp, ip, 0);
1745
1746 if (truncate) {
1747 ip->i_d.di_size = 0;
1748 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1749
1750 error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
1751 if (error)
1752 goto out_cancel;
1753
1754 ASSERT(ip->i_d.di_nextents == 0);
1755 }
1756 1784
1757 /* 1785 /*
1758 * If there are attributes associated with the file then blow them away 1786 * If there are attributes associated with the file then blow them away
@@ -1763,25 +1791,9 @@ xfs_inactive(
1763 if (ip->i_d.di_anextents > 0) { 1791 if (ip->i_d.di_anextents > 0) {
1764 ASSERT(ip->i_d.di_forkoff != 0); 1792 ASSERT(ip->i_d.di_forkoff != 0);
1765 1793
1766 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1767 if (error)
1768 goto out_unlock;
1769
1770 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1771
1772 error = xfs_attr_inactive(ip); 1794 error = xfs_attr_inactive(ip);
1773 if (error) 1795 if (error)
1774 goto out; 1796 goto out;
1775
1776 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1777 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree, 0, 0);
1778 if (error) {
1779 xfs_trans_cancel(tp, 0);
1780 goto out;
1781 }
1782
1783 xfs_ilock(ip, XFS_ILOCK_EXCL);
1784 xfs_trans_ijoin(tp, ip, 0);
1785 } 1797 }
1786 1798
1787 if (ip->i_afp) 1799 if (ip->i_afp)
@@ -1789,6 +1801,17 @@ xfs_inactive(
1789 1801
1790 ASSERT(ip->i_d.di_anextents == 0); 1802 ASSERT(ip->i_d.di_anextents == 0);
1791 1803
1804 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1805 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree, 0, 0);
1806 if (error) {
1807 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1808 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
1809 goto out;
1810 }
1811
1812 xfs_ilock(ip, XFS_ILOCK_EXCL);
1813 xfs_trans_ijoin(tp, ip, 0);
1814
1792 /* 1815 /*
1793 * Free the inode. 1816 * Free the inode.
1794 */ 1817 */
@@ -1831,13 +1854,9 @@ xfs_inactive(
1831 * Release the dquots held by inode, if any. 1854 * Release the dquots held by inode, if any.
1832 */ 1855 */
1833 xfs_qm_dqdetach(ip); 1856 xfs_qm_dqdetach(ip);
1834out_unlock:
1835 xfs_iunlock(ip, XFS_ILOCK_EXCL); 1857 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1836out: 1858out:
1837 return VN_INACTIVE_CACHE; 1859 return VN_INACTIVE_CACHE;
1838out_cancel:
1839 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
1840 goto out_unlock;
1841} 1860}
1842 1861
1843/* 1862/*