diff options
-rw-r--r-- | fs/xfs/xfs_attr.c | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.c | 225 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.h | 50 | ||||
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 10 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.c | 12 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 20 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 6 | ||||
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 19 |
8 files changed, 135 insertions, 212 deletions
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 41ef02b7185a..5484766938f9 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -2039,10 +2039,9 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) | |||
2039 | */ | 2039 | */ |
2040 | xfs_bmap_init(args->flist, args->firstblock); | 2040 | xfs_bmap_init(args->flist, args->firstblock); |
2041 | nmap = 1; | 2041 | nmap = 1; |
2042 | error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno, | 2042 | error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, |
2043 | blkcnt, | 2043 | blkcnt, |
2044 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA | | 2044 | XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA, |
2045 | XFS_BMAPI_WRITE, | ||
2046 | args->firstblock, args->total, &map, &nmap, | 2045 | args->firstblock, args->total, &map, &nmap, |
2047 | args->flist); | 2046 | args->flist); |
2048 | if (!error) { | 2047 | if (!error) { |
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 || |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index c70c19c7f1fa..be235f56d2a6 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -62,25 +62,23 @@ typedef struct xfs_bmap_free | |||
62 | #define XFS_BMAP_MAX_NMAP 4 | 62 | #define XFS_BMAP_MAX_NMAP 4 |
63 | 63 | ||
64 | /* | 64 | /* |
65 | * Flags for xfs_bmapi | 65 | * Flags for xfs_bmapi_* |
66 | */ | 66 | */ |
67 | #define XFS_BMAPI_WRITE 0x001 /* write operation: allocate space */ | 67 | #define XFS_BMAPI_ENTIRE 0x001 /* return entire extent, not trimmed */ |
68 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ | 68 | #define XFS_BMAPI_METADATA 0x002 /* mapping metadata not user data */ |
69 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ | 69 | #define XFS_BMAPI_ATTRFORK 0x004 /* use attribute fork not data */ |
70 | #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ | 70 | #define XFS_BMAPI_PREALLOC 0x008 /* preallocation op: unwritten space */ |
71 | #define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */ | 71 | #define XFS_BMAPI_IGSTATE 0x010 /* Ignore state - */ |
72 | #define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */ | ||
73 | /* combine contig. space */ | 72 | /* combine contig. space */ |
74 | #define XFS_BMAPI_CONTIG 0x100 /* must allocate only one extent */ | 73 | #define XFS_BMAPI_CONTIG 0x020 /* must allocate only one extent */ |
75 | /* | 74 | /* |
76 | * unwritten extent conversion - this needs write cache flushing and no additional | 75 | * unwritten extent conversion - this needs write cache flushing and no additional |
77 | * allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts | 76 | * allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts |
78 | * from written to unwritten, otherwise convert from unwritten to written. | 77 | * from written to unwritten, otherwise convert from unwritten to written. |
79 | */ | 78 | */ |
80 | #define XFS_BMAPI_CONVERT 0x200 | 79 | #define XFS_BMAPI_CONVERT 0x040 |
81 | 80 | ||
82 | #define XFS_BMAPI_FLAGS \ | 81 | #define XFS_BMAPI_FLAGS \ |
83 | { XFS_BMAPI_WRITE, "WRITE" }, \ | ||
84 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ | 82 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ |
85 | { XFS_BMAPI_METADATA, "METADATA" }, \ | 83 | { XFS_BMAPI_METADATA, "METADATA" }, \ |
86 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ | 84 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ |
@@ -265,39 +263,17 @@ xfs_bmap_read_extents( | |||
265 | struct xfs_inode *ip, /* incore inode */ | 263 | struct xfs_inode *ip, /* incore inode */ |
266 | int whichfork); /* data or attr fork */ | 264 | int whichfork); /* data or attr fork */ |
267 | 265 | ||
268 | /* | ||
269 | * Map file blocks to filesystem blocks. | ||
270 | * File range is given by the bno/len pair. | ||
271 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) | ||
272 | * into a hole or past eof. | ||
273 | * Only allocates blocks from a single allocation group, | ||
274 | * to avoid locking problems. | ||
275 | * The returned value in "firstblock" from the first call in a transaction | ||
276 | * must be remembered and presented to subsequent calls in "firstblock". | ||
277 | * An upper bound for the number of blocks to be allocated is supplied to | ||
278 | * the first call in "total"; if no allocation group has that many free | ||
279 | * blocks then the call will fail (return NULLFSBLOCK in "firstblock"). | ||
280 | */ | ||
281 | int /* error */ | ||
282 | xfs_bmapi( | ||
283 | struct xfs_trans *tp, /* transaction pointer */ | ||
284 | struct xfs_inode *ip, /* incore inode */ | ||
285 | xfs_fileoff_t bno, /* starting file offs. mapped */ | ||
286 | xfs_filblks_t len, /* length to map in file */ | ||
287 | int flags, /* XFS_BMAPI_... */ | ||
288 | xfs_fsblock_t *firstblock, /* first allocated block | ||
289 | controls a.g. for allocs */ | ||
290 | xfs_extlen_t total, /* total blocks needed */ | ||
291 | struct xfs_bmbt_irec *mval, /* output: map values */ | ||
292 | int *nmap, /* i/o: mval size/count */ | ||
293 | xfs_bmap_free_t *flist); /* i/o: list extents to free */ | ||
294 | |||
295 | int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, | 266 | int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, |
296 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, | 267 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, |
297 | int *nmap, int flags); | 268 | int *nmap, int flags); |
298 | int xfs_bmapi_delay(struct xfs_inode *ip, xfs_fileoff_t bno, | 269 | int xfs_bmapi_delay(struct xfs_inode *ip, xfs_fileoff_t bno, |
299 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, | 270 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, |
300 | int *nmap, int flags); | 271 | int *nmap, int flags); |
272 | int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, | ||
273 | xfs_fileoff_t bno, xfs_filblks_t len, int flags, | ||
274 | xfs_fsblock_t *firstblock, xfs_extlen_t total, | ||
275 | struct xfs_bmbt_irec *mval, int *nmap, | ||
276 | struct xfs_bmap_free *flist); | ||
301 | 277 | ||
302 | /* | 278 | /* |
303 | * Unmap (remove) blocks from a file. | 279 | * Unmap (remove) blocks from a file. |
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index 70a5f580e5ed..46c8aa2740da 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -1578,9 +1578,8 @@ xfs_da_grow_inode_int( | |||
1578 | */ | 1578 | */ |
1579 | nmap = 1; | 1579 | nmap = 1; |
1580 | ASSERT(args->firstblock != NULL); | 1580 | ASSERT(args->firstblock != NULL); |
1581 | error = xfs_bmapi(tp, dp, *bno, count, | 1581 | error = xfs_bmapi_write(tp, dp, *bno, count, |
1582 | xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA| | 1582 | xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG, |
1583 | XFS_BMAPI_CONTIG, | ||
1584 | args->firstblock, args->total, &map, &nmap, | 1583 | args->firstblock, args->total, &map, &nmap, |
1585 | args->flist); | 1584 | args->flist); |
1586 | if (error) | 1585 | if (error) |
@@ -1602,9 +1601,8 @@ xfs_da_grow_inode_int( | |||
1602 | for (b = *bno, mapi = 0; b < *bno + count; ) { | 1601 | for (b = *bno, mapi = 0; b < *bno + count; ) { |
1603 | nmap = MIN(XFS_BMAP_MAX_NMAP, count); | 1602 | nmap = MIN(XFS_BMAP_MAX_NMAP, count); |
1604 | c = (int)(*bno + count - b); | 1603 | c = (int)(*bno + count - b); |
1605 | error = xfs_bmapi(tp, dp, b, c, | 1604 | error = xfs_bmapi_write(tp, dp, b, c, |
1606 | xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE| | 1605 | xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA, |
1607 | XFS_BMAPI_METADATA, | ||
1608 | args->firstblock, args->total, | 1606 | args->firstblock, args->total, |
1609 | &mapp[mapi], &nmap, args->flist); | 1607 | &mapp[mapi], &nmap, args->flist); |
1610 | if (error) | 1608 | if (error) |
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index c377961657ee..179673531f20 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -379,14 +379,12 @@ xfs_qm_dqalloc( | |||
379 | 379 | ||
380 | xfs_trans_ijoin_ref(tp, quotip, XFS_ILOCK_EXCL); | 380 | xfs_trans_ijoin_ref(tp, quotip, XFS_ILOCK_EXCL); |
381 | nmaps = 1; | 381 | nmaps = 1; |
382 | if ((error = xfs_bmapi(tp, quotip, | 382 | error = xfs_bmapi_write(tp, quotip, offset_fsb, |
383 | offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB, | 383 | XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, |
384 | XFS_BMAPI_METADATA | XFS_BMAPI_WRITE, | 384 | &firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), |
385 | &firstblock, | 385 | &map, &nmaps, &flist); |
386 | XFS_QM_DQALLOC_SPACE_RES(mp), | 386 | if (error) |
387 | &map, &nmaps, &flist))) { | ||
388 | goto error0; | 387 | goto error0; |
389 | } | ||
390 | ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); | 388 | ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); |
391 | ASSERT(nmaps == 1); | 389 | ASSERT(nmaps == 1); |
392 | ASSERT((map.br_startblock != DELAYSTARTBLOCK) && | 390 | ASSERT((map.br_startblock != DELAYSTARTBLOCK) && |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 681ba34c9233..da5bf05c5bb7 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -210,20 +210,18 @@ xfs_iomap_write_direct( | |||
210 | 210 | ||
211 | xfs_trans_ijoin(tp, ip); | 211 | xfs_trans_ijoin(tp, ip); |
212 | 212 | ||
213 | bmapi_flag = XFS_BMAPI_WRITE; | 213 | bmapi_flag = 0; |
214 | if (offset < ip->i_size || extsz) | 214 | if (offset < ip->i_size || extsz) |
215 | bmapi_flag |= XFS_BMAPI_PREALLOC; | 215 | bmapi_flag |= XFS_BMAPI_PREALLOC; |
216 | 216 | ||
217 | /* | 217 | /* |
218 | * Issue the xfs_bmapi() call to allocate the blocks. | ||
219 | * | ||
220 | * From this point onwards we overwrite the imap pointer that the | 218 | * From this point onwards we overwrite the imap pointer that the |
221 | * caller gave to us. | 219 | * caller gave to us. |
222 | */ | 220 | */ |
223 | xfs_bmap_init(&free_list, &firstfsb); | 221 | xfs_bmap_init(&free_list, &firstfsb); |
224 | nimaps = 1; | 222 | nimaps = 1; |
225 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag, | 223 | error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, bmapi_flag, |
226 | &firstfsb, 0, imap, &nimaps, &free_list); | 224 | &firstfsb, 0, imap, &nimaps, &free_list); |
227 | if (error) | 225 | if (error) |
228 | goto error0; | 226 | goto error0; |
229 | 227 | ||
@@ -582,14 +580,12 @@ xfs_iomap_write_allocate( | |||
582 | } | 580 | } |
583 | 581 | ||
584 | /* | 582 | /* |
585 | * Go get the actual blocks. | ||
586 | * | ||
587 | * From this point onwards we overwrite the imap | 583 | * From this point onwards we overwrite the imap |
588 | * pointer that the caller gave to us. | 584 | * pointer that the caller gave to us. |
589 | */ | 585 | */ |
590 | error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb, | 586 | error = xfs_bmapi_write(tp, ip, map_start_fsb, |
591 | XFS_BMAPI_WRITE, &first_block, 1, | 587 | count_fsb, 0, &first_block, 1, |
592 | imap, &nimaps, &free_list); | 588 | imap, &nimaps, &free_list); |
593 | if (error) | 589 | if (error) |
594 | goto trans_cancel; | 590 | goto trans_cancel; |
595 | 591 | ||
@@ -703,8 +699,8 @@ xfs_iomap_write_unwritten( | |||
703 | */ | 699 | */ |
704 | xfs_bmap_init(&free_list, &firstfsb); | 700 | xfs_bmap_init(&free_list, &firstfsb); |
705 | nimaps = 1; | 701 | nimaps = 1; |
706 | error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, | 702 | error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, |
707 | XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb, | 703 | XFS_BMAPI_CONVERT, &firstfsb, |
708 | 1, &imap, &nimaps, &free_list); | 704 | 1, &imap, &nimaps, &free_list); |
709 | if (error) | 705 | if (error) |
710 | goto error_on_bmapi_transaction; | 706 | goto error_on_bmapi_transaction; |
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index e5f40c6460b2..f29424964521 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c | |||
@@ -120,9 +120,9 @@ xfs_growfs_rt_alloc( | |||
120 | */ | 120 | */ |
121 | nmap = 1; | 121 | nmap = 1; |
122 | cancelflags |= XFS_TRANS_ABORT; | 122 | cancelflags |= XFS_TRANS_ABORT; |
123 | error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks, | 123 | error = xfs_bmapi_write(tp, ip, oblocks, nblocks - oblocks, |
124 | XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock, | 124 | XFS_BMAPI_METADATA, &firstblock, |
125 | resblks, &map, &nmap, &flist); | 125 | resblks, &map, &nmap, &flist); |
126 | if (!error && nmap < 1) | 126 | if (!error && nmap < 1) |
127 | error = XFS_ERROR(ENOSPC); | 127 | error = XFS_ERROR(ENOSPC); |
128 | if (error) | 128 | if (error) |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 63874a87b378..f47ecee8d437 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -1633,10 +1633,9 @@ xfs_symlink( | |||
1633 | first_fsb = 0; | 1633 | first_fsb = 0; |
1634 | nmaps = SYMLINK_MAPS; | 1634 | nmaps = SYMLINK_MAPS; |
1635 | 1635 | ||
1636 | error = xfs_bmapi(tp, ip, first_fsb, fs_blocks, | 1636 | error = xfs_bmapi_write(tp, ip, first_fsb, fs_blocks, |
1637 | XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, | 1637 | XFS_BMAPI_METADATA, &first_block, resblks, |
1638 | &first_block, resblks, mval, &nmaps, | 1638 | mval, &nmaps, &free_list); |
1639 | &free_list); | ||
1640 | if (error) | 1639 | if (error) |
1641 | goto error2; | 1640 | goto error2; |
1642 | 1641 | ||
@@ -1782,7 +1781,6 @@ xfs_alloc_file_space( | |||
1782 | xfs_fileoff_t startoffset_fsb; | 1781 | xfs_fileoff_t startoffset_fsb; |
1783 | xfs_fsblock_t firstfsb; | 1782 | xfs_fsblock_t firstfsb; |
1784 | int nimaps; | 1783 | int nimaps; |
1785 | int bmapi_flag; | ||
1786 | int quota_flag; | 1784 | int quota_flag; |
1787 | int rt; | 1785 | int rt; |
1788 | xfs_trans_t *tp; | 1786 | xfs_trans_t *tp; |
@@ -1810,7 +1808,6 @@ xfs_alloc_file_space( | |||
1810 | count = len; | 1808 | count = len; |
1811 | imapp = &imaps[0]; | 1809 | imapp = &imaps[0]; |
1812 | nimaps = 1; | 1810 | nimaps = 1; |
1813 | bmapi_flag = XFS_BMAPI_WRITE | alloc_type; | ||
1814 | startoffset_fsb = XFS_B_TO_FSBT(mp, offset); | 1811 | startoffset_fsb = XFS_B_TO_FSBT(mp, offset); |
1815 | allocatesize_fsb = XFS_B_TO_FSB(mp, count); | 1812 | allocatesize_fsb = XFS_B_TO_FSB(mp, count); |
1816 | 1813 | ||
@@ -1883,14 +1880,10 @@ xfs_alloc_file_space( | |||
1883 | 1880 | ||
1884 | xfs_trans_ijoin(tp, ip); | 1881 | xfs_trans_ijoin(tp, ip); |
1885 | 1882 | ||
1886 | /* | ||
1887 | * Issue the xfs_bmapi() call to allocate the blocks | ||
1888 | */ | ||
1889 | xfs_bmap_init(&free_list, &firstfsb); | 1883 | xfs_bmap_init(&free_list, &firstfsb); |
1890 | error = xfs_bmapi(tp, ip, startoffset_fsb, | 1884 | error = xfs_bmapi_write(tp, ip, startoffset_fsb, |
1891 | allocatesize_fsb, bmapi_flag, | 1885 | allocatesize_fsb, alloc_type, &firstfsb, |
1892 | &firstfsb, 0, imapp, &nimaps, | 1886 | 0, imapp, &nimaps, &free_list); |
1893 | &free_list); | ||
1894 | if (error) { | 1887 | if (error) { |
1895 | goto error0; | 1888 | goto error0; |
1896 | } | 1889 | } |