aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_bmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_bmap.c')
-rw-r--r--fs/xfs/xfs_bmap.c112
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 |=