diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-09-18 16:40:47 -0400 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-10-11 22:15:04 -0400 |
commit | b64dfe4e180ab5047c59bcbe379538eb23be4d8e (patch) | |
tree | 1c159801e7c7c0f947c0edd572e8ec26baf42ada /fs/xfs | |
parent | 5b777ad517ee75d3bb8d67c142d808822e46601b (diff) |
xfs: factor delalloc reservations out of xfs_bmapi
Move the reservation of delayed allocations, and addition of delalloc
regions to the extent trees into a new helper function. For now
this adds some twisted goto logic to xfs_bmapi, but that will be
cleaned up in the following patches.
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.c | 202 |
1 files changed, 118 insertions, 84 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index fd06bf17d09..cd01783a89d 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4441,6 +4441,120 @@ xfs_bmapi_read( | |||
4441 | return 0; | 4441 | return 0; |
4442 | } | 4442 | } |
4443 | 4443 | ||
4444 | STATIC int | ||
4445 | xfs_bmapi_reserve_delalloc( | ||
4446 | struct xfs_inode *ip, | ||
4447 | xfs_fileoff_t aoff, | ||
4448 | xfs_filblks_t len, | ||
4449 | struct xfs_bmbt_irec *got, | ||
4450 | struct xfs_bmbt_irec *prev, | ||
4451 | xfs_extnum_t *lastx, | ||
4452 | int eof) | ||
4453 | { | ||
4454 | struct xfs_mount *mp = ip->i_mount; | ||
4455 | struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); | ||
4456 | xfs_extlen_t alen; | ||
4457 | xfs_extlen_t indlen; | ||
4458 | xfs_fsblock_t firstblock = NULLFSBLOCK; | ||
4459 | struct xfs_btree_cur *cur = NULL; | ||
4460 | int tmp_logflags = 0; | ||
4461 | char rt = XFS_IS_REALTIME_INODE(ip); | ||
4462 | xfs_extlen_t extsz; | ||
4463 | int error; | ||
4464 | |||
4465 | alen = XFS_FILBLKS_MIN(len, MAXEXTLEN); | ||
4466 | if (!eof) | ||
4467 | alen = XFS_FILBLKS_MIN(alen, got->br_startoff - aoff); | ||
4468 | |||
4469 | /* Figure out the extent size, adjust alen */ | ||
4470 | extsz = xfs_get_extsz_hint(ip); | ||
4471 | if (extsz) { | ||
4472 | /* | ||
4473 | * Make sure we don't exceed a single extent length when we | ||
4474 | * align the extent by reducing length we are going to | ||
4475 | * allocate by the maximum amount extent size aligment may | ||
4476 | * require. | ||
4477 | */ | ||
4478 | alen = XFS_FILBLKS_MIN(len, MAXEXTLEN - (2 * extsz - 1)); | ||
4479 | error = xfs_bmap_extsize_align(mp, got, prev, extsz, rt, eof, | ||
4480 | 1, 0, &aoff, &alen); | ||
4481 | ASSERT(!error); | ||
4482 | } | ||
4483 | |||
4484 | if (rt) | ||
4485 | extsz = alen / mp->m_sb.sb_rextsize; | ||
4486 | |||
4487 | /* | ||
4488 | * Make a transaction-less quota reservation for delayed allocation | ||
4489 | * blocks. This number gets adjusted later. We return if we haven't | ||
4490 | * allocated blocks already inside this loop. | ||
4491 | */ | ||
4492 | error = xfs_trans_reserve_quota_nblks(NULL, ip, (long)alen, 0, | ||
4493 | rt ? XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); | ||
4494 | if (error) | ||
4495 | return error; | ||
4496 | |||
4497 | /* | ||
4498 | * Split changing sb for alen and indlen since they could be coming | ||
4499 | * from different places. | ||
4500 | */ | ||
4501 | indlen = (xfs_extlen_t)xfs_bmap_worst_indlen(ip, alen); | ||
4502 | ASSERT(indlen > 0); | ||
4503 | |||
4504 | if (rt) { | ||
4505 | error = xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, | ||
4506 | -((int64_t)extsz), 0); | ||
4507 | } else { | ||
4508 | error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | ||
4509 | -((int64_t)alen), 0); | ||
4510 | } | ||
4511 | |||
4512 | if (error) | ||
4513 | goto out_unreserve_quota; | ||
4514 | |||
4515 | error = xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, | ||
4516 | -((int64_t)indlen), 0); | ||
4517 | if (error) | ||
4518 | goto out_unreserve_blocks; | ||
4519 | |||
4520 | |||
4521 | ip->i_delayed_blks += alen; | ||
4522 | |||
4523 | got->br_startoff = aoff; | ||
4524 | got->br_startblock = nullstartblock(indlen); | ||
4525 | got->br_blockcount = alen; | ||
4526 | got->br_state = XFS_EXT_NORM; | ||
4527 | |||
4528 | error = xfs_bmap_add_extent(NULL, ip, lastx, &cur, got, &firstblock, | ||
4529 | NULL, &tmp_logflags, XFS_DATA_FORK); | ||
4530 | ASSERT(!error); | ||
4531 | ASSERT(!tmp_logflags); | ||
4532 | ASSERT(!cur); | ||
4533 | |||
4534 | /* | ||
4535 | * Update our extent pointer, given that xfs_bmap_add_extent might | ||
4536 | * have merged it into one of the neighbouring ones. | ||
4537 | */ | ||
4538 | xfs_bmbt_get_all(xfs_iext_get_ext(ifp, *lastx), got); | ||
4539 | |||
4540 | ASSERT(got->br_startoff <= aoff); | ||
4541 | ASSERT(got->br_startoff + got->br_blockcount >= aoff + alen); | ||
4542 | ASSERT(isnullstartblock(got->br_startblock)); | ||
4543 | ASSERT(got->br_state == XFS_EXT_NORM); | ||
4544 | return 0; | ||
4545 | |||
4546 | out_unreserve_blocks: | ||
4547 | if (rt) | ||
4548 | xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, extsz, 0); | ||
4549 | else | ||
4550 | xfs_icsb_modify_counters(mp, XFS_SBS_FDBLOCKS, alen, 0); | ||
4551 | out_unreserve_quota: | ||
4552 | if (XFS_IS_QUOTA_ON(mp)) | ||
4553 | xfs_trans_unreserve_quota_nblks(NULL, ip, alen, 0, rt ? | ||
4554 | XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS); | ||
4555 | return error; | ||
4556 | } | ||
4557 | |||
4444 | /* | 4558 | /* |
4445 | * Map file blocks to filesystem blocks. | 4559 | * Map file blocks to filesystem blocks. |
4446 | * File range is given by the bno/len pair. | 4560 | * File range is given by the bno/len pair. |
@@ -4479,7 +4593,6 @@ xfs_bmapi( | |||
4479 | int error; /* error return */ | 4593 | int error; /* error return */ |
4480 | xfs_bmbt_irec_t got; /* current file extent record */ | 4594 | xfs_bmbt_irec_t got; /* current file extent record */ |
4481 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4595 | xfs_ifork_t *ifp; /* inode fork pointer */ |
4482 | xfs_extlen_t indlen; /* indirect blocks length */ | ||
4483 | xfs_extnum_t lastx; /* last useful extent number */ | 4596 | xfs_extnum_t lastx; /* last useful extent number */ |
4484 | int logflags; /* flags for transaction logging */ | 4597 | int logflags; /* flags for transaction logging */ |
4485 | xfs_extlen_t minleft; /* min blocks left after allocation */ | 4598 | xfs_extlen_t minleft; /* min blocks left after allocation */ |
@@ -4615,43 +4728,8 @@ xfs_bmapi( | |||
4615 | } | 4728 | } |
4616 | minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; | 4729 | minlen = (flags & XFS_BMAPI_CONTIG) ? alen : 1; |
4617 | if (flags & XFS_BMAPI_DELAY) { | 4730 | if (flags & XFS_BMAPI_DELAY) { |
4618 | xfs_extlen_t extsz; | 4731 | error = xfs_bmapi_reserve_delalloc(ip, bno, len, &got, |
4619 | 4732 | &prev, &lastx, eof); | |
4620 | /* Figure out the extent size, adjust alen */ | ||
4621 | extsz = xfs_get_extsz_hint(ip); | ||
4622 | if (extsz) { | ||
4623 | /* | ||
4624 | * make sure we don't exceed a single | ||
4625 | * extent length when we align the | ||
4626 | * extent by reducing length we are | ||
4627 | * going to allocate by the maximum | ||
4628 | * amount extent size aligment may | ||
4629 | * require. | ||
4630 | */ | ||
4631 | alen = XFS_FILBLKS_MIN(len, | ||
4632 | MAXEXTLEN - (2 * extsz - 1)); | ||
4633 | error = xfs_bmap_extsize_align(mp, | ||
4634 | &got, &prev, extsz, | ||
4635 | rt, eof, | ||
4636 | flags&XFS_BMAPI_DELAY, | ||
4637 | flags&XFS_BMAPI_CONVERT, | ||
4638 | &aoff, &alen); | ||
4639 | ASSERT(!error); | ||
4640 | } | ||
4641 | |||
4642 | if (rt) | ||
4643 | extsz = alen / mp->m_sb.sb_rextsize; | ||
4644 | |||
4645 | /* | ||
4646 | * Make a transaction-less quota reservation for | ||
4647 | * delayed allocation blocks. This number gets | ||
4648 | * adjusted later. We return if we haven't | ||
4649 | * allocated blocks already inside this loop. | ||
4650 | */ | ||
4651 | error = xfs_trans_reserve_quota_nblks( | ||
4652 | NULL, ip, (long)alen, 0, | ||
4653 | rt ? XFS_QMOPT_RES_RTBLKS : | ||
4654 | XFS_QMOPT_RES_REGBLKS); | ||
4655 | if (error) { | 4733 | if (error) { |
4656 | if (n == 0) { | 4734 | if (n == 0) { |
4657 | *nmap = 0; | 4735 | *nmap = 0; |
@@ -4661,51 +4739,7 @@ xfs_bmapi( | |||
4661 | break; | 4739 | break; |
4662 | } | 4740 | } |
4663 | 4741 | ||
4664 | /* | 4742 | goto trim_extent; |
4665 | * Split changing sb for alen and indlen since | ||
4666 | * they could be coming from different places. | ||
4667 | */ | ||
4668 | indlen = (xfs_extlen_t) | ||
4669 | xfs_bmap_worst_indlen(ip, alen); | ||
4670 | ASSERT(indlen > 0); | ||
4671 | |||
4672 | if (rt) { | ||
4673 | error = xfs_mod_incore_sb(mp, | ||
4674 | XFS_SBS_FREXTENTS, | ||
4675 | -((int64_t)extsz), 0); | ||
4676 | } else { | ||
4677 | error = xfs_icsb_modify_counters(mp, | ||
4678 | XFS_SBS_FDBLOCKS, | ||
4679 | -((int64_t)alen), 0); | ||
4680 | } | ||
4681 | if (!error) { | ||
4682 | error = xfs_icsb_modify_counters(mp, | ||
4683 | XFS_SBS_FDBLOCKS, | ||
4684 | -((int64_t)indlen), 0); | ||
4685 | if (error && rt) | ||
4686 | xfs_mod_incore_sb(mp, | ||
4687 | XFS_SBS_FREXTENTS, | ||
4688 | (int64_t)extsz, 0); | ||
4689 | else if (error) | ||
4690 | xfs_icsb_modify_counters(mp, | ||
4691 | XFS_SBS_FDBLOCKS, | ||
4692 | (int64_t)alen, 0); | ||
4693 | } | ||
4694 | |||
4695 | if (error) { | ||
4696 | if (XFS_IS_QUOTA_ON(mp)) | ||
4697 | /* unreserve the blocks now */ | ||
4698 | (void) | ||
4699 | xfs_trans_unreserve_quota_nblks( | ||
4700 | NULL, ip, | ||
4701 | (long)alen, 0, rt ? | ||
4702 | XFS_QMOPT_RES_RTBLKS : | ||
4703 | XFS_QMOPT_RES_REGBLKS); | ||
4704 | break; | ||
4705 | } | ||
4706 | |||
4707 | ip->i_delayed_blks += alen; | ||
4708 | abno = nullstartblock(indlen); | ||
4709 | } else { | 4743 | } else { |
4710 | /* | 4744 | /* |
4711 | * If first time, allocate and fill in | 4745 | * If first time, allocate and fill in |
@@ -4843,7 +4877,7 @@ xfs_bmapi( | |||
4843 | n++; | 4877 | n++; |
4844 | continue; | 4878 | continue; |
4845 | } | 4879 | } |
4846 | 4880 | trim_extent: | |
4847 | /* Deal with the allocated space we found. */ | 4881 | /* Deal with the allocated space we found. */ |
4848 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); | 4882 | xfs_bmapi_trim_map(mval, &got, &bno, len, obno, end, n, flags); |
4849 | 4883 | ||