diff options
author | Christoph Hellwig <hch@infradead.org> | 2011-03-04 07:59:55 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2011-03-09 09:23:47 -0500 |
commit | ecb6928fcf969b302929f109e175981df1dba697 (patch) | |
tree | 7cb8ecaa05615c3a1f445088e74ea89e896dfabe /fs/xfs/xfs_alloc.c | |
parent | 86fa8af69d8e90b7b40b8dab84d168527143ae20 (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.c | 129 |
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 | ||
466 | STATIC int | ||
467 | xfs_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 | ||