diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-09-18 16:40:48 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-10-11 22:15:04 -0400 |
commit | 4403280aa5c00c6074f2dc23e1cfc11f2bfb0032 (patch) | |
tree | 322f188e78d6faf1cae53cb56ed7918d49702366 | |
parent | b64dfe4e180ab5047c59bcbe379538eb23be4d8e (diff) |
xfs: introduce xfs_bmapi_delay()
Delalloc reservations are much simpler than allocations, so give
them a separate bmapi-level interface. Using the previously added
xfs_bmapi_reserve_delalloc we get a function that is only minimally
more complicated than xfs_bmapi_read, which is far from the complexity
in xfs_bmapi. Also remove the XFS_BMAPI_DELAY code after switching
over the only user to xfs_bmapi_delay.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
-rw-r--r-- | fs/xfs/xfs_bmap.c | 115 | ||||
-rw-r--r-- | fs/xfs/xfs_bmap.h | 5 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 9 |
3 files changed, 94 insertions, 35 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index cd01783a89d7..6f3276974555 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4238,7 +4238,7 @@ xfs_bmap_validate_ret( | |||
4238 | ASSERT(i == 0 || | 4238 | ASSERT(i == 0 || |
4239 | mval[i - 1].br_startoff + mval[i - 1].br_blockcount == | 4239 | mval[i - 1].br_startoff + mval[i - 1].br_blockcount == |
4240 | mval[i].br_startoff); | 4240 | mval[i].br_startoff); |
4241 | if ((flags & XFS_BMAPI_WRITE) && !(flags & XFS_BMAPI_DELAY)) | 4241 | if (flags & XFS_BMAPI_WRITE) |
4242 | ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && | 4242 | ASSERT(mval[i].br_startblock != DELAYSTARTBLOCK && |
4243 | mval[i].br_startblock != HOLESTARTBLOCK); | 4243 | mval[i].br_startblock != HOLESTARTBLOCK); |
4244 | ASSERT(mval[i].br_state == XFS_EXT_NORM || | 4244 | ASSERT(mval[i].br_state == XFS_EXT_NORM || |
@@ -4556,6 +4556,90 @@ out_unreserve_quota: | |||
4556 | } | 4556 | } |
4557 | 4557 | ||
4558 | /* | 4558 | /* |
4559 | * Map file blocks to filesystem blocks, adding delayed allocations as needed. | ||
4560 | */ | ||
4561 | int | ||
4562 | xfs_bmapi_delay( | ||
4563 | struct xfs_inode *ip, /* incore inode */ | ||
4564 | xfs_fileoff_t bno, /* starting file offs. mapped */ | ||
4565 | xfs_filblks_t len, /* length to map in file */ | ||
4566 | struct xfs_bmbt_irec *mval, /* output: map values */ | ||
4567 | int *nmap, /* i/o: mval size/count */ | ||
4568 | int flags) /* XFS_BMAPI_... */ | ||
4569 | { | ||
4570 | struct xfs_mount *mp = ip->i_mount; | ||
4571 | struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); | ||
4572 | struct xfs_bmbt_irec got; /* current file extent record */ | ||
4573 | struct xfs_bmbt_irec prev; /* previous file extent record */ | ||
4574 | xfs_fileoff_t obno; /* old block number (offset) */ | ||
4575 | xfs_fileoff_t end; /* end of mapped file region */ | ||
4576 | xfs_extnum_t lastx; /* last useful extent number */ | ||
4577 | int eof; /* we've hit the end of extents */ | ||
4578 | int n = 0; /* current extent index */ | ||
4579 | int error = 0; | ||
4580 | |||
4581 | ASSERT(*nmap >= 1); | ||
4582 | ASSERT(*nmap <= XFS_BMAP_MAX_NMAP); | ||
4583 | ASSERT(!(flags & ~XFS_BMAPI_ENTIRE)); | ||
4584 | |||
4585 | if (unlikely(XFS_TEST_ERROR( | ||
4586 | (XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_EXTENTS && | ||
4587 | XFS_IFORK_FORMAT(ip, XFS_DATA_FORK) != XFS_DINODE_FMT_BTREE), | ||
4588 | mp, XFS_ERRTAG_BMAPIFORMAT, XFS_RANDOM_BMAPIFORMAT))) { | ||
4589 | XFS_ERROR_REPORT("xfs_bmapi_delay", XFS_ERRLEVEL_LOW, mp); | ||
4590 | return XFS_ERROR(EFSCORRUPTED); | ||
4591 | } | ||
4592 | |||
4593 | if (XFS_FORCED_SHUTDOWN(mp)) | ||
4594 | return XFS_ERROR(EIO); | ||
4595 | |||
4596 | XFS_STATS_INC(xs_blk_mapw); | ||
4597 | |||
4598 | if (!(ifp->if_flags & XFS_IFEXTENTS)) { | ||
4599 | error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); | ||
4600 | if (error) | ||
4601 | return error; | ||
4602 | } | ||
4603 | |||
4604 | xfs_bmap_search_extents(ip, bno, XFS_DATA_FORK, &eof, &lastx, &got, &prev); | ||
4605 | end = bno + len; | ||
4606 | obno = bno; | ||
4607 | |||
4608 | while (bno < end && n < *nmap) { | ||
4609 | if (eof || got.br_startoff > bno) { | ||
4610 | error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got, | ||
4611 | &prev, &lastx, eof); | ||
4612 | if (error) { | ||
4613 | if (n == 0) { | ||
4614 | *nmap = 0; | ||
4615 | return error; | ||
4616 | } | ||
4617 | break; | ||
4618 | } | ||
4619 | } | ||
4620 | |||
4621 | /* set up the extent map to return. */ | ||
4622 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); | ||
4623 | xfs_bmapi_update_map(&mval, &bno, &len, obno, end, &n, flags); | ||
4624 | |||
4625 | /* If we're done, stop now. */ | ||
4626 | if (bno >= end || n >= *nmap) | ||
4627 | break; | ||
4628 | |||
4629 | /* Else go on to the next record. */ | ||
4630 | prev = got; | ||
4631 | if (++lastx < ifp->if_bytes / sizeof(xfs_bmbt_rec_t)) | ||
4632 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, lastx), &got); | ||
4633 | else | ||
4634 | eof = 1; | ||
4635 | } | ||
4636 | |||
4637 | *nmap = n; | ||
4638 | return 0; | ||
4639 | } | ||
4640 | |||
4641 | |||
4642 | /* | ||
4559 | * Map file blocks to filesystem blocks. | 4643 | * Map file blocks to filesystem blocks. |
4560 | * File range is given by the bno/len pair. | 4644 | * File range is given by the bno/len pair. |
4561 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) | 4645 | * Adds blocks to file if a write ("flags & XFS_BMAPI_WRITE" set) |
@@ -4663,7 +4747,6 @@ xfs_bmapi( | |||
4663 | */ | 4747 | */ |
4664 | if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ | 4748 | if ((flags & XFS_BMAPI_IGSTATE) && wr) /* if writing unwritten space */ |
4665 | wr = 0; /* no allocations are allowed */ | 4749 | wr = 0; /* no allocations are allowed */ |
4666 | ASSERT(wr || !(flags & XFS_BMAPI_DELAY)); | ||
4667 | logflags = 0; | 4750 | logflags = 0; |
4668 | nallocs = 0; | 4751 | nallocs = 0; |
4669 | cur = NULL; | 4752 | cur = NULL; |
@@ -4698,8 +4781,7 @@ xfs_bmapi( | |||
4698 | if (eof && !wr) | 4781 | if (eof && !wr) |
4699 | got.br_startoff = end; | 4782 | got.br_startoff = end; |
4700 | inhole = eof || got.br_startoff > bno; | 4783 | inhole = eof || got.br_startoff > bno; |
4701 | wasdelay = wr && !inhole && !(flags & XFS_BMAPI_DELAY) && | 4784 | wasdelay = wr && !inhole && isnullstartblock(got.br_startblock); |
4702 | isnullstartblock(got.br_startblock); | ||
4703 | /* | 4785 | /* |
4704 | * First, deal with the hole before the allocated space | 4786 | * First, deal with the hole before the allocated space |
4705 | * that we found, if any. | 4787 | * that we found, if any. |
@@ -4727,20 +4809,7 @@ xfs_bmapi( | |||
4727 | aoff = bno; | 4809 | aoff = bno; |
4728 | } | 4810 | } |
4729 | minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; | 4811 | minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; |
4730 | if (flags & XFS_BMAPI_DELAY) { | 4812 | { |
4731 | error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got, | ||
4732 | &prev, &lastx, eof); | ||
4733 | if (error) { | ||
4734 | if (n == 0) { | ||
4735 | *nmap = 0; | ||
4736 | ASSERT(cur == NULL); | ||
4737 | return error; | ||
4738 | } | ||
4739 | break; | ||
4740 | } | ||
4741 | |||
4742 | goto trim_extent; | ||
4743 | } else { | ||
4744 | /* | 4813 | /* |
4745 | * If first time, allocate and fill in | 4814 | * If first time, allocate and fill in |
4746 | * once-only bma fields. | 4815 | * once-only bma fields. |
@@ -4851,14 +4920,8 @@ xfs_bmapi( | |||
4851 | ASSERT(got.br_startoff <= aoff); | 4920 | ASSERT(got.br_startoff <= aoff); |
4852 | ASSERT(got.br_startoff + got.br_blockcount >= | 4921 | ASSERT(got.br_startoff + got.br_blockcount >= |
4853 | aoff + alen); | 4922 | aoff + alen); |
4854 | #ifdef DEBUG | ||
4855 | if (flags & XFS_BMAPI_DELAY) { | ||
4856 | ASSERT(isnullstartblock(got.br_startblock)); | ||
4857 | ASSERT(startblockval(got.br_startblock) > 0); | ||
4858 | } | ||
4859 | ASSERT(got.br_state == XFS_EXT_NORM || | 4923 | ASSERT(got.br_state == XFS_EXT_NORM || |
4860 | got.br_state == XFS_EXT_UNWRITTEN); | 4924 | got.br_state == XFS_EXT_UNWRITTEN); |
4861 | #endif | ||
4862 | /* | 4925 | /* |
4863 | * Fall down into the found allocated space case. | 4926 | * Fall down into the found allocated space case. |
4864 | */ | 4927 | */ |
@@ -4877,7 +4940,7 @@ xfs_bmapi( | |||
4877 | n++; | 4940 | n++; |
4878 | continue; | 4941 | continue; |
4879 | } | 4942 | } |
4880 | trim_extent: | 4943 | |
4881 | /* Deal with the allocated space we found. */ | 4944 | /* Deal with the allocated space we found. */ |
4882 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); | 4945 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); |
4883 | 4946 | ||
@@ -4887,7 +4950,7 @@ trim_extent: | |||
4887 | */ | 4950 | */ |
4888 | if (wr && | 4951 | if (wr && |
4889 | ((mval->br_state == XFS_EXT_UNWRITTEN && | 4952 | ((mval->br_state == XFS_EXT_UNWRITTEN && |
4890 | ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_DELAY)) == 0)) || | 4953 | ((flags & XFS_BMAPI_PREALLOC) == 0)) || |
4891 | (mval->br_state == XFS_EXT_NORM && | 4954 | (mval->br_state == XFS_EXT_NORM && |
4892 | ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) == | 4955 | ((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT)) == |
4893 | (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) { | 4956 | (XFS_BMAPI_PREALLOC|XFS_BMAPI_CONVERT))))) { |
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h index 01693390df21..c70c19c7f1fa 100644 --- a/fs/xfs/xfs_bmap.h +++ b/fs/xfs/xfs_bmap.h | |||
@@ -65,7 +65,6 @@ typedef struct xfs_bmap_free | |||
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_WRITE 0x001 /* write operation: allocate space */ |
68 | #define XFS_BMAPI_DELAY 0x002 /* delayed write operation */ | ||
69 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ | 68 | #define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */ |
70 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ | 69 | #define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */ |
71 | #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ | 70 | #define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */ |
@@ -82,7 +81,6 @@ typedef struct xfs_bmap_free | |||
82 | 81 | ||
83 | #define XFS_BMAPI_FLAGS \ | 82 | #define XFS_BMAPI_FLAGS \ |
84 | { XFS_BMAPI_WRITE, "WRITE" }, \ | 83 | { XFS_BMAPI_WRITE, "WRITE" }, \ |
85 | { XFS_BMAPI_DELAY, "DELAY" }, \ | ||
86 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ | 84 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ |
87 | { XFS_BMAPI_METADATA, "METADATA" }, \ | 85 | { XFS_BMAPI_METADATA, "METADATA" }, \ |
88 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ | 86 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ |
@@ -297,6 +295,9 @@ xfs_bmapi( | |||
297 | int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, | 295 | int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, |
298 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, | 296 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, |
299 | int *nmap, int flags); | 297 | int *nmap, int flags); |
298 | int xfs_bmapi_delay(struct xfs_inode *ip, xfs_fileoff_t bno, | ||
299 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, | ||
300 | int *nmap, int flags); | ||
300 | 301 | ||
301 | /* | 302 | /* |
302 | * Unmap (remove) blocks from a file. | 303 | * Unmap (remove) blocks from a file. |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 544f053860f1..681ba34c9233 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -381,7 +381,6 @@ xfs_iomap_write_delay( | |||
381 | xfs_fileoff_t last_fsb; | 381 | xfs_fileoff_t last_fsb; |
382 | xfs_off_t aligned_offset; | 382 | xfs_off_t aligned_offset; |
383 | xfs_fileoff_t ioalign; | 383 | xfs_fileoff_t ioalign; |
384 | xfs_fsblock_t firstblock; | ||
385 | xfs_extlen_t extsz; | 384 | xfs_extlen_t extsz; |
386 | int nimaps; | 385 | int nimaps; |
387 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; | 386 | xfs_bmbt_irec_t imap[XFS_WRITE_IMAPS]; |
@@ -425,12 +424,8 @@ retry: | |||
425 | } | 424 | } |
426 | 425 | ||
427 | nimaps = XFS_WRITE_IMAPS; | 426 | nimaps = XFS_WRITE_IMAPS; |
428 | firstblock = NULLFSBLOCK; | 427 | error = xfs_bmapi_delay(ip, offset_fsb, last_fsb - offset_fsb, |
429 | error = xfs_bmapi(NULL, ip, offset_fsb, | 428 | imap, &nimaps, XFS_BMAPI_ENTIRE); |
430 | (xfs_filblks_t)(last_fsb - offset_fsb), | ||
431 | XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | | ||
432 | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, | ||
433 | &nimaps, NULL); | ||
434 | switch (error) { | 429 | switch (error) { |
435 | case 0: | 430 | case 0: |
436 | case ENOSPC: | 431 | case ENOSPC: |