aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c144
1 files changed, 62 insertions, 82 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 8cd6e8d8fe9c..d53c39de7d05 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1940,10 +1940,10 @@ xfs_ifree_cluster(
1940 int blks_per_cluster; 1940 int blks_per_cluster;
1941 int nbufs; 1941 int nbufs;
1942 int ninodes; 1942 int ninodes;
1943 int i, j, found, pre_flushed; 1943 int i, j;
1944 xfs_daddr_t blkno; 1944 xfs_daddr_t blkno;
1945 xfs_buf_t *bp; 1945 xfs_buf_t *bp;
1946 xfs_inode_t *ip, **ip_found; 1946 xfs_inode_t *ip;
1947 xfs_inode_log_item_t *iip; 1947 xfs_inode_log_item_t *iip;
1948 xfs_log_item_t *lip; 1948 xfs_log_item_t *lip;
1949 struct xfs_perag *pag; 1949 struct xfs_perag *pag;
@@ -1960,114 +1960,97 @@ xfs_ifree_cluster(
1960 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; 1960 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster;
1961 } 1961 }
1962 1962
1963 ip_found = kmem_alloc(ninodes * sizeof(xfs_inode_t *), KM_NOFS);
1964
1965 for (j = 0; j < nbufs; j++, inum += ninodes) { 1963 for (j = 0; j < nbufs; j++, inum += ninodes) {
1964 int found = 0;
1965
1966 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), 1966 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),
1967 XFS_INO_TO_AGBNO(mp, inum)); 1967 XFS_INO_TO_AGBNO(mp, inum));
1968 1968
1969 /*
1970 * We obtain and lock the backing buffer first in the process
1971 * here, as we have to ensure that any dirty inode that we
1972 * can't get the flush lock on is attached to the buffer.
1973 * If we scan the in-memory inodes first, then buffer IO can
1974 * complete before we get a lock on it, and hence we may fail
1975 * to mark all the active inodes on the buffer stale.
1976 */
1977 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
1978 mp->m_bsize * blks_per_cluster,
1979 XBF_LOCK);
1980
1981 /*
1982 * Walk the inodes already attached to the buffer and mark them
1983 * stale. These will all have the flush locks held, so an
1984 * in-memory inode walk can't lock them.
1985 */
1986 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
1987 while (lip) {
1988 if (lip->li_type == XFS_LI_INODE) {
1989 iip = (xfs_inode_log_item_t *)lip;
1990 ASSERT(iip->ili_logged == 1);
1991 lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
1992 xfs_trans_ail_copy_lsn(mp->m_ail,
1993 &iip->ili_flush_lsn,
1994 &iip->ili_item.li_lsn);
1995 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
1996 found++;
1997 }
1998 lip = lip->li_bio_list;
1999 }
1969 2000
1970 /* 2001 /*
1971 * Look for each inode in memory and attempt to lock it, 2002 * For each inode in memory attempt to add it to the inode
1972 * we can be racing with flush and tail pushing here. 2003 * buffer and set it up for being staled on buffer IO
1973 * any inode we get the locks on, add to an array of 2004 * completion. This is safe as we've locked out tail pushing
1974 * inode items to process later. 2005 * and flushing by locking the buffer.
1975 * 2006 *
1976 * The get the buffer lock, we could beat a flush 2007 * We have already marked every inode that was part of a
1977 * or tail pushing thread to the lock here, in which 2008 * transaction stale above, which means there is no point in
1978 * case they will go looking for the inode buffer 2009 * even trying to lock them.
1979 * and fail, we need some other form of interlock
1980 * here.
1981 */ 2010 */
1982 found = 0;
1983 for (i = 0; i < ninodes; i++) { 2011 for (i = 0; i < ninodes; i++) {
1984 read_lock(&pag->pag_ici_lock); 2012 read_lock(&pag->pag_ici_lock);
1985 ip = radix_tree_lookup(&pag->pag_ici_root, 2013 ip = radix_tree_lookup(&pag->pag_ici_root,
1986 XFS_INO_TO_AGINO(mp, (inum + i))); 2014 XFS_INO_TO_AGINO(mp, (inum + i)));
1987 2015
1988 /* Inode not in memory or we found it already, 2016 /* Inode not in memory or stale, nothing to do */
1989 * nothing to do
1990 */
1991 if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { 2017 if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {
1992 read_unlock(&pag->pag_ici_lock); 2018 read_unlock(&pag->pag_ici_lock);
1993 continue; 2019 continue;
1994 } 2020 }
1995 2021
1996 if (xfs_inode_clean(ip)) { 2022 /* don't try to lock/unlock the current inode */
1997 read_unlock(&pag->pag_ici_lock); 2023 if (ip != free_ip &&
1998 continue; 2024 !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {
1999 }
2000
2001 /* If we can get the locks then add it to the
2002 * list, otherwise by the time we get the bp lock
2003 * below it will already be attached to the
2004 * inode buffer.
2005 */
2006
2007 /* This inode will already be locked - by us, lets
2008 * keep it that way.
2009 */
2010
2011 if (ip == free_ip) {
2012 if (xfs_iflock_nowait(ip)) {
2013 xfs_iflags_set(ip, XFS_ISTALE);
2014 if (xfs_inode_clean(ip)) {
2015 xfs_ifunlock(ip);
2016 } else {
2017 ip_found[found++] = ip;
2018 }
2019 }
2020 read_unlock(&pag->pag_ici_lock); 2025 read_unlock(&pag->pag_ici_lock);
2021 continue; 2026 continue;
2022 } 2027 }
2028 read_unlock(&pag->pag_ici_lock);
2023 2029
2024 if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { 2030 if (!xfs_iflock_nowait(ip)) {
2025 if (xfs_iflock_nowait(ip)) { 2031 if (ip != free_ip)
2026 xfs_iflags_set(ip, XFS_ISTALE);
2027
2028 if (xfs_inode_clean(ip)) {
2029 xfs_ifunlock(ip);
2030 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2031 } else {
2032 ip_found[found++] = ip;
2033 }
2034 } else {
2035 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2032 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2036 } 2033 continue;
2037 } 2034 }
2038 read_unlock(&pag->pag_ici_lock);
2039 }
2040 2035
2041 bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, 2036 xfs_iflags_set(ip, XFS_ISTALE);
2042 mp->m_bsize * blks_per_cluster, 2037 if (xfs_inode_clean(ip)) {
2043 XBF_LOCK); 2038 ASSERT(ip != free_ip);
2044 2039 xfs_ifunlock(ip);
2045 pre_flushed = 0; 2040 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2046 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); 2041 continue;
2047 while (lip) {
2048 if (lip->li_type == XFS_LI_INODE) {
2049 iip = (xfs_inode_log_item_t *)lip;
2050 ASSERT(iip->ili_logged == 1);
2051 lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
2052 xfs_trans_ail_copy_lsn(mp->m_ail,
2053 &iip->ili_flush_lsn,
2054 &iip->ili_item.li_lsn);
2055 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);
2056 pre_flushed++;
2057 } 2042 }
2058 lip = lip->li_bio_list;
2059 }
2060 2043
2061 for (i = 0; i < found; i++) {
2062 ip = ip_found[i];
2063 iip = ip->i_itemp; 2044 iip = ip->i_itemp;
2064
2065 if (!iip) { 2045 if (!iip) {
2046 /* inode with unlogged changes only */
2047 ASSERT(ip != free_ip);
2066 ip->i_update_core = 0; 2048 ip->i_update_core = 0;
2067 xfs_ifunlock(ip); 2049 xfs_ifunlock(ip);
2068 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2050 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2069 continue; 2051 continue;
2070 } 2052 }
2053 found++;
2071 2054
2072 iip->ili_last_fields = iip->ili_format.ilf_fields; 2055 iip->ili_last_fields = iip->ili_format.ilf_fields;
2073 iip->ili_format.ilf_fields = 0; 2056 iip->ili_format.ilf_fields = 0;
@@ -2078,17 +2061,16 @@ xfs_ifree_cluster(
2078 xfs_buf_attach_iodone(bp, 2061 xfs_buf_attach_iodone(bp,
2079 (void(*)(xfs_buf_t*,xfs_log_item_t*)) 2062 (void(*)(xfs_buf_t*,xfs_log_item_t*))
2080 xfs_istale_done, (xfs_log_item_t *)iip); 2063 xfs_istale_done, (xfs_log_item_t *)iip);
2081 if (ip != free_ip) { 2064
2065 if (ip != free_ip)
2082 xfs_iunlock(ip, XFS_ILOCK_EXCL); 2066 xfs_iunlock(ip, XFS_ILOCK_EXCL);
2083 }
2084 } 2067 }
2085 2068
2086 if (found || pre_flushed) 2069 if (found)
2087 xfs_trans_stale_inode_buf(tp, bp); 2070 xfs_trans_stale_inode_buf(tp, bp);
2088 xfs_trans_binval(tp, bp); 2071 xfs_trans_binval(tp, bp);
2089 } 2072 }
2090 2073
2091 kmem_free(ip_found);
2092 xfs_perag_put(pag); 2074 xfs_perag_put(pag);
2093} 2075}
2094 2076
@@ -2649,8 +2631,6 @@ xfs_iflush_cluster(
2649 int i; 2631 int i;
2650 2632
2651 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); 2633 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
2652 ASSERT(pag->pagi_inodeok);
2653 ASSERT(pag->pag_ici_init);
2654 2634
2655 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; 2635 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog;
2656 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); 2636 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);