diff options
author | Dave Chinner <dchinner@redhat.com> | 2011-09-18 16:40:52 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-10-11 22:15:04 -0400 |
commit | c0dc7828af6952643219292be29e482ef74cb261 (patch) | |
tree | 02f12935ec56f61a9ed396d1b902b21aaf4ffb3e /fs/xfs/xfs_bmap.c | |
parent | b447fe5a05cbd01c4bf7fe2fa41cb9e99ce7e58e (diff) |
xfs: rename xfs_bmapi to xfs_bmapi_write
Now that all the read-only users of xfs_bmapi have been converted to
use xfs_bmapi_read(), we can remove all the read-only handling cases
from xfs_bmapi().
Once this is done, rename xfs_bmapi to xfs_bmapi_write to reflect
the fact it is for allocation only. This enables us to kill the
XFS_BMAPI_WRITE flag as well.
Also clean up xfs_bmapi_write to the style used in the newly added
xfs_bmapi_read/delay functions.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 225 |
1 files changed, 94 insertions, 131 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index c2e49fd18bfd..595cc6311937 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4211,9 +4211,8 @@ xfs_bmap_validate_ret( | |||
4211 | ASSERT(i == 0 || | 4211 | ASSERT(i == 0 || |
4212 | mval[i - 1].br_startoff + mval[i - 1].br_blockcount == | 4212 | mval[i - 1].br_startoff + mval[i - 1].br_blockcount == |
4213 | mval[i].br_startoff); | 4213 | mval[i].br_startoff); |
4214 | if (flags & XFS_BMAPI_WRITE) | 4214 | ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && |
4215 | ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && | 4215 | mval[i].br_startblock != HOLESTARTBLOCK); |
4216 | mval[i].br_startblock != HOLESTARTBLOCK); | ||
4217 | ASSERT(mval[i].br_state == XFS_EXT_NORM || | 4216 | ASSERT(mval[i].br_state == XFS_EXT_NORM || |
4218 | mval[i].br_state == XFS_EXT_UNWRITTEN); | 4217 | mval[i].br_state == XFS_EXT_UNWRITTEN); |
4219 | } | 4218 | } |
@@ -4809,60 +4808,57 @@ xfs_bmapi_convert_unwritten( | |||
4809 | } | 4808 | } |
4810 | 4809 | ||
4811 | /* | 4810 | /* |
4812 | * Map file blocks to filesystem blocks. | 4811 | * Map file blocks to filesystem blocks, and allocate blocks or convert the |
4813 | * File range is given by the bno/len pair. | 4812 | * extent state if necessary. Details behaviour is controlled by the flags |
4814 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) | 4813 | * parameter. Only allocates blocks from a single allocation group, to avoid |
4815 | * into a hole or past eof. | 4814 | * locking problems. |
4816 | * Only allocates blocks from a single allocation group, | 4815 | * |
4817 | * to avoid locking problems. | ||
4818 | * The returned value in "firstblock" from the first call in a transaction | 4816 | * The returned value in "firstblock" from the first call in a transaction |
4819 | * must be remembered and presented to subsequent calls in "firstblock". | 4817 | * must be remembered and presented to subsequent calls in "firstblock". |
4820 | * An upper bound for the number of blocks to be allocated is supplied to | 4818 | * An upper bound for the number of blocks to be allocated is supplied to |
4821 | * the first call in "total"; if no allocation group has that many free | 4819 | * the first call in "total"; if no allocation group has that many free |
4822 | * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). | 4820 | * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). |
4823 | */ | 4821 | */ |
4824 | int /* error */ | 4822 | int |
4825 | xfs_bmapi( | 4823 | xfs_bmapi_write( |
4826 | xfs_trans_t *tp, /* transaction pointer */ | 4824 | struct xfs_trans *tp, /* transaction pointer */ |
4827 | xfs_inode_t *ip, /* incore inode */ | 4825 | struct xfs_inode *ip, /* incore inode */ |
4828 | xfs_fileoff_t bno, /* starting file offs. mapped */ | 4826 | xfs_fileoff_t bno, /* starting file offs. mapped */ |
4829 | xfs_filblks_t len, /* length to map in file */ | 4827 | xfs_filblks_t len, /* length to map in file */ |
4830 | int flags, /* XFS_BMAPI_... */ | 4828 | int flags, /* XFS_BMAPI_... */ |
4831 | xfs_fsblock_t *firstblock, /* first allocated block | 4829 | xfs_fsblock_t *firstblock, /* first allocated block |
4832 | controls a.g. for allocs */ | 4830 | controls a.g. for allocs */ |
4833 | xfs_extlen_t total, /* total blocks needed */ | 4831 | xfs_extlen_t total, /* total blocks needed */ |
4834 | xfs_bmbt_irec_t *mval, /* output: map values */ | 4832 | struct xfs_bmbt_irec *mval, /* output: map values */ |
4835 | int *nmap, /* i/o: mval size/count */ | 4833 | int *nmap, /* i/o: mval size/count */ |
4836 | xfs_bmap_free_t *flist) /* i/o: list extents to free */ | 4834 | struct xfs_bmap_free *flist) /* i/o: list extents to free */ |
4837 | { | 4835 | { |
4838 | xfs_bmalloca_t bma = { 0 }; /* args for xfs_bmap_alloc */ | 4836 | struct xfs_mount *mp = ip->i_mount; |
4839 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 4837 | struct xfs_ifork *ifp; |
4840 | xfs_fileoff_t end; /* end of mapped file region */ | 4838 | struct xfs_bmalloca bma = { 0 }; /* args for xfs_bmap_alloc */ |
4841 | int eof; /* we've hit the end of extents */ | 4839 | struct xfs_btree_cur *cur; /* bmap btree cursor */ |
4842 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ | 4840 | xfs_fileoff_t end; /* end of mapped file region */ |
4843 | int error; /* error return */ | 4841 | int eof; /* after the end of extents */ |
4844 | xfs_bmbt_irec_t got; /* current file extent record */ | 4842 | int error; /* error return */ |
4845 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4843 | struct xfs_bmbt_irec got; /* current file extent record */ |
4846 | xfs_extnum_t lastx; /* last useful extent number */ | 4844 | xfs_extnum_t lastx; /* last useful extent number */ |
4847 | int logflags; /* flags for transaction logging */ | 4845 | int logflags; /* flags for transaction logging */ |
4848 | xfs_extlen_t minleft; /* min blocks left after allocation */ | 4846 | xfs_extlen_t minleft; /* min blocks left after allocation */ |
4849 | xfs_mount_t *mp; /* xfs mount structure */ | 4847 | int n; /* current extent index */ |
4850 | int n; /* current extent index */ | 4848 | int nallocs; /* number of extents alloc'd */ |
4851 | int nallocs; /* number of extents alloc'd */ | 4849 | xfs_fileoff_t obno; /* old block number (offset) */ |
4852 | xfs_fileoff_t obno; /* old block number (offset) */ | 4850 | struct xfs_bmbt_irec prev; /* previous file extent record */ |
4853 | xfs_bmbt_irec_t prev; /* previous file extent record */ | 4851 | int tmp_logflags; /* temp flags holder */ |
4854 | int tmp_logflags; /* temp flags holder */ | 4852 | int whichfork; /* data or attr fork */ |
4855 | int whichfork; /* data or attr fork */ | 4853 | char inhole; /* current location is hole in file */ |
4856 | char inhole; /* current location is hole in file */ | 4854 | char wasdelay; /* old extent was delayed */ |
4857 | char wasdelay; /* old extent was delayed */ | 4855 | |
4858 | char wr; /* this is a write request */ | ||
4859 | char rt; /* this is a realtime file */ | ||
4860 | #ifdef DEBUG | 4856 | #ifdef DEBUG |
4861 | xfs_fileoff_t orig_bno; /* original block number value */ | 4857 | xfs_fileoff_t orig_bno; /* original block number value */ |
4862 | int orig_flags; /* original flags arg value */ | 4858 | int orig_flags; /* original flags arg value */ |
4863 | xfs_filblks_t orig_len; /* original value of len arg */ | 4859 | xfs_filblks_t orig_len; /* original value of len arg */ |
4864 | xfs_bmbt_irec_t *orig_mval; /* original value of mval */ | 4860 | struct xfs_bmbt_irec *orig_mval; /* original value of mval */ |
4865 | int orig_nmap; /* original value of *nmap */ | 4861 | int orig_nmap; /* original value of *nmap */ |
4866 | 4862 | ||
4867 | orig_bno = bno; | 4863 | orig_bno = bno; |
4868 | orig_len = len; | 4864 | orig_len = len; |
@@ -4870,69 +4866,60 @@ xfs_bmapi( | |||
4870 | orig_mval = mval; | 4866 | orig_mval = mval; |
4871 | orig_nmap = *nmap; | 4867 | orig_nmap = *nmap; |
4872 | #endif | 4868 | #endif |
4869 | |||
4873 | ASSERT(*nmap >= 1); | 4870 | ASSERT(*nmap >= 1); |
4874 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP || !(flags & XFS_BMAPI_WRITE)); | 4871 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); |
4872 | ASSERT(!(flags & XFS_BMAPI_IGSTATE)); | ||
4873 | ASSERT(tp != NULL); | ||
4874 | |||
4875 | whichfork = (flags & XFS_BMAPI_ATTRFORK) ? | 4875 | whichfork = (flags & XFS_BMAPI_ATTRFORK) ? |
4876 | XFS_ATTR_FORK : XFS_DATA_FORK; | 4876 | XFS_ATTR_FORK : XFS_DATA_FORK; |
4877 | mp = ip->i_mount; | 4877 | |
4878 | if (unlikely(XFS_TEST_ERROR( | 4878 | if (unlikely(XFS_TEST_ERROR( |
4879 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && | 4879 | (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && |
4880 | XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && | 4880 | XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE && |
4881 | XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), | 4881 | XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL), |
4882 | mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { | 4882 | mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { |
4883 | XFS_ERROR_REPORT("xfs_bmapi", XFS_ERRLEVEL_LOW, mp); | 4883 | XFS_ERROR_REPORT("xfs_bmapi_write", XFS_ERRLEVEL_LOW, mp); |
4884 | return XFS_ERROR(EFSCORRUPTED); | 4884 | return XFS_ERROR(EFSCORRUPTED); |
4885 | } | 4885 | } |
4886 | |||
4886 | if (XFS_FORCED_SHUTDOWN(mp)) | 4887 | if (XFS_FORCED_SHUTDOWN(mp)) |
4887 | return XFS_ERROR(EIO); | 4888 | return XFS_ERROR(EIO); |
4888 | rt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); | 4889 | |
4889 | ifp = XFS_IFORK_PTR(ip, whichfork); | 4890 | ifp = XFS_IFORK_PTR(ip, whichfork); |
4890 | ASSERT(ifp->if_ext_max == | 4891 | ASSERT(ifp->if_ext_max == |
4891 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); | 4892 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); |
4892 | if ((wr = (flags & XFS_BMAPI_WRITE)) != 0) | 4893 | |
4893 | XFS_STATS_INC(xs_blk_mapw); | 4894 | XFS_STATS_INC(xs_blk_mapw); |
4894 | else | 4895 | |
4895 | XFS_STATS_INC(xs_blk_mapr); | ||
4896 | /* | ||
4897 | * IGSTATE flag is used to combine extents which | ||
4898 | * differ only due to the state of the extents. | ||
4899 | * This technique is used from xfs_getbmap() | ||
4900 | * when the caller does not wish to see the | ||
4901 | * separation (which is the default). | ||
4902 | * | ||
4903 | * This technique is also used when writing a | ||
4904 | * buffer which has been partially written, | ||
4905 | * (usually by being flushed during a chunkread), | ||
4906 | * to ensure one write takes place. This also | ||
4907 | * prevents a change in the xfs inode extents at | ||
4908 | * this time, intentionally. This change occurs | ||
4909 | * on completion of the write operation, in | ||
4910 | * xfs_strat_comp(), where the xfs_bmapi() call | ||
4911 | * is transactioned, and the extents combined. | ||
4912 | */ | ||
4913 | if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ | ||
4914 | wr = 0; /* no allocations are allowed */ | ||
4915 | logflags = 0; | 4896 | logflags = 0; |
4916 | nallocs = 0; | 4897 | nallocs = 0; |
4917 | cur = NULL; | 4898 | cur = NULL; |
4899 | |||
4918 | if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { | 4900 | if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) { |
4919 | ASSERT(wr && tp); | 4901 | error = xfs_bmap_local_to_extents(tp, ip, firstblock, total, |
4920 | if ((error = xfs_bmap_local_to_extents(tp, ip, | 4902 | &logflags, whichfork); |
4921 | firstblock, total, &logflags, whichfork))) | 4903 | if (error) |
4922 | goto error0; | 4904 | goto error0; |
4923 | } | 4905 | } |
4924 | if (wr && *firstblock == NULLFSBLOCK) { | 4906 | |
4907 | if (*firstblock == NULLFSBLOCK) { | ||
4925 | if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) | 4908 | if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) |
4926 | minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; | 4909 | minleft = be16_to_cpu(ifp->if_broot->bb_level) + 1; |
4927 | else | 4910 | else |
4928 | minleft = 1; | 4911 | minleft = 1; |
4929 | } else | 4912 | } else { |
4930 | minleft = 0; | 4913 | minleft = 0; |
4931 | if (!(ifp->if_flags & XFS_IFEXTENTS) && | 4914 | } |
4932 | (error = xfs_iread_extents(tp, ip, whichfork))) | 4915 | |
4933 | goto error0; | 4916 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { |
4934 | ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, | 4917 | error = xfs_iread_extents(tp, ip, whichfork); |
4935 | &prev); | 4918 | if (error) |
4919 | goto error0; | ||
4920 | } | ||
4921 | |||
4922 | xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got, &prev); | ||
4936 | n = 0; | 4923 | n = 0; |
4937 | end = bno + len; | 4924 | end = bno + len; |
4938 | obno = bno; | 4925 | obno = bno; |
@@ -4945,19 +4932,14 @@ xfs_bmapi( | |||
4945 | bma.userdata = 0; | 4932 | bma.userdata = 0; |
4946 | 4933 | ||
4947 | while (bno < end && n < *nmap) { | 4934 | while (bno < end && n < *nmap) { |
4948 | /* | ||
4949 | * Reading past eof, act as though there's a hole | ||
4950 | * up to end. | ||
4951 | */ | ||
4952 | if (eof && !wr) | ||
4953 | got.br_startoff = end; | ||
4954 | inhole = eof || got.br_startoff > bno; | 4935 | inhole = eof || got.br_startoff > bno; |
4955 | wasdelay = wr && !inhole && isnullstartblock(got.br_startblock); | 4936 | wasdelay = !inhole && isnullstartblock(got.br_startblock); |
4937 | |||
4956 | /* | 4938 | /* |
4957 | * First, deal with the hole before the allocated space | 4939 | * First, deal with the hole before the allocated space |
4958 | * that we found, if any. | 4940 | * that we found, if any. |
4959 | */ | 4941 | */ |
4960 | if (wr && (inhole || wasdelay)) { | 4942 | if (inhole || wasdelay) { |
4961 | bma.eof = eof; | 4943 | bma.eof = eof; |
4962 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); | 4944 | bma.conv = !!(flags & XFS_BMAPI_CONVERT); |
4963 | bma.wasdel = wasdelay; | 4945 | bma.wasdel = wasdelay; |
@@ -4975,36 +4957,20 @@ xfs_bmapi( | |||
4975 | minleft = 0; | 4957 | minleft = 0; |
4976 | if (bma.rval == NULLFSBLOCK) | 4958 | if (bma.rval == NULLFSBLOCK) |
4977 | break; | 4959 | break; |
4978 | } else if (inhole) { | ||
4979 | /* | ||
4980 | * Reading in a hole. | ||
4981 | */ | ||
4982 | mval->br_startoff = bno; | ||
4983 | mval->br_startblock = HOLESTARTBLOCK; | ||
4984 | mval->br_blockcount = | ||
4985 | XFS_FILBLKS_MIN(len, got.br_startoff - bno); | ||
4986 | mval->br_state = XFS_EXT_NORM; | ||
4987 | bno += mval->br_blockcount; | ||
4988 | len -= mval->br_blockcount; | ||
4989 | mval++; | ||
4990 | n++; | ||
4991 | continue; | ||
4992 | } | 4960 | } |
4993 | 4961 | ||
4994 | /* Deal with the allocated space we found. */ | 4962 | /* Deal with the allocated space we found. */ |
4995 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); | 4963 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); |
4996 | 4964 | ||
4997 | /* Execute unwritten extent conversion if necessary */ | 4965 | /* Execute unwritten extent conversion if necessary */ |
4998 | if (wr) { | 4966 | error = xfs_bmapi_convert_unwritten(&bma, mval, len, &lastx, |
4999 | error = xfs_bmapi_convert_unwritten(&bma, mval, len, | 4967 | &cur, firstblock, flist, |
5000 | &lastx, &cur, firstblock, flist, flags, | 4968 | flags, &tmp_logflags); |
5001 | &tmp_logflags); | 4969 | logflags |= tmp_logflags; |
5002 | logflags |= tmp_logflags; | 4970 | if (error == EAGAIN) |
5003 | if (error == EAGAIN) | 4971 | continue; |
5004 | continue; | 4972 | if (error) |
5005 | if (error) | 4973 | goto error0; |
5006 | goto error0; | ||
5007 | } | ||
5008 | 4974 | ||
5009 | /* update the extent map to return */ | 4975 | /* update the extent map to return */ |
5010 | xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); | 4976 | xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); |
@@ -5016,24 +4982,22 @@ xfs_bmapi( | |||
5016 | */ | 4982 | */ |
5017 | if (bno >= end || n >= *nmap || nallocs >= *nmap) | 4983 | if (bno >= end || n >= *nmap || nallocs >= *nmap) |
5018 | break; | 4984 | break; |
5019 | /* | 4985 | |
5020 | * Else go on to the next record. | 4986 | /* Else go on to the next record. */ |
5021 | */ | ||
5022 | prev = got; | 4987 | prev = got; |
5023 | if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) { | 4988 | if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) |
5024 | ep = xfs_iext_get_ext(ifp, lastx); | 4989 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); |
5025 | xfs_bmbt_get_all(ep, &got); | 4990 | else |
5026 | } else { | ||
5027 | eof = 1; | 4991 | eof = 1; |
5028 | } | ||
5029 | } | 4992 | } |
5030 | *nmap = n; | 4993 | *nmap = n; |
4994 | |||
5031 | /* | 4995 | /* |
5032 | * Transform from btree to extents, give it cur. | 4996 | * Transform from btree to extents, give it cur. |
5033 | */ | 4997 | */ |
5034 | if (tp && XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && | 4998 | if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE && |
5035 | XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { | 4999 | XFS_IFORK_NEXTENTS(ip, whichfork) <= ifp->if_ext_max) { |
5036 | ASSERT(wr && cur); | 5000 | ASSERT(cur); |
5037 | error = xfs_bmap_btree_to_extents(tp, ip, cur, | 5001 | error = xfs_bmap_btree_to_extents(tp, ip, cur, |
5038 | &tmp_logflags, whichfork); | 5002 | &tmp_logflags, whichfork); |
5039 | logflags |= tmp_logflags; | 5003 | logflags |= tmp_logflags; |
@@ -5061,10 +5025,9 @@ error0: | |||
5061 | * detecting a case where the data is changed, there's an error, | 5025 | * detecting a case where the data is changed, there's an error, |
5062 | * and it's not logged so we don't shutdown when we should. | 5026 | * and it's not logged so we don't shutdown when we should. |
5063 | */ | 5027 | */ |
5064 | if (logflags) { | 5028 | if (logflags) |
5065 | ASSERT(tp && wr); | ||
5066 | xfs_trans_log_inode(tp, ip, logflags); | 5029 | xfs_trans_log_inode(tp, ip, logflags); |
5067 | } | 5030 | |
5068 | if (cur) { | 5031 | if (cur) { |
5069 | if (!error) { | 5032 | if (!error) { |
5070 | ASSERT(*firstblock == NULLFSBLOCK || | 5033 | ASSERT(*firstblock == NULLFSBLOCK || |