diff options
Diffstat (limited to 'fs/xfs/libxfs')
| -rw-r--r-- | fs/xfs/libxfs/xfs_alloc.c | 104 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.c | 150 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.h | 6 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 554 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.h | 13 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 24 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_da_btree.c | 8 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_da_format.h | 14 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_dir2_data.c | 39 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_format.h | 62 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 48 | ||||
| -rw-r--r-- | fs/xfs/libxfs/xfs_sb.c | 20 |
12 files changed, 661 insertions, 381 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index a6fbf4472017..516162be1398 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c | |||
| @@ -260,6 +260,7 @@ xfs_alloc_fix_len( | |||
| 260 | rlen = rlen - (k - args->mod); | 260 | rlen = rlen - (k - args->mod); |
| 261 | else | 261 | else |
| 262 | rlen = rlen - args->prod + (args->mod - k); | 262 | rlen = rlen - args->prod + (args->mod - k); |
| 263 | /* casts to (int) catch length underflows */ | ||
| 263 | if ((int)rlen < (int)args->minlen) | 264 | if ((int)rlen < (int)args->minlen) |
| 264 | return; | 265 | return; |
| 265 | ASSERT(rlen >= args->minlen && rlen <= args->maxlen); | 266 | ASSERT(rlen >= args->minlen && rlen <= args->maxlen); |
| @@ -286,7 +287,8 @@ xfs_alloc_fix_minleft( | |||
| 286 | if (diff >= 0) | 287 | if (diff >= 0) |
| 287 | return 1; | 288 | return 1; |
| 288 | args->len += diff; /* shrink the allocated space */ | 289 | args->len += diff; /* shrink the allocated space */ |
| 289 | if (args->len >= args->minlen) | 290 | /* casts to (int) catch length underflows */ |
| 291 | if ((int)args->len >= (int)args->minlen) | ||
| 290 | return 1; | 292 | return 1; |
| 291 | args->agbno = NULLAGBLOCK; | 293 | args->agbno = NULLAGBLOCK; |
| 292 | return 0; | 294 | return 0; |
| @@ -315,6 +317,9 @@ xfs_alloc_fixup_trees( | |||
| 315 | xfs_agblock_t nfbno2; /* second new free startblock */ | 317 | xfs_agblock_t nfbno2; /* second new free startblock */ |
| 316 | xfs_extlen_t nflen1=0; /* first new free length */ | 318 | xfs_extlen_t nflen1=0; /* first new free length */ |
| 317 | xfs_extlen_t nflen2=0; /* second new free length */ | 319 | xfs_extlen_t nflen2=0; /* second new free length */ |
| 320 | struct xfs_mount *mp; | ||
| 321 | |||
| 322 | mp = cnt_cur->bc_mp; | ||
| 318 | 323 | ||
| 319 | /* | 324 | /* |
| 320 | * Look up the record in the by-size tree if necessary. | 325 | * Look up the record in the by-size tree if necessary. |
| @@ -323,13 +328,13 @@ xfs_alloc_fixup_trees( | |||
| 323 | #ifdef DEBUG | 328 | #ifdef DEBUG |
| 324 | if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i))) | 329 | if ((error = xfs_alloc_get_rec(cnt_cur, &nfbno1, &nflen1, &i))) |
| 325 | return error; | 330 | return error; |
| 326 | XFS_WANT_CORRUPTED_RETURN( | 331 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 327 | i == 1 && nfbno1 == fbno && nflen1 == flen); | 332 | i == 1 && nfbno1 == fbno && nflen1 == flen); |
| 328 | #endif | 333 | #endif |
| 329 | } else { | 334 | } else { |
| 330 | if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i))) | 335 | if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i))) |
| 331 | return error; | 336 | return error; |
| 332 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 337 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 333 | } | 338 | } |
| 334 | /* | 339 | /* |
| 335 | * Look up the record in the by-block tree if necessary. | 340 | * Look up the record in the by-block tree if necessary. |
| @@ -338,13 +343,13 @@ xfs_alloc_fixup_trees( | |||
| 338 | #ifdef DEBUG | 343 | #ifdef DEBUG |
| 339 | if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i))) | 344 | if ((error = xfs_alloc_get_rec(bno_cur, &nfbno1, &nflen1, &i))) |
| 340 | return error; | 345 | return error; |
| 341 | XFS_WANT_CORRUPTED_RETURN( | 346 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 342 | i == 1 && nfbno1 == fbno && nflen1 == flen); | 347 | i == 1 && nfbno1 == fbno && nflen1 == flen); |
| 343 | #endif | 348 | #endif |
| 344 | } else { | 349 | } else { |
| 345 | if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i))) | 350 | if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i))) |
| 346 | return error; | 351 | return error; |
| 347 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 352 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 348 | } | 353 | } |
| 349 | 354 | ||
| 350 | #ifdef DEBUG | 355 | #ifdef DEBUG |
| @@ -355,7 +360,7 @@ xfs_alloc_fixup_trees( | |||
| 355 | bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); | 360 | bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]); |
| 356 | cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); | 361 | cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]); |
| 357 | 362 | ||
| 358 | XFS_WANT_CORRUPTED_RETURN( | 363 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 359 | bnoblock->bb_numrecs == cntblock->bb_numrecs); | 364 | bnoblock->bb_numrecs == cntblock->bb_numrecs); |
| 360 | } | 365 | } |
| 361 | #endif | 366 | #endif |
| @@ -386,25 +391,25 @@ xfs_alloc_fixup_trees( | |||
| 386 | */ | 391 | */ |
| 387 | if ((error = xfs_btree_delete(cnt_cur, &i))) | 392 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
| 388 | return error; | 393 | return error; |
| 389 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 394 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 390 | /* | 395 | /* |
| 391 | * Add new by-size btree entry(s). | 396 | * Add new by-size btree entry(s). |
| 392 | */ | 397 | */ |
| 393 | if (nfbno1 != NULLAGBLOCK) { | 398 | if (nfbno1 != NULLAGBLOCK) { |
| 394 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) | 399 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i))) |
| 395 | return error; | 400 | return error; |
| 396 | XFS_WANT_CORRUPTED_RETURN(i == 0); | 401 | XFS_WANT_CORRUPTED_RETURN(mp, i == 0); |
| 397 | if ((error = xfs_btree_insert(cnt_cur, &i))) | 402 | if ((error = xfs_btree_insert(cnt_cur, &i))) |
| 398 | return error; | 403 | return error; |
| 399 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 404 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 400 | } | 405 | } |
| 401 | if (nfbno2 != NULLAGBLOCK) { | 406 | if (nfbno2 != NULLAGBLOCK) { |
| 402 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) | 407 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i))) |
| 403 | return error; | 408 | return error; |
| 404 | XFS_WANT_CORRUPTED_RETURN(i == 0); | 409 | XFS_WANT_CORRUPTED_RETURN(mp, i == 0); |
| 405 | if ((error = xfs_btree_insert(cnt_cur, &i))) | 410 | if ((error = xfs_btree_insert(cnt_cur, &i))) |
| 406 | return error; | 411 | return error; |
| 407 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 412 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 408 | } | 413 | } |
| 409 | /* | 414 | /* |
| 410 | * Fix up the by-block btree entry(s). | 415 | * Fix up the by-block btree entry(s). |
| @@ -415,7 +420,7 @@ xfs_alloc_fixup_trees( | |||
| 415 | */ | 420 | */ |
| 416 | if ((error = xfs_btree_delete(bno_cur, &i))) | 421 | if ((error = xfs_btree_delete(bno_cur, &i))) |
| 417 | return error; | 422 | return error; |
| 418 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 423 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 419 | } else { | 424 | } else { |
| 420 | /* | 425 | /* |
| 421 | * Update the by-block entry to start later|be shorter. | 426 | * Update the by-block entry to start later|be shorter. |
| @@ -429,10 +434,10 @@ xfs_alloc_fixup_trees( | |||
| 429 | */ | 434 | */ |
| 430 | if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) | 435 | if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i))) |
| 431 | return error; | 436 | return error; |
| 432 | XFS_WANT_CORRUPTED_RETURN(i == 0); | 437 | XFS_WANT_CORRUPTED_RETURN(mp, i == 0); |
| 433 | if ((error = xfs_btree_insert(bno_cur, &i))) | 438 | if ((error = xfs_btree_insert(bno_cur, &i))) |
| 434 | return error; | 439 | return error; |
| 435 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 440 | XFS_WANT_CORRUPTED_RETURN(mp, i == 1); |
| 436 | } | 441 | } |
| 437 | return 0; | 442 | return 0; |
| 438 | } | 443 | } |
| @@ -682,7 +687,7 @@ xfs_alloc_ag_vextent_exact( | |||
| 682 | error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i); | 687 | error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i); |
| 683 | if (error) | 688 | if (error) |
| 684 | goto error0; | 689 | goto error0; |
| 685 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 690 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 686 | ASSERT(fbno <= args->agbno); | 691 | ASSERT(fbno <= args->agbno); |
| 687 | 692 | ||
| 688 | /* | 693 | /* |
| @@ -783,7 +788,7 @@ xfs_alloc_find_best_extent( | |||
| 783 | error = xfs_alloc_get_rec(*scur, sbno, slen, &i); | 788 | error = xfs_alloc_get_rec(*scur, sbno, slen, &i); |
| 784 | if (error) | 789 | if (error) |
| 785 | goto error0; | 790 | goto error0; |
| 786 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 791 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 787 | xfs_alloc_compute_aligned(args, *sbno, *slen, sbnoa, slena); | 792 | xfs_alloc_compute_aligned(args, *sbno, *slen, sbnoa, slena); |
| 788 | 793 | ||
| 789 | /* | 794 | /* |
| @@ -946,7 +951,7 @@ restart: | |||
| 946 | if ((error = xfs_alloc_get_rec(cnt_cur, <bno, | 951 | if ((error = xfs_alloc_get_rec(cnt_cur, <bno, |
| 947 | <len, &i))) | 952 | <len, &i))) |
| 948 | goto error0; | 953 | goto error0; |
| 949 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 954 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 950 | if (ltlen >= args->minlen) | 955 | if (ltlen >= args->minlen) |
| 951 | break; | 956 | break; |
| 952 | if ((error = xfs_btree_increment(cnt_cur, 0, &i))) | 957 | if ((error = xfs_btree_increment(cnt_cur, 0, &i))) |
| @@ -966,7 +971,7 @@ restart: | |||
| 966 | */ | 971 | */ |
| 967 | if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) | 972 | if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) |
| 968 | goto error0; | 973 | goto error0; |
| 969 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 974 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 970 | xfs_alloc_compute_aligned(args, ltbno, ltlen, | 975 | xfs_alloc_compute_aligned(args, ltbno, ltlen, |
| 971 | <bnoa, <lena); | 976 | <bnoa, <lena); |
| 972 | if (ltlena < args->minlen) | 977 | if (ltlena < args->minlen) |
| @@ -999,7 +1004,7 @@ restart: | |||
| 999 | cnt_cur->bc_ptrs[0] = besti; | 1004 | cnt_cur->bc_ptrs[0] = besti; |
| 1000 | if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) | 1005 | if ((error = xfs_alloc_get_rec(cnt_cur, <bno, <len, &i))) |
| 1001 | goto error0; | 1006 | goto error0; |
| 1002 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1007 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1003 | ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); | 1008 | ASSERT(ltbno + ltlen <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); |
| 1004 | args->len = blen; | 1009 | args->len = blen; |
| 1005 | if (!xfs_alloc_fix_minleft(args)) { | 1010 | if (!xfs_alloc_fix_minleft(args)) { |
| @@ -1088,7 +1093,7 @@ restart: | |||
| 1088 | if (bno_cur_lt) { | 1093 | if (bno_cur_lt) { |
| 1089 | if ((error = xfs_alloc_get_rec(bno_cur_lt, <bno, <len, &i))) | 1094 | if ((error = xfs_alloc_get_rec(bno_cur_lt, <bno, <len, &i))) |
| 1090 | goto error0; | 1095 | goto error0; |
| 1091 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1096 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1092 | xfs_alloc_compute_aligned(args, ltbno, ltlen, | 1097 | xfs_alloc_compute_aligned(args, ltbno, ltlen, |
| 1093 | <bnoa, <lena); | 1098 | <bnoa, <lena); |
| 1094 | if (ltlena >= args->minlen) | 1099 | if (ltlena >= args->minlen) |
| @@ -1104,7 +1109,7 @@ restart: | |||
| 1104 | if (bno_cur_gt) { | 1109 | if (bno_cur_gt) { |
| 1105 | if ((error = xfs_alloc_get_rec(bno_cur_gt, >bno, >len, &i))) | 1110 | if ((error = xfs_alloc_get_rec(bno_cur_gt, >bno, >len, &i))) |
| 1106 | goto error0; | 1111 | goto error0; |
| 1107 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1112 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1108 | xfs_alloc_compute_aligned(args, gtbno, gtlen, | 1113 | xfs_alloc_compute_aligned(args, gtbno, gtlen, |
| 1109 | >bnoa, >lena); | 1114 | >bnoa, >lena); |
| 1110 | if (gtlena >= args->minlen) | 1115 | if (gtlena >= args->minlen) |
| @@ -1303,7 +1308,7 @@ restart: | |||
| 1303 | error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i); | 1308 | error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, &i); |
| 1304 | if (error) | 1309 | if (error) |
| 1305 | goto error0; | 1310 | goto error0; |
| 1306 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1311 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1307 | 1312 | ||
| 1308 | xfs_alloc_compute_aligned(args, fbno, flen, | 1313 | xfs_alloc_compute_aligned(args, fbno, flen, |
| 1309 | &rbno, &rlen); | 1314 | &rbno, &rlen); |
| @@ -1342,7 +1347,7 @@ restart: | |||
| 1342 | * This can't happen in the second case above. | 1347 | * This can't happen in the second case above. |
| 1343 | */ | 1348 | */ |
| 1344 | rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); | 1349 | rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); |
| 1345 | XFS_WANT_CORRUPTED_GOTO(rlen == 0 || | 1350 | XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 || |
| 1346 | (rlen <= flen && rbno + rlen <= fbno + flen), error0); | 1351 | (rlen <= flen && rbno + rlen <= fbno + flen), error0); |
| 1347 | if (rlen < args->maxlen) { | 1352 | if (rlen < args->maxlen) { |
| 1348 | xfs_agblock_t bestfbno; | 1353 | xfs_agblock_t bestfbno; |
| @@ -1362,13 +1367,13 @@ restart: | |||
| 1362 | if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, | 1367 | if ((error = xfs_alloc_get_rec(cnt_cur, &fbno, &flen, |
| 1363 | &i))) | 1368 | &i))) |
| 1364 | goto error0; | 1369 | goto error0; |
| 1365 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1370 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1366 | if (flen < bestrlen) | 1371 | if (flen < bestrlen) |
| 1367 | break; | 1372 | break; |
| 1368 | xfs_alloc_compute_aligned(args, fbno, flen, | 1373 | xfs_alloc_compute_aligned(args, fbno, flen, |
| 1369 | &rbno, &rlen); | 1374 | &rbno, &rlen); |
| 1370 | rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); | 1375 | rlen = XFS_EXTLEN_MIN(args->maxlen, rlen); |
| 1371 | XFS_WANT_CORRUPTED_GOTO(rlen == 0 || | 1376 | XFS_WANT_CORRUPTED_GOTO(args->mp, rlen == 0 || |
| 1372 | (rlen <= flen && rbno + rlen <= fbno + flen), | 1377 | (rlen <= flen && rbno + rlen <= fbno + flen), |
| 1373 | error0); | 1378 | error0); |
| 1374 | if (rlen > bestrlen) { | 1379 | if (rlen > bestrlen) { |
| @@ -1383,7 +1388,7 @@ restart: | |||
| 1383 | if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen, | 1388 | if ((error = xfs_alloc_lookup_eq(cnt_cur, bestfbno, bestflen, |
| 1384 | &i))) | 1389 | &i))) |
| 1385 | goto error0; | 1390 | goto error0; |
| 1386 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1391 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1387 | rlen = bestrlen; | 1392 | rlen = bestrlen; |
| 1388 | rbno = bestrbno; | 1393 | rbno = bestrbno; |
| 1389 | flen = bestflen; | 1394 | flen = bestflen; |
| @@ -1408,7 +1413,7 @@ restart: | |||
| 1408 | if (!xfs_alloc_fix_minleft(args)) | 1413 | if (!xfs_alloc_fix_minleft(args)) |
| 1409 | goto out_nominleft; | 1414 | goto out_nominleft; |
| 1410 | rlen = args->len; | 1415 | rlen = args->len; |
| 1411 | XFS_WANT_CORRUPTED_GOTO(rlen <= flen, error0); | 1416 | XFS_WANT_CORRUPTED_GOTO(args->mp, rlen <= flen, error0); |
| 1412 | /* | 1417 | /* |
| 1413 | * Allocate and initialize a cursor for the by-block tree. | 1418 | * Allocate and initialize a cursor for the by-block tree. |
| 1414 | */ | 1419 | */ |
| @@ -1422,7 +1427,7 @@ restart: | |||
| 1422 | cnt_cur = bno_cur = NULL; | 1427 | cnt_cur = bno_cur = NULL; |
| 1423 | args->len = rlen; | 1428 | args->len = rlen; |
| 1424 | args->agbno = rbno; | 1429 | args->agbno = rbno; |
| 1425 | XFS_WANT_CORRUPTED_GOTO( | 1430 | XFS_WANT_CORRUPTED_GOTO(args->mp, |
| 1426 | args->agbno + args->len <= | 1431 | args->agbno + args->len <= |
| 1427 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), | 1432 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), |
| 1428 | error0); | 1433 | error0); |
| @@ -1467,7 +1472,7 @@ xfs_alloc_ag_vextent_small( | |||
| 1467 | if (i) { | 1472 | if (i) { |
| 1468 | if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) | 1473 | if ((error = xfs_alloc_get_rec(ccur, &fbno, &flen, &i))) |
| 1469 | goto error0; | 1474 | goto error0; |
| 1470 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1475 | XFS_WANT_CORRUPTED_GOTO(args->mp, i == 1, error0); |
| 1471 | } | 1476 | } |
| 1472 | /* | 1477 | /* |
| 1473 | * Nothing in the btree, try the freelist. Make sure | 1478 | * Nothing in the btree, try the freelist. Make sure |
| @@ -1493,7 +1498,7 @@ xfs_alloc_ag_vextent_small( | |||
| 1493 | } | 1498 | } |
| 1494 | args->len = 1; | 1499 | args->len = 1; |
| 1495 | args->agbno = fbno; | 1500 | args->agbno = fbno; |
| 1496 | XFS_WANT_CORRUPTED_GOTO( | 1501 | XFS_WANT_CORRUPTED_GOTO(args->mp, |
| 1497 | args->agbno + args->len <= | 1502 | args->agbno + args->len <= |
| 1498 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), | 1503 | be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length), |
| 1499 | error0); | 1504 | error0); |
| @@ -1579,7 +1584,7 @@ xfs_free_ag_extent( | |||
| 1579 | */ | 1584 | */ |
| 1580 | if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i))) | 1585 | if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i))) |
| 1581 | goto error0; | 1586 | goto error0; |
| 1582 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1587 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1583 | /* | 1588 | /* |
| 1584 | * It's not contiguous, though. | 1589 | * It's not contiguous, though. |
| 1585 | */ | 1590 | */ |
| @@ -1591,7 +1596,8 @@ xfs_free_ag_extent( | |||
| 1591 | * space was invalid, it's (partly) already free. | 1596 | * space was invalid, it's (partly) already free. |
| 1592 | * Very bad. | 1597 | * Very bad. |
| 1593 | */ | 1598 | */ |
| 1594 | XFS_WANT_CORRUPTED_GOTO(ltbno + ltlen <= bno, error0); | 1599 | XFS_WANT_CORRUPTED_GOTO(mp, |
| 1600 | ltbno + ltlen <= bno, error0); | ||
| 1595 | } | 1601 | } |
| 1596 | } | 1602 | } |
| 1597 | /* | 1603 | /* |
| @@ -1606,7 +1612,7 @@ xfs_free_ag_extent( | |||
| 1606 | */ | 1612 | */ |
| 1607 | if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i))) | 1613 | if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i))) |
| 1608 | goto error0; | 1614 | goto error0; |
| 1609 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1615 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1610 | /* | 1616 | /* |
| 1611 | * It's not contiguous, though. | 1617 | * It's not contiguous, though. |
| 1612 | */ | 1618 | */ |
| @@ -1618,7 +1624,7 @@ xfs_free_ag_extent( | |||
| 1618 | * space was invalid, it's (partly) already free. | 1624 | * space was invalid, it's (partly) already free. |
| 1619 | * Very bad. | 1625 | * Very bad. |
| 1620 | */ | 1626 | */ |
| 1621 | XFS_WANT_CORRUPTED_GOTO(gtbno >= bno + len, error0); | 1627 | XFS_WANT_CORRUPTED_GOTO(mp, gtbno >= bno + len, error0); |
| 1622 | } | 1628 | } |
| 1623 | } | 1629 | } |
| 1624 | /* | 1630 | /* |
| @@ -1635,31 +1641,31 @@ xfs_free_ag_extent( | |||
| 1635 | */ | 1641 | */ |
| 1636 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) | 1642 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) |
| 1637 | goto error0; | 1643 | goto error0; |
| 1638 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1644 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1639 | if ((error = xfs_btree_delete(cnt_cur, &i))) | 1645 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
| 1640 | goto error0; | 1646 | goto error0; |
| 1641 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1647 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1642 | /* | 1648 | /* |
| 1643 | * Delete the old by-size entry on the right. | 1649 | * Delete the old by-size entry on the right. |
| 1644 | */ | 1650 | */ |
| 1645 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) | 1651 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) |
| 1646 | goto error0; | 1652 | goto error0; |
| 1647 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1653 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1648 | if ((error = xfs_btree_delete(cnt_cur, &i))) | 1654 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
| 1649 | goto error0; | 1655 | goto error0; |
| 1650 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1656 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1651 | /* | 1657 | /* |
| 1652 | * Delete the old by-block entry for the right block. | 1658 | * Delete the old by-block entry for the right block. |
| 1653 | */ | 1659 | */ |
| 1654 | if ((error = xfs_btree_delete(bno_cur, &i))) | 1660 | if ((error = xfs_btree_delete(bno_cur, &i))) |
| 1655 | goto error0; | 1661 | goto error0; |
| 1656 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1662 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1657 | /* | 1663 | /* |
| 1658 | * Move the by-block cursor back to the left neighbor. | 1664 | * Move the by-block cursor back to the left neighbor. |
| 1659 | */ | 1665 | */ |
| 1660 | if ((error = xfs_btree_decrement(bno_cur, 0, &i))) | 1666 | if ((error = xfs_btree_decrement(bno_cur, 0, &i))) |
| 1661 | goto error0; | 1667 | goto error0; |
| 1662 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1668 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1663 | #ifdef DEBUG | 1669 | #ifdef DEBUG |
| 1664 | /* | 1670 | /* |
| 1665 | * Check that this is the right record: delete didn't | 1671 | * Check that this is the right record: delete didn't |
| @@ -1672,7 +1678,7 @@ xfs_free_ag_extent( | |||
| 1672 | if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen, | 1678 | if ((error = xfs_alloc_get_rec(bno_cur, &xxbno, &xxlen, |
| 1673 | &i))) | 1679 | &i))) |
| 1674 | goto error0; | 1680 | goto error0; |
| 1675 | XFS_WANT_CORRUPTED_GOTO( | 1681 | XFS_WANT_CORRUPTED_GOTO(mp, |
| 1676 | i == 1 && xxbno == ltbno && xxlen == ltlen, | 1682 | i == 1 && xxbno == ltbno && xxlen == ltlen, |
| 1677 | error0); | 1683 | error0); |
| 1678 | } | 1684 | } |
| @@ -1695,17 +1701,17 @@ xfs_free_ag_extent( | |||
| 1695 | */ | 1701 | */ |
| 1696 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) | 1702 | if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i))) |
| 1697 | goto error0; | 1703 | goto error0; |
| 1698 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1704 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1699 | if ((error = xfs_btree_delete(cnt_cur, &i))) | 1705 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
| 1700 | goto error0; | 1706 | goto error0; |
| 1701 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1707 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1702 | /* | 1708 | /* |
| 1703 | * Back up the by-block cursor to the left neighbor, and | 1709 | * Back up the by-block cursor to the left neighbor, and |
| 1704 | * update its length. | 1710 | * update its length. |
| 1705 | */ | 1711 | */ |
| 1706 | if ((error = xfs_btree_decrement(bno_cur, 0, &i))) | 1712 | if ((error = xfs_btree_decrement(bno_cur, 0, &i))) |
| 1707 | goto error0; | 1713 | goto error0; |
| 1708 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1714 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1709 | nbno = ltbno; | 1715 | nbno = ltbno; |
| 1710 | nlen = len + ltlen; | 1716 | nlen = len + ltlen; |
| 1711 | if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) | 1717 | if ((error = xfs_alloc_update(bno_cur, nbno, nlen))) |
| @@ -1721,10 +1727,10 @@ xfs_free_ag_extent( | |||
| 1721 | */ | 1727 | */ |
| 1722 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) | 1728 | if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i))) |
| 1723 | goto error0; | 1729 | goto error0; |
| 1724 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1730 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1725 | if ((error = xfs_btree_delete(cnt_cur, &i))) | 1731 | if ((error = xfs_btree_delete(cnt_cur, &i))) |
| 1726 | goto error0; | 1732 | goto error0; |
| 1727 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1733 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1728 | /* | 1734 | /* |
| 1729 | * Update the starting block and length of the right | 1735 | * Update the starting block and length of the right |
| 1730 | * neighbor in the by-block tree. | 1736 | * neighbor in the by-block tree. |
| @@ -1743,7 +1749,7 @@ xfs_free_ag_extent( | |||
| 1743 | nlen = len; | 1749 | nlen = len; |
| 1744 | if ((error = xfs_btree_insert(bno_cur, &i))) | 1750 | if ((error = xfs_btree_insert(bno_cur, &i))) |
| 1745 | goto error0; | 1751 | goto error0; |
| 1746 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1752 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1747 | } | 1753 | } |
| 1748 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); | 1754 | xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); |
| 1749 | bno_cur = NULL; | 1755 | bno_cur = NULL; |
| @@ -1752,10 +1758,10 @@ xfs_free_ag_extent( | |||
| 1752 | */ | 1758 | */ |
| 1753 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) | 1759 | if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i))) |
| 1754 | goto error0; | 1760 | goto error0; |
| 1755 | XFS_WANT_CORRUPTED_GOTO(i == 0, error0); | 1761 | XFS_WANT_CORRUPTED_GOTO(mp, i == 0, error0); |
| 1756 | if ((error = xfs_btree_insert(cnt_cur, &i))) | 1762 | if ((error = xfs_btree_insert(cnt_cur, &i))) |
| 1757 | goto error0; | 1763 | goto error0; |
| 1758 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1764 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1759 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); | 1765 | xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); |
| 1760 | cnt_cur = NULL; | 1766 | cnt_cur = NULL; |
| 1761 | 1767 | ||
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 15105dbc9e28..04e79d57bca6 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c | |||
| @@ -86,8 +86,83 @@ STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args, | |||
| 86 | int move_count); | 86 | int move_count); |
| 87 | STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); | 87 | STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index); |
| 88 | 88 | ||
| 89 | /* | ||
| 90 | * attr3 block 'firstused' conversion helpers. | ||
| 91 | * | ||
| 92 | * firstused refers to the offset of the first used byte of the nameval region | ||
| 93 | * of an attr leaf block. The region starts at the tail of the block and expands | ||
| 94 | * backwards towards the middle. As such, firstused is initialized to the block | ||
| 95 | * size for an empty leaf block and is reduced from there. | ||
| 96 | * | ||
| 97 | * The attr3 block size is pegged to the fsb size and the maximum fsb is 64k. | ||
| 98 | * The in-core firstused field is 32-bit and thus supports the maximum fsb size. | ||
| 99 | * The on-disk field is only 16-bit, however, and overflows at 64k. Since this | ||
| 100 | * only occurs at exactly 64k, we use zero as a magic on-disk value to represent | ||
| 101 | * the attr block size. The following helpers manage the conversion between the | ||
| 102 | * in-core and on-disk formats. | ||
| 103 | */ | ||
| 104 | |||
| 105 | static void | ||
| 106 | xfs_attr3_leaf_firstused_from_disk( | ||
| 107 | struct xfs_da_geometry *geo, | ||
| 108 | struct xfs_attr3_icleaf_hdr *to, | ||
| 109 | struct xfs_attr_leafblock *from) | ||
| 110 | { | ||
| 111 | struct xfs_attr3_leaf_hdr *hdr3; | ||
| 112 | |||
| 113 | if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) { | ||
| 114 | hdr3 = (struct xfs_attr3_leaf_hdr *) from; | ||
| 115 | to->firstused = be16_to_cpu(hdr3->firstused); | ||
| 116 | } else { | ||
| 117 | to->firstused = be16_to_cpu(from->hdr.firstused); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 121 | * Convert from the magic fsb size value to actual blocksize. This | ||
| 122 | * should only occur for empty blocks when the block size overflows | ||
| 123 | * 16-bits. | ||
| 124 | */ | ||
| 125 | if (to->firstused == XFS_ATTR3_LEAF_NULLOFF) { | ||
| 126 | ASSERT(!to->count && !to->usedbytes); | ||
| 127 | ASSERT(geo->blksize > USHRT_MAX); | ||
| 128 | to->firstused = geo->blksize; | ||
| 129 | } | ||
| 130 | } | ||
| 131 | |||
| 132 | static void | ||
| 133 | xfs_attr3_leaf_firstused_to_disk( | ||
| 134 | struct xfs_da_geometry *geo, | ||
| 135 | struct xfs_attr_leafblock *to, | ||
| 136 | struct xfs_attr3_icleaf_hdr *from) | ||
| 137 | { | ||
| 138 | struct xfs_attr3_leaf_hdr *hdr3; | ||
| 139 | uint32_t firstused; | ||
| 140 | |||
| 141 | /* magic value should only be seen on disk */ | ||
| 142 | ASSERT(from->firstused != XFS_ATTR3_LEAF_NULLOFF); | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Scale down the 32-bit in-core firstused value to the 16-bit on-disk | ||
| 146 | * value. This only overflows at the max supported value of 64k. Use the | ||
| 147 | * magic on-disk value to represent block size in this case. | ||
| 148 | */ | ||
| 149 | firstused = from->firstused; | ||
| 150 | if (firstused > USHRT_MAX) { | ||
| 151 | ASSERT(from->firstused == geo->blksize); | ||
| 152 | firstused = XFS_ATTR3_LEAF_NULLOFF; | ||
| 153 | } | ||
| 154 | |||
| 155 | if (from->magic == XFS_ATTR3_LEAF_MAGIC) { | ||
| 156 | hdr3 = (struct xfs_attr3_leaf_hdr *) to; | ||
| 157 | hdr3->firstused = cpu_to_be16(firstused); | ||
| 158 | } else { | ||
| 159 | to->hdr.firstused = cpu_to_be16(firstused); | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 89 | void | 163 | void |
| 90 | xfs_attr3_leaf_hdr_from_disk( | 164 | xfs_attr3_leaf_hdr_from_disk( |
| 165 | struct xfs_da_geometry *geo, | ||
| 91 | struct xfs_attr3_icleaf_hdr *to, | 166 | struct xfs_attr3_icleaf_hdr *to, |
| 92 | struct xfs_attr_leafblock *from) | 167 | struct xfs_attr_leafblock *from) |
| 93 | { | 168 | { |
| @@ -104,7 +179,7 @@ xfs_attr3_leaf_hdr_from_disk( | |||
| 104 | to->magic = be16_to_cpu(hdr3->info.hdr.magic); | 179 | to->magic = be16_to_cpu(hdr3->info.hdr.magic); |
| 105 | to->count = be16_to_cpu(hdr3->count); | 180 | to->count = be16_to_cpu(hdr3->count); |
| 106 | to->usedbytes = be16_to_cpu(hdr3->usedbytes); | 181 | to->usedbytes = be16_to_cpu(hdr3->usedbytes); |
| 107 | to->firstused = be16_to_cpu(hdr3->firstused); | 182 | xfs_attr3_leaf_firstused_from_disk(geo, to, from); |
| 108 | to->holes = hdr3->holes; | 183 | to->holes = hdr3->holes; |
| 109 | 184 | ||
| 110 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { | 185 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { |
| @@ -118,7 +193,7 @@ xfs_attr3_leaf_hdr_from_disk( | |||
| 118 | to->magic = be16_to_cpu(from->hdr.info.magic); | 193 | to->magic = be16_to_cpu(from->hdr.info.magic); |
| 119 | to->count = be16_to_cpu(from->hdr.count); | 194 | to->count = be16_to_cpu(from->hdr.count); |
| 120 | to->usedbytes = be16_to_cpu(from->hdr.usedbytes); | 195 | to->usedbytes = be16_to_cpu(from->hdr.usedbytes); |
| 121 | to->firstused = be16_to_cpu(from->hdr.firstused); | 196 | xfs_attr3_leaf_firstused_from_disk(geo, to, from); |
| 122 | to->holes = from->hdr.holes; | 197 | to->holes = from->hdr.holes; |
| 123 | 198 | ||
| 124 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { | 199 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { |
| @@ -129,10 +204,11 @@ xfs_attr3_leaf_hdr_from_disk( | |||
| 129 | 204 | ||
| 130 | void | 205 | void |
| 131 | xfs_attr3_leaf_hdr_to_disk( | 206 | xfs_attr3_leaf_hdr_to_disk( |
| 207 | struct xfs_da_geometry *geo, | ||
| 132 | struct xfs_attr_leafblock *to, | 208 | struct xfs_attr_leafblock *to, |
| 133 | struct xfs_attr3_icleaf_hdr *from) | 209 | struct xfs_attr3_icleaf_hdr *from) |
| 134 | { | 210 | { |
| 135 | int i; | 211 | int i; |
| 136 | 212 | ||
| 137 | ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC || | 213 | ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC || |
| 138 | from->magic == XFS_ATTR3_LEAF_MAGIC); | 214 | from->magic == XFS_ATTR3_LEAF_MAGIC); |
| @@ -145,7 +221,7 @@ xfs_attr3_leaf_hdr_to_disk( | |||
| 145 | hdr3->info.hdr.magic = cpu_to_be16(from->magic); | 221 | hdr3->info.hdr.magic = cpu_to_be16(from->magic); |
| 146 | hdr3->count = cpu_to_be16(from->count); | 222 | hdr3->count = cpu_to_be16(from->count); |
| 147 | hdr3->usedbytes = cpu_to_be16(from->usedbytes); | 223 | hdr3->usedbytes = cpu_to_be16(from->usedbytes); |
| 148 | hdr3->firstused = cpu_to_be16(from->firstused); | 224 | xfs_attr3_leaf_firstused_to_disk(geo, to, from); |
| 149 | hdr3->holes = from->holes; | 225 | hdr3->holes = from->holes; |
| 150 | hdr3->pad1 = 0; | 226 | hdr3->pad1 = 0; |
| 151 | 227 | ||
| @@ -160,7 +236,7 @@ xfs_attr3_leaf_hdr_to_disk( | |||
| 160 | to->hdr.info.magic = cpu_to_be16(from->magic); | 236 | to->hdr.info.magic = cpu_to_be16(from->magic); |
| 161 | to->hdr.count = cpu_to_be16(from->count); | 237 | to->hdr.count = cpu_to_be16(from->count); |
| 162 | to->hdr.usedbytes = cpu_to_be16(from->usedbytes); | 238 | to->hdr.usedbytes = cpu_to_be16(from->usedbytes); |
| 163 | to->hdr.firstused = cpu_to_be16(from->firstused); | 239 | xfs_attr3_leaf_firstused_to_disk(geo, to, from); |
| 164 | to->hdr.holes = from->holes; | 240 | to->hdr.holes = from->holes; |
| 165 | to->hdr.pad1 = 0; | 241 | to->hdr.pad1 = 0; |
| 166 | 242 | ||
| @@ -178,7 +254,7 @@ xfs_attr3_leaf_verify( | |||
| 178 | struct xfs_attr_leafblock *leaf = bp->b_addr; | 254 | struct xfs_attr_leafblock *leaf = bp->b_addr; |
| 179 | struct xfs_attr3_icleaf_hdr ichdr; | 255 | struct xfs_attr3_icleaf_hdr ichdr; |
| 180 | 256 | ||
| 181 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 257 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); |
| 182 | 258 | ||
| 183 | if (xfs_sb_version_hascrc(&mp->m_sb)) { | 259 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
| 184 | struct xfs_da3_node_hdr *hdr3 = bp->b_addr; | 260 | struct xfs_da3_node_hdr *hdr3 = bp->b_addr; |
| @@ -757,9 +833,10 @@ xfs_attr_shortform_allfit( | |||
| 757 | struct xfs_attr3_icleaf_hdr leafhdr; | 833 | struct xfs_attr3_icleaf_hdr leafhdr; |
| 758 | int bytes; | 834 | int bytes; |
| 759 | int i; | 835 | int i; |
| 836 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
| 760 | 837 | ||
| 761 | leaf = bp->b_addr; | 838 | leaf = bp->b_addr; |
| 762 | xfs_attr3_leaf_hdr_from_disk(&leafhdr, leaf); | 839 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf); |
| 763 | entry = xfs_attr3_leaf_entryp(leaf); | 840 | entry = xfs_attr3_leaf_entryp(leaf); |
| 764 | 841 | ||
| 765 | bytes = sizeof(struct xfs_attr_sf_hdr); | 842 | bytes = sizeof(struct xfs_attr_sf_hdr); |
| @@ -812,7 +889,7 @@ xfs_attr3_leaf_to_shortform( | |||
| 812 | memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); | 889 | memcpy(tmpbuffer, bp->b_addr, args->geo->blksize); |
| 813 | 890 | ||
| 814 | leaf = (xfs_attr_leafblock_t *)tmpbuffer; | 891 | leaf = (xfs_attr_leafblock_t *)tmpbuffer; |
| 815 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 892 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 816 | entry = xfs_attr3_leaf_entryp(leaf); | 893 | entry = xfs_attr3_leaf_entryp(leaf); |
| 817 | 894 | ||
| 818 | /* XXX (dgc): buffer is about to be marked stale - why zero it? */ | 895 | /* XXX (dgc): buffer is about to be marked stale - why zero it? */ |
| @@ -923,7 +1000,7 @@ xfs_attr3_leaf_to_node( | |||
| 923 | btree = dp->d_ops->node_tree_p(node); | 1000 | btree = dp->d_ops->node_tree_p(node); |
| 924 | 1001 | ||
| 925 | leaf = bp2->b_addr; | 1002 | leaf = bp2->b_addr; |
| 926 | xfs_attr3_leaf_hdr_from_disk(&icleafhdr, leaf); | 1003 | xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf); |
| 927 | entries = xfs_attr3_leaf_entryp(leaf); | 1004 | entries = xfs_attr3_leaf_entryp(leaf); |
| 928 | 1005 | ||
| 929 | /* both on-disk, don't endian-flip twice */ | 1006 | /* both on-disk, don't endian-flip twice */ |
| @@ -988,7 +1065,7 @@ xfs_attr3_leaf_create( | |||
| 988 | } | 1065 | } |
| 989 | ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; | 1066 | ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base; |
| 990 | 1067 | ||
| 991 | xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); | 1068 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); |
| 992 | xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1); | 1069 | xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1); |
| 993 | 1070 | ||
| 994 | *bpp = bp; | 1071 | *bpp = bp; |
| @@ -1073,7 +1150,7 @@ xfs_attr3_leaf_add( | |||
| 1073 | trace_xfs_attr_leaf_add(args); | 1150 | trace_xfs_attr_leaf_add(args); |
| 1074 | 1151 | ||
| 1075 | leaf = bp->b_addr; | 1152 | leaf = bp->b_addr; |
| 1076 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 1153 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 1077 | ASSERT(args->index >= 0 && args->index <= ichdr.count); | 1154 | ASSERT(args->index >= 0 && args->index <= ichdr.count); |
| 1078 | entsize = xfs_attr_leaf_newentsize(args, NULL); | 1155 | entsize = xfs_attr_leaf_newentsize(args, NULL); |
| 1079 | 1156 | ||
| @@ -1126,7 +1203,7 @@ xfs_attr3_leaf_add( | |||
| 1126 | tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); | 1203 | tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0); |
| 1127 | 1204 | ||
| 1128 | out_log_hdr: | 1205 | out_log_hdr: |
| 1129 | xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); | 1206 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); |
| 1130 | xfs_trans_log_buf(args->trans, bp, | 1207 | xfs_trans_log_buf(args->trans, bp, |
| 1131 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, | 1208 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, |
| 1132 | xfs_attr3_leaf_hdr_size(leaf))); | 1209 | xfs_attr3_leaf_hdr_size(leaf))); |
| @@ -1294,7 +1371,7 @@ xfs_attr3_leaf_compact( | |||
| 1294 | ichdr_dst->freemap[0].base; | 1371 | ichdr_dst->freemap[0].base; |
| 1295 | 1372 | ||
| 1296 | /* write the header back to initialise the underlying buffer */ | 1373 | /* write the header back to initialise the underlying buffer */ |
| 1297 | xfs_attr3_leaf_hdr_to_disk(leaf_dst, ichdr_dst); | 1374 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf_dst, ichdr_dst); |
| 1298 | 1375 | ||
| 1299 | /* | 1376 | /* |
| 1300 | * Copy all entry's in the same (sorted) order, | 1377 | * Copy all entry's in the same (sorted) order, |
| @@ -1344,9 +1421,10 @@ xfs_attr_leaf_order( | |||
| 1344 | { | 1421 | { |
| 1345 | struct xfs_attr3_icleaf_hdr ichdr1; | 1422 | struct xfs_attr3_icleaf_hdr ichdr1; |
| 1346 | struct xfs_attr3_icleaf_hdr ichdr2; | 1423 | struct xfs_attr3_icleaf_hdr ichdr2; |
| 1424 | struct xfs_mount *mp = leaf1_bp->b_target->bt_mount; | ||
| 1347 | 1425 | ||
| 1348 | xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1_bp->b_addr); | 1426 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr); |
| 1349 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2_bp->b_addr); | 1427 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr); |
| 1350 | return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2); | 1428 | return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2); |
| 1351 | } | 1429 | } |
| 1352 | 1430 | ||
| @@ -1388,8 +1466,8 @@ xfs_attr3_leaf_rebalance( | |||
| 1388 | ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); | 1466 | ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC); |
| 1389 | leaf1 = blk1->bp->b_addr; | 1467 | leaf1 = blk1->bp->b_addr; |
| 1390 | leaf2 = blk2->bp->b_addr; | 1468 | leaf2 = blk2->bp->b_addr; |
| 1391 | xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1); | 1469 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1); |
| 1392 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2); | 1470 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2); |
| 1393 | ASSERT(ichdr2.count == 0); | 1471 | ASSERT(ichdr2.count == 0); |
| 1394 | args = state->args; | 1472 | args = state->args; |
| 1395 | 1473 | ||
| @@ -1490,8 +1568,8 @@ xfs_attr3_leaf_rebalance( | |||
| 1490 | ichdr1.count, count); | 1568 | ichdr1.count, count); |
| 1491 | } | 1569 | } |
| 1492 | 1570 | ||
| 1493 | xfs_attr3_leaf_hdr_to_disk(leaf1, &ichdr1); | 1571 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1); |
| 1494 | xfs_attr3_leaf_hdr_to_disk(leaf2, &ichdr2); | 1572 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2); |
| 1495 | xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1); | 1573 | xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1); |
| 1496 | xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1); | 1574 | xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1); |
| 1497 | 1575 | ||
| @@ -1684,7 +1762,7 @@ xfs_attr3_leaf_toosmall( | |||
| 1684 | */ | 1762 | */ |
| 1685 | blk = &state->path.blk[ state->path.active-1 ]; | 1763 | blk = &state->path.blk[ state->path.active-1 ]; |
| 1686 | leaf = blk->bp->b_addr; | 1764 | leaf = blk->bp->b_addr; |
| 1687 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 1765 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf); |
| 1688 | bytes = xfs_attr3_leaf_hdr_size(leaf) + | 1766 | bytes = xfs_attr3_leaf_hdr_size(leaf) + |
| 1689 | ichdr.count * sizeof(xfs_attr_leaf_entry_t) + | 1767 | ichdr.count * sizeof(xfs_attr_leaf_entry_t) + |
| 1690 | ichdr.usedbytes; | 1768 | ichdr.usedbytes; |
| @@ -1740,7 +1818,7 @@ xfs_attr3_leaf_toosmall( | |||
| 1740 | if (error) | 1818 | if (error) |
| 1741 | return error; | 1819 | return error; |
| 1742 | 1820 | ||
| 1743 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, bp->b_addr); | 1821 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr); |
| 1744 | 1822 | ||
| 1745 | bytes = state->args->geo->blksize - | 1823 | bytes = state->args->geo->blksize - |
| 1746 | (state->args->geo->blksize >> 2) - | 1824 | (state->args->geo->blksize >> 2) - |
| @@ -1805,7 +1883,7 @@ xfs_attr3_leaf_remove( | |||
| 1805 | trace_xfs_attr_leaf_remove(args); | 1883 | trace_xfs_attr_leaf_remove(args); |
| 1806 | 1884 | ||
| 1807 | leaf = bp->b_addr; | 1885 | leaf = bp->b_addr; |
| 1808 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 1886 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 1809 | 1887 | ||
| 1810 | ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8); | 1888 | ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8); |
| 1811 | ASSERT(args->index >= 0 && args->index < ichdr.count); | 1889 | ASSERT(args->index >= 0 && args->index < ichdr.count); |
| @@ -1918,12 +1996,11 @@ xfs_attr3_leaf_remove( | |||
| 1918 | tmp = be16_to_cpu(entry->nameidx); | 1996 | tmp = be16_to_cpu(entry->nameidx); |
| 1919 | } | 1997 | } |
| 1920 | ichdr.firstused = tmp; | 1998 | ichdr.firstused = tmp; |
| 1921 | if (!ichdr.firstused) | 1999 | ASSERT(ichdr.firstused != 0); |
| 1922 | ichdr.firstused = tmp - XFS_ATTR_LEAF_NAME_ALIGN; | ||
| 1923 | } else { | 2000 | } else { |
| 1924 | ichdr.holes = 1; /* mark as needing compaction */ | 2001 | ichdr.holes = 1; /* mark as needing compaction */ |
| 1925 | } | 2002 | } |
| 1926 | xfs_attr3_leaf_hdr_to_disk(leaf, &ichdr); | 2003 | xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr); |
| 1927 | xfs_trans_log_buf(args->trans, bp, | 2004 | xfs_trans_log_buf(args->trans, bp, |
| 1928 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, | 2005 | XFS_DA_LOGRANGE(leaf, &leaf->hdr, |
| 1929 | xfs_attr3_leaf_hdr_size(leaf))); | 2006 | xfs_attr3_leaf_hdr_size(leaf))); |
| @@ -1957,8 +2034,8 @@ xfs_attr3_leaf_unbalance( | |||
| 1957 | 2034 | ||
| 1958 | drop_leaf = drop_blk->bp->b_addr; | 2035 | drop_leaf = drop_blk->bp->b_addr; |
| 1959 | save_leaf = save_blk->bp->b_addr; | 2036 | save_leaf = save_blk->bp->b_addr; |
| 1960 | xfs_attr3_leaf_hdr_from_disk(&drophdr, drop_leaf); | 2037 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf); |
| 1961 | xfs_attr3_leaf_hdr_from_disk(&savehdr, save_leaf); | 2038 | xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf); |
| 1962 | entry = xfs_attr3_leaf_entryp(drop_leaf); | 2039 | entry = xfs_attr3_leaf_entryp(drop_leaf); |
| 1963 | 2040 | ||
| 1964 | /* | 2041 | /* |
| @@ -2012,7 +2089,7 @@ xfs_attr3_leaf_unbalance( | |||
| 2012 | tmphdr.firstused = state->args->geo->blksize; | 2089 | tmphdr.firstused = state->args->geo->blksize; |
| 2013 | 2090 | ||
| 2014 | /* write the header to the temp buffer to initialise it */ | 2091 | /* write the header to the temp buffer to initialise it */ |
| 2015 | xfs_attr3_leaf_hdr_to_disk(tmp_leaf, &tmphdr); | 2092 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr); |
| 2016 | 2093 | ||
| 2017 | if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, | 2094 | if (xfs_attr3_leaf_order(save_blk->bp, &savehdr, |
| 2018 | drop_blk->bp, &drophdr)) { | 2095 | drop_blk->bp, &drophdr)) { |
| @@ -2039,7 +2116,7 @@ xfs_attr3_leaf_unbalance( | |||
| 2039 | kmem_free(tmp_leaf); | 2116 | kmem_free(tmp_leaf); |
| 2040 | } | 2117 | } |
| 2041 | 2118 | ||
| 2042 | xfs_attr3_leaf_hdr_to_disk(save_leaf, &savehdr); | 2119 | xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr); |
| 2043 | xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, | 2120 | xfs_trans_log_buf(state->args->trans, save_blk->bp, 0, |
| 2044 | state->args->geo->blksize - 1); | 2121 | state->args->geo->blksize - 1); |
| 2045 | 2122 | ||
| @@ -2085,7 +2162,7 @@ xfs_attr3_leaf_lookup_int( | |||
| 2085 | trace_xfs_attr_leaf_lookup(args); | 2162 | trace_xfs_attr_leaf_lookup(args); |
| 2086 | 2163 | ||
| 2087 | leaf = bp->b_addr; | 2164 | leaf = bp->b_addr; |
| 2088 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2165 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2089 | entries = xfs_attr3_leaf_entryp(leaf); | 2166 | entries = xfs_attr3_leaf_entryp(leaf); |
| 2090 | ASSERT(ichdr.count < args->geo->blksize / 8); | 2167 | ASSERT(ichdr.count < args->geo->blksize / 8); |
| 2091 | 2168 | ||
| @@ -2190,7 +2267,7 @@ xfs_attr3_leaf_getvalue( | |||
| 2190 | int valuelen; | 2267 | int valuelen; |
| 2191 | 2268 | ||
| 2192 | leaf = bp->b_addr; | 2269 | leaf = bp->b_addr; |
| 2193 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2270 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2194 | ASSERT(ichdr.count < args->geo->blksize / 8); | 2271 | ASSERT(ichdr.count < args->geo->blksize / 8); |
| 2195 | ASSERT(args->index < ichdr.count); | 2272 | ASSERT(args->index < ichdr.count); |
| 2196 | 2273 | ||
| @@ -2391,8 +2468,9 @@ xfs_attr_leaf_lasthash( | |||
| 2391 | { | 2468 | { |
| 2392 | struct xfs_attr3_icleaf_hdr ichdr; | 2469 | struct xfs_attr3_icleaf_hdr ichdr; |
| 2393 | struct xfs_attr_leaf_entry *entries; | 2470 | struct xfs_attr_leaf_entry *entries; |
| 2471 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
| 2394 | 2472 | ||
| 2395 | xfs_attr3_leaf_hdr_from_disk(&ichdr, bp->b_addr); | 2473 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr); |
| 2396 | entries = xfs_attr3_leaf_entryp(bp->b_addr); | 2474 | entries = xfs_attr3_leaf_entryp(bp->b_addr); |
| 2397 | if (count) | 2475 | if (count) |
| 2398 | *count = ichdr.count; | 2476 | *count = ichdr.count; |
| @@ -2486,7 +2564,7 @@ xfs_attr3_leaf_clearflag( | |||
| 2486 | ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); | 2564 | ASSERT(entry->flags & XFS_ATTR_INCOMPLETE); |
| 2487 | 2565 | ||
| 2488 | #ifdef DEBUG | 2566 | #ifdef DEBUG |
| 2489 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2567 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2490 | ASSERT(args->index < ichdr.count); | 2568 | ASSERT(args->index < ichdr.count); |
| 2491 | ASSERT(args->index >= 0); | 2569 | ASSERT(args->index >= 0); |
| 2492 | 2570 | ||
| @@ -2550,7 +2628,7 @@ xfs_attr3_leaf_setflag( | |||
| 2550 | 2628 | ||
| 2551 | leaf = bp->b_addr; | 2629 | leaf = bp->b_addr; |
| 2552 | #ifdef DEBUG | 2630 | #ifdef DEBUG |
| 2553 | xfs_attr3_leaf_hdr_from_disk(&ichdr, leaf); | 2631 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
| 2554 | ASSERT(args->index < ichdr.count); | 2632 | ASSERT(args->index < ichdr.count); |
| 2555 | ASSERT(args->index >= 0); | 2633 | ASSERT(args->index >= 0); |
| 2556 | #endif | 2634 | #endif |
| @@ -2629,11 +2707,11 @@ xfs_attr3_leaf_flipflags( | |||
| 2629 | entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2]; | 2707 | entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2]; |
| 2630 | 2708 | ||
| 2631 | #ifdef DEBUG | 2709 | #ifdef DEBUG |
| 2632 | xfs_attr3_leaf_hdr_from_disk(&ichdr1, leaf1); | 2710 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1); |
| 2633 | ASSERT(args->index < ichdr1.count); | 2711 | ASSERT(args->index < ichdr1.count); |
| 2634 | ASSERT(args->index >= 0); | 2712 | ASSERT(args->index >= 0); |
| 2635 | 2713 | ||
| 2636 | xfs_attr3_leaf_hdr_from_disk(&ichdr2, leaf2); | 2714 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2); |
| 2637 | ASSERT(args->index2 < ichdr2.count); | 2715 | ASSERT(args->index2 < ichdr2.count); |
| 2638 | ASSERT(args->index2 >= 0); | 2716 | ASSERT(args->index2 >= 0); |
| 2639 | 2717 | ||
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index e2929da7c3ba..025c4b820c03 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h | |||
| @@ -100,9 +100,11 @@ int xfs_attr_leaf_newentsize(struct xfs_da_args *args, int *local); | |||
| 100 | int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, | 100 | int xfs_attr3_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, |
| 101 | xfs_dablk_t bno, xfs_daddr_t mappedbno, | 101 | xfs_dablk_t bno, xfs_daddr_t mappedbno, |
| 102 | struct xfs_buf **bpp); | 102 | struct xfs_buf **bpp); |
| 103 | void xfs_attr3_leaf_hdr_from_disk(struct xfs_attr3_icleaf_hdr *to, | 103 | void xfs_attr3_leaf_hdr_from_disk(struct xfs_da_geometry *geo, |
| 104 | struct xfs_attr3_icleaf_hdr *to, | ||
| 104 | struct xfs_attr_leafblock *from); | 105 | struct xfs_attr_leafblock *from); |
| 105 | void xfs_attr3_leaf_hdr_to_disk(struct xfs_attr_leafblock *to, | 106 | void xfs_attr3_leaf_hdr_to_disk(struct xfs_da_geometry *geo, |
| 107 | struct xfs_attr_leafblock *to, | ||
| 106 | struct xfs_attr3_icleaf_hdr *from); | 108 | struct xfs_attr3_icleaf_hdr *from); |
| 107 | 109 | ||
| 108 | #endif /* __XFS_ATTR_LEAF_H__ */ | 110 | #endif /* __XFS_ATTR_LEAF_H__ */ |
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 | } | ||
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index b9d8a499d2c4..6aaa0c1c7200 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h | |||
| @@ -166,6 +166,11 @@ static inline void xfs_bmap_init(xfs_bmap_free_t *flp, xfs_fsblock_t *fbp) | |||
| 166 | */ | 166 | */ |
| 167 | #define XFS_BMAP_MAX_SHIFT_EXTENTS 1 | 167 | #define XFS_BMAP_MAX_SHIFT_EXTENTS 1 |
| 168 | 168 | ||
| 169 | enum shift_direction { | ||
| 170 | SHIFT_LEFT = 0, | ||
| 171 | SHIFT_RIGHT, | ||
| 172 | }; | ||
| 173 | |||
| 169 | #ifdef DEBUG | 174 | #ifdef DEBUG |
| 170 | void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, | 175 | void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, |
| 171 | int whichfork, unsigned long caller_ip); | 176 | int whichfork, unsigned long caller_ip); |
| @@ -211,8 +216,10 @@ int xfs_check_nostate_extents(struct xfs_ifork *ifp, xfs_extnum_t idx, | |||
| 211 | xfs_extnum_t num); | 216 | xfs_extnum_t num); |
| 212 | uint xfs_default_attroffset(struct xfs_inode *ip); | 217 | uint xfs_default_attroffset(struct xfs_inode *ip); |
| 213 | int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip, | 218 | int xfs_bmap_shift_extents(struct xfs_trans *tp, struct xfs_inode *ip, |
| 214 | xfs_fileoff_t start_fsb, xfs_fileoff_t offset_shift_fsb, | 219 | xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, |
| 215 | int *done, xfs_fileoff_t *next_fsb, xfs_fsblock_t *firstblock, | 220 | int *done, xfs_fileoff_t stop_fsb, xfs_fsblock_t *firstblock, |
| 216 | struct xfs_bmap_free *flist, int num_exts); | 221 | struct xfs_bmap_free *flist, enum shift_direction direction, |
| 222 | int num_exts); | ||
| 223 | int xfs_bmap_split_extent(struct xfs_inode *ip, xfs_fileoff_t split_offset); | ||
| 217 | 224 | ||
| 218 | #endif /* __XFS_BMAP_H__ */ | 225 | #endif /* __XFS_BMAP_H__ */ |
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 81cad433df85..c72283dd8d44 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c | |||
| @@ -168,7 +168,7 @@ xfs_btree_check_lptr( | |||
| 168 | xfs_fsblock_t bno, /* btree block disk address */ | 168 | xfs_fsblock_t bno, /* btree block disk address */ |
| 169 | int level) /* btree block level */ | 169 | int level) /* btree block level */ |
| 170 | { | 170 | { |
| 171 | XFS_WANT_CORRUPTED_RETURN( | 171 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, |
| 172 | level > 0 && | 172 | level > 0 && |
| 173 | bno != NULLFSBLOCK && | 173 | bno != NULLFSBLOCK && |
| 174 | XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); | 174 | XFS_FSB_SANITY_CHECK(cur->bc_mp, bno)); |
| @@ -187,7 +187,7 @@ xfs_btree_check_sptr( | |||
| 187 | { | 187 | { |
| 188 | xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks; | 188 | xfs_agblock_t agblocks = cur->bc_mp->m_sb.sb_agblocks; |
| 189 | 189 | ||
| 190 | XFS_WANT_CORRUPTED_RETURN( | 190 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, |
| 191 | level > 0 && | 191 | level > 0 && |
| 192 | bno != NULLAGBLOCK && | 192 | bno != NULLAGBLOCK && |
| 193 | bno != 0 && | 193 | bno != 0 && |
| @@ -1825,7 +1825,7 @@ xfs_btree_lookup( | |||
| 1825 | error = xfs_btree_increment(cur, 0, &i); | 1825 | error = xfs_btree_increment(cur, 0, &i); |
| 1826 | if (error) | 1826 | if (error) |
| 1827 | goto error0; | 1827 | goto error0; |
| 1828 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1828 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 1829 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); | 1829 | XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); |
| 1830 | *stat = 1; | 1830 | *stat = 1; |
| 1831 | return 0; | 1831 | return 0; |
| @@ -2285,7 +2285,7 @@ xfs_btree_rshift( | |||
| 2285 | if (error) | 2285 | if (error) |
| 2286 | goto error0; | 2286 | goto error0; |
| 2287 | i = xfs_btree_lastrec(tcur, level); | 2287 | i = xfs_btree_lastrec(tcur, level); |
| 2288 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 2288 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 2289 | 2289 | ||
| 2290 | error = xfs_btree_increment(tcur, level, &i); | 2290 | error = xfs_btree_increment(tcur, level, &i); |
| 2291 | if (error) | 2291 | if (error) |
| @@ -3138,7 +3138,7 @@ xfs_btree_insert( | |||
| 3138 | goto error0; | 3138 | goto error0; |
| 3139 | } | 3139 | } |
| 3140 | 3140 | ||
| 3141 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3141 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3142 | level++; | 3142 | level++; |
| 3143 | 3143 | ||
| 3144 | /* | 3144 | /* |
| @@ -3582,15 +3582,15 @@ xfs_btree_delrec( | |||
| 3582 | * Actually any entry but the first would suffice. | 3582 | * Actually any entry but the first would suffice. |
| 3583 | */ | 3583 | */ |
| 3584 | i = xfs_btree_lastrec(tcur, level); | 3584 | i = xfs_btree_lastrec(tcur, level); |
| 3585 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3585 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3586 | 3586 | ||
| 3587 | error = xfs_btree_increment(tcur, level, &i); | 3587 | error = xfs_btree_increment(tcur, level, &i); |
| 3588 | if (error) | 3588 | if (error) |
| 3589 | goto error0; | 3589 | goto error0; |
| 3590 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3590 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3591 | 3591 | ||
| 3592 | i = xfs_btree_lastrec(tcur, level); | 3592 | i = xfs_btree_lastrec(tcur, level); |
| 3593 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3593 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3594 | 3594 | ||
| 3595 | /* Grab a pointer to the block. */ | 3595 | /* Grab a pointer to the block. */ |
| 3596 | right = xfs_btree_get_block(tcur, level, &rbp); | 3596 | right = xfs_btree_get_block(tcur, level, &rbp); |
| @@ -3634,12 +3634,12 @@ xfs_btree_delrec( | |||
| 3634 | rrecs = xfs_btree_get_numrecs(right); | 3634 | rrecs = xfs_btree_get_numrecs(right); |
| 3635 | if (!xfs_btree_ptr_is_null(cur, &lptr)) { | 3635 | if (!xfs_btree_ptr_is_null(cur, &lptr)) { |
| 3636 | i = xfs_btree_firstrec(tcur, level); | 3636 | i = xfs_btree_firstrec(tcur, level); |
| 3637 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3637 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3638 | 3638 | ||
| 3639 | error = xfs_btree_decrement(tcur, level, &i); | 3639 | error = xfs_btree_decrement(tcur, level, &i); |
| 3640 | if (error) | 3640 | if (error) |
| 3641 | goto error0; | 3641 | goto error0; |
| 3642 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3642 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3643 | } | 3643 | } |
| 3644 | } | 3644 | } |
| 3645 | 3645 | ||
| @@ -3653,13 +3653,13 @@ xfs_btree_delrec( | |||
| 3653 | * previous block. | 3653 | * previous block. |
| 3654 | */ | 3654 | */ |
| 3655 | i = xfs_btree_firstrec(tcur, level); | 3655 | i = xfs_btree_firstrec(tcur, level); |
| 3656 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3656 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3657 | 3657 | ||
| 3658 | error = xfs_btree_decrement(tcur, level, &i); | 3658 | error = xfs_btree_decrement(tcur, level, &i); |
| 3659 | if (error) | 3659 | if (error) |
| 3660 | goto error0; | 3660 | goto error0; |
| 3661 | i = xfs_btree_firstrec(tcur, level); | 3661 | i = xfs_btree_firstrec(tcur, level); |
| 3662 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 3662 | XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, i == 1, error0); |
| 3663 | 3663 | ||
| 3664 | /* Grab a pointer to the block. */ | 3664 | /* Grab a pointer to the block. */ |
| 3665 | left = xfs_btree_get_block(tcur, level, &lbp); | 3665 | left = xfs_btree_get_block(tcur, level, &lbp); |
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 9cb0115c6bd1..2385f8cd08ab 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c | |||
| @@ -538,12 +538,12 @@ xfs_da3_root_split( | |||
| 538 | oldroot = blk1->bp->b_addr; | 538 | oldroot = blk1->bp->b_addr; |
| 539 | if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || | 539 | if (oldroot->hdr.info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC) || |
| 540 | oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { | 540 | oldroot->hdr.info.magic == cpu_to_be16(XFS_DA3_NODE_MAGIC)) { |
| 541 | struct xfs_da3_icnode_hdr nodehdr; | 541 | struct xfs_da3_icnode_hdr icnodehdr; |
| 542 | 542 | ||
| 543 | dp->d_ops->node_hdr_from_disk(&nodehdr, oldroot); | 543 | dp->d_ops->node_hdr_from_disk(&icnodehdr, oldroot); |
| 544 | btree = dp->d_ops->node_tree_p(oldroot); | 544 | btree = dp->d_ops->node_tree_p(oldroot); |
| 545 | size = (int)((char *)&btree[nodehdr.count] - (char *)oldroot); | 545 | size = (int)((char *)&btree[icnodehdr.count] - (char *)oldroot); |
| 546 | level = nodehdr.level; | 546 | level = icnodehdr.level; |
| 547 | 547 | ||
| 548 | /* | 548 | /* |
| 549 | * we are about to copy oldroot to bp, so set up the type | 549 | * we are about to copy oldroot to bp, so set up the type |
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h index 0a49b0286372..74bcbabfa523 100644 --- a/fs/xfs/libxfs/xfs_da_format.h +++ b/fs/xfs/libxfs/xfs_da_format.h | |||
| @@ -725,7 +725,13 @@ struct xfs_attr3_icleaf_hdr { | |||
| 725 | __uint16_t magic; | 725 | __uint16_t magic; |
| 726 | __uint16_t count; | 726 | __uint16_t count; |
| 727 | __uint16_t usedbytes; | 727 | __uint16_t usedbytes; |
| 728 | __uint16_t firstused; | 728 | /* |
| 729 | * firstused is 32-bit here instead of 16-bit like the on-disk variant | ||
| 730 | * to support maximum fsb size of 64k without overflow issues throughout | ||
| 731 | * the attr code. Instead, the overflow condition is handled on | ||
| 732 | * conversion to/from disk. | ||
| 733 | */ | ||
| 734 | __uint32_t firstused; | ||
| 729 | __u8 holes; | 735 | __u8 holes; |
| 730 | struct { | 736 | struct { |
| 731 | __uint16_t base; | 737 | __uint16_t base; |
| @@ -734,6 +740,12 @@ struct xfs_attr3_icleaf_hdr { | |||
| 734 | }; | 740 | }; |
| 735 | 741 | ||
| 736 | /* | 742 | /* |
| 743 | * Special value to represent fs block size in the leaf header firstused field. | ||
| 744 | * Only used when block size overflows the 2-bytes available on disk. | ||
| 745 | */ | ||
| 746 | #define XFS_ATTR3_LEAF_NULLOFF 0 | ||
| 747 | |||
| 748 | /* | ||
| 737 | * Flags used in the leaf_entry[i].flags field. | 749 | * Flags used in the leaf_entry[i].flags field. |
| 738 | * NOTE: the INCOMPLETE bit must not collide with the flags bits specified | 750 | * NOTE: the INCOMPLETE bit must not collide with the flags bits specified |
| 739 | * on the system call, they are "or"ed together for various operations. | 751 | * on the system call, they are "or"ed together for various operations. |
diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index 5ff31be9b1cd..de1ea16f5748 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c | |||
| @@ -89,7 +89,7 @@ __xfs_dir3_data_check( | |||
| 89 | * so just ensure that the count falls somewhere inside the | 89 | * so just ensure that the count falls somewhere inside the |
| 90 | * block right now. | 90 | * block right now. |
| 91 | */ | 91 | */ |
| 92 | XFS_WANT_CORRUPTED_RETURN(be32_to_cpu(btp->count) < | 92 | XFS_WANT_CORRUPTED_RETURN(mp, be32_to_cpu(btp->count) < |
| 93 | ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry)); | 93 | ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry)); |
| 94 | break; | 94 | break; |
| 95 | case cpu_to_be32(XFS_DIR3_DATA_MAGIC): | 95 | case cpu_to_be32(XFS_DIR3_DATA_MAGIC): |
| @@ -107,21 +107,21 @@ __xfs_dir3_data_check( | |||
| 107 | bf = ops->data_bestfree_p(hdr); | 107 | bf = ops->data_bestfree_p(hdr); |
| 108 | count = lastfree = freeseen = 0; | 108 | count = lastfree = freeseen = 0; |
| 109 | if (!bf[0].length) { | 109 | if (!bf[0].length) { |
| 110 | XFS_WANT_CORRUPTED_RETURN(!bf[0].offset); | 110 | XFS_WANT_CORRUPTED_RETURN(mp, !bf[0].offset); |
| 111 | freeseen |= 1 << 0; | 111 | freeseen |= 1 << 0; |
| 112 | } | 112 | } |
| 113 | if (!bf[1].length) { | 113 | if (!bf[1].length) { |
| 114 | XFS_WANT_CORRUPTED_RETURN(!bf[1].offset); | 114 | XFS_WANT_CORRUPTED_RETURN(mp, !bf[1].offset); |
| 115 | freeseen |= 1 << 1; | 115 | freeseen |= 1 << 1; |
| 116 | } | 116 | } |
| 117 | if (!bf[2].length) { | 117 | if (!bf[2].length) { |
| 118 | XFS_WANT_CORRUPTED_RETURN(!bf[2].offset); | 118 | XFS_WANT_CORRUPTED_RETURN(mp, !bf[2].offset); |
| 119 | freeseen |= 1 << 2; | 119 | freeseen |= 1 << 2; |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[0].length) >= | 122 | XFS_WANT_CORRUPTED_RETURN(mp, be16_to_cpu(bf[0].length) >= |
| 123 | be16_to_cpu(bf[1].length)); | 123 | be16_to_cpu(bf[1].length)); |
| 124 | XFS_WANT_CORRUPTED_RETURN(be16_to_cpu(bf[1].length) >= | 124 | XFS_WANT_CORRUPTED_RETURN(mp, be16_to_cpu(bf[1].length) >= |
| 125 | be16_to_cpu(bf[2].length)); | 125 | be16_to_cpu(bf[2].length)); |
| 126 | /* | 126 | /* |
| 127 | * Loop over the data/unused entries. | 127 | * Loop over the data/unused entries. |
| @@ -134,18 +134,18 @@ __xfs_dir3_data_check( | |||
| 134 | * doesn't need to be there. | 134 | * doesn't need to be there. |
| 135 | */ | 135 | */ |
| 136 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { | 136 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { |
| 137 | XFS_WANT_CORRUPTED_RETURN(lastfree == 0); | 137 | XFS_WANT_CORRUPTED_RETURN(mp, lastfree == 0); |
| 138 | XFS_WANT_CORRUPTED_RETURN( | 138 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 139 | be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == | 139 | be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == |
| 140 | (char *)dup - (char *)hdr); | 140 | (char *)dup - (char *)hdr); |
| 141 | dfp = xfs_dir2_data_freefind(hdr, bf, dup); | 141 | dfp = xfs_dir2_data_freefind(hdr, bf, dup); |
| 142 | if (dfp) { | 142 | if (dfp) { |
| 143 | i = (int)(dfp - bf); | 143 | i = (int)(dfp - bf); |
| 144 | XFS_WANT_CORRUPTED_RETURN( | 144 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 145 | (freeseen & (1 << i)) == 0); | 145 | (freeseen & (1 << i)) == 0); |
| 146 | freeseen |= 1 << i; | 146 | freeseen |= 1 << i; |
| 147 | } else { | 147 | } else { |
| 148 | XFS_WANT_CORRUPTED_RETURN( | 148 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 149 | be16_to_cpu(dup->length) <= | 149 | be16_to_cpu(dup->length) <= |
| 150 | be16_to_cpu(bf[2].length)); | 150 | be16_to_cpu(bf[2].length)); |
| 151 | } | 151 | } |
| @@ -160,13 +160,13 @@ __xfs_dir3_data_check( | |||
| 160 | * The linear search is crude but this is DEBUG code. | 160 | * The linear search is crude but this is DEBUG code. |
| 161 | */ | 161 | */ |
| 162 | dep = (xfs_dir2_data_entry_t *)p; | 162 | dep = (xfs_dir2_data_entry_t *)p; |
| 163 | XFS_WANT_CORRUPTED_RETURN(dep->namelen != 0); | 163 | XFS_WANT_CORRUPTED_RETURN(mp, dep->namelen != 0); |
| 164 | XFS_WANT_CORRUPTED_RETURN( | 164 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 165 | !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))); | 165 | !xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber))); |
| 166 | XFS_WANT_CORRUPTED_RETURN( | 166 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 167 | be16_to_cpu(*ops->data_entry_tag_p(dep)) == | 167 | be16_to_cpu(*ops->data_entry_tag_p(dep)) == |
| 168 | (char *)dep - (char *)hdr); | 168 | (char *)dep - (char *)hdr); |
| 169 | XFS_WANT_CORRUPTED_RETURN( | 169 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 170 | ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX); | 170 | ops->data_get_ftype(dep) < XFS_DIR3_FT_MAX); |
| 171 | count++; | 171 | count++; |
| 172 | lastfree = 0; | 172 | lastfree = 0; |
| @@ -183,14 +183,15 @@ __xfs_dir3_data_check( | |||
| 183 | be32_to_cpu(lep[i].hashval) == hash) | 183 | be32_to_cpu(lep[i].hashval) == hash) |
| 184 | break; | 184 | break; |
| 185 | } | 185 | } |
| 186 | XFS_WANT_CORRUPTED_RETURN(i < be32_to_cpu(btp->count)); | 186 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 187 | i < be32_to_cpu(btp->count)); | ||
| 187 | } | 188 | } |
| 188 | p += ops->data_entsize(dep->namelen); | 189 | p += ops->data_entsize(dep->namelen); |
| 189 | } | 190 | } |
| 190 | /* | 191 | /* |
| 191 | * Need to have seen all the entries and all the bestfree slots. | 192 | * Need to have seen all the entries and all the bestfree slots. |
| 192 | */ | 193 | */ |
| 193 | XFS_WANT_CORRUPTED_RETURN(freeseen == 7); | 194 | XFS_WANT_CORRUPTED_RETURN(mp, freeseen == 7); |
| 194 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || | 195 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
| 195 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { | 196 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { |
| 196 | for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { | 197 | for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { |
| @@ -198,13 +199,13 @@ __xfs_dir3_data_check( | |||
| 198 | cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) | 199 | cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
| 199 | stale++; | 200 | stale++; |
| 200 | if (i > 0) | 201 | if (i > 0) |
| 201 | XFS_WANT_CORRUPTED_RETURN( | 202 | XFS_WANT_CORRUPTED_RETURN(mp, |
| 202 | be32_to_cpu(lep[i].hashval) >= | 203 | be32_to_cpu(lep[i].hashval) >= |
| 203 | be32_to_cpu(lep[i - 1].hashval)); | 204 | be32_to_cpu(lep[i - 1].hashval)); |
| 204 | } | 205 | } |
| 205 | XFS_WANT_CORRUPTED_RETURN(count == | 206 | XFS_WANT_CORRUPTED_RETURN(mp, count == |
| 206 | be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); | 207 | be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)); |
| 207 | XFS_WANT_CORRUPTED_RETURN(stale == be32_to_cpu(btp->stale)); | 208 | XFS_WANT_CORRUPTED_RETURN(mp, stale == be32_to_cpu(btp->stale)); |
| 208 | } | 209 | } |
| 209 | return 0; | 210 | return 0; |
| 210 | } | 211 | } |
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 8eb718979383..4daaa662337b 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h | |||
| @@ -264,68 +264,6 @@ typedef struct xfs_dsb { | |||
| 264 | /* must be padded to 64 bit alignment */ | 264 | /* must be padded to 64 bit alignment */ |
| 265 | } xfs_dsb_t; | 265 | } xfs_dsb_t; |
| 266 | 266 | ||
| 267 | /* | ||
| 268 | * Sequence number values for the fields. | ||
| 269 | */ | ||
| 270 | typedef enum { | ||
| 271 | XFS_SBS_MAGICNUM, XFS_SBS_BLOCKSIZE, XFS_SBS_DBLOCKS, XFS_SBS_RBLOCKS, | ||
| 272 | XFS_SBS_REXTENTS, XFS_SBS_UUID, XFS_SBS_LOGSTART, XFS_SBS_ROOTINO, | ||
| 273 | XFS_SBS_RBMINO, XFS_SBS_RSUMINO, XFS_SBS_REXTSIZE, XFS_SBS_AGBLOCKS, | ||
| 274 | XFS_SBS_AGCOUNT, XFS_SBS_RBMBLOCKS, XFS_SBS_LOGBLOCKS, | ||
| 275 | XFS_SBS_VERSIONNUM, XFS_SBS_SECTSIZE, XFS_SBS_INODESIZE, | ||
| 276 | XFS_SBS_INOPBLOCK, XFS_SBS_FNAME, XFS_SBS_BLOCKLOG, | ||
| 277 | XFS_SBS_SECTLOG, XFS_SBS_INODELOG, XFS_SBS_INOPBLOG, XFS_SBS_AGBLKLOG, | ||
| 278 | XFS_SBS_REXTSLOG, XFS_SBS_INPROGRESS, XFS_SBS_IMAX_PCT, XFS_SBS_ICOUNT, | ||
| 279 | XFS_SBS_IFREE, XFS_SBS_FDBLOCKS, XFS_SBS_FREXTENTS, XFS_SBS_UQUOTINO, | ||
| 280 | XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN, | ||
| 281 | XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG, | ||
| 282 | XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT, | ||
| 283 | XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2, XFS_SBS_FEATURES_COMPAT, | ||
| 284 | XFS_SBS_FEATURES_RO_COMPAT, XFS_SBS_FEATURES_INCOMPAT, | ||
| 285 | XFS_SBS_FEATURES_LOG_INCOMPAT, XFS_SBS_CRC, XFS_SBS_PAD, | ||
| 286 | XFS_SBS_PQUOTINO, XFS_SBS_LSN, | ||
| 287 | XFS_SBS_FIELDCOUNT | ||
| 288 | } xfs_sb_field_t; | ||
| 289 | |||
| 290 | /* | ||
| 291 | * Mask values, defined based on the xfs_sb_field_t values. | ||
| 292 | * Only define the ones we're using. | ||
| 293 | */ | ||
| 294 | #define XFS_SB_MVAL(x) (1LL << XFS_SBS_ ## x) | ||
| 295 | #define XFS_SB_UUID XFS_SB_MVAL(UUID) | ||
| 296 | #define XFS_SB_FNAME XFS_SB_MVAL(FNAME) | ||
| 297 | #define XFS_SB_ROOTINO XFS_SB_MVAL(ROOTINO) | ||
| 298 | #define XFS_SB_RBMINO XFS_SB_MVAL(RBMINO) | ||
| 299 | #define XFS_SB_RSUMINO XFS_SB_MVAL(RSUMINO) | ||
| 300 | #define XFS_SB_VERSIONNUM XFS_SB_MVAL(VERSIONNUM) | ||
| 301 | #define XFS_SB_UQUOTINO XFS_SB_MVAL(UQUOTINO) | ||
| 302 | #define XFS_SB_GQUOTINO XFS_SB_MVAL(GQUOTINO) | ||
| 303 | #define XFS_SB_QFLAGS XFS_SB_MVAL(QFLAGS) | ||
| 304 | #define XFS_SB_SHARED_VN XFS_SB_MVAL(SHARED_VN) | ||
| 305 | #define XFS_SB_UNIT XFS_SB_MVAL(UNIT) | ||
| 306 | #define XFS_SB_WIDTH XFS_SB_MVAL(WIDTH) | ||
| 307 | #define XFS_SB_ICOUNT XFS_SB_MVAL(ICOUNT) | ||
| 308 | #define XFS_SB_IFREE XFS_SB_MVAL(IFREE) | ||
| 309 | #define XFS_SB_FDBLOCKS XFS_SB_MVAL(FDBLOCKS) | ||
| 310 | #define XFS_SB_FEATURES2 (XFS_SB_MVAL(FEATURES2) | \ | ||
| 311 | XFS_SB_MVAL(BAD_FEATURES2)) | ||
| 312 | #define XFS_SB_FEATURES_COMPAT XFS_SB_MVAL(FEATURES_COMPAT) | ||
| 313 | #define XFS_SB_FEATURES_RO_COMPAT XFS_SB_MVAL(FEATURES_RO_COMPAT) | ||
| 314 | #define XFS_SB_FEATURES_INCOMPAT XFS_SB_MVAL(FEATURES_INCOMPAT) | ||
| 315 | #define XFS_SB_FEATURES_LOG_INCOMPAT XFS_SB_MVAL(FEATURES_LOG_INCOMPAT) | ||
| 316 | #define XFS_SB_CRC XFS_SB_MVAL(CRC) | ||
| 317 | #define XFS_SB_PQUOTINO XFS_SB_MVAL(PQUOTINO) | ||
| 318 | #define XFS_SB_NUM_BITS ((int)XFS_SBS_FIELDCOUNT) | ||
| 319 | #define XFS_SB_ALL_BITS ((1LL << XFS_SB_NUM_BITS) - 1) | ||
| 320 | #define XFS_SB_MOD_BITS \ | ||
| 321 | (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \ | ||
| 322 | XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \ | ||
| 323 | XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \ | ||
| 324 | XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \ | ||
| 325 | XFS_SB_FEATURES_COMPAT | XFS_SB_FEATURES_RO_COMPAT | \ | ||
| 326 | XFS_SB_FEATURES_INCOMPAT | XFS_SB_FEATURES_LOG_INCOMPAT | \ | ||
| 327 | XFS_SB_PQUOTINO) | ||
| 328 | |||
| 329 | 267 | ||
| 330 | /* | 268 | /* |
| 331 | * Misc. Flags - warning - these will be cleared by xfs_repair unless | 269 | * Misc. Flags - warning - these will be cleared by xfs_repair unless |
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 116ef1ddb3e3..07349a183a11 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c | |||
| @@ -376,7 +376,8 @@ xfs_ialloc_ag_alloc( | |||
| 376 | */ | 376 | */ |
| 377 | newlen = args.mp->m_ialloc_inos; | 377 | newlen = args.mp->m_ialloc_inos; |
| 378 | if (args.mp->m_maxicount && | 378 | if (args.mp->m_maxicount && |
| 379 | args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount) | 379 | percpu_counter_read(&args.mp->m_icount) + newlen > |
| 380 | args.mp->m_maxicount) | ||
| 380 | return -ENOSPC; | 381 | return -ENOSPC; |
| 381 | args.minlen = args.maxlen = args.mp->m_ialloc_blks; | 382 | args.minlen = args.maxlen = args.mp->m_ialloc_blks; |
| 382 | /* | 383 | /* |
| @@ -700,7 +701,7 @@ xfs_ialloc_next_rec( | |||
| 700 | error = xfs_inobt_get_rec(cur, rec, &i); | 701 | error = xfs_inobt_get_rec(cur, rec, &i); |
| 701 | if (error) | 702 | if (error) |
| 702 | return error; | 703 | return error; |
| 703 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 704 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 704 | } | 705 | } |
| 705 | 706 | ||
| 706 | return 0; | 707 | return 0; |
| @@ -724,7 +725,7 @@ xfs_ialloc_get_rec( | |||
| 724 | error = xfs_inobt_get_rec(cur, rec, &i); | 725 | error = xfs_inobt_get_rec(cur, rec, &i); |
| 725 | if (error) | 726 | if (error) |
| 726 | return error; | 727 | return error; |
| 727 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 728 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 728 | } | 729 | } |
| 729 | 730 | ||
| 730 | return 0; | 731 | return 0; |
| @@ -783,12 +784,12 @@ xfs_dialloc_ag_inobt( | |||
| 783 | error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); | 784 | error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i); |
| 784 | if (error) | 785 | if (error) |
| 785 | goto error0; | 786 | goto error0; |
| 786 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 787 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 787 | 788 | ||
| 788 | error = xfs_inobt_get_rec(cur, &rec, &j); | 789 | error = xfs_inobt_get_rec(cur, &rec, &j); |
| 789 | if (error) | 790 | if (error) |
| 790 | goto error0; | 791 | goto error0; |
| 791 | XFS_WANT_CORRUPTED_GOTO(j == 1, error0); | 792 | XFS_WANT_CORRUPTED_GOTO(mp, j == 1, error0); |
| 792 | 793 | ||
| 793 | if (rec.ir_freecount > 0) { | 794 | if (rec.ir_freecount > 0) { |
| 794 | /* | 795 | /* |
| @@ -944,19 +945,19 @@ newino: | |||
| 944 | error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); | 945 | error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); |
| 945 | if (error) | 946 | if (error) |
| 946 | goto error0; | 947 | goto error0; |
| 947 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 948 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 948 | 949 | ||
| 949 | for (;;) { | 950 | for (;;) { |
| 950 | error = xfs_inobt_get_rec(cur, &rec, &i); | 951 | error = xfs_inobt_get_rec(cur, &rec, &i); |
| 951 | if (error) | 952 | if (error) |
| 952 | goto error0; | 953 | goto error0; |
| 953 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 954 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 954 | if (rec.ir_freecount > 0) | 955 | if (rec.ir_freecount > 0) |
| 955 | break; | 956 | break; |
| 956 | error = xfs_btree_increment(cur, 0, &i); | 957 | error = xfs_btree_increment(cur, 0, &i); |
| 957 | if (error) | 958 | if (error) |
| 958 | goto error0; | 959 | goto error0; |
| 959 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 960 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 960 | } | 961 | } |
| 961 | 962 | ||
| 962 | alloc_inode: | 963 | alloc_inode: |
| @@ -1016,7 +1017,7 @@ xfs_dialloc_ag_finobt_near( | |||
| 1016 | error = xfs_inobt_get_rec(lcur, rec, &i); | 1017 | error = xfs_inobt_get_rec(lcur, rec, &i); |
| 1017 | if (error) | 1018 | if (error) |
| 1018 | return error; | 1019 | return error; |
| 1019 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1020 | XFS_WANT_CORRUPTED_RETURN(lcur->bc_mp, i == 1); |
| 1020 | 1021 | ||
| 1021 | /* | 1022 | /* |
| 1022 | * See if we've landed in the parent inode record. The finobt | 1023 | * See if we've landed in the parent inode record. The finobt |
| @@ -1039,10 +1040,10 @@ xfs_dialloc_ag_finobt_near( | |||
| 1039 | error = xfs_inobt_get_rec(rcur, &rrec, &j); | 1040 | error = xfs_inobt_get_rec(rcur, &rrec, &j); |
| 1040 | if (error) | 1041 | if (error) |
| 1041 | goto error_rcur; | 1042 | goto error_rcur; |
| 1042 | XFS_WANT_CORRUPTED_GOTO(j == 1, error_rcur); | 1043 | XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, j == 1, error_rcur); |
| 1043 | } | 1044 | } |
| 1044 | 1045 | ||
| 1045 | XFS_WANT_CORRUPTED_GOTO(i == 1 || j == 1, error_rcur); | 1046 | XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, i == 1 || j == 1, error_rcur); |
| 1046 | if (i == 1 && j == 1) { | 1047 | if (i == 1 && j == 1) { |
| 1047 | /* | 1048 | /* |
| 1048 | * Both the left and right records are valid. Choose the closer | 1049 | * Both the left and right records are valid. Choose the closer |
| @@ -1095,7 +1096,7 @@ xfs_dialloc_ag_finobt_newino( | |||
| 1095 | error = xfs_inobt_get_rec(cur, rec, &i); | 1096 | error = xfs_inobt_get_rec(cur, rec, &i); |
| 1096 | if (error) | 1097 | if (error) |
| 1097 | return error; | 1098 | return error; |
| 1098 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1099 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 1099 | return 0; | 1100 | return 0; |
| 1100 | } | 1101 | } |
| 1101 | } | 1102 | } |
| @@ -1106,12 +1107,12 @@ xfs_dialloc_ag_finobt_newino( | |||
| 1106 | error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); | 1107 | error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i); |
| 1107 | if (error) | 1108 | if (error) |
| 1108 | return error; | 1109 | return error; |
| 1109 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1110 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 1110 | 1111 | ||
| 1111 | error = xfs_inobt_get_rec(cur, rec, &i); | 1112 | error = xfs_inobt_get_rec(cur, rec, &i); |
| 1112 | if (error) | 1113 | if (error) |
| 1113 | return error; | 1114 | return error; |
| 1114 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1115 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 1115 | 1116 | ||
| 1116 | return 0; | 1117 | return 0; |
| 1117 | } | 1118 | } |
| @@ -1133,19 +1134,19 @@ xfs_dialloc_ag_update_inobt( | |||
| 1133 | error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i); | 1134 | error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i); |
| 1134 | if (error) | 1135 | if (error) |
| 1135 | return error; | 1136 | return error; |
| 1136 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1137 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 1137 | 1138 | ||
| 1138 | error = xfs_inobt_get_rec(cur, &rec, &i); | 1139 | error = xfs_inobt_get_rec(cur, &rec, &i); |
| 1139 | if (error) | 1140 | if (error) |
| 1140 | return error; | 1141 | return error; |
| 1141 | XFS_WANT_CORRUPTED_RETURN(i == 1); | 1142 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1); |
| 1142 | ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) % | 1143 | ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) % |
| 1143 | XFS_INODES_PER_CHUNK) == 0); | 1144 | XFS_INODES_PER_CHUNK) == 0); |
| 1144 | 1145 | ||
| 1145 | rec.ir_free &= ~XFS_INOBT_MASK(offset); | 1146 | rec.ir_free &= ~XFS_INOBT_MASK(offset); |
| 1146 | rec.ir_freecount--; | 1147 | rec.ir_freecount--; |
| 1147 | 1148 | ||
| 1148 | XFS_WANT_CORRUPTED_RETURN((rec.ir_free == frec->ir_free) && | 1149 | XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, (rec.ir_free == frec->ir_free) && |
| 1149 | (rec.ir_freecount == frec->ir_freecount)); | 1150 | (rec.ir_freecount == frec->ir_freecount)); |
| 1150 | 1151 | ||
| 1151 | return xfs_inobt_update(cur, &rec); | 1152 | return xfs_inobt_update(cur, &rec); |
| @@ -1340,7 +1341,8 @@ xfs_dialloc( | |||
| 1340 | * inode. | 1341 | * inode. |
| 1341 | */ | 1342 | */ |
| 1342 | if (mp->m_maxicount && | 1343 | if (mp->m_maxicount && |
| 1343 | mp->m_sb.sb_icount + mp->m_ialloc_inos > mp->m_maxicount) { | 1344 | percpu_counter_read(&mp->m_icount) + mp->m_ialloc_inos > |
| 1345 | mp->m_maxicount) { | ||
| 1344 | noroom = 1; | 1346 | noroom = 1; |
| 1345 | okalloc = 0; | 1347 | okalloc = 0; |
| 1346 | } | 1348 | } |
| @@ -1475,14 +1477,14 @@ xfs_difree_inobt( | |||
| 1475 | __func__, error); | 1477 | __func__, error); |
| 1476 | goto error0; | 1478 | goto error0; |
| 1477 | } | 1479 | } |
| 1478 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1480 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1479 | error = xfs_inobt_get_rec(cur, &rec, &i); | 1481 | error = xfs_inobt_get_rec(cur, &rec, &i); |
| 1480 | if (error) { | 1482 | if (error) { |
| 1481 | xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.", | 1483 | xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.", |
| 1482 | __func__, error); | 1484 | __func__, error); |
| 1483 | goto error0; | 1485 | goto error0; |
| 1484 | } | 1486 | } |
| 1485 | XFS_WANT_CORRUPTED_GOTO(i == 1, error0); | 1487 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0); |
| 1486 | /* | 1488 | /* |
| 1487 | * Get the offset in the inode chunk. | 1489 | * Get the offset in the inode chunk. |
| 1488 | */ | 1490 | */ |
| @@ -1592,7 +1594,7 @@ xfs_difree_finobt( | |||
| 1592 | * freed an inode in a previously fully allocated chunk. If not, | 1594 | * freed an inode in a previously fully allocated chunk. If not, |
| 1593 | * something is out of sync. | 1595 | * something is out of sync. |
| 1594 | */ | 1596 | */ |
| 1595 | XFS_WANT_CORRUPTED_GOTO(ibtrec->ir_freecount == 1, error); | 1597 | XFS_WANT_CORRUPTED_GOTO(mp, ibtrec->ir_freecount == 1, error); |
| 1596 | 1598 | ||
| 1597 | error = xfs_inobt_insert_rec(cur, ibtrec->ir_freecount, | 1599 | error = xfs_inobt_insert_rec(cur, ibtrec->ir_freecount, |
| 1598 | ibtrec->ir_free, &i); | 1600 | ibtrec->ir_free, &i); |
| @@ -1613,12 +1615,12 @@ xfs_difree_finobt( | |||
| 1613 | error = xfs_inobt_get_rec(cur, &rec, &i); | 1615 | error = xfs_inobt_get_rec(cur, &rec, &i); |
| 1614 | if (error) | 1616 | if (error) |
| 1615 | goto error; | 1617 | goto error; |
| 1616 | XFS_WANT_CORRUPTED_GOTO(i == 1, error); | 1618 | XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error); |
| 1617 | 1619 | ||
| 1618 | rec.ir_free |= XFS_INOBT_MASK(offset); | 1620 | rec.ir_free |= XFS_INOBT_MASK(offset); |
| 1619 | rec.ir_freecount++; | 1621 | rec.ir_freecount++; |
| 1620 | 1622 | ||
| 1621 | XFS_WANT_CORRUPTED_GOTO((rec.ir_free == ibtrec->ir_free) && | 1623 | XFS_WANT_CORRUPTED_GOTO(mp, (rec.ir_free == ibtrec->ir_free) && |
| 1622 | (rec.ir_freecount == ibtrec->ir_freecount), | 1624 | (rec.ir_freecount == ibtrec->ir_freecount), |
| 1623 | error); | 1625 | error); |
| 1624 | 1626 | ||
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index b0a5fe95a3e2..dc4bfc5d88fc 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c | |||
| @@ -111,14 +111,6 @@ xfs_mount_validate_sb( | |||
| 111 | bool check_inprogress, | 111 | bool check_inprogress, |
| 112 | bool check_version) | 112 | bool check_version) |
| 113 | { | 113 | { |
| 114 | |||
| 115 | /* | ||
| 116 | * If the log device and data device have the | ||
| 117 | * same device number, the log is internal. | ||
| 118 | * Consequently, the sb_logstart should be non-zero. If | ||
| 119 | * we have a zero sb_logstart in this case, we may be trying to mount | ||
| 120 | * a volume filesystem in a non-volume manner. | ||
| 121 | */ | ||
| 122 | if (sbp->sb_magicnum != XFS_SB_MAGIC) { | 114 | if (sbp->sb_magicnum != XFS_SB_MAGIC) { |
| 123 | xfs_warn(mp, "bad magic number"); | 115 | xfs_warn(mp, "bad magic number"); |
| 124 | return -EWRONGFS; | 116 | return -EWRONGFS; |
| @@ -743,17 +735,15 @@ xfs_initialize_perag_data( | |||
| 743 | btree += pag->pagf_btreeblks; | 735 | btree += pag->pagf_btreeblks; |
| 744 | xfs_perag_put(pag); | 736 | xfs_perag_put(pag); |
| 745 | } | 737 | } |
| 746 | /* | 738 | |
| 747 | * Overwrite incore superblock counters with just-read data | 739 | /* Overwrite incore superblock counters with just-read data */ |
| 748 | */ | ||
| 749 | spin_lock(&mp->m_sb_lock); | 740 | spin_lock(&mp->m_sb_lock); |
| 750 | sbp->sb_ifree = ifree; | 741 | sbp->sb_ifree = ifree; |
| 751 | sbp->sb_icount = ialloc; | 742 | sbp->sb_icount = ialloc; |
| 752 | sbp->sb_fdblocks = bfree + bfreelst + btree; | 743 | sbp->sb_fdblocks = bfree + bfreelst + btree; |
| 753 | spin_unlock(&mp->m_sb_lock); | 744 | spin_unlock(&mp->m_sb_lock); |
| 754 | 745 | ||
| 755 | /* Fixup the per-cpu counters as well. */ | 746 | xfs_reinit_percpu_counters(mp); |
| 756 | xfs_icsb_reinit_counters(mp); | ||
| 757 | 747 | ||
| 758 | return 0; | 748 | return 0; |
| 759 | } | 749 | } |
| @@ -771,6 +761,10 @@ xfs_log_sb( | |||
| 771 | struct xfs_mount *mp = tp->t_mountp; | 761 | struct xfs_mount *mp = tp->t_mountp; |
| 772 | struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0); | 762 | struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0); |
| 773 | 763 | ||
| 764 | mp->m_sb.sb_icount = percpu_counter_sum(&mp->m_icount); | ||
| 765 | mp->m_sb.sb_ifree = percpu_counter_sum(&mp->m_ifree); | ||
| 766 | mp->m_sb.sb_fdblocks = percpu_counter_sum(&mp->m_fdblocks); | ||
| 767 | |||
| 774 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); | 768 | xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); |
| 775 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); | 769 | xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); |
| 776 | xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); | 770 | xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); |
