diff options
-rw-r--r-- | fs/xfs/xfs_bmap.c | 79 |
1 files changed, 37 insertions, 42 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 81a95b684b6b..da8fa0cd79c1 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4629,10 +4629,6 @@ xfs_bmapi( | |||
4629 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 4629 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
4630 | xfs_fileoff_t end; /* end of mapped file region */ | 4630 | xfs_fileoff_t end; /* end of mapped file region */ |
4631 | int eof; /* we've hit the end of extents */ | 4631 | int eof; /* we've hit the end of extents */ |
4632 | char contig; /* allocation must be one extent */ | ||
4633 | char delay; /* this request is for delayed alloc */ | ||
4634 | char exact; /* don't do all of wasdelayed extent */ | ||
4635 | char convert; /* unwritten extent I/O completion */ | ||
4636 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 4632 | xfs_bmbt_rec_t *ep; /* extent record pointer */ |
4637 | int error; /* error return */ | 4633 | int error; /* error return */ |
4638 | xfs_bmbt_irec_t got; /* current file extent record */ | 4634 | xfs_bmbt_irec_t got; /* current file extent record */ |
@@ -4651,13 +4647,9 @@ xfs_bmapi( | |||
4651 | int tmp_logflags; /* temp flags holder */ | 4647 | int tmp_logflags; /* temp flags holder */ |
4652 | int whichfork; /* data or attr fork */ | 4648 | int whichfork; /* data or attr fork */ |
4653 | char inhole; /* current location is hole in file */ | 4649 | char inhole; /* current location is hole in file */ |
4654 | char stateless; /* ignore state flag set */ | ||
4655 | char trim; /* output trimmed to match range */ | ||
4656 | char userdata; /* allocating non-metadata */ | ||
4657 | char wasdelay; /* old extent was delayed */ | 4650 | char wasdelay; /* old extent was delayed */ |
4658 | char wr; /* this is a write request */ | 4651 | char wr; /* this is a write request */ |
4659 | char rt; /* this is a realtime file */ | 4652 | char rt; /* this is a realtime file */ |
4660 | char rsvd; /* OK to allocate reserved blocks */ | ||
4661 | #ifdef DEBUG | 4653 | #ifdef DEBUG |
4662 | xfs_fileoff_t orig_bno; /* original block number value */ | 4654 | xfs_fileoff_t orig_bno; /* original block number value */ |
4663 | int orig_flags; /* original flags arg value */ | 4655 | int orig_flags; /* original flags arg value */ |
@@ -4694,15 +4686,8 @@ xfs_bmapi( | |||
4694 | XFS_STATS_INC(xs_blk_mapw); | 4686 | XFS_STATS_INC(xs_blk_mapw); |
4695 | else | 4687 | else |
4696 | XFS_STATS_INC(xs_blk_mapr); | 4688 | XFS_STATS_INC(xs_blk_mapr); |
4697 | delay = (flags & XFS_BMAPI_DELAY) != 0; | ||
4698 | trim = (flags & XFS_BMAPI_ENTIRE) == 0; | ||
4699 | userdata = (flags & XFS_BMAPI_METADATA) == 0; | ||
4700 | convert = (flags & XFS_BMAPI_CONVERT) != 0; | ||
4701 | exact = (flags & XFS_BMAPI_EXACT) != 0; | ||
4702 | rsvd = (flags & XFS_BMAPI_RSVBLOCKS) != 0; | ||
4703 | contig = (flags & XFS_BMAPI_CONTIG) != 0; | ||
4704 | /* | 4689 | /* |
4705 | * stateless is used to combine extents which | 4690 | * IGSTATE flag is used to combine extents which |
4706 | * differ only due to the state of the extents. | 4691 | * differ only due to the state of the extents. |
4707 | * This technique is used from xfs_getbmap() | 4692 | * This technique is used from xfs_getbmap() |
4708 | * when the caller does not wish to see the | 4693 | * when the caller does not wish to see the |
@@ -4718,10 +4703,9 @@ xfs_bmapi( | |||
4718 | * xfs_strat_comp(), where the xfs_bmapi() call | 4703 | * xfs_strat_comp(), where the xfs_bmapi() call |
4719 | * is transactioned, and the extents combined. | 4704 | * is transactioned, and the extents combined. |
4720 | */ | 4705 | */ |
4721 | stateless = (flags & XFS_BMAPI_IGSTATE) != 0; | 4706 | if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ |
4722 | if (stateless && wr) /* if writing unwritten space, no */ | 4707 | wr = 0; /* no allocations are allowed */ |
4723 | wr = 0; /* allocations are allowed */ | 4708 | ASSERT(wr || !(flags & XFS_BMAPI_DELAY)); |
4724 | ASSERT(wr || !delay); | ||
4725 | logflags = 0; | 4709 | logflags = 0; |
4726 | nallocs = 0; | 4710 | nallocs = 0; |
4727 | cur = NULL; | 4711 | cur = NULL; |
@@ -4756,7 +4740,7 @@ xfs_bmapi( | |||
4756 | if (eof && !wr) | 4740 | if (eof && !wr) |
4757 | got.br_startoff = end; | 4741 | got.br_startoff = end; |
4758 | inhole = eof || got.br_startoff > bno; | 4742 | inhole = eof || got.br_startoff > bno; |
4759 | wasdelay = wr && !inhole && !delay && | 4743 | wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) && |
4760 | ISNULLSTARTBLOCK(got.br_startblock); | 4744 | ISNULLSTARTBLOCK(got.br_startblock); |
4761 | /* | 4745 | /* |
4762 | * First, deal with the hole before the allocated space | 4746 | * First, deal with the hole before the allocated space |
@@ -4768,7 +4752,7 @@ xfs_bmapi( | |||
4768 | * allocate the stuff asked for in this bmap call | 4752 | * allocate the stuff asked for in this bmap call |
4769 | * but that wouldn't be as good. | 4753 | * but that wouldn't be as good. |
4770 | */ | 4754 | */ |
4771 | if (wasdelay && !exact) { | 4755 | if (wasdelay && !(flags & XFS_BMAPI_EXACT)) { |
4772 | alen = (xfs_extlen_t)got.br_blockcount; | 4756 | alen = (xfs_extlen_t)got.br_blockcount; |
4773 | aoff = got.br_startoff; | 4757 | aoff = got.br_startoff; |
4774 | if (lastx != NULLEXTNUM && lastx) { | 4758 | if (lastx != NULLEXTNUM && lastx) { |
@@ -4790,8 +4774,8 @@ xfs_bmapi( | |||
4790 | got.br_startoff - bno); | 4774 | got.br_startoff - bno); |
4791 | aoff = bno; | 4775 | aoff = bno; |
4792 | } | 4776 | } |
4793 | minlen = contig ? alen : 1; | 4777 | minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; |
4794 | if (delay) { | 4778 | if (flags & XFS_BMAPI_DELAY) { |
4795 | xfs_extlen_t extsz; | 4779 | xfs_extlen_t extsz; |
4796 | 4780 | ||
4797 | /* Figure out the extent size, adjust alen */ | 4781 | /* Figure out the extent size, adjust alen */ |
@@ -4804,7 +4788,9 @@ xfs_bmapi( | |||
4804 | if (extsz) { | 4788 | if (extsz) { |
4805 | error = xfs_bmap_extsize_align(mp, | 4789 | error = xfs_bmap_extsize_align(mp, |
4806 | &got, &prev, extsz, | 4790 | &got, &prev, extsz, |
4807 | rt, eof, delay, convert, | 4791 | rt, eof, |
4792 | flags&XFS_BMAPI_DELAY, | ||
4793 | flags&XFS_BMAPI_CONVERT, | ||
4808 | &aoff, &alen); | 4794 | &aoff, &alen); |
4809 | ASSERT(!error); | 4795 | ASSERT(!error); |
4810 | } | 4796 | } |
@@ -4842,24 +4828,29 @@ xfs_bmapi( | |||
4842 | if (rt) { | 4828 | if (rt) { |
4843 | error = xfs_mod_incore_sb(mp, | 4829 | error = xfs_mod_incore_sb(mp, |
4844 | XFS_SBS_FREXTENTS, | 4830 | XFS_SBS_FREXTENTS, |
4845 | -(extsz), rsvd); | 4831 | -(extsz), (flags & |
4832 | XFS_BMAPI_RSVBLOCKS)); | ||
4846 | } else { | 4833 | } else { |
4847 | error = xfs_mod_incore_sb(mp, | 4834 | error = xfs_mod_incore_sb(mp, |
4848 | XFS_SBS_FDBLOCKS, | 4835 | XFS_SBS_FDBLOCKS, |
4849 | -(alen), rsvd); | 4836 | -(alen), (flags & |
4837 | XFS_BMAPI_RSVBLOCKS)); | ||
4850 | } | 4838 | } |
4851 | if (!error) { | 4839 | if (!error) { |
4852 | error = xfs_mod_incore_sb(mp, | 4840 | error = xfs_mod_incore_sb(mp, |
4853 | XFS_SBS_FDBLOCKS, | 4841 | XFS_SBS_FDBLOCKS, |
4854 | -(indlen), rsvd); | 4842 | -(indlen), (flags & |
4843 | XFS_BMAPI_RSVBLOCKS)); | ||
4855 | if (error && rt) | 4844 | if (error && rt) |
4856 | xfs_mod_incore_sb(mp, | 4845 | xfs_mod_incore_sb(mp, |
4857 | XFS_SBS_FREXTENTS, | 4846 | XFS_SBS_FREXTENTS, |
4858 | extsz, rsvd); | 4847 | extsz, (flags & |
4848 | XFS_BMAPI_RSVBLOCKS)); | ||
4859 | else if (error) | 4849 | else if (error) |
4860 | xfs_mod_incore_sb(mp, | 4850 | xfs_mod_incore_sb(mp, |
4861 | XFS_SBS_FDBLOCKS, | 4851 | XFS_SBS_FDBLOCKS, |
4862 | alen, rsvd); | 4852 | alen, (flags & |
4853 | XFS_BMAPI_RSVBLOCKS)); | ||
4863 | } | 4854 | } |
4864 | 4855 | ||
4865 | if (error) { | 4856 | if (error) { |
@@ -4892,7 +4883,7 @@ xfs_bmapi( | |||
4892 | /* Indicate if this is the first user data | 4883 | /* Indicate if this is the first user data |
4893 | * in the file, or just any user data. | 4884 | * in the file, or just any user data. |
4894 | */ | 4885 | */ |
4895 | if (userdata) { | 4886 | if (!(flags & XFS_BMAPI_METADATA)) { |
4896 | bma.userdata = (aoff == 0) ? | 4887 | bma.userdata = (aoff == 0) ? |
4897 | XFS_ALLOC_INITIAL_USER_DATA : | 4888 | XFS_ALLOC_INITIAL_USER_DATA : |
4898 | XFS_ALLOC_USERDATA; | 4889 | XFS_ALLOC_USERDATA; |
@@ -4904,7 +4895,7 @@ xfs_bmapi( | |||
4904 | bma.firstblock = *firstblock; | 4895 | bma.firstblock = *firstblock; |
4905 | bma.alen = alen; | 4896 | bma.alen = alen; |
4906 | bma.off = aoff; | 4897 | bma.off = aoff; |
4907 | bma.conv = convert; | 4898 | bma.conv = (flags & XFS_BMAPI_CONVERT); |
4908 | bma.wasdel = wasdelay; | 4899 | bma.wasdel = wasdelay; |
4909 | bma.minlen = minlen; | 4900 | bma.minlen = minlen; |
4910 | bma.low = flist->xbf_low; | 4901 | bma.low = flist->xbf_low; |
@@ -4915,7 +4906,8 @@ xfs_bmapi( | |||
4915 | * is larger than a stripe unit. | 4906 | * is larger than a stripe unit. |
4916 | */ | 4907 | */ |
4917 | if (mp->m_dalign && alen >= mp->m_dalign && | 4908 | if (mp->m_dalign && alen >= mp->m_dalign && |
4918 | userdata && whichfork == XFS_DATA_FORK) { | 4909 | (!(flags & XFS_BMAPI_METADATA)) && |
4910 | (whichfork == XFS_DATA_FORK)) { | ||
4919 | if ((error = xfs_bmap_isaeof(ip, aoff, | 4911 | if ((error = xfs_bmap_isaeof(ip, aoff, |
4920 | whichfork, &bma.aeof))) | 4912 | whichfork, &bma.aeof))) |
4921 | goto error0; | 4913 | goto error0; |
@@ -4978,7 +4970,7 @@ xfs_bmapi( | |||
4978 | } | 4970 | } |
4979 | error = xfs_bmap_add_extent(ip, lastx, &cur, &got, | 4971 | error = xfs_bmap_add_extent(ip, lastx, &cur, &got, |
4980 | firstblock, flist, &tmp_logflags, whichfork, | 4972 | firstblock, flist, &tmp_logflags, whichfork, |
4981 | rsvd); | 4973 | (flags & XFS_BMAPI_RSVBLOCKS)); |
4982 | logflags |= tmp_logflags; | 4974 | logflags |= tmp_logflags; |
4983 | if (error) | 4975 | if (error) |
4984 | goto error0; | 4976 | goto error0; |
@@ -4990,7 +4982,7 @@ xfs_bmapi( | |||
4990 | ASSERT(got.br_startoff + got.br_blockcount >= | 4982 | ASSERT(got.br_startoff + got.br_blockcount >= |
4991 | aoff + alen); | 4983 | aoff + alen); |
4992 | #ifdef DEBUG | 4984 | #ifdef DEBUG |
4993 | if (delay) { | 4985 | if (flags & XFS_BMAPI_DELAY) { |
4994 | ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); | 4986 | ASSERT(ISNULLSTARTBLOCK(got.br_startblock)); |
4995 | ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); | 4987 | ASSERT(STARTBLOCKVAL(got.br_startblock) > 0); |
4996 | } | 4988 | } |
@@ -5019,14 +5011,15 @@ xfs_bmapi( | |||
5019 | * Then deal with the allocated space we found. | 5011 | * Then deal with the allocated space we found. |
5020 | */ | 5012 | */ |
5021 | ASSERT(ep != NULL); | 5013 | ASSERT(ep != NULL); |
5022 | if (trim && (got.br_startoff + got.br_blockcount > obno)) { | 5014 | if (!(flags & XFS_BMAPI_ENTIRE) && |
5015 | (got.br_startoff + got.br_blockcount > obno)) { | ||
5023 | if (obno > bno) | 5016 | if (obno > bno) |
5024 | bno = obno; | 5017 | bno = obno; |
5025 | ASSERT((bno >= obno) || (n == 0)); | 5018 | ASSERT((bno >= obno) || (n == 0)); |
5026 | ASSERT(bno < end); | 5019 | ASSERT(bno < end); |
5027 | mval->br_startoff = bno; | 5020 | mval->br_startoff = bno; |
5028 | if (ISNULLSTARTBLOCK(got.br_startblock)) { | 5021 | if (ISNULLSTARTBLOCK(got.br_startblock)) { |
5029 | ASSERT(!wr || delay); | 5022 | ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); |
5030 | mval->br_startblock = DELAYSTARTBLOCK; | 5023 | mval->br_startblock = DELAYSTARTBLOCK; |
5031 | } else | 5024 | } else |
5032 | mval->br_startblock = | 5025 | mval->br_startblock = |
@@ -5048,7 +5041,7 @@ xfs_bmapi( | |||
5048 | } else { | 5041 | } else { |
5049 | *mval = got; | 5042 | *mval = got; |
5050 | if (ISNULLSTARTBLOCK(mval->br_startblock)) { | 5043 | if (ISNULLSTARTBLOCK(mval->br_startblock)) { |
5051 | ASSERT(!wr || delay); | 5044 | ASSERT(!wr || (flags & XFS_BMAPI_DELAY)); |
5052 | mval->br_startblock = DELAYSTARTBLOCK; | 5045 | mval->br_startblock = DELAYSTARTBLOCK; |
5053 | } | 5046 | } |
5054 | } | 5047 | } |
@@ -5074,7 +5067,7 @@ xfs_bmapi( | |||
5074 | mval->br_state = XFS_EXT_NORM; | 5067 | mval->br_state = XFS_EXT_NORM; |
5075 | error = xfs_bmap_add_extent(ip, lastx, &cur, mval, | 5068 | error = xfs_bmap_add_extent(ip, lastx, &cur, mval, |
5076 | firstblock, flist, &tmp_logflags, whichfork, | 5069 | firstblock, flist, &tmp_logflags, whichfork, |
5077 | rsvd); | 5070 | (flags & XFS_BMAPI_RSVBLOCKS)); |
5078 | logflags |= tmp_logflags; | 5071 | logflags |= tmp_logflags; |
5079 | if (error) | 5072 | if (error) |
5080 | goto error0; | 5073 | goto error0; |
@@ -5091,9 +5084,10 @@ xfs_bmapi( | |||
5091 | continue; | 5084 | continue; |
5092 | } | 5085 | } |
5093 | 5086 | ||
5094 | ASSERT(!trim || | 5087 | ASSERT((flags & XFS_BMAPI_ENTIRE) || |
5095 | ((mval->br_startoff + mval->br_blockcount) <= end)); | 5088 | ((mval->br_startoff + mval->br_blockcount) <= end)); |
5096 | ASSERT(!trim || (mval->br_blockcount <= len) || | 5089 | ASSERT((flags & XFS_BMAPI_ENTIRE) || |
5090 | (mval->br_blockcount <= len) || | ||
5097 | (mval->br_startoff < obno)); | 5091 | (mval->br_startoff < obno)); |
5098 | bno = mval->br_startoff + mval->br_blockcount; | 5092 | bno = mval->br_startoff + mval->br_blockcount; |
5099 | len = end - bno; | 5093 | len = end - bno; |
@@ -5108,7 +5102,8 @@ xfs_bmapi( | |||
5108 | mval[-1].br_startblock != HOLESTARTBLOCK && | 5102 | mval[-1].br_startblock != HOLESTARTBLOCK && |
5109 | mval->br_startblock == | 5103 | mval->br_startblock == |
5110 | mval[-1].br_startblock + mval[-1].br_blockcount && | 5104 | mval[-1].br_startblock + mval[-1].br_blockcount && |
5111 | (stateless || mval[-1].br_state == mval->br_state)) { | 5105 | ((flags & XFS_BMAPI_IGSTATE) || |
5106 | mval[-1].br_state == mval->br_state)) { | ||
5112 | ASSERT(mval->br_startoff == | 5107 | ASSERT(mval->br_startoff == |
5113 | mval[-1].br_startoff + mval[-1].br_blockcount); | 5108 | mval[-1].br_startoff + mval[-1].br_blockcount); |
5114 | mval[-1].br_blockcount += mval->br_blockcount; | 5109 | mval[-1].br_blockcount += mval->br_blockcount; |