aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-09-18 16:40:48 -0400
committerAlex Elder <aelder@sgi.com>2011-10-11 22:15:04 -0400
commit4403280aa5c00c6074f2dc23e1cfc11f2bfb0032 (patch)
tree322f188e78d6faf1cae53cb56ed7918d49702366 /fs/xfs
parentb64dfe4e180ab5047c59bcbe379538eb23be4d8e (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>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_bmap.c115
-rw-r--r--fs/xfs/xfs_bmap.h5
-rw-r--r--fs/xfs/xfs_iomap.c9
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 */
4561int
4562xfs_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 }
4880trim_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(
297int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, 295int 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);
298int 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: