diff options
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
-rw-r--r-- | fs/xfs/xfs_alloc.c | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 8e9a40aa0cd3..98f95d4c4bcc 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -1447,7 +1447,8 @@ xfs_alloc_ag_vextent_small( | |||
1447 | else if (args->minlen == 1 && args->alignment == 1 && !args->isfl && | 1447 | else if (args->minlen == 1 && args->alignment == 1 && !args->isfl && |
1448 | (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) | 1448 | (be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount) |
1449 | > args->minleft)) { | 1449 | > args->minleft)) { |
1450 | if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno))) | 1450 | error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0); |
1451 | if (error) | ||
1451 | goto error0; | 1452 | goto error0; |
1452 | if (fbno != NULLAGBLOCK) { | 1453 | if (fbno != NULLAGBLOCK) { |
1453 | if (args->userdata) { | 1454 | if (args->userdata) { |
@@ -1923,7 +1924,8 @@ xfs_alloc_fix_freelist( | |||
1923 | while (be32_to_cpu(agf->agf_flcount) > need) { | 1924 | while (be32_to_cpu(agf->agf_flcount) > need) { |
1924 | xfs_buf_t *bp; | 1925 | xfs_buf_t *bp; |
1925 | 1926 | ||
1926 | if ((error = xfs_alloc_get_freelist(tp, agbp, &bno))) | 1927 | error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); |
1928 | if (error) | ||
1927 | return error; | 1929 | return error; |
1928 | if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) | 1930 | if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) |
1929 | return error; | 1931 | return error; |
@@ -1973,8 +1975,9 @@ xfs_alloc_fix_freelist( | |||
1973 | * Put each allocated block on the list. | 1975 | * Put each allocated block on the list. |
1974 | */ | 1976 | */ |
1975 | for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { | 1977 | for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) { |
1976 | if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp, | 1978 | error = xfs_alloc_put_freelist(tp, agbp, |
1977 | bno))) | 1979 | agflbp, bno, 0); |
1980 | if (error) | ||
1978 | return error; | 1981 | return error; |
1979 | } | 1982 | } |
1980 | } | 1983 | } |
@@ -1991,13 +1994,15 @@ int /* error */ | |||
1991 | xfs_alloc_get_freelist( | 1994 | xfs_alloc_get_freelist( |
1992 | xfs_trans_t *tp, /* transaction pointer */ | 1995 | xfs_trans_t *tp, /* transaction pointer */ |
1993 | xfs_buf_t *agbp, /* buffer containing the agf structure */ | 1996 | xfs_buf_t *agbp, /* buffer containing the agf structure */ |
1994 | xfs_agblock_t *bnop) /* block address retrieved from freelist */ | 1997 | xfs_agblock_t *bnop, /* block address retrieved from freelist */ |
1998 | int btreeblk) /* destination is a AGF btree */ | ||
1995 | { | 1999 | { |
1996 | xfs_agf_t *agf; /* a.g. freespace structure */ | 2000 | xfs_agf_t *agf; /* a.g. freespace structure */ |
1997 | xfs_agfl_t *agfl; /* a.g. freelist structure */ | 2001 | xfs_agfl_t *agfl; /* a.g. freelist structure */ |
1998 | xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */ | 2002 | xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */ |
1999 | xfs_agblock_t bno; /* block number returned */ | 2003 | xfs_agblock_t bno; /* block number returned */ |
2000 | int error; | 2004 | int error; |
2005 | int logflags; | ||
2001 | #ifdef XFS_ALLOC_TRACE | 2006 | #ifdef XFS_ALLOC_TRACE |
2002 | static char fname[] = "xfs_alloc_get_freelist"; | 2007 | static char fname[] = "xfs_alloc_get_freelist"; |
2003 | #endif | 2008 | #endif |
@@ -2032,8 +2037,16 @@ xfs_alloc_get_freelist( | |||
2032 | be32_add(&agf->agf_flcount, -1); | 2037 | be32_add(&agf->agf_flcount, -1); |
2033 | xfs_trans_agflist_delta(tp, -1); | 2038 | xfs_trans_agflist_delta(tp, -1); |
2034 | pag->pagf_flcount--; | 2039 | pag->pagf_flcount--; |
2035 | TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT); | 2040 | |
2036 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT); | 2041 | logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT; |
2042 | if (btreeblk) { | ||
2043 | be32_add(&agf->agf_btreeblks, 1); | ||
2044 | pag->pagf_btreeblks++; | ||
2045 | logflags |= XFS_AGF_BTREEBLKS; | ||
2046 | } | ||
2047 | |||
2048 | TRACE_MODAGF(NULL, agf, logflags); | ||
2049 | xfs_alloc_log_agf(tp, agbp, logflags); | ||
2037 | *bnop = bno; | 2050 | *bnop = bno; |
2038 | 2051 | ||
2039 | /* | 2052 | /* |
@@ -2071,6 +2084,7 @@ xfs_alloc_log_agf( | |||
2071 | offsetof(xfs_agf_t, agf_flcount), | 2084 | offsetof(xfs_agf_t, agf_flcount), |
2072 | offsetof(xfs_agf_t, agf_freeblks), | 2085 | offsetof(xfs_agf_t, agf_freeblks), |
2073 | offsetof(xfs_agf_t, agf_longest), | 2086 | offsetof(xfs_agf_t, agf_longest), |
2087 | offsetof(xfs_agf_t, agf_btreeblks), | ||
2074 | sizeof(xfs_agf_t) | 2088 | sizeof(xfs_agf_t) |
2075 | }; | 2089 | }; |
2076 | 2090 | ||
@@ -2106,12 +2120,14 @@ xfs_alloc_put_freelist( | |||
2106 | xfs_trans_t *tp, /* transaction pointer */ | 2120 | xfs_trans_t *tp, /* transaction pointer */ |
2107 | xfs_buf_t *agbp, /* buffer for a.g. freelist header */ | 2121 | xfs_buf_t *agbp, /* buffer for a.g. freelist header */ |
2108 | xfs_buf_t *agflbp,/* buffer for a.g. free block array */ | 2122 | xfs_buf_t *agflbp,/* buffer for a.g. free block array */ |
2109 | xfs_agblock_t bno) /* block being freed */ | 2123 | xfs_agblock_t bno, /* block being freed */ |
2124 | int btreeblk) /* block came from a AGF btree */ | ||
2110 | { | 2125 | { |
2111 | xfs_agf_t *agf; /* a.g. freespace structure */ | 2126 | xfs_agf_t *agf; /* a.g. freespace structure */ |
2112 | xfs_agfl_t *agfl; /* a.g. free block array */ | 2127 | xfs_agfl_t *agfl; /* a.g. free block array */ |
2113 | __be32 *blockp;/* pointer to array entry */ | 2128 | __be32 *blockp;/* pointer to array entry */ |
2114 | int error; | 2129 | int error; |
2130 | int logflags; | ||
2115 | #ifdef XFS_ALLOC_TRACE | 2131 | #ifdef XFS_ALLOC_TRACE |
2116 | static char fname[] = "xfs_alloc_put_freelist"; | 2132 | static char fname[] = "xfs_alloc_put_freelist"; |
2117 | #endif | 2133 | #endif |
@@ -2132,11 +2148,22 @@ xfs_alloc_put_freelist( | |||
2132 | be32_add(&agf->agf_flcount, 1); | 2148 | be32_add(&agf->agf_flcount, 1); |
2133 | xfs_trans_agflist_delta(tp, 1); | 2149 | xfs_trans_agflist_delta(tp, 1); |
2134 | pag->pagf_flcount++; | 2150 | pag->pagf_flcount++; |
2151 | |||
2152 | logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT; | ||
2153 | if (btreeblk) { | ||
2154 | be32_add(&agf->agf_btreeblks, -1); | ||
2155 | pag->pagf_btreeblks--; | ||
2156 | logflags |= XFS_AGF_BTREEBLKS; | ||
2157 | } | ||
2158 | |||
2159 | TRACE_MODAGF(NULL, agf, logflags); | ||
2160 | xfs_alloc_log_agf(tp, agbp, logflags); | ||
2161 | |||
2135 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); | 2162 | ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)); |
2136 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; | 2163 | blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)]; |
2137 | *blockp = cpu_to_be32(bno); | 2164 | *blockp = cpu_to_be32(bno); |
2138 | TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); | 2165 | TRACE_MODAGF(NULL, agf, logflags); |
2139 | xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT); | 2166 | xfs_alloc_log_agf(tp, agbp, logflags); |
2140 | xfs_trans_log_buf(tp, agflbp, | 2167 | xfs_trans_log_buf(tp, agflbp, |
2141 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), | 2168 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl), |
2142 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + | 2169 | (int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl + |
@@ -2196,6 +2223,7 @@ xfs_alloc_read_agf( | |||
2196 | pag = &mp->m_perag[agno]; | 2223 | pag = &mp->m_perag[agno]; |
2197 | if (!pag->pagf_init) { | 2224 | if (!pag->pagf_init) { |
2198 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); | 2225 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); |
2226 | pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks); | ||
2199 | pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); | 2227 | pag->pagf_flcount = be32_to_cpu(agf->agf_flcount); |
2200 | pag->pagf_longest = be32_to_cpu(agf->agf_longest); | 2228 | pag->pagf_longest = be32_to_cpu(agf->agf_longest); |
2201 | pag->pagf_levels[XFS_BTNUM_BNOi] = | 2229 | pag->pagf_levels[XFS_BTNUM_BNOi] = |