Commit 55d6af64cb8bf8c7e9a84b254d2c3479be8c067c
Committed by
Ben Myers
1 parent
4bb61069d2
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
xfs: refactor xfs_ialloc_ag_select
Loop over the in-core perag structures and prefer using pagi_freecount over going out to the AGI buffer where possible. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Mark Tinguely <tinguely@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Showing 1 changed file with 44 additions and 51 deletions Side-by-side Diff
fs/xfs/xfs_ialloc.c
... | ... | @@ -442,14 +442,13 @@ |
442 | 442 | * Select an allocation group to look for a free inode in, based on the parent |
443 | 443 | * inode and then mode. Return the allocation group buffer. |
444 | 444 | */ |
445 | -STATIC xfs_buf_t * /* allocation group buffer */ | |
445 | +STATIC xfs_agnumber_t | |
446 | 446 | xfs_ialloc_ag_select( |
447 | 447 | xfs_trans_t *tp, /* transaction pointer */ |
448 | 448 | xfs_ino_t parent, /* parent directory inode number */ |
449 | 449 | umode_t mode, /* bits set to indicate file type */ |
450 | 450 | int okalloc) /* ok to allocate more space */ |
451 | 451 | { |
452 | - xfs_buf_t *agbp; /* allocation group header buffer */ | |
453 | 452 | xfs_agnumber_t agcount; /* number of ag's in the filesystem */ |
454 | 453 | xfs_agnumber_t agno; /* current ag number */ |
455 | 454 | int flags; /* alloc buffer locking flags */ |
... | ... | @@ -459,6 +458,7 @@ |
459 | 458 | int needspace; /* file mode implies space allocated */ |
460 | 459 | xfs_perag_t *pag; /* per allocation group data */ |
461 | 460 | xfs_agnumber_t pagno; /* parent (starting) ag number */ |
461 | + int error; | |
462 | 462 | |
463 | 463 | /* |
464 | 464 | * Files of these types need at least one block if length > 0 |
465 | 465 | |
... | ... | @@ -474,7 +474,9 @@ |
474 | 474 | if (pagno >= agcount) |
475 | 475 | pagno = 0; |
476 | 476 | } |
477 | + | |
477 | 478 | ASSERT(pagno < agcount); |
479 | + | |
478 | 480 | /* |
479 | 481 | * Loop through allocation groups, looking for one with a little |
480 | 482 | * free space in it. Note we don't look for free inodes, exactly. |
481 | 483 | |
482 | 484 | |
483 | 485 | |
484 | 486 | |
485 | 487 | |
486 | 488 | |
487 | 489 | |
... | ... | @@ -486,51 +488,45 @@ |
486 | 488 | flags = XFS_ALLOC_FLAG_TRYLOCK; |
487 | 489 | for (;;) { |
488 | 490 | pag = xfs_perag_get(mp, agno); |
491 | + if (!pag->pagi_inodeok) { | |
492 | + xfs_ialloc_next_ag(mp); | |
493 | + goto nextag; | |
494 | + } | |
495 | + | |
489 | 496 | if (!pag->pagi_init) { |
490 | - if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | |
491 | - agbp = NULL; | |
497 | + error = xfs_ialloc_pagi_init(mp, tp, agno); | |
498 | + if (error) | |
492 | 499 | goto nextag; |
493 | - } | |
494 | - } else | |
495 | - agbp = NULL; | |
500 | + } | |
496 | 501 | |
497 | - if (!pag->pagi_inodeok) { | |
498 | - xfs_ialloc_next_ag(mp); | |
499 | - goto unlock_nextag; | |
502 | + if (pag->pagi_freecount) { | |
503 | + xfs_perag_put(pag); | |
504 | + return agno; | |
500 | 505 | } |
501 | 506 | |
507 | + if (!okalloc) | |
508 | + goto nextag; | |
509 | + | |
510 | + if (!pag->pagf_init) { | |
511 | + error = xfs_alloc_pagf_init(mp, tp, agno, flags); | |
512 | + if (error) | |
513 | + goto nextag; | |
514 | + } | |
515 | + | |
502 | 516 | /* |
503 | - * Is there enough free space for the file plus a block | |
504 | - * of inodes (if we need to allocate some)? | |
517 | + * Is there enough free space for the file plus a block of | |
518 | + * inodes? (if we need to allocate some)? | |
505 | 519 | */ |
506 | - ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp); | |
507 | - if (ineed && !pag->pagf_init) { | |
508 | - if (agbp == NULL && | |
509 | - xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | |
510 | - agbp = NULL; | |
511 | - goto nextag; | |
512 | - } | |
513 | - (void)xfs_alloc_pagf_init(mp, tp, agno, flags); | |
520 | + ineed = XFS_IALLOC_BLOCKS(mp); | |
521 | + longest = pag->pagf_longest; | |
522 | + if (!longest) | |
523 | + longest = pag->pagf_flcount > 0; | |
524 | + | |
525 | + if (pag->pagf_freeblks >= needspace + ineed && | |
526 | + longest >= ineed) { | |
527 | + xfs_perag_put(pag); | |
528 | + return agno; | |
514 | 529 | } |
515 | - if (!ineed || pag->pagf_init) { | |
516 | - if (ineed && !(longest = pag->pagf_longest)) | |
517 | - longest = pag->pagf_flcount > 0; | |
518 | - if (!ineed || | |
519 | - (pag->pagf_freeblks >= needspace + ineed && | |
520 | - longest >= ineed && | |
521 | - okalloc)) { | |
522 | - if (agbp == NULL && | |
523 | - xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { | |
524 | - agbp = NULL; | |
525 | - goto nextag; | |
526 | - } | |
527 | - xfs_perag_put(pag); | |
528 | - return agbp; | |
529 | - } | |
530 | - } | |
531 | -unlock_nextag: | |
532 | - if (agbp) | |
533 | - xfs_trans_brelse(tp, agbp); | |
534 | 530 | nextag: |
535 | 531 | xfs_perag_put(pag); |
536 | 532 | /* |
537 | 533 | |
... | ... | @@ -538,13 +534,13 @@ |
538 | 534 | * down. |
539 | 535 | */ |
540 | 536 | if (XFS_FORCED_SHUTDOWN(mp)) |
541 | - return NULL; | |
537 | + return NULLAGNUMBER; | |
542 | 538 | agno++; |
543 | 539 | if (agno >= agcount) |
544 | 540 | agno = 0; |
545 | 541 | if (agno == pagno) { |
546 | 542 | if (flags == 0) |
547 | - return NULL; | |
543 | + return NULLAGNUMBER; | |
548 | 544 | flags = 0; |
549 | 545 | } |
550 | 546 | } |
551 | 547 | |
... | ... | @@ -901,13 +897,13 @@ |
901 | 897 | struct xfs_buf **IO_agbp, |
902 | 898 | xfs_ino_t *inop) |
903 | 899 | { |
900 | + struct xfs_mount *mp = tp->t_mountp; | |
904 | 901 | struct xfs_buf *agbp; |
905 | 902 | xfs_agnumber_t agno; |
906 | 903 | struct xfs_agi *agi; |
907 | 904 | int error; |
908 | 905 | int ialloced; |
909 | 906 | int noroom = 0; |
910 | - struct xfs_mount *mp; | |
911 | 907 | xfs_agnumber_t tagno; |
912 | 908 | struct xfs_perag *pag; |
913 | 909 | |
914 | 910 | |
915 | 911 | |
... | ... | @@ -925,20 +921,17 @@ |
925 | 921 | * We do not have an agbp, so select an initial allocation |
926 | 922 | * group for inode allocation. |
927 | 923 | */ |
928 | - agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc); | |
929 | - | |
930 | - /* | |
931 | - * Couldn't find an allocation group satisfying the | |
932 | - * criteria, give up. | |
933 | - */ | |
934 | - if (!agbp) { | |
924 | + agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc); | |
925 | + if (agno == NULLAGNUMBER) { | |
935 | 926 | *inop = NULLFSINO; |
936 | 927 | return 0; |
937 | 928 | } |
929 | + | |
930 | + error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); | |
931 | + if (error) | |
932 | + return XFS_ERROR(error); | |
938 | 933 | agi = XFS_BUF_TO_AGI(agbp); |
939 | 934 | |
940 | - mp = tp->t_mountp; | |
941 | - agno = be32_to_cpu(agi->agi_seqno); | |
942 | 935 | tagno = agno; |
943 | 936 | |
944 | 937 | /* |