diff options
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r-- | fs/xfs/xfs_bmap.c | 112 |
1 files changed, 64 insertions, 48 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index f6f5ad35734c..6f5d283888aa 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -4545,18 +4545,17 @@ xfs_bmapi( | |||
4545 | xfs_extlen_t alen; /* allocated extent length */ | 4545 | xfs_extlen_t alen; /* allocated extent length */ |
4546 | xfs_fileoff_t aoff; /* allocated file offset */ | 4546 | xfs_fileoff_t aoff; /* allocated file offset */ |
4547 | xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ | 4547 | xfs_bmalloca_t bma; /* args for xfs_bmap_alloc */ |
4548 | char contig; /* allocation must be one extent */ | ||
4549 | xfs_btree_cur_t *cur; /* bmap btree cursor */ | 4548 | xfs_btree_cur_t *cur; /* bmap btree cursor */ |
4550 | char delay; /* this request is for delayed alloc */ | ||
4551 | xfs_fileoff_t end; /* end of mapped file region */ | 4549 | xfs_fileoff_t end; /* end of mapped file region */ |
4552 | int eof; /* we've hit the end of extent list */ | 4550 | int eof; /* we've hit the end of extent list */ |
4551 | char contig; /* allocation must be one extent */ | ||
4552 | char delay; /* this request is for delayed alloc */ | ||
4553 | char exact; /* don't do all of wasdelayed extent */ | ||
4553 | xfs_bmbt_rec_t *ep; /* extent list entry pointer */ | 4554 | xfs_bmbt_rec_t *ep; /* extent list entry pointer */ |
4554 | int error; /* error return */ | 4555 | int error; /* error return */ |
4555 | char exact; /* don't do all of wasdelayed extent */ | ||
4556 | xfs_bmbt_irec_t got; /* current extent list record */ | 4556 | xfs_bmbt_irec_t got; /* current extent list record */ |
4557 | xfs_ifork_t *ifp; /* inode fork pointer */ | 4557 | xfs_ifork_t *ifp; /* inode fork pointer */ |
4558 | xfs_extlen_t indlen; /* indirect blocks length */ | 4558 | xfs_extlen_t indlen; /* indirect blocks length */ |
4559 | char inhole; /* current location is hole in file */ | ||
4560 | xfs_extnum_t lastx; /* last useful extent number */ | 4559 | xfs_extnum_t lastx; /* last useful extent number */ |
4561 | int logflags; /* flags for transaction logging */ | 4560 | int logflags; /* flags for transaction logging */ |
4562 | xfs_extlen_t minleft; /* min blocks left after allocation */ | 4561 | xfs_extlen_t minleft; /* min blocks left after allocation */ |
@@ -4567,13 +4566,15 @@ xfs_bmapi( | |||
4567 | xfs_extnum_t nextents; /* number of extents in file */ | 4566 | xfs_extnum_t nextents; /* number of extents in file */ |
4568 | xfs_fileoff_t obno; /* old block number (offset) */ | 4567 | xfs_fileoff_t obno; /* old block number (offset) */ |
4569 | xfs_bmbt_irec_t prev; /* previous extent list record */ | 4568 | xfs_bmbt_irec_t prev; /* previous extent list record */ |
4570 | char stateless; /* ignore state flag set */ | ||
4571 | int tmp_logflags; /* temp flags holder */ | 4569 | int tmp_logflags; /* temp flags holder */ |
4570 | int whichfork; /* data or attr fork */ | ||
4571 | char inhole; /* current location is hole in file */ | ||
4572 | char stateless; /* ignore state flag set */ | ||
4572 | char trim; /* output trimmed to match range */ | 4573 | char trim; /* output trimmed to match range */ |
4573 | char userdata; /* allocating non-metadata */ | 4574 | char userdata; /* allocating non-metadata */ |
4574 | char wasdelay; /* old extent was delayed */ | 4575 | char wasdelay; /* old extent was delayed */ |
4575 | int whichfork; /* data or attr fork */ | ||
4576 | char wr; /* this is a write request */ | 4576 | char wr; /* this is a write request */ |
4577 | char rt; /* this is a realtime file */ | ||
4577 | char rsvd; /* OK to allocate reserved blocks */ | 4578 | char rsvd; /* OK to allocate reserved blocks */ |
4578 | #ifdef DEBUG | 4579 | #ifdef DEBUG |
4579 | xfs_fileoff_t orig_bno; /* original block number value */ | 4580 | xfs_fileoff_t orig_bno; /* original block number value */ |
@@ -4603,6 +4604,7 @@ xfs_bmapi( | |||
4603 | } | 4604 | } |
4604 | if (XFS_FORCED_SHUTDOWN(mp)) | 4605 | if (XFS_FORCED_SHUTDOWN(mp)) |
4605 | return XFS_ERROR(EIO); | 4606 | return XFS_ERROR(EIO); |
4607 | rt = XFS_IS_REALTIME_INODE(ip); | ||
4606 | ifp = XFS_IFORK_PTR(ip, whichfork); | 4608 | ifp = XFS_IFORK_PTR(ip, whichfork); |
4607 | ASSERT(ifp->if_ext_max == | 4609 | ASSERT(ifp->if_ext_max == |
4608 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); | 4610 | XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t)); |
@@ -4707,9 +4709,16 @@ xfs_bmapi( | |||
4707 | } | 4709 | } |
4708 | minlen = contig ? alen : 1; | 4710 | minlen = contig ? alen : 1; |
4709 | if (delay) { | 4711 | if (delay) { |
4710 | indlen = (xfs_extlen_t) | 4712 | xfs_extlen_t extsz = 0; |
4711 | xfs_bmap_worst_indlen(ip, alen); | 4713 | |
4712 | ASSERT(indlen > 0); | 4714 | /* Figure out the extent size, adjust alen */ |
4715 | if (rt) { | ||
4716 | if (!(extsz = ip->i_d.di_extsize)) | ||
4717 | extsz = mp->m_sb.sb_rextsize; | ||
4718 | alen = roundup(alen, extsz); | ||
4719 | extsz = alen / mp->m_sb.sb_rextsize; | ||
4720 | } | ||
4721 | |||
4713 | /* | 4722 | /* |
4714 | * Make a transaction-less quota reservation for | 4723 | * Make a transaction-less quota reservation for |
4715 | * delayed allocation blocks. This number gets | 4724 | * delayed allocation blocks. This number gets |
@@ -4717,8 +4726,10 @@ xfs_bmapi( | |||
4717 | * We return EDQUOT if we haven't allocated | 4726 | * We return EDQUOT if we haven't allocated |
4718 | * blks already inside this loop; | 4727 | * blks already inside this loop; |
4719 | */ | 4728 | */ |
4720 | if (XFS_TRANS_RESERVE_BLKQUOTA( | 4729 | if (XFS_TRANS_RESERVE_QUOTA_NBLKS( |
4721 | mp, NULL, ip, (long)alen)) { | 4730 | mp, NULL, ip, (long)alen, 0, |
4731 | rt ? XFS_QMOPT_RES_RTBLKS : | ||
4732 | XFS_QMOPT_RES_REGBLKS)) { | ||
4722 | if (n == 0) { | 4733 | if (n == 0) { |
4723 | *nmap = 0; | 4734 | *nmap = 0; |
4724 | ASSERT(cur == NULL); | 4735 | ASSERT(cur == NULL); |
@@ -4731,40 +4742,34 @@ xfs_bmapi( | |||
4731 | * Split changing sb for alen and indlen since | 4742 | * Split changing sb for alen and indlen since |
4732 | * they could be coming from different places. | 4743 | * they could be coming from different places. |
4733 | */ | 4744 | */ |
4734 | if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { | 4745 | indlen = (xfs_extlen_t) |
4735 | xfs_extlen_t extsz; | 4746 | xfs_bmap_worst_indlen(ip, alen); |
4736 | xfs_extlen_t ralen; | 4747 | ASSERT(indlen > 0); |
4737 | if (!(extsz = ip->i_d.di_extsize)) | ||
4738 | extsz = mp->m_sb.sb_rextsize; | ||
4739 | ralen = roundup(alen, extsz); | ||
4740 | ralen = ralen / mp->m_sb.sb_rextsize; | ||
4741 | if (xfs_mod_incore_sb(mp, | ||
4742 | XFS_SBS_FREXTENTS, | ||
4743 | -(ralen), rsvd)) { | ||
4744 | if (XFS_IS_QUOTA_ON(ip->i_mount)) | ||
4745 | XFS_TRANS_UNRESERVE_BLKQUOTA( | ||
4746 | mp, NULL, ip, | ||
4747 | (long)alen); | ||
4748 | break; | ||
4749 | } | ||
4750 | } else { | ||
4751 | if (xfs_mod_incore_sb(mp, | ||
4752 | XFS_SBS_FDBLOCKS, | ||
4753 | -(alen), rsvd)) { | ||
4754 | if (XFS_IS_QUOTA_ON(ip->i_mount)) | ||
4755 | XFS_TRANS_UNRESERVE_BLKQUOTA( | ||
4756 | mp, NULL, ip, | ||
4757 | (long)alen); | ||
4758 | break; | ||
4759 | } | ||
4760 | } | ||
4761 | 4748 | ||
4762 | if (xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, | 4749 | if (rt) |
4763 | -(indlen), rsvd)) { | 4750 | error = xfs_mod_incore_sb(mp, |
4764 | XFS_TRANS_UNRESERVE_BLKQUOTA( | 4751 | XFS_SBS_FREXTENTS, |
4765 | mp, NULL, ip, (long)alen); | 4752 | -(extsz), rsvd); |
4753 | else | ||
4754 | error = xfs_mod_incore_sb(mp, | ||
4755 | XFS_SBS_FDBLOCKS, | ||
4756 | -(alen), rsvd); | ||
4757 | if (!error) | ||
4758 | error = xfs_mod_incore_sb(mp, | ||
4759 | XFS_SBS_FDBLOCKS, | ||
4760 | -(indlen), rsvd); | ||
4761 | |||
4762 | if (error) { | ||
4763 | if (XFS_IS_QUOTA_ON(ip->i_mount)) | ||
4764 | /* unreserve the blocks now */ | ||
4765 | XFS_TRANS_UNRESERVE_QUOTA_NBLKS( | ||
4766 | mp, NULL, ip, | ||
4767 | (long)alen, 0, rt ? | ||
4768 | XFS_QMOPT_RES_RTBLKS : | ||
4769 | XFS_QMOPT_RES_REGBLKS); | ||
4766 | break; | 4770 | break; |
4767 | } | 4771 | } |
4772 | |||
4768 | ip->i_delayed_blks += alen; | 4773 | ip->i_delayed_blks += alen; |
4769 | abno = NULLSTARTBLOCK(indlen); | 4774 | abno = NULLSTARTBLOCK(indlen); |
4770 | } else { | 4775 | } else { |
@@ -5389,13 +5394,24 @@ xfs_bunmapi( | |||
5389 | } | 5394 | } |
5390 | if (wasdel) { | 5395 | if (wasdel) { |
5391 | ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); | 5396 | ASSERT(STARTBLOCKVAL(del.br_startblock) > 0); |
5392 | xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, | 5397 | /* Update realtim/data freespace, unreserve quota */ |
5393 | (int)del.br_blockcount, rsvd); | 5398 | if (isrt) { |
5394 | /* Unreserve our quota space */ | 5399 | xfs_filblks_t rtexts; |
5395 | XFS_TRANS_RESERVE_QUOTA_NBLKS( | 5400 | |
5396 | mp, NULL, ip, -((long)del.br_blockcount), 0, | 5401 | rtexts = XFS_FSB_TO_B(mp, del.br_blockcount); |
5397 | isrt ? XFS_QMOPT_RES_RTBLKS : | 5402 | do_div(rtexts, mp->m_sb.sb_rextsize); |
5403 | xfs_mod_incore_sb(mp, XFS_SBS_FREXTENTS, | ||
5404 | (int)rtexts, rsvd); | ||
5405 | XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, | ||
5406 | -((long)del.br_blockcount), 0, | ||
5407 | XFS_QMOPT_RES_RTBLKS); | ||
5408 | } else { | ||
5409 | xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, | ||
5410 | (int)del.br_blockcount, rsvd); | ||
5411 | XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, NULL, ip, | ||
5412 | -((long)del.br_blockcount), 0, | ||
5398 | XFS_QMOPT_RES_REGBLKS); | 5413 | XFS_QMOPT_RES_REGBLKS); |
5414 | } | ||
5399 | ip->i_delayed_blks -= del.br_blockcount; | 5415 | ip->i_delayed_blks -= del.br_blockcount; |
5400 | if (cur) | 5416 | if (cur) |
5401 | cur->bc_private.b.flags |= | 5417 | cur->bc_private.b.flags |= |