aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_bmap.c79
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;