diff options
| -rw-r--r-- | fs/xfs/xfs_iomap.c | 61 | ||||
| -rw-r--r-- | fs/xfs/xfs_iomap.h | 3 |
2 files changed, 16 insertions, 48 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7b8b17071030..5aaa2d7ec155 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
| @@ -338,38 +338,6 @@ xfs_iomap_eof_align_last_fsb( | |||
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | STATIC int | 340 | STATIC int |
| 341 | xfs_flush_space( | ||
| 342 | xfs_inode_t *ip, | ||
| 343 | int *fsynced, | ||
| 344 | int *ioflags) | ||
| 345 | { | ||
| 346 | switch (*fsynced) { | ||
| 347 | case 0: | ||
| 348 | if (ip->i_delayed_blks) { | ||
| 349 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 350 | delay(1); | ||
| 351 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 352 | *fsynced = 1; | ||
| 353 | } else { | ||
| 354 | *ioflags |= BMAPI_SYNC; | ||
| 355 | *fsynced = 2; | ||
| 356 | } | ||
| 357 | return 0; | ||
| 358 | case 1: | ||
| 359 | *fsynced = 2; | ||
| 360 | *ioflags |= BMAPI_SYNC; | ||
| 361 | return 0; | ||
| 362 | case 2: | ||
| 363 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 364 | xfs_flush_inodes(ip); | ||
| 365 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 366 | *fsynced = 3; | ||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | return 1; | ||
| 370 | } | ||
| 371 | |||
| 372 | STATIC int | ||
| 373 | xfs_cmn_err_fsblock_zero( | 341 | xfs_cmn_err_fsblock_zero( |
| 374 | xfs_inode_t *ip, | 342 | xfs_inode_t *ip, |
| 375 | xfs_bmbt_irec_t *imap) | 343 | xfs_bmbt_irec_t *imap) |
| @@ -538,15 +506,9 @@ error_out: | |||
| 538 | } | 506 | } |
| 539 | 507 | ||
| 540 | /* | 508 | /* |
| 541 | * If the caller is doing a write at the end of the file, | 509 | * If the caller is doing a write at the end of the file, then extend the |
| 542 | * then extend the allocation out to the file system's write | 510 | * allocation out to the file system's write iosize. We clean up any extra |
| 543 | * iosize. We clean up any extra space left over when the | 511 | * space left over when the file is closed in xfs_inactive(). |
| 544 | * file is closed in xfs_inactive(). | ||
| 545 | * | ||
| 546 | * For sync writes, we are flushing delayed allocate space to | ||
| 547 | * try to make additional space available for allocation near | ||
| 548 | * the filesystem full boundary - preallocation hurts in that | ||
| 549 | * situation, of course. | ||
| 550 | */ | 512 | */ |
| 551 | STATIC int | 513 | STATIC int |
| 552 | xfs_iomap_eof_want_preallocate( | 514 | xfs_iomap_eof_want_preallocate( |
| @@ -565,7 +527,7 @@ xfs_iomap_eof_want_preallocate( | |||
| 565 | int n, error, imaps; | 527 | int n, error, imaps; |
| 566 | 528 | ||
| 567 | *prealloc = 0; | 529 | *prealloc = 0; |
| 568 | if ((ioflag & BMAPI_SYNC) || (offset + count) <= ip->i_size) | 530 | if ((offset + count) <= ip->i_size) |
| 569 | return 0; | 531 | return 0; |
| 570 | 532 | ||
| 571 | /* | 533 | /* |
| @@ -611,7 +573,7 @@ xfs_iomap_write_delay( | |||
| 611 | xfs_extlen_t extsz; | 573 | xfs_extlen_t extsz; |
| 612 | int nimaps; | 574 | int nimaps; |
| 613 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; | 575 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; |
| 614 | int prealloc, fsynced = 0; | 576 | int prealloc, flushed = 0; |
| 615 | int error; | 577 | int error; |
| 616 | 578 | ||
| 617 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 579 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
| @@ -627,12 +589,12 @@ xfs_iomap_write_delay( | |||
| 627 | extsz = xfs_get_extsz_hint(ip); | 589 | extsz = xfs_get_extsz_hint(ip); |
| 628 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 590 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
| 629 | 591 | ||
| 630 | retry: | ||
| 631 | error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count, | 592 | error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count, |
| 632 | ioflag, imap, XFS_WRITE_IMAPS, &prealloc); | 593 | ioflag, imap, XFS_WRITE_IMAPS, &prealloc); |
| 633 | if (error) | 594 | if (error) |
| 634 | return error; | 595 | return error; |
| 635 | 596 | ||
| 597 | retry: | ||
| 636 | if (prealloc) { | 598 | if (prealloc) { |
| 637 | aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); | 599 | aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); |
| 638 | ioalign = XFS_B_TO_FSBT(mp, aligned_offset); | 600 | ioalign = XFS_B_TO_FSBT(mp, aligned_offset); |
| @@ -659,15 +621,22 @@ retry: | |||
| 659 | 621 | ||
| 660 | /* | 622 | /* |
| 661 | * If bmapi returned us nothing, and if we didn't get back EDQUOT, | 623 | * If bmapi returned us nothing, and if we didn't get back EDQUOT, |
| 662 | * then we must have run out of space - flush delalloc, and retry.. | 624 | * then we must have run out of space - flush all other inodes with |
| 625 | * delalloc blocks and retry without EOF preallocation. | ||
| 663 | */ | 626 | */ |
| 664 | if (nimaps == 0) { | 627 | if (nimaps == 0) { |
| 665 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, | 628 | xfs_iomap_enter_trace(XFS_IOMAP_WRITE_NOSPACE, |
| 666 | ip, offset, count); | 629 | ip, offset, count); |
| 667 | if (xfs_flush_space(ip, &fsynced, &ioflag)) | 630 | if (flushed) |
| 668 | return XFS_ERROR(ENOSPC); | 631 | return XFS_ERROR(ENOSPC); |
| 669 | 632 | ||
| 633 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
| 634 | xfs_flush_inodes(ip); | ||
| 635 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
| 636 | |||
| 637 | flushed = 1; | ||
| 670 | error = 0; | 638 | error = 0; |
| 639 | prealloc = 0; | ||
| 671 | goto retry; | 640 | goto retry; |
| 672 | } | 641 | } |
| 673 | 642 | ||
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index a1cc1322fc0f..fdcf7b82747f 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h | |||
| @@ -40,8 +40,7 @@ typedef enum { | |||
| 40 | BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ | 40 | BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ |
| 41 | BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ | 41 | BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ |
| 42 | BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ | 42 | BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ |
| 43 | BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ | 43 | BMAPI_TRYLOCK = (1 << 7), /* non-blocking request */ |
| 44 | BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ | ||
| 45 | } bmapi_flags_t; | 44 | } bmapi_flags_t; |
| 46 | 45 | ||
| 47 | 46 | ||
