aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iomap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iomap.c')
-rw-r--r--fs/xfs/xfs_iomap.c170
1 files changed, 57 insertions, 113 deletions
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index ab69caa685b4..6af1d3ec0a9c 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -677,25 +677,19 @@ out_unlock:
677 */ 677 */
678int 678int
679xfs_iomap_write_allocate( 679xfs_iomap_write_allocate(
680 xfs_inode_t *ip, 680 struct xfs_inode *ip,
681 int whichfork, 681 int whichfork,
682 xfs_off_t offset, 682 xfs_off_t offset,
683 xfs_bmbt_irec_t *imap, 683 struct xfs_bmbt_irec *imap,
684 unsigned int *seq) 684 unsigned int *seq)
685{ 685{
686 xfs_mount_t *mp = ip->i_mount; 686 struct xfs_mount *mp = ip->i_mount;
687 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork); 687 struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
688 xfs_fileoff_t offset_fsb, last_block; 688 xfs_fileoff_t offset_fsb;
689 xfs_fileoff_t end_fsb, map_start_fsb; 689 xfs_fileoff_t map_start_fsb;
690 xfs_filblks_t count_fsb; 690 xfs_extlen_t map_count_fsb;
691 xfs_trans_t *tp; 691 struct xfs_trans *tp;
692 int nimaps; 692 int error = 0;
693 int error = 0;
694 int flags = XFS_BMAPI_DELALLOC;
695 int nres;
696
697 if (whichfork == XFS_COW_FORK)
698 flags |= XFS_BMAPI_COWFORK | XFS_BMAPI_PREALLOC;
699 693
700 /* 694 /*
701 * Make sure that the dquots are there. 695 * Make sure that the dquots are there.
@@ -704,106 +698,60 @@ xfs_iomap_write_allocate(
704 if (error) 698 if (error)
705 return error; 699 return error;
706 700
701 /*
702 * Store the file range the caller is interested in because it encodes
703 * state such as potential overlap with COW fork blocks. We must trim
704 * the allocated extent down to this range to maintain consistency with
705 * what the caller expects. Revalidation of the range itself is the
706 * responsibility of the caller.
707 */
707 offset_fsb = XFS_B_TO_FSBT(mp, offset); 708 offset_fsb = XFS_B_TO_FSBT(mp, offset);
708 count_fsb = imap->br_blockcount;
709 map_start_fsb = imap->br_startoff; 709 map_start_fsb = imap->br_startoff;
710 map_count_fsb = imap->br_blockcount;
710 711
711 XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); 712 XFS_STATS_ADD(mp, xs_xstrat_bytes,
713 XFS_FSB_TO_B(mp, imap->br_blockcount));
712 714
713 while (count_fsb != 0) { 715 while (true) {
714 /* 716 /*
715 * Set up a transaction with which to allocate the 717 * Allocate in a loop because it may take several attempts to
716 * backing store for the file. Do allocations in a 718 * allocate real blocks for a contiguous delalloc extent if free
717 * loop until we get some space in the range we are 719 * space is sufficiently fragmented. Note that space for the
718 * interested in. The other space that might be allocated 720 * extent and indirect blocks was reserved when the delalloc
719 * is in the delayed allocation extent on which we sit 721 * extent was created so there's no need to do so here.
720 * but before our buffer starts.
721 */ 722 */
722 nimaps = 0; 723 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0, 0,
723 while (nimaps == 0) { 724 XFS_TRANS_RESERVE, &tp);
724 nres = XFS_EXTENTADD_SPACE_RES(mp, XFS_DATA_FORK); 725 if (error)
725 /* 726 return error;
726 * We have already reserved space for the extent and any
727 * indirect blocks when creating the delalloc extent,
728 * there is no need to reserve space in this transaction
729 * again.
730 */
731 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_write, 0,
732 0, XFS_TRANS_RESERVE, &tp);
733 if (error)
734 return error;
735
736 xfs_ilock(ip, XFS_ILOCK_EXCL);
737 xfs_trans_ijoin(tp, ip, 0);
738
739 /*
740 * it is possible that the extents have changed since
741 * we did the read call as we dropped the ilock for a
742 * while. We have to be careful about truncates or hole
743 * punchs here - we are not allowed to allocate
744 * non-delalloc blocks here.
745 *
746 * The only protection against truncation is the pages
747 * for the range we are being asked to convert are
748 * locked and hence a truncate will block on them
749 * first.
750 *
751 * As a result, if we go beyond the range we really
752 * need and hit an delalloc extent boundary followed by
753 * a hole while we have excess blocks in the map, we
754 * will fill the hole incorrectly and overrun the
755 * transaction reservation.
756 *
757 * Using a single map prevents this as we are forced to
758 * check each map we look for overlap with the desired
759 * range and abort as soon as we find it. Also, given
760 * that we only return a single map, having one beyond
761 * what we can return is probably a bit silly.
762 *
763 * We also need to check that we don't go beyond EOF;
764 * this is a truncate optimisation as a truncate sets
765 * the new file size before block on the pages we
766 * currently have locked under writeback. Because they
767 * are about to be tossed, we don't need to write them
768 * back....
769 */
770 nimaps = 1;
771 end_fsb = XFS_B_TO_FSB(mp, XFS_ISIZE(ip));
772 error = xfs_bmap_last_offset(ip, &last_block,
773 XFS_DATA_FORK);
774 if (error)
775 goto trans_cancel;
776 727
777 last_block = XFS_FILEOFF_MAX(last_block, end_fsb); 728 xfs_ilock(ip, XFS_ILOCK_EXCL);
778 if ((map_start_fsb + count_fsb) > last_block) { 729 xfs_trans_ijoin(tp, ip, 0);
779 count_fsb = last_block - map_start_fsb;
780 if (count_fsb == 0) {
781 error = -EAGAIN;
782 goto trans_cancel;
783 }
784 }
785 730
786 /* 731 /*
787 * From this point onwards we overwrite the imap 732 * ilock was dropped since imap was populated which means it
788 * pointer that the caller gave to us. 733 * might no longer be valid. The current page is held locked so
789 */ 734 * nothing could have removed the block backing offset_fsb.
790 error = xfs_bmapi_write(tp, ip, map_start_fsb, 735 * Attempt to allocate whatever delalloc extent currently backs
791 count_fsb, flags, nres, imap, 736 * offset_fsb and put the result in the imap pointer from the
792 &nimaps); 737 * caller. We'll trim it down to the caller's most recently
793 if (error) 738 * validated range before we return.
794 goto trans_cancel; 739 */
740 error = xfs_bmapi_convert_delalloc(tp, ip, offset_fsb,
741 whichfork, imap);
742 if (error)
743 goto trans_cancel;
795 744
796 error = xfs_trans_commit(tp); 745 error = xfs_trans_commit(tp);
797 if (error) 746 if (error)
798 goto error0; 747 goto error0;
799 748
800 *seq = READ_ONCE(ifp->if_seq); 749 *seq = READ_ONCE(ifp->if_seq);
801 xfs_iunlock(ip, XFS_ILOCK_EXCL); 750 xfs_iunlock(ip, XFS_ILOCK_EXCL);
802 }
803 751
804 /* 752 /*
805 * See if we were able to allocate an extent that 753 * See if we were able to allocate an extent that covers at
806 * covers at least part of the callers request 754 * least part of the callers request.
807 */ 755 */
808 if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) 756 if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip)))
809 return xfs_alert_fsblock_zero(ip, imap); 757 return xfs_alert_fsblock_zero(ip, imap);
@@ -812,15 +760,11 @@ xfs_iomap_write_allocate(
812 (offset_fsb < (imap->br_startoff + 760 (offset_fsb < (imap->br_startoff +
813 imap->br_blockcount))) { 761 imap->br_blockcount))) {
814 XFS_STATS_INC(mp, xs_xstrat_quick); 762 XFS_STATS_INC(mp, xs_xstrat_quick);
763 xfs_trim_extent(imap, map_start_fsb, map_count_fsb);
764 ASSERT(offset_fsb >= imap->br_startoff &&
765 offset_fsb < imap->br_startoff + imap->br_blockcount);
815 return 0; 766 return 0;
816 } 767 }
817
818 /*
819 * So far we have not mapped the requested part of the
820 * file, just surrounding data, try again.
821 */
822 count_fsb -= imap->br_blockcount;
823 map_start_fsb = imap->br_startoff + imap->br_blockcount;
824 } 768 }
825 769
826trans_cancel: 770trans_cancel: