diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 554 |
1 files changed, 397 insertions, 157 deletions
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 61ec015dca16..aeffeaaac0ec 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c | |||
| @@ -244,30 +244,6 @@ xfs_bmap_forkoff_reset( | |||
| 244 | } | 244 | } |
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | /* | ||
| 248 | * Debug/sanity checking code | ||
| 249 | */ | ||
| 250 | |||
| 251 | STATIC int | ||
| 252 | xfs_bmap_sanity_check( | ||
| 253 | struct xfs_mount *mp, | ||
| 254 | struct xfs_buf *bp, | ||
| 255 | int level) | ||
| 256 | { | ||
| 257 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); | ||
| 258 | |||
| 259 | if (block->bb_magic != cpu_to_be32(XFS_BMAP_CRC_MAGIC) && | ||
| 260 | block->bb_magic != cpu_to_be32(XFS_BMAP_MAGIC)) | ||
| 261 | return 0; | ||
| 262 | |||
| 263 | if (be16_to_cpu(block->bb_level) != level || | ||
| 264 | be16_to_cpu(block->bb_numrecs) == 0 || | ||
| 265 | be16_to_cpu(block->bb_numrecs) > mp->m_bmap_dmxr[level != 0]) | ||
| 266 | return 0; | ||
| 267 | |||
| 268 | return 1; | ||
| 269 | } | ||
| 270 | |||
| 271 | #ifdef DEBUG | 247 | #ifdef DEBUG |
| 272 | STATIC struct xfs_buf * | 248 | STATIC struct xfs_buf * |
| 273 | xfs_bmap_get_bp( | 249 | xfs_bmap_get_bp( |
| @@ -410,9 +386,6 @@ xfs_bmap_check_leaf_extents( | |||
| 410 | goto error_norelse; | 386 | goto error_norelse; |
| 411 | } | 387 | } |
| 412 | block = XFS_BUF_TO_BLOCK(bp); | 388 | block = XFS_BUF_TO_BLOCK(bp); |
| 413 | XFS_WANT_CORRUPTED_GOTO( | ||
| 414 | xfs_bmap_sanity_check(mp, bp, level), | ||
| 415 | error0); | ||
| 416 | if (level == 0) | 389 | if (level == 0) |
| 417 | break; | 390 | break; |
| 418 | 391 | ||
| @@ -424,7 +397,8 @@ xfs_bmap_check_leaf_extents( | |||
| 424 | xfs_check_block(block, mp, 0, 0); | 397 | xfs_check_block(block, mp, 0, 0); |
| 425 | pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); | 398 | pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); |
| 426 | bno = be64_to_cpu(*pp); | 399 | bno = be64_to_cpu(*pp); |
| 427 | XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); | 400 | XFS_WANT_CORRUPTED_GOTO(mp, |
| 401 | XFS_FSB_SANITY_CHECK(mp, bno), error0); | ||
| 428 | if (bp_release) { | 402 | if (bp_release) { |
| 429 | bp_release = 0; | 403 | bp_release = 0; |
| 430 | xfs_trans_brelse(NULL, bp); | 404 | xfs_trans_brelse(NULL, bp); |
| @@ -1029,7 +1003,7 @@ xfs_bmap_add_attrfork_btree( | |||
| 1029 | if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) | 1003 | if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat))) |
| 1030 | goto error0; | 1004 | goto error0; |
| 1031 | /* must be at least one entry */ | 1005 | /* must be at least one entry */ |
| 1032 | XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); | 1006 | XFS_WANT_CORRUPTED_GOTO(mp, stat == 1, error0); |
| 1033 | if ((error = xfs_btree_new_iroot(cur, flags, &stat))) | 1007 | if ((error = xfs_btree_new_iroot(cur, flags, &stat))) |
| 1034 | goto error0; | 1008 | goto error0; |
| 1035 | if (stat == 0) { | 1009 | if (stat == 0) { |
| @@ -1311,14 +1285,12 @@ xfs_bmap_read_extents( | |||
| 1311 | if (error) | 1285 | if (error) |
| 1312 | return error; | 1286 | return error; |
| 1313 | block = XFS_BUF_TO_BLOCK(bp); | 1287 | block = XFS_BUF_TO_BLOCK(bp); |
| 1314 | XFS_WANT_CORRUPTED_GOTO( | ||
| 1315 | xfs_bmap_sanity_check(mp, bp, level), | ||
| 1316 | error0); | ||
| 1317 | if (level == 0) | 1288 | if (level == 0) |
| 1318 | break; | 1289 | break; |
| 1319 | pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); | 1290 | pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); |
| 1320 | bno = be64_to_cpu(*pp); | 1291 | bno = be64_to_cpu(*pp); |
| 1321 | XFS_WANT_CORRUPTED_GOTO(XFS_FSB_SANITY_CHECK(mp, bno), error0); | 1292 | XFS_WANT_CORRUPTED_GOTO(mp, |
| 1293 | XFS_FSB_SANITY_CHECK(mp, bno), error0); | ||
| 1322 | xfs_trans_brelse(tp, bp); | 1294 | xfs_trans_brelse(tp, bp); |
| 1323 | } | 1295 | } |
| 1324 | /* | 1296 | /* |
| @@ -1345,9 +1317,6 @@ xfs_bmap_read_extents( | |||
| 1345 | XFS_ERRLEVEL_LOW, ip->i_mount, block); | 1317 | XFS_ERRLEVEL_LOW, ip->i_mount, block); |
| 1346 | goto error0; | 1318 | goto error0; |
| 1347 | } | 1319 | } |
| 1348 | XFS_WANT_CORRUPTED_GOTO( | ||
| 1349 | xfs_bmap_sanity_check(mp, bp, 0), | ||
| 1350 | error0); | ||
| 1351 | /* | 1320 | /* |
| 1352 | * Read-ahead the next leaf block, if any. | 1321 | * Read-ahead the next leaf block, if any. |
| 1353 | */ | 1322 | */ |
| @@ -1755,7 +1724,9 @@ xfs_bmap_add_extent_delay_real( | |||
| 1755 | xfs_filblks_t temp=0; /* value for da_new calculations */ | 1724 | xfs_filblks_t temp=0; /* value for da_new calculations */ |
| 1756 | xfs_filblks_t temp2=0;/* value for da_new calculations */ | 1725 | xfs_filblks_t temp2=0;/* value for da_new calculations */ |
| 1757 | int tmp_rval; /* partial logging flags */ | 1726 | int tmp_rval; /* partial logging flags */ |
| 1727 | struct xfs_mount *mp; | ||
| 1758 | 1728 | ||
| 1729 | mp = bma->tp ? bma->tp->t_mountp : NULL; | ||
| 1759 | ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); | 1730 | ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); |
| 1760 | 1731 | ||
| 1761 | ASSERT(bma->idx >= 0); | 1732 | ASSERT(bma->idx >= 0); |
| @@ -1866,15 +1837,15 @@ xfs_bmap_add_extent_delay_real( | |||
| 1866 | RIGHT.br_blockcount, &i); | 1837 | RIGHT.br_blockcount, &i); |
| 1867 | if (error) | 1838 | if (error) |
| 1868 | goto done; | 1839 | goto done; |
| 1869 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1840 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 1870 | error = xfs_btree_delete(bma->cur, &i); | 1841 | error = xfs_btree_delete(bma->cur, &i); |
| 1871 | if (error) | 1842 | if (error) |
| 1872 | goto done; | 1843 | goto done; |
| 1873 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1844 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 1874 | error = xfs_btree_decrement(bma->cur, 0, &i); | 1845 | error = xfs_btree_decrement(bma->cur, 0, &i); |
| 1875 | if (error) | 1846 | if (error) |
| 1876 | goto done; | 1847 | goto done; |
| 1877 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1848 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 1878 | error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, | 1849 | error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, |
| 1879 | LEFT.br_startblock, | 1850 | LEFT.br_startblock, |
| 1880 | LEFT.br_blockcount + | 1851 | LEFT.br_blockcount + |
| @@ -1907,7 +1878,7 @@ xfs_bmap_add_extent_delay_real( | |||
| 1907 | &i); | 1878 | &i); |
| 1908 | if (error) | 1879 | if (error) |
| 1909 | goto done; | 1880 | goto done; |
| 1910 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1881 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 1911 | error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, | 1882 | error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, |
| 1912 | LEFT.br_startblock, | 1883 | LEFT.br_startblock, |
| 1913 | LEFT.br_blockcount + | 1884 | LEFT.br_blockcount + |
| @@ -1938,7 +1909,7 @@ xfs_bmap_add_extent_delay_real( | |||
| 1938 | RIGHT.br_blockcount, &i); | 1909 | RIGHT.br_blockcount, &i); |
| 1939 | if (error) | 1910 | if (error) |
| 1940 | goto done; | 1911 | goto done; |
| 1941 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1912 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 1942 | error = xfs_bmbt_update(bma->cur, PREV.br_startoff, | 1913 | error = xfs_bmbt_update(bma->cur, PREV.br_startoff, |
| 1943 | new->br_startblock, | 1914 | new->br_startblock, |
| 1944 | PREV.br_blockcount + | 1915 | PREV.br_blockcount + |
| @@ -1968,12 +1939,12 @@ xfs_bmap_add_extent_delay_real( | |||
| 1968 | &i); | 1939 | &i); |
| 1969 | if (error) | 1940 | if (error) |
| 1970 | goto done; | 1941 | goto done; |
| 1971 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 1942 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 1972 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; | 1943 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; |
| 1973 | error = xfs_btree_insert(bma->cur, &i); | 1944 | error = xfs_btree_insert(bma->cur, &i); |
| 1974 | if (error) | 1945 | if (error) |
| 1975 | goto done; | 1946 | goto done; |
| 1976 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1947 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 1977 | } | 1948 | } |
| 1978 | break; | 1949 | break; |
| 1979 | 1950 | ||
| @@ -2001,7 +1972,7 @@ xfs_bmap_add_extent_delay_real( | |||
| 2001 | &i); | 1972 | &i); |
| 2002 | if (error) | 1973 | if (error) |
| 2003 | goto done; | 1974 | goto done; |
| 2004 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 1975 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2005 | error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, | 1976 | error = xfs_bmbt_update(bma->cur, LEFT.br_startoff, |
| 2006 | LEFT.br_startblock, | 1977 | LEFT.br_startblock, |
| 2007 | LEFT.br_blockcount + | 1978 | LEFT.br_blockcount + |
| @@ -2038,12 +2009,12 @@ xfs_bmap_add_extent_delay_real( | |||
| 2038 | &i); | 2009 | &i); |
| 2039 | if (error) | 2010 | if (error) |
| 2040 | goto done; | 2011 | goto done; |
| 2041 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 2012 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 2042 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; | 2013 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; |
| 2043 | error = xfs_btree_insert(bma->cur, &i); | 2014 | error = xfs_btree_insert(bma->cur, &i); |
| 2044 | if (error) | 2015 | if (error) |
| 2045 | goto done; | 2016 | goto done; |
| 2046 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2017 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2047 | } | 2018 | } |
| 2048 | 2019 | ||
| 2049 | if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { | 2020 | if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { |
| @@ -2084,7 +2055,7 @@ xfs_bmap_add_extent_delay_real( | |||
| 2084 | RIGHT.br_blockcount, &i); | 2055 | RIGHT.br_blockcount, &i); |
| 2085 | if (error) | 2056 | if (error) |
| 2086 | goto done; | 2057 | goto done; |
| 2087 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2058 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2088 | error = xfs_bmbt_update(bma->cur, new->br_startoff, | 2059 | error = xfs_bmbt_update(bma->cur, new->br_startoff, |
| 2089 | new->br_startblock, | 2060 | new->br_startblock, |
| 2090 | new->br_blockcount + | 2061 | new->br_blockcount + |
| @@ -2122,12 +2093,12 @@ xfs_bmap_add_extent_delay_real( | |||
| 2122 | &i); | 2093 | &i); |
| 2123 | if (error) | 2094 | if (error) |
| 2124 | goto done; | 2095 | goto done; |
| 2125 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 2096 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 2126 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; | 2097 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; |
| 2127 | error = xfs_btree_insert(bma->cur, &i); | 2098 | error = xfs_btree_insert(bma->cur, &i); |
| 2128 | if (error) | 2099 | if (error) |
| 2129 | goto done; | 2100 | goto done; |
| 2130 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2101 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2131 | } | 2102 | } |
| 2132 | 2103 | ||
| 2133 | if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { | 2104 | if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { |
| @@ -2191,12 +2162,12 @@ xfs_bmap_add_extent_delay_real( | |||
| 2191 | &i); | 2162 | &i); |
| 2192 | if (error) | 2163 | if (error) |
| 2193 | goto done; | 2164 | goto done; |
| 2194 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 2165 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 2195 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; | 2166 | bma->cur->bc_rec.b.br_state = XFS_EXT_NORM; |
| 2196 | error = xfs_btree_insert(bma->cur, &i); | 2167 | error = xfs_btree_insert(bma->cur, &i); |
| 2197 | if (error) | 2168 | if (error) |
| 2198 | goto done; | 2169 | goto done; |
| 2199 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2170 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2200 | } | 2171 | } |
| 2201 | 2172 | ||
| 2202 | if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { | 2173 | if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { |
| @@ -2212,9 +2183,8 @@ xfs_bmap_add_extent_delay_real( | |||
| 2212 | diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - | 2183 | diff = (int)(temp + temp2 - startblockval(PREV.br_startblock) - |
| 2213 | (bma->cur ? bma->cur->bc_private.b.allocated : 0)); | 2184 | (bma->cur ? bma->cur->bc_private.b.allocated : 0)); |
| 2214 | if (diff > 0) { | 2185 | if (diff > 0) { |
| 2215 | error = xfs_icsb_modify_counters(bma->ip->i_mount, | 2186 | error = xfs_mod_fdblocks(bma->ip->i_mount, |
| 2216 | XFS_SBS_FDBLOCKS, | 2187 | -((int64_t)diff), false); |
| 2217 | -((int64_t)diff), 0); | ||
| 2218 | ASSERT(!error); | 2188 | ASSERT(!error); |
| 2219 | if (error) | 2189 | if (error) |
| 2220 | goto done; | 2190 | goto done; |
| @@ -2265,9 +2235,8 @@ xfs_bmap_add_extent_delay_real( | |||
| 2265 | temp += bma->cur->bc_private.b.allocated; | 2235 | temp += bma->cur->bc_private.b.allocated; |
| 2266 | ASSERT(temp <= da_old); | 2236 | ASSERT(temp <= da_old); |
| 2267 | if (temp < da_old) | 2237 | if (temp < da_old) |
| 2268 | xfs_icsb_modify_counters(bma->ip->i_mount, | 2238 | xfs_mod_fdblocks(bma->ip->i_mount, |
| 2269 | XFS_SBS_FDBLOCKS, | 2239 | (int64_t)(da_old - temp), false); |
| 2270 | (int64_t)(da_old - temp), 0); | ||
| 2271 | } | 2240 | } |
| 2272 | 2241 | ||
| 2273 | /* clear out the allocated field, done with it now in any case. */ | 2242 | /* clear out the allocated field, done with it now in any case. */ |
| @@ -2309,6 +2278,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2309 | /* left is 0, right is 1, prev is 2 */ | 2278 | /* left is 0, right is 1, prev is 2 */ |
| 2310 | int rval=0; /* return value (logging flags) */ | 2279 | int rval=0; /* return value (logging flags) */ |
| 2311 | int state = 0;/* state bits, accessed thru macros */ | 2280 | int state = 0;/* state bits, accessed thru macros */ |
| 2281 | struct xfs_mount *mp = tp->t_mountp; | ||
| 2312 | 2282 | ||
| 2313 | *logflagsp = 0; | 2283 | *logflagsp = 0; |
| 2314 | 2284 | ||
| @@ -2421,19 +2391,19 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2421 | RIGHT.br_startblock, | 2391 | RIGHT.br_startblock, |
| 2422 | RIGHT.br_blockcount, &i))) | 2392 | RIGHT.br_blockcount, &i))) |
| 2423 | goto done; | 2393 | goto done; |
| 2424 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2394 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2425 | if ((error = xfs_btree_delete(cur, &i))) | 2395 | if ((error = xfs_btree_delete(cur, &i))) |
| 2426 | goto done; | 2396 | goto done; |
| 2427 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2397 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2428 | if ((error = xfs_btree_decrement(cur, 0, &i))) | 2398 | if ((error = xfs_btree_decrement(cur, 0, &i))) |
| 2429 | goto done; | 2399 | goto done; |
| 2430 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2400 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2431 | if ((error = xfs_btree_delete(cur, &i))) | 2401 | if ((error = xfs_btree_delete(cur, &i))) |
| 2432 | goto done; | 2402 | goto done; |
| 2433 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2403 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2434 | if ((error = xfs_btree_decrement(cur, 0, &i))) | 2404 | if ((error = xfs_btree_decrement(cur, 0, &i))) |
| 2435 | goto done; | 2405 | goto done; |
| 2436 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2406 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2437 | if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, | 2407 | if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, |
| 2438 | LEFT.br_startblock, | 2408 | LEFT.br_startblock, |
| 2439 | LEFT.br_blockcount + PREV.br_blockcount + | 2409 | LEFT.br_blockcount + PREV.br_blockcount + |
| @@ -2464,13 +2434,13 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2464 | PREV.br_startblock, PREV.br_blockcount, | 2434 | PREV.br_startblock, PREV.br_blockcount, |
| 2465 | &i))) | 2435 | &i))) |
| 2466 | goto done; | 2436 | goto done; |
| 2467 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2437 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2468 | if ((error = xfs_btree_delete(cur, &i))) | 2438 | if ((error = xfs_btree_delete(cur, &i))) |
| 2469 | goto done; | 2439 | goto done; |
| 2470 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2440 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2471 | if ((error = xfs_btree_decrement(cur, 0, &i))) | 2441 | if ((error = xfs_btree_decrement(cur, 0, &i))) |
| 2472 | goto done; | 2442 | goto done; |
| 2473 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2443 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2474 | if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, | 2444 | if ((error = xfs_bmbt_update(cur, LEFT.br_startoff, |
| 2475 | LEFT.br_startblock, | 2445 | LEFT.br_startblock, |
| 2476 | LEFT.br_blockcount + PREV.br_blockcount, | 2446 | LEFT.br_blockcount + PREV.br_blockcount, |
| @@ -2499,13 +2469,13 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2499 | RIGHT.br_startblock, | 2469 | RIGHT.br_startblock, |
| 2500 | RIGHT.br_blockcount, &i))) | 2470 | RIGHT.br_blockcount, &i))) |
| 2501 | goto done; | 2471 | goto done; |
| 2502 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2472 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2503 | if ((error = xfs_btree_delete(cur, &i))) | 2473 | if ((error = xfs_btree_delete(cur, &i))) |
| 2504 | goto done; | 2474 | goto done; |
| 2505 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2475 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2506 | if ((error = xfs_btree_decrement(cur, 0, &i))) | 2476 | if ((error = xfs_btree_decrement(cur, 0, &i))) |
| 2507 | goto done; | 2477 | goto done; |
| 2508 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2478 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2509 | if ((error = xfs_bmbt_update(cur, new->br_startoff, | 2479 | if ((error = xfs_bmbt_update(cur, new->br_startoff, |
| 2510 | new->br_startblock, | 2480 | new->br_startblock, |
| 2511 | new->br_blockcount + RIGHT.br_blockcount, | 2481 | new->br_blockcount + RIGHT.br_blockcount, |
| @@ -2532,7 +2502,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2532 | new->br_startblock, new->br_blockcount, | 2502 | new->br_startblock, new->br_blockcount, |
| 2533 | &i))) | 2503 | &i))) |
| 2534 | goto done; | 2504 | goto done; |
| 2535 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2505 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2536 | if ((error = xfs_bmbt_update(cur, new->br_startoff, | 2506 | if ((error = xfs_bmbt_update(cur, new->br_startoff, |
| 2537 | new->br_startblock, new->br_blockcount, | 2507 | new->br_startblock, new->br_blockcount, |
| 2538 | newext))) | 2508 | newext))) |
| @@ -2569,7 +2539,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2569 | PREV.br_startblock, PREV.br_blockcount, | 2539 | PREV.br_startblock, PREV.br_blockcount, |
| 2570 | &i))) | 2540 | &i))) |
| 2571 | goto done; | 2541 | goto done; |
| 2572 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2542 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2573 | if ((error = xfs_bmbt_update(cur, | 2543 | if ((error = xfs_bmbt_update(cur, |
| 2574 | PREV.br_startoff + new->br_blockcount, | 2544 | PREV.br_startoff + new->br_blockcount, |
| 2575 | PREV.br_startblock + new->br_blockcount, | 2545 | PREV.br_startblock + new->br_blockcount, |
| @@ -2611,7 +2581,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2611 | PREV.br_startblock, PREV.br_blockcount, | 2581 | PREV.br_startblock, PREV.br_blockcount, |
| 2612 | &i))) | 2582 | &i))) |
| 2613 | goto done; | 2583 | goto done; |
| 2614 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2584 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2615 | if ((error = xfs_bmbt_update(cur, | 2585 | if ((error = xfs_bmbt_update(cur, |
| 2616 | PREV.br_startoff + new->br_blockcount, | 2586 | PREV.br_startoff + new->br_blockcount, |
| 2617 | PREV.br_startblock + new->br_blockcount, | 2587 | PREV.br_startblock + new->br_blockcount, |
| @@ -2621,7 +2591,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2621 | cur->bc_rec.b = *new; | 2591 | cur->bc_rec.b = *new; |
| 2622 | if ((error = xfs_btree_insert(cur, &i))) | 2592 | if ((error = xfs_btree_insert(cur, &i))) |
| 2623 | goto done; | 2593 | goto done; |
| 2624 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2594 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2625 | } | 2595 | } |
| 2626 | break; | 2596 | break; |
| 2627 | 2597 | ||
| @@ -2651,7 +2621,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2651 | PREV.br_startblock, | 2621 | PREV.br_startblock, |
| 2652 | PREV.br_blockcount, &i))) | 2622 | PREV.br_blockcount, &i))) |
| 2653 | goto done; | 2623 | goto done; |
| 2654 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2624 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2655 | if ((error = xfs_bmbt_update(cur, PREV.br_startoff, | 2625 | if ((error = xfs_bmbt_update(cur, PREV.br_startoff, |
| 2656 | PREV.br_startblock, | 2626 | PREV.br_startblock, |
| 2657 | PREV.br_blockcount - new->br_blockcount, | 2627 | PREV.br_blockcount - new->br_blockcount, |
| @@ -2689,7 +2659,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2689 | PREV.br_startblock, PREV.br_blockcount, | 2659 | PREV.br_startblock, PREV.br_blockcount, |
| 2690 | &i))) | 2660 | &i))) |
| 2691 | goto done; | 2661 | goto done; |
| 2692 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2662 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2693 | if ((error = xfs_bmbt_update(cur, PREV.br_startoff, | 2663 | if ((error = xfs_bmbt_update(cur, PREV.br_startoff, |
| 2694 | PREV.br_startblock, | 2664 | PREV.br_startblock, |
| 2695 | PREV.br_blockcount - new->br_blockcount, | 2665 | PREV.br_blockcount - new->br_blockcount, |
| @@ -2699,11 +2669,11 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2699 | new->br_startblock, new->br_blockcount, | 2669 | new->br_startblock, new->br_blockcount, |
| 2700 | &i))) | 2670 | &i))) |
| 2701 | goto done; | 2671 | goto done; |
| 2702 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 2672 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 2703 | cur->bc_rec.b.br_state = XFS_EXT_NORM; | 2673 | cur->bc_rec.b.br_state = XFS_EXT_NORM; |
| 2704 | if ((error = xfs_btree_insert(cur, &i))) | 2674 | if ((error = xfs_btree_insert(cur, &i))) |
| 2705 | goto done; | 2675 | goto done; |
| 2706 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2676 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2707 | } | 2677 | } |
| 2708 | break; | 2678 | break; |
| 2709 | 2679 | ||
| @@ -2737,7 +2707,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2737 | PREV.br_startblock, PREV.br_blockcount, | 2707 | PREV.br_startblock, PREV.br_blockcount, |
| 2738 | &i))) | 2708 | &i))) |
| 2739 | goto done; | 2709 | goto done; |
| 2740 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2710 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2741 | /* new right extent - oldext */ | 2711 | /* new right extent - oldext */ |
| 2742 | if ((error = xfs_bmbt_update(cur, r[1].br_startoff, | 2712 | if ((error = xfs_bmbt_update(cur, r[1].br_startoff, |
| 2743 | r[1].br_startblock, r[1].br_blockcount, | 2713 | r[1].br_startblock, r[1].br_blockcount, |
| @@ -2749,7 +2719,7 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2749 | new->br_startoff - PREV.br_startoff; | 2719 | new->br_startoff - PREV.br_startoff; |
| 2750 | if ((error = xfs_btree_insert(cur, &i))) | 2720 | if ((error = xfs_btree_insert(cur, &i))) |
| 2751 | goto done; | 2721 | goto done; |
| 2752 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2722 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2753 | /* | 2723 | /* |
| 2754 | * Reset the cursor to the position of the new extent | 2724 | * Reset the cursor to the position of the new extent |
| 2755 | * we are about to insert as we can't trust it after | 2725 | * we are about to insert as we can't trust it after |
| @@ -2759,12 +2729,12 @@ xfs_bmap_add_extent_unwritten_real( | |||
| 2759 | new->br_startblock, new->br_blockcount, | 2729 | new->br_startblock, new->br_blockcount, |
| 2760 | &i))) | 2730 | &i))) |
| 2761 | goto done; | 2731 | goto done; |
| 2762 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 2732 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 2763 | /* new middle extent - newext */ | 2733 | /* new middle extent - newext */ |
| 2764 | cur->bc_rec.b.br_state = new->br_state; | 2734 | cur->bc_rec.b.br_state = new->br_state; |
| 2765 | if ((error = xfs_btree_insert(cur, &i))) | 2735 | if ((error = xfs_btree_insert(cur, &i))) |
| 2766 | goto done; | 2736 | goto done; |
| 2767 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 2737 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 2768 | } | 2738 | } |
| 2769 | break; | 2739 | break; |
| 2770 | 2740 | ||
| @@ -2944,8 +2914,8 @@ xfs_bmap_add_extent_hole_delay( | |||
| 2944 | } | 2914 | } |
| 2945 | if (oldlen != newlen) { | 2915 | if (oldlen != newlen) { |
| 2946 | ASSERT(oldlen > newlen); | 2916 | ASSERT(oldlen > newlen); |
| 2947 | xfs_icsb_modify_counters(ip->i_mount, XFS_SBS_FDBLOCKS, | 2917 | xfs_mod_fdblocks(ip->i_mount, (int64_t)(oldlen - newlen), |
| 2948 | (int64_t)(oldlen - newlen), 0); | 2918 | false); |
| 2949 | /* | 2919 | /* |
| 2950 | * Nothing to do for disk quota accounting here. | 2920 | * Nothing to do for disk quota accounting here. |
| 2951 | */ | 2921 | */ |
| @@ -2968,7 +2938,9 @@ xfs_bmap_add_extent_hole_real( | |||
| 2968 | xfs_bmbt_irec_t right; /* right neighbor extent entry */ | 2938 | xfs_bmbt_irec_t right; /* right neighbor extent entry */ |
| 2969 | int rval=0; /* return value (logging flags) */ | 2939 | int rval=0; /* return value (logging flags) */ |
| 2970 | int state; /* state bits, accessed thru macros */ | 2940 | int state; /* state bits, accessed thru macros */ |
| 2941 | struct xfs_mount *mp; | ||
| 2971 | 2942 | ||
| 2943 | mp = bma->tp ? bma->tp->t_mountp : NULL; | ||
| 2972 | ifp = XFS_IFORK_PTR(bma->ip, whichfork); | 2944 | ifp = XFS_IFORK_PTR(bma->ip, whichfork); |
| 2973 | 2945 | ||
| 2974 | ASSERT(bma->idx >= 0); | 2946 | ASSERT(bma->idx >= 0); |
| @@ -3056,15 +3028,15 @@ xfs_bmap_add_extent_hole_real( | |||
| 3056 | &i); | 3028 | &i); |
| 3057 | if (error) | 3029 | if (error) |
| 3058 | goto done; | 3030 | goto done; |
| 3059 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 3031 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 3060 | error = xfs_btree_delete(bma->cur, &i); | 3032 | error = xfs_btree_delete(bma->cur, &i); |
| 3061 | if (error) | 3033 | if (error) |
| 3062 | goto done; | 3034 | goto done; |
| 3063 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 3035 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 3064 | error = xfs_btree_decrement(bma->cur, 0, &i); | 3036 | error = xfs_btree_decrement(bma->cur, 0, &i); |
| 3065 | if (error) | 3037 | if (error) |
| 3066 | goto done; | 3038 | goto done; |
| 3067 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 3039 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 3068 | error = xfs_bmbt_update(bma->cur, left.br_startoff, | 3040 | error = xfs_bmbt_update(bma->cur, left.br_startoff, |
| 3069 | left.br_startblock, | 3041 | left.br_startblock, |
| 3070 | left.br_blockcount + | 3042 | left.br_blockcount + |
| @@ -3097,7 +3069,7 @@ xfs_bmap_add_extent_hole_real( | |||
| 3097 | &i); | 3069 | &i); |
| 3098 | if (error) | 3070 | if (error) |
| 3099 | goto done; | 3071 | goto done; |
| 3100 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 3072 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 3101 | error = xfs_bmbt_update(bma->cur, left.br_startoff, | 3073 | error = xfs_bmbt_update(bma->cur, left.br_startoff, |
| 3102 | left.br_startblock, | 3074 | left.br_startblock, |
| 3103 | left.br_blockcount + | 3075 | left.br_blockcount + |
| @@ -3131,7 +3103,7 @@ xfs_bmap_add_extent_hole_real( | |||
| 3131 | right.br_blockcount, &i); | 3103 | right.br_blockcount, &i); |
| 3132 | if (error) | 3104 | if (error) |
| 3133 | goto done; | 3105 | goto done; |
| 3134 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 3106 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 3135 | error = xfs_bmbt_update(bma->cur, new->br_startoff, | 3107 | error = xfs_bmbt_update(bma->cur, new->br_startoff, |
| 3136 | new->br_startblock, | 3108 | new->br_startblock, |
| 3137 | new->br_blockcount + | 3109 | new->br_blockcount + |
| @@ -3161,12 +3133,12 @@ xfs_bmap_add_extent_hole_real( | |||
| 3161 | new->br_blockcount, &i); | 3133 | new->br_blockcount, &i); |
| 3162 | if (error) | 3134 | if (error) |
| 3163 | goto done; | 3135 | goto done; |
| 3164 | XFS_WANT_CORRUPTED_GOTO(i == 0, done); | 3136 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, done); |
| 3165 | bma->cur->bc_rec.b.br_state = new->br_state; | 3137 | bma->cur->bc_rec.b.br_state = new->br_state; |
| 3166 | error = xfs_btree_insert(bma->cur, &i); | 3138 | error = xfs_btree_insert(bma->cur, &i); |
| 3167 | if (error) | 3139 | if (error) |
| 3168 | goto done; | 3140 | goto done; |
| 3169 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 3141 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 3170 | } | 3142 | } |
| 3171 | break; | 3143 | break; |
| 3172 | } | 3144 | } |
| @@ -4160,18 +4132,15 @@ xfs_bmapi_reserve_delalloc( | |||
| 4160 | ASSERT(indlen > 0); | 4132 | ASSERT(indlen > 0); |
| 4161 | 4133 | ||
| 4162 | if (rt) { | 4134 | if (rt) { |
| 4163 | error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, | 4135 | error = xfs_mod_frextents(mp, -((int64_t)extsz)); |
| 4164 | -((int64_t)extsz), 0); | ||
| 4165 | } else { | 4136 | } else { |
| 4166 | error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | 4137 | error = xfs_mod_fdblocks(mp, -((int64_t)alen), false); |
| 4167 | -((int64_t)alen), 0); | ||
| 4168 | } | 4138 | } |
| 4169 | 4139 | ||
| 4170 | if (error) | 4140 | if (error) |
| 4171 | goto out_unreserve_quota; | 4141 | goto out_unreserve_quota; |
| 4172 | 4142 | ||
| 4173 | error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | 4143 | error = xfs_mod_fdblocks(mp, -((int64_t)indlen), false); |
| 4174 | -((int64_t)indlen), 0); | ||
| 4175 | if (error) | 4144 | if (error) |
| 4176 | goto out_unreserve_blocks; | 4145 | goto out_unreserve_blocks; |
| 4177 | 4146 | ||
| @@ -4198,9 +4167,9 @@ xfs_bmapi_reserve_delalloc( | |||
| 4198 | 4167 | ||
| 4199 | out_unreserve_blocks: | 4168 | out_unreserve_blocks: |
| 4200 | if (rt) | 4169 | if (rt) |
| 4201 | xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0); | 4170 | xfs_mod_frextents(mp, extsz); |
| 4202 | else | 4171 | else |
| 4203 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, alen, 0); | 4172 | xfs_mod_fdblocks(mp, alen, false); |
| 4204 | out_unreserve_quota: | 4173 | out_unreserve_quota: |
| 4205 | if (XFS_IS_QUOTA_ON(mp)) | 4174 | if (XFS_IS_QUOTA_ON(mp)) |
| 4206 | xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ? | 4175 | xfs_trans_unreserve_quota_nblks(NULL, ip, (long)alen, 0, rt ? |
| @@ -4801,7 +4770,7 @@ xfs_bmap_del_extent( | |||
| 4801 | got.br_startblock, got.br_blockcount, | 4770 | got.br_startblock, got.br_blockcount, |
| 4802 | &i))) | 4771 | &i))) |
| 4803 | goto done; | 4772 | goto done; |
| 4804 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 4773 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 4805 | } | 4774 | } |
| 4806 | da_old = da_new = 0; | 4775 | da_old = da_new = 0; |
| 4807 | } else { | 4776 | } else { |
| @@ -4835,7 +4804,7 @@ xfs_bmap_del_extent( | |||
| 4835 | } | 4804 | } |
| 4836 | if ((error = xfs_btree_delete(cur, &i))) | 4805 | if ((error = xfs_btree_delete(cur, &i))) |
| 4837 | goto done; | 4806 | goto done; |
| 4838 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 4807 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 4839 | break; | 4808 | break; |
| 4840 | 4809 | ||
| 4841 | case 2: | 4810 | case 2: |
| @@ -4935,7 +4904,8 @@ xfs_bmap_del_extent( | |||
| 4935 | got.br_startblock, | 4904 | got.br_startblock, |
| 4936 | temp, &i))) | 4905 | temp, &i))) |
| 4937 | goto done; | 4906 | goto done; |
| 4938 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 4907 | XFS_WANT_CORRUPTED_GOTO(mp, |
| 4908 | i == 1, done); | ||
| 4939 | /* | 4909 | /* |
| 4940 | * Update the btree record back | 4910 | * Update the btree record back |
| 4941 | * to the original value. | 4911 | * to the original value. |
| @@ -4956,7 +4926,7 @@ xfs_bmap_del_extent( | |||
| 4956 | error = -ENOSPC; | 4926 | error = -ENOSPC; |
| 4957 | goto done; | 4927 | goto done; |
| 4958 | } | 4928 | } |
| 4959 | XFS_WANT_CORRUPTED_GOTO(i == 1, done); | 4929 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); |
| 4960 | } else | 4930 | } else |
| 4961 | flags |= xfs_ilog_fext(whichfork); | 4931 | flags |= xfs_ilog_fext(whichfork); |
| 4962 | XFS_IFORK_NEXT_SET(ip, whichfork, | 4932 | XFS_IFORK_NEXT_SET(ip, whichfork, |
| @@ -5012,10 +4982,8 @@ xfs_bmap_del_extent( | |||
| 5012 | * Nothing to do for disk quota accounting here. | 4982 | * Nothing to do for disk quota accounting here. |
| 5013 | */ | 4983 | */ |
| 5014 | ASSERT(da_old >= da_new); | 4984 | ASSERT(da_old >= da_new); |
| 5015 | if (da_old > da_new) { | 4985 | if (da_old > da_new) |
| 5016 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | 4986 | xfs_mod_fdblocks(mp, (int64_t)(da_old - da_new), false); |
| 5017 | (int64_t)(da_old - da_new), 0); | ||
| 5018 | } | ||
| 5019 | done: | 4987 | done: |
| 5020 | *logflagsp = flags; | 4988 | *logflagsp = flags; |
| 5021 | return error; | 4989 | return error; |
| @@ -5284,14 +5252,13 @@ xfs_bunmapi( | |||
| 5284 | 5252 | ||
| 5285 | rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); | 5253 | rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); |
| 5286 | do_div(rtexts, mp->m_sb.sb_rextsize); | 5254 | do_div(rtexts, mp->m_sb.sb_rextsize); |
| 5287 | xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, | 5255 | xfs_mod_frextents(mp, (int64_t)rtexts); |
| 5288 | (int64_t)rtexts, 0); | ||
| 5289 | (void)xfs_trans_reserve_quota_nblks(NULL, | 5256 | (void)xfs_trans_reserve_quota_nblks(NULL, |
| 5290 | ip, -((long)del.br_blockcount), 0, | 5257 | ip, -((long)del.br_blockcount), 0, |
| 5291 | XFS_QMOPT_RES_RTBLKS); | 5258 | XFS_QMOPT_RES_RTBLKS); |
| 5292 | } else { | 5259 | } else { |
| 5293 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | 5260 | xfs_mod_fdblocks(mp, (int64_t)del.br_blockcount, |
| 5294 | (int64_t)del.br_blockcount, 0); | 5261 | false); |
| 5295 | (void)xfs_trans_reserve_quota_nblks(NULL, | 5262 | (void)xfs_trans_reserve_quota_nblks(NULL, |
| 5296 | ip, -((long)del.br_blockcount), 0, | 5263 | ip, -((long)del.br_blockcount), 0, |
| 5297 | XFS_QMOPT_RES_REGBLKS); | 5264 | XFS_QMOPT_RES_REGBLKS); |
| @@ -5453,6 +5420,7 @@ xfs_bmse_merge( | |||
| 5453 | struct xfs_bmbt_irec left; | 5420 | struct xfs_bmbt_irec left; |
| 5454 | xfs_filblks_t blockcount; | 5421 | xfs_filblks_t blockcount; |
| 5455 | int error, i; | 5422 | int error, i; |
| 5423 | struct xfs_mount *mp = ip->i_mount; | ||
| 5456 | 5424 | ||
| 5457 | xfs_bmbt_get_all(gotp, &got); | 5425 | xfs_bmbt_get_all(gotp, &got); |
| 5458 | xfs_bmbt_get_all(leftp, &left); | 5426 | xfs_bmbt_get_all(leftp, &left); |
| @@ -5487,19 +5455,19 @@ xfs_bmse_merge( | |||
| 5487 | got.br_blockcount, &i); | 5455 | got.br_blockcount, &i); |
| 5488 | if (error) | 5456 | if (error) |
| 5489 | return error; | 5457 | return error; |
| 5490 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 5458 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 5491 | 5459 | ||
| 5492 | error = xfs_btree_delete(cur, &i); | 5460 | error = xfs_btree_delete(cur, &i); |
| 5493 | if (error) | 5461 | if (error) |
| 5494 | return error; | 5462 | return error; |
| 5495 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 5463 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 5496 | 5464 | ||
| 5497 | /* lookup and update size of the previous extent */ | 5465 | /* lookup and update size of the previous extent */ |
| 5498 | error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, | 5466 | error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock, |
| 5499 | left.br_blockcount, &i); | 5467 | left.br_blockcount, &i); |
| 5500 | if (error) | 5468 | if (error) |
| 5501 | return error; | 5469 | return error; |
| 5502 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 5470 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 5503 | 5471 | ||
| 5504 | left.br_blockcount = blockcount; | 5472 | left.br_blockcount = blockcount; |
| 5505 | 5473 | ||
| @@ -5518,50 +5486,92 @@ xfs_bmse_shift_one( | |||
| 5518 | int *current_ext, | 5486 | int *current_ext, |
| 5519 | struct xfs_bmbt_rec_host *gotp, | 5487 | struct xfs_bmbt_rec_host *gotp, |
| 5520 | struct xfs_btree_cur *cur, | 5488 | struct xfs_btree_cur *cur, |
| 5521 | int *logflags) | 5489 | int *logflags, |
| 5490 | enum shift_direction direction) | ||
| 5522 | { | 5491 | { |
| 5523 | struct xfs_ifork *ifp; | 5492 | struct xfs_ifork *ifp; |
| 5493 | struct xfs_mount *mp; | ||
| 5524 | xfs_fileoff_t startoff; | 5494 | xfs_fileoff_t startoff; |
| 5525 | struct xfs_bmbt_rec_host *leftp; | 5495 | struct xfs_bmbt_rec_host *adj_irecp; |
| 5526 | struct xfs_bmbt_irec got; | 5496 | struct xfs_bmbt_irec got; |
| 5527 | struct xfs_bmbt_irec left; | 5497 | struct xfs_bmbt_irec adj_irec; |
| 5528 | int error; | 5498 | int error; |
| 5529 | int i; | 5499 | int i; |
| 5500 | int total_extents; | ||
| 5530 | 5501 | ||
| 5502 | mp = ip->i_mount; | ||
| 5531 | ifp = XFS_IFORK_PTR(ip, whichfork); | 5503 | ifp = XFS_IFORK_PTR(ip, whichfork); |
| 5504 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | ||
| 5532 | 5505 | ||
| 5533 | xfs_bmbt_get_all(gotp, &got); | 5506 | xfs_bmbt_get_all(gotp, &got); |
| 5534 | startoff = got.br_startoff - offset_shift_fsb; | ||
| 5535 | 5507 | ||
| 5536 | /* delalloc extents should be prevented by caller */ | 5508 | /* delalloc extents should be prevented by caller */ |
| 5537 | XFS_WANT_CORRUPTED_RETURN(!isnullstartblock(got.br_startblock)); | 5509 | XFS_WANT_CORRUPTED_RETURN(mp, !isnullstartblock(got.br_startblock)); |
| 5538 | 5510 | ||
| 5539 | /* | 5511 | if (direction == SHIFT_LEFT) { |
| 5540 | * Check for merge if we've got an extent to the left, otherwise make | 5512 | startoff = got.br_startoff - offset_shift_fsb; |
| 5541 | * sure there's enough room at the start of the file for the shift. | 5513 | |
| 5542 | */ | 5514 | /* |
| 5543 | if (*current_ext) { | 5515 | * Check for merge if we've got an extent to the left, |
| 5544 | /* grab the left extent and check for a large enough hole */ | 5516 | * otherwise make sure there's enough room at the start |
| 5545 | leftp = xfs_iext_get_ext(ifp, *current_ext - 1); | 5517 | * of the file for the shift. |
| 5546 | xfs_bmbt_get_all(leftp, &left); | 5518 | */ |
| 5519 | if (!*current_ext) { | ||
| 5520 | if (got.br_startoff < offset_shift_fsb) | ||
| 5521 | return -EINVAL; | ||
| 5522 | goto update_current_ext; | ||
| 5523 | } | ||
| 5524 | /* | ||
| 5525 | * grab the left extent and check for a large | ||
| 5526 | * enough hole. | ||
| 5527 | */ | ||
| 5528 | adj_irecp = xfs_iext_get_ext(ifp, *current_ext - 1); | ||
| 5529 | xfs_bmbt_get_all(adj_irecp, &adj_irec); | ||
| 5547 | 5530 | ||
| 5548 | if (startoff < left.br_startoff + left.br_blockcount) | 5531 | if (startoff < |
| 5532 | adj_irec.br_startoff + adj_irec.br_blockcount) | ||
| 5549 | return -EINVAL; | 5533 | return -EINVAL; |
| 5550 | 5534 | ||
| 5551 | /* check whether to merge the extent or shift it down */ | 5535 | /* check whether to merge the extent or shift it down */ |
| 5552 | if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) { | 5536 | if (xfs_bmse_can_merge(&adj_irec, &got, |
| 5537 | offset_shift_fsb)) { | ||
| 5553 | return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, | 5538 | return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, |
| 5554 | *current_ext, gotp, leftp, cur, | 5539 | *current_ext, gotp, adj_irecp, |
| 5555 | logflags); | 5540 | cur, logflags); |
| 5556 | } | 5541 | } |
| 5557 | } else if (got.br_startoff < offset_shift_fsb) | 5542 | } else { |
| 5558 | return -EINVAL; | 5543 | startoff = got.br_startoff + offset_shift_fsb; |
| 5559 | 5544 | /* nothing to move if this is the last extent */ | |
| 5545 | if (*current_ext >= (total_extents - 1)) | ||
| 5546 | goto update_current_ext; | ||
| 5547 | /* | ||
| 5548 | * If this is not the last extent in the file, make sure there | ||
| 5549 | * is enough room between current extent and next extent for | ||
| 5550 | * accommodating the shift. | ||
| 5551 | */ | ||
| 5552 | adj_irecp = xfs_iext_get_ext(ifp, *current_ext + 1); | ||
| 5553 | xfs_bmbt_get_all(adj_irecp, &adj_irec); | ||
| 5554 | if (startoff + got.br_blockcount > adj_irec.br_startoff) | ||
| 5555 | return -EINVAL; | ||
| 5556 | /* | ||
| 5557 | * Unlike a left shift (which involves a hole punch), | ||
| 5558 | * a right shift does not modify extent neighbors | ||
| 5559 | * in any way. We should never find mergeable extents | ||
| 5560 | * in this scenario. Check anyways and warn if we | ||
| 5561 | * encounter two extents that could be one. | ||
| 5562 | */ | ||
| 5563 | if (xfs_bmse_can_merge(&got, &adj_irec, offset_shift_fsb)) | ||
| 5564 | WARN_ON_ONCE(1); | ||
| 5565 | } | ||
| 5560 | /* | 5566 | /* |
| 5561 | * Increment the extent index for the next iteration, update the start | 5567 | * Increment the extent index for the next iteration, update the start |
| 5562 | * offset of the in-core extent and update the btree if applicable. | 5568 | * offset of the in-core extent and update the btree if applicable. |
| 5563 | */ | 5569 | */ |
| 5564 | (*current_ext)++; | 5570 | update_current_ext: |
| 5571 | if (direction == SHIFT_LEFT) | ||
| 5572 | (*current_ext)++; | ||
| 5573 | else | ||
| 5574 | (*current_ext)--; | ||
| 5565 | xfs_bmbt_set_startoff(gotp, startoff); | 5575 | xfs_bmbt_set_startoff(gotp, startoff); |
| 5566 | *logflags |= XFS_ILOG_CORE; | 5576 | *logflags |= XFS_ILOG_CORE; |
| 5567 | if (!cur) { | 5577 | if (!cur) { |
| @@ -5573,18 +5583,18 @@ xfs_bmse_shift_one( | |||
| 5573 | got.br_blockcount, &i); | 5583 | got.br_blockcount, &i); |
| 5574 | if (error) | 5584 | if (error) |
| 5575 | return error; | 5585 | return error; |
| 5576 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 5586 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 5577 | 5587 | ||
| 5578 | got.br_startoff = startoff; | 5588 | got.br_startoff = startoff; |
| 5579 | return xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, | 5589 | return xfs_bmbt_update(cur, got.br_startoff, got.br_startblock, |
| 5580 | got.br_blockcount, got.br_state); | 5590 | got.br_blockcount, got.br_state); |
| 5581 | } | 5591 | } |
| 5582 | 5592 | ||
| 5583 | /* | 5593 | /* |
| 5584 | * Shift extent records to the left to cover a hole. | 5594 | * Shift extent records to the left/right to cover/create a hole. |
| 5585 | * | 5595 | * |
| 5586 | * The maximum number of extents to be shifted in a single operation is | 5596 | * The maximum number of extents to be shifted in a single operation is |
| 5587 | * @num_exts. @start_fsb specifies the file offset to start the shift and the | 5597 | * @num_exts. @stop_fsb specifies the file offset at which to stop shift and the |
| 5588 | * file offset where we've left off is returned in @next_fsb. @offset_shift_fsb | 5598 | * file offset where we've left off is returned in @next_fsb. @offset_shift_fsb |
| 5589 | * is the length by which each extent is shifted. If there is no hole to shift | 5599 | * is the length by which each extent is shifted. If there is no hole to shift |
| 5590 | * the extents into, this will be considered invalid operation and we abort | 5600 | * the extents into, this will be considered invalid operation and we abort |
| @@ -5594,12 +5604,13 @@ int | |||
| 5594 | xfs_bmap_shift_extents( | 5604 | xfs_bmap_shift_extents( |
| 5595 | struct xfs_trans *tp, | 5605 | struct xfs_trans *tp, |
| 5596 | struct xfs_inode *ip, | 5606 | struct xfs_inode *ip, |
| 5597 | xfs_fileoff_t start_fsb, | 5607 | xfs_fileoff_t *next_fsb, |
| 5598 | xfs_fileoff_t offset_shift_fsb, | 5608 | xfs_fileoff_t offset_shift_fsb, |
| 5599 | int *done, | 5609 | int *done, |
| 5600 | xfs_fileoff_t *next_fsb, | 5610 | xfs_fileoff_t stop_fsb, |
| 5601 | xfs_fsblock_t *firstblock, | 5611 | xfs_fsblock_t *firstblock, |
| 5602 | struct xfs_bmap_free *flist, | 5612 | struct xfs_bmap_free *flist, |
| 5613 | enum shift_direction direction, | ||
| 5603 | int num_exts) | 5614 | int num_exts) |
| 5604 | { | 5615 | { |
| 5605 | struct xfs_btree_cur *cur = NULL; | 5616 | struct xfs_btree_cur *cur = NULL; |
| @@ -5609,10 +5620,11 @@ xfs_bmap_shift_extents( | |||
| 5609 | struct xfs_ifork *ifp; | 5620 | struct xfs_ifork *ifp; |
| 5610 | xfs_extnum_t nexts = 0; | 5621 | xfs_extnum_t nexts = 0; |
| 5611 | xfs_extnum_t current_ext; | 5622 | xfs_extnum_t current_ext; |
| 5623 | xfs_extnum_t total_extents; | ||
| 5624 | xfs_extnum_t stop_extent; | ||
| 5612 | int error = 0; | 5625 | int error = 0; |
| 5613 | int whichfork = XFS_DATA_FORK; | 5626 | int whichfork = XFS_DATA_FORK; |
| 5614 | int logflags = 0; | 5627 | int logflags = 0; |
| 5615 | int total_extents; | ||
| 5616 | 5628 | ||
| 5617 | if (unlikely(XFS_TEST_ERROR( | 5629 | if (unlikely(XFS_TEST_ERROR( |
| 5618 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && | 5630 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && |
| @@ -5628,6 +5640,8 @@ xfs_bmap_shift_extents( | |||
| 5628 | 5640 | ||
| 5629 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | 5641 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
| 5630 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 5642 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
| 5643 | ASSERT(direction == SHIFT_LEFT || direction == SHIFT_RIGHT); | ||
| 5644 | ASSERT(*next_fsb != NULLFSBLOCK || direction == SHIFT_RIGHT); | ||
| 5631 | 5645 | ||
| 5632 | ifp = XFS_IFORK_PTR(ip, whichfork); | 5646 | ifp = XFS_IFORK_PTR(ip, whichfork); |
| 5633 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { | 5647 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { |
| @@ -5645,43 +5659,83 @@ xfs_bmap_shift_extents( | |||
| 5645 | } | 5659 | } |
| 5646 | 5660 | ||
| 5647 | /* | 5661 | /* |
| 5662 | * There may be delalloc extents in the data fork before the range we | ||
| 5663 | * are collapsing out, so we cannot use the count of real extents here. | ||
| 5664 | * Instead we have to calculate it from the incore fork. | ||
| 5665 | */ | ||
| 5666 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | ||
| 5667 | if (total_extents == 0) { | ||
| 5668 | *done = 1; | ||
| 5669 | goto del_cursor; | ||
| 5670 | } | ||
| 5671 | |||
| 5672 | /* | ||
| 5673 | * In case of first right shift, we need to initialize next_fsb | ||
| 5674 | */ | ||
| 5675 | if (*next_fsb == NULLFSBLOCK) { | ||
| 5676 | gotp = xfs_iext_get_ext(ifp, total_extents - 1); | ||
| 5677 | xfs_bmbt_get_all(gotp, &got); | ||
| 5678 | *next_fsb = got.br_startoff; | ||
| 5679 | if (stop_fsb > *next_fsb) { | ||
| 5680 | *done = 1; | ||
| 5681 | goto del_cursor; | ||
| 5682 | } | ||
| 5683 | } | ||
| 5684 | |||
| 5685 | /* Lookup the extent index at which we have to stop */ | ||
| 5686 | if (direction == SHIFT_RIGHT) { | ||
| 5687 | gotp = xfs_iext_bno_to_ext(ifp, stop_fsb, &stop_extent); | ||
| 5688 | /* Make stop_extent exclusive of shift range */ | ||
| 5689 | stop_extent--; | ||
| 5690 | } else | ||
| 5691 | stop_extent = total_extents; | ||
| 5692 | |||
| 5693 | /* | ||
| 5648 | * Look up the extent index for the fsb where we start shifting. We can | 5694 | * Look up the extent index for the fsb where we start shifting. We can |
| 5649 | * henceforth iterate with current_ext as extent list changes are locked | 5695 | * henceforth iterate with current_ext as extent list changes are locked |
| 5650 | * out via ilock. | 5696 | * out via ilock. |
| 5651 | * | 5697 | * |
| 5652 | * gotp can be null in 2 cases: 1) if there are no extents or 2) | 5698 | * gotp can be null in 2 cases: 1) if there are no extents or 2) |
| 5653 | * start_fsb lies in a hole beyond which there are no extents. Either | 5699 | * *next_fsb lies in a hole beyond which there are no extents. Either |
| 5654 | * way, we are done. | 5700 | * way, we are done. |
| 5655 | */ | 5701 | */ |
| 5656 | gotp = xfs_iext_bno_to_ext(ifp, start_fsb, ¤t_ext); | 5702 | gotp = xfs_iext_bno_to_ext(ifp, *next_fsb, ¤t_ext); |
| 5657 | if (!gotp) { | 5703 | if (!gotp) { |
| 5658 | *done = 1; | 5704 | *done = 1; |
| 5659 | goto del_cursor; | 5705 | goto del_cursor; |
| 5660 | } | 5706 | } |
| 5661 | 5707 | ||
| 5662 | /* | 5708 | /* some sanity checking before we finally start shifting extents */ |
| 5663 | * There may be delalloc extents in the data fork before the range we | 5709 | if ((direction == SHIFT_LEFT && current_ext >= stop_extent) || |
| 5664 | * are collapsing out, so we cannot use the count of real extents here. | 5710 | (direction == SHIFT_RIGHT && current_ext <= stop_extent)) { |
| 5665 | * Instead we have to calculate it from the incore fork. | 5711 | error = -EIO; |
| 5666 | */ | 5712 | goto del_cursor; |
| 5667 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | 5713 | } |
| 5668 | while (nexts++ < num_exts && current_ext < total_extents) { | 5714 | |
| 5715 | while (nexts++ < num_exts) { | ||
| 5669 | error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, | 5716 | error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, |
| 5670 | ¤t_ext, gotp, cur, &logflags); | 5717 | ¤t_ext, gotp, cur, &logflags, |
| 5718 | direction); | ||
| 5671 | if (error) | 5719 | if (error) |
| 5672 | goto del_cursor; | 5720 | goto del_cursor; |
| 5721 | /* | ||
| 5722 | * If there was an extent merge during the shift, the extent | ||
| 5723 | * count can change. Update the total and grade the next record. | ||
| 5724 | */ | ||
| 5725 | if (direction == SHIFT_LEFT) { | ||
| 5726 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | ||
| 5727 | stop_extent = total_extents; | ||
| 5728 | } | ||
| 5673 | 5729 | ||
| 5674 | /* update total extent count and grab the next record */ | 5730 | if (current_ext == stop_extent) { |
| 5675 | total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); | 5731 | *done = 1; |
| 5676 | if (current_ext >= total_extents) | 5732 | *next_fsb = NULLFSBLOCK; |
| 5677 | break; | 5733 | break; |
| 5734 | } | ||
| 5678 | gotp = xfs_iext_get_ext(ifp, current_ext); | 5735 | gotp = xfs_iext_get_ext(ifp, current_ext); |
| 5679 | } | 5736 | } |
| 5680 | 5737 | ||
| 5681 | /* Check if we are done */ | 5738 | if (!*done) { |
| 5682 | if (current_ext == total_extents) { | ||
| 5683 | *done = 1; | ||
| 5684 | } else if (next_fsb) { | ||
| 5685 | xfs_bmbt_get_all(gotp, &got); | 5739 | xfs_bmbt_get_all(gotp, &got); |
| 5686 | *next_fsb = got.br_startoff; | 5740 | *next_fsb = got.br_startoff; |
| 5687 | } | 5741 | } |
| @@ -5696,3 +5750,189 @@ del_cursor: | |||
| 5696 | 5750 | ||
| 5697 | return error; | 5751 | return error; |
| 5698 | } | 5752 | } |
| 5753 | |||
| 5754 | /* | ||
| 5755 | * Splits an extent into two extents at split_fsb block such that it is | ||
| 5756 | * the first block of the current_ext. @current_ext is a target extent | ||
| 5757 | * to be split. @split_fsb is a block where the extents is split. | ||
| 5758 | * If split_fsb lies in a hole or the first block of extents, just return 0. | ||
| 5759 | */ | ||
| 5760 | STATIC int | ||
| 5761 | xfs_bmap_split_extent_at( | ||
| 5762 | struct xfs_trans *tp, | ||
| 5763 | struct xfs_inode *ip, | ||
| 5764 | xfs_fileoff_t split_fsb, | ||
| 5765 | xfs_fsblock_t *firstfsb, | ||
| 5766 | struct xfs_bmap_free *free_list) | ||
| 5767 | { | ||
| 5768 | int whichfork = XFS_DATA_FORK; | ||
| 5769 | struct xfs_btree_cur *cur = NULL; | ||
| 5770 | struct xfs_bmbt_rec_host *gotp; | ||
| 5771 | struct xfs_bmbt_irec got; | ||
| 5772 | struct xfs_bmbt_irec new; /* split extent */ | ||
| 5773 | struct xfs_mount *mp = ip->i_mount; | ||
| 5774 | struct xfs_ifork *ifp; | ||
| 5775 | xfs_fsblock_t gotblkcnt; /* new block count for got */ | ||
| 5776 | xfs_extnum_t current_ext; | ||
| 5777 | int error = 0; | ||
| 5778 | int logflags = 0; | ||
| 5779 | int i = 0; | ||
| 5780 | |||
| 5781 | if (unlikely(XFS_TEST_ERROR( | ||
| 5782 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && | ||
| 5783 | XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), | ||
| 5784 | mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { | ||
| 5785 | XFS_ERROR_REPORT("xfs_bmap_split_extent_at", | ||
| 5786 | XFS_ERRLEVEL_LOW, mp); | ||
| 5787 | return -EFSCORRUPTED; | ||
| 5788 | } | ||
| 5789 | |||
| 5790 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
| 5791 | return -EIO; | ||
| 5792 | |||
| 5793 | ifp = XFS_IFORK_PTR(ip, whichfork); | ||
| 5794 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { | ||
| 5795 | /* Read in all the extents */ | ||
| 5796 | error = xfs_iread_extents(tp, ip, whichfork); | ||
| 5797 | if (error) | ||
| 5798 | return error; | ||
| 5799 | } | ||
| 5800 | |||
| 5801 | /* | ||
| 5802 | * gotp can be null in 2 cases: 1) if there are no extents | ||
| 5803 | * or 2) split_fsb lies in a hole beyond which there are | ||
| 5804 | * no extents. Either way, we are done. | ||
| 5805 | */ | ||
| 5806 | gotp = xfs_iext_bno_to_ext(ifp, split_fsb, ¤t_ext); | ||
| 5807 | if (!gotp) | ||
| 5808 | return 0; | ||
| 5809 | |||
| 5810 | xfs_bmbt_get_all(gotp, &got); | ||
| 5811 | |||
| 5812 | /* | ||
| 5813 | * Check split_fsb lies in a hole or the start boundary offset | ||
| 5814 | * of the extent. | ||
| 5815 | */ | ||
| 5816 | if (got.br_startoff >= split_fsb) | ||
| 5817 | return 0; | ||
| 5818 | |||
| 5819 | gotblkcnt = split_fsb - got.br_startoff; | ||
| 5820 | new.br_startoff = split_fsb; | ||
| 5821 | new.br_startblock = got.br_startblock + gotblkcnt; | ||
| 5822 | new.br_blockcount = got.br_blockcount - gotblkcnt; | ||
| 5823 | new.br_state = got.br_state; | ||
| 5824 | |||
| 5825 | if (ifp->if_flags & XFS_IFBROOT) { | ||
| 5826 | cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); | ||
| 5827 | cur->bc_private.b.firstblock = *firstfsb; | ||
| 5828 | cur->bc_private.b.flist = free_list; | ||
| 5829 | cur->bc_private.b.flags = 0; | ||
| 5830 | error = xfs_bmbt_lookup_eq(cur, got.br_startoff, | ||
| 5831 | got.br_startblock, | ||
| 5832 | got.br_blockcount, | ||
| 5833 | &i); | ||
| 5834 | if (error) | ||
| 5835 | goto del_cursor; | ||
| 5836 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); | ||
| 5837 | } | ||
| 5838 | |||
| 5839 | xfs_bmbt_set_blockcount(gotp, gotblkcnt); | ||
| 5840 | got.br_blockcount = gotblkcnt; | ||
| 5841 | |||
| 5842 | logflags = XFS_ILOG_CORE; | ||
| 5843 | if (cur) { | ||
| 5844 | error = xfs_bmbt_update(cur, got.br_startoff, | ||
| 5845 | got.br_startblock, | ||
| 5846 | got.br_blockcount, | ||
| 5847 | got.br_state); | ||
| 5848 | if (error) | ||
| 5849 | goto del_cursor; | ||
| 5850 | } else | ||
| 5851 | logflags |= XFS_ILOG_DEXT; | ||
| 5852 | |||
| 5853 | /* Add new extent */ | ||
| 5854 | current_ext++; | ||
| 5855 | xfs_iext_insert(ip, current_ext, 1, &new, 0); | ||
| 5856 | XFS_IFORK_NEXT_SET(ip, whichfork, | ||
| 5857 | XFS_IFORK_NEXTENTS(ip, whichfork) + 1); | ||
| 5858 | |||
| 5859 | if (cur) { | ||
| 5860 | error = xfs_bmbt_lookup_eq(cur, new.br_startoff, | ||
| 5861 | new.br_startblock, new.br_blockcount, | ||
| 5862 | &i); | ||
| 5863 | if (error) | ||
| 5864 | goto del_cursor; | ||
| 5865 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, del_cursor); | ||
| 5866 | cur->bc_rec.b.br_state = new.br_state; | ||
| 5867 | |||
| 5868 | error = xfs_btree_insert(cur, &i); | ||
| 5869 | if (error) | ||
| 5870 | goto del_cursor; | ||
| 5871 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); | ||
| 5872 | } | ||
| 5873 | |||
| 5874 | /* | ||
| 5875 | * Convert to a btree if necessary. | ||
| 5876 | */ | ||
| 5877 | if (xfs_bmap_needs_btree(ip, whichfork)) { | ||
| 5878 | int tmp_logflags; /* partial log flag return val */ | ||
| 5879 | |||
| 5880 | ASSERT(cur == NULL); | ||
| 5881 | error = xfs_bmap_extents_to_btree(tp, ip, firstfsb, free_list, | ||
| 5882 | &cur, 0, &tmp_logflags, whichfork); | ||
| 5883 | logflags |= tmp_logflags; | ||
| 5884 | } | ||
| 5885 | |||
| 5886 | del_cursor: | ||
| 5887 | if (cur) { | ||
| 5888 | cur->bc_private.b.allocated = 0; | ||
| 5889 | xfs_btree_del_cursor(cur, | ||
| 5890 | error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); | ||
| 5891 | } | ||
| 5892 | |||
| 5893 | if (logflags) | ||
| 5894 | xfs_trans_log_inode(tp, ip, logflags); | ||
| 5895 | return error; | ||
| 5896 | } | ||
| 5897 | |||
| 5898 | int | ||
| 5899 | xfs_bmap_split_extent( | ||
| 5900 | struct xfs_inode *ip, | ||
| 5901 | xfs_fileoff_t split_fsb) | ||
| 5902 | { | ||
| 5903 | struct xfs_mount *mp = ip->i_mount; | ||
| 5904 | struct xfs_trans *tp; | ||
| 5905 | struct xfs_bmap_free free_list; | ||
| 5906 | xfs_fsblock_t firstfsb; | ||
| 5907 | int committed; | ||
| 5908 | int error; | ||
| 5909 | |||
| 5910 | tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); | ||
| 5911 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, | ||
| 5912 | XFS_DIOSTRAT_SPACE_RES(mp, 0), 0); | ||
| 5913 | if (error) { | ||
| 5914 | xfs_trans_cancel(tp, 0); | ||
| 5915 | return error; | ||
| 5916 | } | ||
| 5917 | |||
| 5918 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 5919 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
| 5920 | |||
| 5921 | xfs_bmap_init(&free_list, &firstfsb); | ||
| 5922 | |||
| 5923 | error = xfs_bmap_split_extent_at(tp, ip, split_fsb, | ||
| 5924 | &firstfsb, &free_list); | ||
| 5925 | if (error) | ||
| 5926 | goto out; | ||
| 5927 | |||
| 5928 | error = xfs_bmap_finish(&tp, &free_list, &committed); | ||
| 5929 | if (error) | ||
| 5930 | goto out; | ||
| 5931 | |||
| 5932 | return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
| 5933 | |||
| 5934 | |||
| 5935 | out: | ||
| 5936 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
| 5937 | return error; | ||
| 5938 | } | ||
