aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_alloc.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2011-03-04 07:59:55 -0500
committerAlex Elder <aelder@sgi.com>2011-03-09 09:23:47 -0500
commitecb6928fcf969b302929f109e175981df1dba697 (patch)
tree7cb8ecaa05615c3a1f445088e74ea89e896dfabe /fs/xfs/xfs_alloc.c
parent86fa8af69d8e90b7b40b8dab84d168527143ae20 (diff)
xfs: factor agf counter updates into a helper
Updating the AGF and transactions counters is duplicated between allocating and freeing extents. Factor the code into a common helper. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_alloc.c')
-rw-r--r--fs/xfs/xfs_alloc.c129
1 files changed, 68 insertions, 61 deletions
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index b5af10713dca..4bc3c649aee4 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -463,6 +463,27 @@ xfs_alloc_read_agfl(
463 return 0; 463 return 0;
464} 464}
465 465
466STATIC int
467xfs_alloc_update_counters(
468 struct xfs_trans *tp,
469 struct xfs_perag *pag,
470 struct xfs_buf *agbp,
471 long len)
472{
473 struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
474
475 pag->pagf_freeblks += len;
476 be32_add_cpu(&agf->agf_freeblks, len);
477
478 xfs_trans_agblocks_delta(tp, len);
479 if (unlikely(be32_to_cpu(agf->agf_freeblks) >
480 be32_to_cpu(agf->agf_length)))
481 return EFSCORRUPTED;
482
483 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
484 return 0;
485}
486
466/* 487/*
467 * Allocation group level functions. 488 * Allocation group level functions.
468 */ 489 */
@@ -504,49 +525,44 @@ xfs_alloc_ag_vextent(
504 ASSERT(0); 525 ASSERT(0);
505 /* NOTREACHED */ 526 /* NOTREACHED */
506 } 527 }
507 if (error) 528
529 if (error || args->agbno == NULLAGBLOCK)
508 return error; 530 return error;
509 /*
510 * If the allocation worked, need to change the agf structure
511 * (and log it), and the superblock.
512 */
513 if (args->agbno != NULLAGBLOCK) {
514 xfs_agf_t *agf; /* allocation group freelist header */
515 long slen = (long)args->len;
516 531
517 ASSERT(args->len >= args->minlen && args->len <= args->maxlen); 532 ASSERT(args->len >= args->minlen);
518 ASSERT(!(args->wasfromfl) || !args->isfl); 533 ASSERT(args->len <= args->maxlen);
519 ASSERT(args->agbno % args->alignment == 0); 534 ASSERT(!args->wasfromfl || !args->isfl);
520 if (!(args->wasfromfl)) { 535 ASSERT(args->agbno % args->alignment == 0);
521 536
522 agf = XFS_BUF_TO_AGF(args->agbp); 537 if (!args->wasfromfl) {
523 be32_add_cpu(&agf->agf_freeblks, -(args->len)); 538 error = xfs_alloc_update_counters(args->tp, args->pag,
524 xfs_trans_agblocks_delta(args->tp, 539 args->agbp,
525 -((long)(args->len))); 540 -((long)(args->len)));
526 args->pag->pagf_freeblks -= args->len; 541 if (error)
527 ASSERT(be32_to_cpu(agf->agf_freeblks) <= 542 return error;
528 be32_to_cpu(agf->agf_length)); 543
529 xfs_alloc_log_agf(args->tp, args->agbp, 544 /*
530 XFS_AGF_FREEBLKS); 545 * Search the busylist for these blocks and mark the
531 /* 546 * transaction as synchronous if blocks are found. This
532 * Search the busylist for these blocks and mark the 547 * avoids the need to block due to a synchronous log
533 * transaction as synchronous if blocks are found. This 548 * force to ensure correct ordering as the synchronous
534 * avoids the need to block due to a synchronous log 549 * transaction will guarantee that for us.
535 * force to ensure correct ordering as the synchronous 550 */
536 * transaction will guarantee that for us. 551 if (xfs_alloc_busy_search(args->mp, args->agno,
537 */ 552 args->agbno, args->len))
538 if (xfs_alloc_busy_search(args->mp, args->agno, 553 xfs_trans_set_sync(args->tp);
539 args->agbno, args->len))
540 xfs_trans_set_sync(args->tp);
541 }
542 if (!args->isfl)
543 xfs_trans_mod_sb(args->tp,
544 args->wasdel ? XFS_TRANS_SB_RES_FDBLOCKS :
545 XFS_TRANS_SB_FDBLOCKS, -slen);
546 XFS_STATS_INC(xs_allocx);
547 XFS_STATS_ADD(xs_allocb, args->len);
548 } 554 }
549 return 0; 555
556 if (!args->isfl) {
557 xfs_trans_mod_sb(args->tp, args->wasdel ?
558 XFS_TRANS_SB_RES_FDBLOCKS :
559 XFS_TRANS_SB_FDBLOCKS,
560 -((long)(args->len)));
561 }
562
563 XFS_STATS_INC(xs_allocx);
564 XFS_STATS_ADD(xs_allocb, args->len);
565 return error;
550} 566}
551 567
552/* 568/*
@@ -1385,6 +1401,7 @@ xfs_free_ag_extent(
1385 xfs_mount_t *mp; /* mount point struct for filesystem */ 1401 xfs_mount_t *mp; /* mount point struct for filesystem */
1386 xfs_agblock_t nbno; /* new starting block of freespace */ 1402 xfs_agblock_t nbno; /* new starting block of freespace */
1387 xfs_extlen_t nlen; /* new length of freespace */ 1403 xfs_extlen_t nlen; /* new length of freespace */
1404 xfs_perag_t *pag; /* per allocation group data */
1388 1405
1389 mp = tp->t_mountp; 1406 mp = tp->t_mountp;
1390 /* 1407 /*
@@ -1583,30 +1600,20 @@ xfs_free_ag_extent(
1583 XFS_WANT_CORRUPTED_GOTO(i == 1, error0); 1600 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1584 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); 1601 xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR);
1585 cnt_cur = NULL; 1602 cnt_cur = NULL;
1603
1586 /* 1604 /*
1587 * Update the freespace totals in the ag and superblock. 1605 * Update the freespace totals in the ag and superblock.
1588 */ 1606 */
1589 { 1607 pag = xfs_perag_get(mp, agno);
1590 xfs_agf_t *agf; 1608 error = xfs_alloc_update_counters(tp, pag, agbp, len);
1591 xfs_perag_t *pag; /* per allocation group data */ 1609 xfs_perag_put(pag);
1592 1610 if (error)
1593 pag = xfs_perag_get(mp, agno); 1611 goto error0;
1594 pag->pagf_freeblks += len; 1612
1595 xfs_perag_put(pag); 1613 if (!isfl)
1596 1614 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
1597 agf = XFS_BUF_TO_AGF(agbp); 1615 XFS_STATS_INC(xs_freex);
1598 be32_add_cpu(&agf->agf_freeblks, len); 1616 XFS_STATS_ADD(xs_freeb, len);
1599 xfs_trans_agblocks_delta(tp, len);
1600 XFS_WANT_CORRUPTED_GOTO(
1601 be32_to_cpu(agf->agf_freeblks) <=
1602 be32_to_cpu(agf->agf_length),
1603 error0);
1604 xfs_alloc_log_agf(tp, agbp, XFS_AGF_FREEBLKS);
1605 if (!isfl)
1606 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len);
1607 XFS_STATS_INC(xs_freex);
1608 XFS_STATS_ADD(xs_freeb, len);
1609 }
1610 1617
1611 trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); 1618 trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright);
1612 1619