aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2013-09-20 11:06:11 -0400
committerBen Myers <bpm@sgi.com>2013-10-08 18:15:01 -0400
commit88877d2b9727a14431bfe48216ff86331ab47ea5 (patch)
treee09e7520d93a55e26f2d56ad7f6a94950ee6e1e5 /fs/xfs
parentf7be2d7f594cbc7a00902b5427332a1ad519a528 (diff)
xfs: push down inactive transaction mgmt for ifree
Push the inode free work performed during xfs_inactive() down into a new xfs_inactive_ifree() helper. This clears xfs_inactive() from all inode locking and transaction management more directly associated with freeing the inode xattrs, extents and the inode itself. 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.c121
1 files changed, 71 insertions, 50 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 7b86f643046b..223d1a163b2d 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1715,6 +1715,74 @@ error_unlock:
1715} 1715}
1716 1716
1717/* 1717/*
1718 * xfs_inactive_ifree()
1719 *
1720 * Perform the inode free when an inode is unlinked.
1721 */
1722STATIC int
1723xfs_inactive_ifree(
1724 struct xfs_inode *ip)
1725{
1726 xfs_bmap_free_t free_list;
1727 xfs_fsblock_t first_block;
1728 int committed;
1729 struct xfs_mount *mp = ip->i_mount;
1730 struct xfs_trans *tp;
1731 int error;
1732
1733 tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
1734 error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ifree, 0, 0);
1735 if (error) {
1736 ASSERT(XFS_FORCED_SHUTDOWN(mp));
1737 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
1738 return error;
1739 }
1740
1741 xfs_ilock(ip, XFS_ILOCK_EXCL);
1742 xfs_trans_ijoin(tp, ip, 0);
1743
1744 xfs_bmap_init(&free_list, &first_block);
1745 error = xfs_ifree(tp, ip, &free_list);
1746 if (error) {
1747 /*
1748 * If we fail to free the inode, shut down. The cancel
1749 * might do that, we need to make sure. Otherwise the
1750 * inode might be lost for a long time or forever.
1751 */
1752 if (!XFS_FORCED_SHUTDOWN(mp)) {
1753 xfs_notice(mp, "%s: xfs_ifree returned error %d",
1754 __func__, error);
1755 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1756 }
1757 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1758 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1759 return error;
1760 }
1761
1762 /*
1763 * Credit the quota account(s). The inode is gone.
1764 */
1765 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
1766
1767 /*
1768 * Just ignore errors at this point. There is nothing we can
1769 * do except to try to keep going. Make sure it's not a silent
1770 * error.
1771 */
1772 error = xfs_bmap_finish(&tp, &free_list, &committed);
1773 if (error)
1774 xfs_notice(mp, "%s: xfs_bmap_finish returned error %d",
1775 __func__, error);
1776 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1777 if (error)
1778 xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
1779 __func__, error);
1780
1781 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1782 return 0;
1783}
1784
1785/*
1718 * xfs_inactive 1786 * xfs_inactive
1719 * 1787 *
1720 * This is called when the vnode reference count for the vnode 1788 * This is called when the vnode reference count for the vnode
@@ -1726,10 +1794,6 @@ int
1726xfs_inactive( 1794xfs_inactive(
1727 xfs_inode_t *ip) 1795 xfs_inode_t *ip)
1728{ 1796{
1729 xfs_bmap_free_t free_list;
1730 xfs_fsblock_t first_block;
1731 int committed;
1732 struct xfs_trans *tp;
1733 struct xfs_mount *mp; 1797 struct xfs_mount *mp;
1734 int error; 1798 int error;
1735 int truncate = 0; 1799 int truncate = 0;
@@ -1801,60 +1865,17 @@ xfs_inactive(
1801 1865
1802 ASSERT(ip->i_d.di_anextents == 0); 1866 ASSERT(ip->i_d.di_anextents == 0);
1803 1867
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
1815 /* 1868 /*
1816 * Free the inode. 1869 * Free the inode.
1817 */ 1870 */
1818 xfs_bmap_init(&free_list, &first_block); 1871 error = xfs_inactive_ifree(ip);
1819 error = xfs_ifree(tp, ip, &free_list); 1872 if (error)
1820 if (error) { 1873 goto out;
1821 /*
1822 * If we fail to free the inode, shut down. The cancel
1823 * might do that, we need to make sure. Otherwise the
1824 * inode might be lost for a long time or forever.
1825 */
1826 if (!XFS_FORCED_SHUTDOWN(mp)) {
1827 xfs_notice(mp, "%s: xfs_ifree returned error %d",
1828 __func__, error);
1829 xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR);
1830 }
1831 xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
1832 } else {
1833 /*
1834 * Credit the quota account(s). The inode is gone.
1835 */
1836 xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_ICOUNT, -1);
1837
1838 /*
1839 * Just ignore errors at this point. There is nothing we can
1840 * do except to try to keep going. Make sure it's not a silent
1841 * error.
1842 */
1843 error = xfs_bmap_finish(&tp, &free_list, &committed);
1844 if (error)
1845 xfs_notice(mp, "%s: xfs_bmap_finish returned error %d",
1846 __func__, error);
1847 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1848 if (error)
1849 xfs_notice(mp, "%s: xfs_trans_commit returned error %d",
1850 __func__, error);
1851 }
1852 1874
1853 /* 1875 /*
1854 * Release the dquots held by inode, if any. 1876 * Release the dquots held by inode, if any.
1855 */ 1877 */
1856 xfs_qm_dqdetach(ip); 1878 xfs_qm_dqdetach(ip);
1857 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1858out: 1879out:
1859 return VN_INACTIVE_CACHE; 1880 return VN_INACTIVE_CACHE;
1860} 1881}