diff options
| author | Brian Foster <bfoster@redhat.com> | 2013-09-20 11:06:11 -0400 |
|---|---|---|
| committer | Ben Myers <bpm@sgi.com> | 2013-10-08 18:15:01 -0400 |
| commit | 88877d2b9727a14431bfe48216ff86331ab47ea5 (patch) | |
| tree | e09e7520d93a55e26f2d56ad7f6a94950ee6e1e5 | |
| parent | f7be2d7f594cbc7a00902b5427332a1ad519a528 (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>
| -rw-r--r-- | fs/xfs/xfs_inode.c | 121 |
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 | */ | ||
| 1722 | STATIC int | ||
| 1723 | xfs_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 | |||
| 1726 | xfs_inactive( | 1794 | xfs_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); | ||
| 1858 | out: | 1879 | out: |
| 1859 | return VN_INACTIVE_CACHE; | 1880 | return VN_INACTIVE_CACHE; |
| 1860 | } | 1881 | } |
