diff options
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
| -rw-r--r-- | fs/xfs/xfs_iomap.c | 65 |
1 files changed, 27 insertions, 38 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 469e1a7939d4..2edd6769e5d3 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
| @@ -385,15 +385,15 @@ xfs_iomap_write_direct( | |||
| 385 | int nimaps, maps; | 385 | int nimaps, maps; |
| 386 | int error; | 386 | int error; |
| 387 | int bmapi_flag; | 387 | int bmapi_flag; |
| 388 | int quota_flag; | ||
| 388 | int rt; | 389 | int rt; |
| 389 | xfs_trans_t *tp; | 390 | xfs_trans_t *tp; |
| 390 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; | 391 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS], *imapp; |
| 391 | xfs_bmap_free_t free_list; | 392 | xfs_bmap_free_t free_list; |
| 392 | int aeof; | 393 | int aeof; |
| 393 | xfs_filblks_t datablocks; | 394 | xfs_filblks_t datablocks, qblocks, resblks; |
| 394 | int committed; | 395 | int committed; |
| 395 | int numrtextents; | 396 | int numrtextents; |
| 396 | uint resblks; | ||
| 397 | 397 | ||
| 398 | /* | 398 | /* |
| 399 | * Make sure that the dquots are there. This doesn't hold | 399 | * Make sure that the dquots are there. This doesn't hold |
| @@ -419,7 +419,6 @@ xfs_iomap_write_direct( | |||
| 419 | xfs_fileoff_t map_last_fsb; | 419 | xfs_fileoff_t map_last_fsb; |
| 420 | 420 | ||
| 421 | map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; | 421 | map_last_fsb = ret_imap->br_blockcount + ret_imap->br_startoff; |
| 422 | |||
| 423 | if (map_last_fsb < last_fsb) { | 422 | if (map_last_fsb < last_fsb) { |
| 424 | last_fsb = map_last_fsb; | 423 | last_fsb = map_last_fsb; |
| 425 | count_fsb = last_fsb - offset_fsb; | 424 | count_fsb = last_fsb - offset_fsb; |
| @@ -428,56 +427,47 @@ xfs_iomap_write_direct( | |||
| 428 | } | 427 | } |
| 429 | 428 | ||
| 430 | /* | 429 | /* |
| 431 | * determine if reserving space on | 430 | * Determine if reserving space on the data or realtime partition. |
| 432 | * the data or realtime partition. | ||
| 433 | */ | 431 | */ |
| 434 | if ((rt = XFS_IS_REALTIME_INODE(ip))) { | 432 | if ((rt = XFS_IS_REALTIME_INODE(ip))) { |
| 435 | int sbrtextsize, iprtextsize; | 433 | xfs_extlen_t extsz; |
| 436 | 434 | ||
| 437 | sbrtextsize = mp->m_sb.sb_rextsize; | 435 | if (!(extsz = ip->i_d.di_extsize)) |
| 438 | iprtextsize = | 436 | extsz = mp->m_sb.sb_rextsize; |
| 439 | ip->i_d.di_extsize ? ip->i_d.di_extsize : sbrtextsize; | 437 | numrtextents = qblocks = (count_fsb + extsz - 1); |
| 440 | numrtextents = (count_fsb + iprtextsize - 1); | 438 | do_div(numrtextents, mp->m_sb.sb_rextsize); |
| 441 | do_div(numrtextents, sbrtextsize); | 439 | quota_flag = XFS_QMOPT_RES_RTBLKS; |
| 442 | datablocks = 0; | 440 | datablocks = 0; |
| 443 | } else { | 441 | } else { |
| 444 | datablocks = count_fsb; | 442 | datablocks = qblocks = count_fsb; |
| 443 | quota_flag = XFS_QMOPT_RES_REGBLKS; | ||
| 445 | numrtextents = 0; | 444 | numrtextents = 0; |
| 446 | } | 445 | } |
| 447 | 446 | ||
| 448 | /* | 447 | /* |
| 449 | * allocate and setup the transaction | 448 | * Allocate and setup the transaction |
| 450 | */ | 449 | */ |
| 451 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 450 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| 452 | tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); | 451 | tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); |
| 453 | |||
| 454 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); | 452 | resblks = XFS_DIOSTRAT_SPACE_RES(mp, datablocks); |
| 455 | |||
| 456 | error = xfs_trans_reserve(tp, resblks, | 453 | error = xfs_trans_reserve(tp, resblks, |
| 457 | XFS_WRITE_LOG_RES(mp), numrtextents, | 454 | XFS_WRITE_LOG_RES(mp), numrtextents, |
| 458 | XFS_TRANS_PERM_LOG_RES, | 455 | XFS_TRANS_PERM_LOG_RES, |
| 459 | XFS_WRITE_LOG_COUNT); | 456 | XFS_WRITE_LOG_COUNT); |
| 460 | 457 | ||
| 461 | /* | 458 | /* |
| 462 | * check for running out of space | 459 | * Check for running out of space, note: need lock to return |
| 463 | */ | 460 | */ |
| 464 | if (error) | 461 | if (error) |
| 465 | /* | ||
| 466 | * Free the transaction structure. | ||
| 467 | */ | ||
| 468 | xfs_trans_cancel(tp, 0); | 462 | xfs_trans_cancel(tp, 0); |
| 469 | |||
| 470 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 463 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| 471 | |||
| 472 | if (error) | 464 | if (error) |
| 473 | goto error_out; /* Don't return in above if .. trans .., | 465 | goto error_out; |
| 474 | need lock to return */ | ||
| 475 | 466 | ||
| 476 | if (XFS_TRANS_RESERVE_BLKQUOTA(mp, tp, ip, resblks)) { | 467 | if (XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag)) { |
| 477 | error = (EDQUOT); | 468 | error = (EDQUOT); |
| 478 | goto error1; | 469 | goto error1; |
| 479 | } | 470 | } |
| 480 | nimaps = 1; | ||
| 481 | 471 | ||
| 482 | bmapi_flag = XFS_BMAPI_WRITE; | 472 | bmapi_flag = XFS_BMAPI_WRITE; |
| 483 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | 473 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); |
| @@ -487,31 +477,29 @@ xfs_iomap_write_direct( | |||
| 487 | bmapi_flag |= XFS_BMAPI_PREALLOC; | 477 | bmapi_flag |= XFS_BMAPI_PREALLOC; |
| 488 | 478 | ||
| 489 | /* | 479 | /* |
| 490 | * issue the bmapi() call to allocate the blocks | 480 | * Issue the bmapi() call to allocate the blocks |
| 491 | */ | 481 | */ |
| 492 | XFS_BMAP_INIT(&free_list, &firstfsb); | 482 | XFS_BMAP_INIT(&free_list, &firstfsb); |
| 483 | nimaps = 1; | ||
| 493 | imapp = &imap[0]; | 484 | imapp = &imap[0]; |
| 494 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, | 485 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, |
| 495 | bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); | 486 | bmapi_flag, &firstfsb, 0, imapp, &nimaps, &free_list); |
| 496 | if (error) { | 487 | if (error) |
| 497 | goto error0; | 488 | goto error0; |
| 498 | } | ||
| 499 | 489 | ||
| 500 | /* | 490 | /* |
| 501 | * complete the transaction | 491 | * Complete the transaction |
| 502 | */ | 492 | */ |
| 503 | |||
| 504 | error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); | 493 | error = xfs_bmap_finish(&tp, &free_list, firstfsb, &committed); |
| 505 | if (error) { | 494 | if (error) |
| 506 | goto error0; | 495 | goto error0; |
| 507 | } | ||
| 508 | |||
| 509 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); | 496 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); |
| 510 | if (error) { | 497 | if (error) |
| 511 | goto error_out; | 498 | goto error_out; |
| 512 | } | ||
| 513 | 499 | ||
| 514 | /* copy any maps to caller's array and return any error. */ | 500 | /* |
| 501 | * Copy any maps to caller's array and return any error. | ||
| 502 | */ | ||
| 515 | if (nimaps == 0) { | 503 | if (nimaps == 0) { |
| 516 | error = (ENOSPC); | 504 | error = (ENOSPC); |
| 517 | goto error_out; | 505 | goto error_out; |
| @@ -530,10 +518,11 @@ xfs_iomap_write_direct( | |||
| 530 | } | 518 | } |
| 531 | return 0; | 519 | return 0; |
| 532 | 520 | ||
| 533 | error0: /* Cancel bmap, unlock inode, and cancel trans */ | 521 | error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ |
| 534 | xfs_bmap_cancel(&free_list); | 522 | xfs_bmap_cancel(&free_list); |
| 523 | XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp, tp, ip, qblocks, 0, quota_flag); | ||
| 535 | 524 | ||
| 536 | error1: /* Just cancel transaction */ | 525 | error1: /* Just cancel transaction */ |
| 537 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | 526 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); |
| 538 | *nmaps = 0; /* nothing set-up here */ | 527 | *nmaps = 0; /* nothing set-up here */ |
| 539 | 528 | ||
