diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 149 |
1 files changed, 63 insertions, 86 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8cd6e8d8fe9c..b76a829d7e20 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -177,7 +177,7 @@ xfs_imap_to_bp( | |||
177 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, | 177 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, |
178 | XFS_ERRTAG_ITOBP_INOTOBP, | 178 | XFS_ERRTAG_ITOBP_INOTOBP, |
179 | XFS_RANDOM_ITOBP_INOTOBP))) { | 179 | XFS_RANDOM_ITOBP_INOTOBP))) { |
180 | if (iget_flags & XFS_IGET_BULKSTAT) { | 180 | if (iget_flags & XFS_IGET_UNTRUSTED) { |
181 | xfs_trans_brelse(tp, bp); | 181 | xfs_trans_brelse(tp, bp); |
182 | return XFS_ERROR(EINVAL); | 182 | return XFS_ERROR(EINVAL); |
183 | } | 183 | } |
@@ -787,7 +787,6 @@ xfs_iread( | |||
787 | xfs_mount_t *mp, | 787 | xfs_mount_t *mp, |
788 | xfs_trans_t *tp, | 788 | xfs_trans_t *tp, |
789 | xfs_inode_t *ip, | 789 | xfs_inode_t *ip, |
790 | xfs_daddr_t bno, | ||
791 | uint iget_flags) | 790 | uint iget_flags) |
792 | { | 791 | { |
793 | xfs_buf_t *bp; | 792 | xfs_buf_t *bp; |
@@ -797,11 +796,9 @@ xfs_iread( | |||
797 | /* | 796 | /* |
798 | * Fill in the location information in the in-core inode. | 797 | * Fill in the location information in the in-core inode. |
799 | */ | 798 | */ |
800 | ip->i_imap.im_blkno = bno; | ||
801 | error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); | 799 | error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); |
802 | if (error) | 800 | if (error) |
803 | return error; | 801 | return error; |
804 | ASSERT(bno == 0 || bno == ip->i_imap.im_blkno); | ||
805 | 802 | ||
806 | /* | 803 | /* |
807 | * Get pointers to the on-disk inode and the buffer containing it. | 804 | * Get pointers to the on-disk inode and the buffer containing it. |
@@ -1940,10 +1937,10 @@ xfs_ifree_cluster( | |||
1940 | int blks_per_cluster; | 1937 | int blks_per_cluster; |
1941 | int nbufs; | 1938 | int nbufs; |
1942 | int ninodes; | 1939 | int ninodes; |
1943 | int i, j, found, pre_flushed; | 1940 | int i, j; |
1944 | xfs_daddr_t blkno; | 1941 | xfs_daddr_t blkno; |
1945 | xfs_buf_t *bp; | 1942 | xfs_buf_t *bp; |
1946 | xfs_inode_t *ip, **ip_found; | 1943 | xfs_inode_t *ip; |
1947 | xfs_inode_log_item_t *iip; | 1944 | xfs_inode_log_item_t *iip; |
1948 | xfs_log_item_t *lip; | 1945 | xfs_log_item_t *lip; |
1949 | struct xfs_perag *pag; | 1946 | struct xfs_perag *pag; |
@@ -1960,114 +1957,97 @@ xfs_ifree_cluster( | |||
1960 | nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; | 1957 | nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster; |
1961 | } | 1958 | } |
1962 | 1959 | ||
1963 | ip_found = kmem_alloc(ninodes * sizeof(xfs_inode_t *), KM_NOFS); | ||
1964 | |||
1965 | for (j = 0; j < nbufs; j++, inum += ninodes) { | 1960 | for (j = 0; j < nbufs; j++, inum += ninodes) { |
1961 | int found = 0; | ||
1962 | |||
1966 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), | 1963 | blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum), |
1967 | XFS_INO_TO_AGBNO(mp, inum)); | 1964 | XFS_INO_TO_AGBNO(mp, inum)); |
1968 | 1965 | ||
1966 | /* | ||
1967 | * We obtain and lock the backing buffer first in the process | ||
1968 | * here, as we have to ensure that any dirty inode that we | ||
1969 | * can't get the flush lock on is attached to the buffer. | ||
1970 | * If we scan the in-memory inodes first, then buffer IO can | ||
1971 | * complete before we get a lock on it, and hence we may fail | ||
1972 | * to mark all the active inodes on the buffer stale. | ||
1973 | */ | ||
1974 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, | ||
1975 | mp->m_bsize * blks_per_cluster, | ||
1976 | XBF_LOCK); | ||
1977 | |||
1978 | /* | ||
1979 | * Walk the inodes already attached to the buffer and mark them | ||
1980 | * stale. These will all have the flush locks held, so an | ||
1981 | * in-memory inode walk can't lock them. | ||
1982 | */ | ||
1983 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); | ||
1984 | while (lip) { | ||
1985 | if (lip->li_type == XFS_LI_INODE) { | ||
1986 | iip = (xfs_inode_log_item_t *)lip; | ||
1987 | ASSERT(iip->ili_logged == 1); | ||
1988 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; | ||
1989 | xfs_trans_ail_copy_lsn(mp->m_ail, | ||
1990 | &iip->ili_flush_lsn, | ||
1991 | &iip->ili_item.li_lsn); | ||
1992 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | ||
1993 | found++; | ||
1994 | } | ||
1995 | lip = lip->li_bio_list; | ||
1996 | } | ||
1969 | 1997 | ||
1970 | /* | 1998 | /* |
1971 | * Look for each inode in memory and attempt to lock it, | 1999 | * For each inode in memory attempt to add it to the inode |
1972 | * we can be racing with flush and tail pushing here. | 2000 | * buffer and set it up for being staled on buffer IO |
1973 | * any inode we get the locks on, add to an array of | 2001 | * completion. This is safe as we've locked out tail pushing |
1974 | * inode items to process later. | 2002 | * and flushing by locking the buffer. |
1975 | * | 2003 | * |
1976 | * The get the buffer lock, we could beat a flush | 2004 | * We have already marked every inode that was part of a |
1977 | * or tail pushing thread to the lock here, in which | 2005 | * transaction stale above, which means there is no point in |
1978 | * case they will go looking for the inode buffer | 2006 | * even trying to lock them. |
1979 | * and fail, we need some other form of interlock | ||
1980 | * here. | ||
1981 | */ | 2007 | */ |
1982 | found = 0; | ||
1983 | for (i = 0; i < ninodes; i++) { | 2008 | for (i = 0; i < ninodes; i++) { |
1984 | read_lock(&pag->pag_ici_lock); | 2009 | read_lock(&pag->pag_ici_lock); |
1985 | ip = radix_tree_lookup(&pag->pag_ici_root, | 2010 | ip = radix_tree_lookup(&pag->pag_ici_root, |
1986 | XFS_INO_TO_AGINO(mp, (inum + i))); | 2011 | XFS_INO_TO_AGINO(mp, (inum + i))); |
1987 | 2012 | ||
1988 | /* Inode not in memory or we found it already, | 2013 | /* Inode not in memory or stale, nothing to do */ |
1989 | * nothing to do | ||
1990 | */ | ||
1991 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { | 2014 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { |
1992 | read_unlock(&pag->pag_ici_lock); | 2015 | read_unlock(&pag->pag_ici_lock); |
1993 | continue; | 2016 | continue; |
1994 | } | 2017 | } |
1995 | 2018 | ||
1996 | if (xfs_inode_clean(ip)) { | 2019 | /* don't try to lock/unlock the current inode */ |
1997 | read_unlock(&pag->pag_ici_lock); | 2020 | if (ip != free_ip && |
1998 | continue; | 2021 | !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); | 2022 | read_unlock(&pag->pag_ici_lock); |
2021 | continue; | 2023 | continue; |
2022 | } | 2024 | } |
2025 | read_unlock(&pag->pag_ici_lock); | ||
2023 | 2026 | ||
2024 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2027 | if (!xfs_iflock_nowait(ip)) { |
2025 | if (xfs_iflock_nowait(ip)) { | 2028 | 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); | 2029 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2036 | } | 2030 | continue; |
2037 | } | 2031 | } |
2038 | read_unlock(&pag->pag_ici_lock); | ||
2039 | } | ||
2040 | 2032 | ||
2041 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, | 2033 | xfs_iflags_set(ip, XFS_ISTALE); |
2042 | mp->m_bsize * blks_per_cluster, | 2034 | if (xfs_inode_clean(ip)) { |
2043 | XBF_LOCK); | 2035 | ASSERT(ip != free_ip); |
2044 | 2036 | xfs_ifunlock(ip); | |
2045 | pre_flushed = 0; | 2037 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2046 | lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); | 2038 | 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 | } | 2039 | } |
2058 | lip = lip->li_bio_list; | ||
2059 | } | ||
2060 | 2040 | ||
2061 | for (i = 0; i < found; i++) { | ||
2062 | ip = ip_found[i]; | ||
2063 | iip = ip->i_itemp; | 2041 | iip = ip->i_itemp; |
2064 | |||
2065 | if (!iip) { | 2042 | if (!iip) { |
2043 | /* inode with unlogged changes only */ | ||
2044 | ASSERT(ip != free_ip); | ||
2066 | ip->i_update_core = 0; | 2045 | ip->i_update_core = 0; |
2067 | xfs_ifunlock(ip); | 2046 | xfs_ifunlock(ip); |
2068 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2047 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2069 | continue; | 2048 | continue; |
2070 | } | 2049 | } |
2050 | found++; | ||
2071 | 2051 | ||
2072 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2052 | iip->ili_last_fields = iip->ili_format.ilf_fields; |
2073 | iip->ili_format.ilf_fields = 0; | 2053 | iip->ili_format.ilf_fields = 0; |
@@ -2078,17 +2058,16 @@ xfs_ifree_cluster( | |||
2078 | xfs_buf_attach_iodone(bp, | 2058 | xfs_buf_attach_iodone(bp, |
2079 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) | 2059 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) |
2080 | xfs_istale_done, (xfs_log_item_t *)iip); | 2060 | xfs_istale_done, (xfs_log_item_t *)iip); |
2081 | if (ip != free_ip) { | 2061 | |
2062 | if (ip != free_ip) | ||
2082 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2063 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2083 | } | ||
2084 | } | 2064 | } |
2085 | 2065 | ||
2086 | if (found || pre_flushed) | 2066 | if (found) |
2087 | xfs_trans_stale_inode_buf(tp, bp); | 2067 | xfs_trans_stale_inode_buf(tp, bp); |
2088 | xfs_trans_binval(tp, bp); | 2068 | xfs_trans_binval(tp, bp); |
2089 | } | 2069 | } |
2090 | 2070 | ||
2091 | kmem_free(ip_found); | ||
2092 | xfs_perag_put(pag); | 2071 | xfs_perag_put(pag); |
2093 | } | 2072 | } |
2094 | 2073 | ||
@@ -2649,8 +2628,6 @@ xfs_iflush_cluster( | |||
2649 | int i; | 2628 | int i; |
2650 | 2629 | ||
2651 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | 2630 | 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 | 2631 | ||
2655 | inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; | 2632 | inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog; |
2656 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); | 2633 | ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *); |