@@ -510,18 +510,18 @@ static const struct rhashtable_params xfs_buf_hash_params = {
510510};
511511
512512int
513- xfs_buf_hash_init (
514- struct xfs_perag * pag )
513+ xfs_buf_cache_init (
514+ struct xfs_buf_cache * bch )
515515{
516- spin_lock_init (& pag -> pag_buf_lock );
517- return rhashtable_init (& pag -> pag_buf_hash , & xfs_buf_hash_params );
516+ spin_lock_init (& bch -> bc_lock );
517+ return rhashtable_init (& bch -> bc_hash , & xfs_buf_hash_params );
518518}
519519
520520void
521- xfs_buf_hash_destroy (
522- struct xfs_perag * pag )
521+ xfs_buf_cache_destroy (
522+ struct xfs_buf_cache * bch )
523523{
524- rhashtable_destroy (& pag -> pag_buf_hash );
524+ rhashtable_destroy (& bch -> bc_hash );
525525}
526526
527527static int
@@ -584,7 +584,7 @@ xfs_buf_find_lock(
584584
585585static inline int
586586xfs_buf_lookup (
587- struct xfs_perag * pag ,
587+ struct xfs_buf_cache * bch ,
588588 struct xfs_buf_map * map ,
589589 xfs_buf_flags_t flags ,
590590 struct xfs_buf * * bpp )
@@ -593,7 +593,7 @@ xfs_buf_lookup(
593593 int error ;
594594
595595 rcu_read_lock ();
596- bp = rhashtable_lookup (& pag -> pag_buf_hash , map , xfs_buf_hash_params );
596+ bp = rhashtable_lookup (& bch -> bc_hash , map , xfs_buf_hash_params );
597597 if (!bp || !atomic_inc_not_zero (& bp -> b_hold )) {
598598 rcu_read_unlock ();
599599 return - ENOENT ;
@@ -618,6 +618,7 @@ xfs_buf_lookup(
618618static int
619619xfs_buf_find_insert (
620620 struct xfs_buftarg * btp ,
621+ struct xfs_buf_cache * bch ,
621622 struct xfs_perag * pag ,
622623 struct xfs_buf_map * cmap ,
623624 struct xfs_buf_map * map ,
@@ -646,18 +647,18 @@ xfs_buf_find_insert(
646647 goto out_free_buf ;
647648 }
648649
649- spin_lock (& pag -> pag_buf_lock );
650- bp = rhashtable_lookup_get_insert_fast (& pag -> pag_buf_hash ,
650+ spin_lock (& bch -> bc_lock );
651+ bp = rhashtable_lookup_get_insert_fast (& bch -> bc_hash ,
651652 & new_bp -> b_rhash_head , xfs_buf_hash_params );
652653 if (IS_ERR (bp )) {
653654 error = PTR_ERR (bp );
654- spin_unlock (& pag -> pag_buf_lock );
655+ spin_unlock (& bch -> bc_lock );
655656 goto out_free_buf ;
656657 }
657658 if (bp ) {
658659 /* found an existing buffer */
659660 atomic_inc (& bp -> b_hold );
660- spin_unlock (& pag -> pag_buf_lock );
661+ spin_unlock (& bch -> bc_lock );
661662 error = xfs_buf_find_lock (bp , flags );
662663 if (error )
663664 xfs_buf_rele (bp );
@@ -668,17 +669,36 @@ xfs_buf_find_insert(
668669
669670 /* The new buffer keeps the perag reference until it is freed. */
670671 new_bp -> b_pag = pag ;
671- spin_unlock (& pag -> pag_buf_lock );
672+ spin_unlock (& bch -> bc_lock );
672673 * bpp = new_bp ;
673674 return 0 ;
674675
675676out_free_buf :
676677 xfs_buf_free (new_bp );
677678out_drop_pag :
678- xfs_perag_put (pag );
679+ if (pag )
680+ xfs_perag_put (pag );
679681 return error ;
680682}
681683
684+ static inline struct xfs_perag *
685+ xfs_buftarg_get_pag (
686+ struct xfs_buftarg * btp ,
687+ const struct xfs_buf_map * map )
688+ {
689+ struct xfs_mount * mp = btp -> bt_mount ;
690+
691+ return xfs_perag_get (mp , xfs_daddr_to_agno (mp , map -> bm_bn ));
692+ }
693+
694+ static inline struct xfs_buf_cache *
695+ xfs_buftarg_buf_cache (
696+ struct xfs_buftarg * btp ,
697+ struct xfs_perag * pag )
698+ {
699+ return & pag -> pag_bcache ;
700+ }
701+
682702/*
683703 * Assembles a buffer covering the specified range. The code is optimised for
684704 * cache hits, as metadata intensive workloads will see 3 orders of magnitude
@@ -692,6 +712,7 @@ xfs_buf_get_map(
692712 xfs_buf_flags_t flags ,
693713 struct xfs_buf * * bpp )
694714{
715+ struct xfs_buf_cache * bch ;
695716 struct xfs_perag * pag ;
696717 struct xfs_buf * bp = NULL ;
697718 struct xfs_buf_map cmap = { .bm_bn = map [0 ].bm_bn };
@@ -707,10 +728,10 @@ xfs_buf_get_map(
707728 if (error )
708729 return error ;
709730
710- pag = xfs_perag_get (btp -> bt_mount ,
711- xfs_daddr_to_agno (btp -> bt_mount , cmap . bm_bn ) );
731+ pag = xfs_buftarg_get_pag (btp , & cmap );
732+ bch = xfs_buftarg_buf_cache (btp , pag );
712733
713- error = xfs_buf_lookup (pag , & cmap , flags , & bp );
734+ error = xfs_buf_lookup (bch , & cmap , flags , & bp );
714735 if (error && error != - ENOENT )
715736 goto out_put_perag ;
716737
@@ -722,13 +743,14 @@ xfs_buf_get_map(
722743 goto out_put_perag ;
723744
724745 /* xfs_buf_find_insert() consumes the perag reference. */
725- error = xfs_buf_find_insert (btp , pag , & cmap , map , nmaps ,
746+ error = xfs_buf_find_insert (btp , bch , pag , & cmap , map , nmaps ,
726747 flags , & bp );
727748 if (error )
728749 return error ;
729750 } else {
730751 XFS_STATS_INC (btp -> bt_mount , xb_get_locked );
731- xfs_perag_put (pag );
752+ if (pag )
753+ xfs_perag_put (pag );
732754 }
733755
734756 /* We do not hold a perag reference anymore. */
@@ -756,7 +778,8 @@ xfs_buf_get_map(
756778 return 0 ;
757779
758780out_put_perag :
759- xfs_perag_put (pag );
781+ if (pag )
782+ xfs_perag_put (pag );
760783 return error ;
761784}
762785
@@ -1016,7 +1039,9 @@ static void
10161039xfs_buf_rele_cached (
10171040 struct xfs_buf * bp )
10181041{
1042+ struct xfs_buftarg * btp = bp -> b_target ;
10191043 struct xfs_perag * pag = bp -> b_pag ;
1044+ struct xfs_buf_cache * bch = xfs_buftarg_buf_cache (btp , pag );
10201045 bool release ;
10211046 bool freebuf = false;
10221047
@@ -1035,7 +1060,7 @@ xfs_buf_rele_cached(
10351060 * leading to a use-after-free scenario.
10361061 */
10371062 spin_lock (& bp -> b_lock );
1038- release = atomic_dec_and_lock (& bp -> b_hold , & pag -> pag_buf_lock );
1063+ release = atomic_dec_and_lock (& bp -> b_hold , & bch -> bc_lock );
10391064 if (!release ) {
10401065 /*
10411066 * Drop the in-flight state if the buffer is already on the LRU
@@ -1056,11 +1081,11 @@ xfs_buf_rele_cached(
10561081 * buffer for the LRU and clear the (now stale) dispose list
10571082 * state flag
10581083 */
1059- if (list_lru_add_obj (& bp -> b_target -> bt_lru , & bp -> b_lru )) {
1084+ if (list_lru_add_obj (& btp -> bt_lru , & bp -> b_lru )) {
10601085 bp -> b_state &= ~XFS_BSTATE_DISPOSE ;
10611086 atomic_inc (& bp -> b_hold );
10621087 }
1063- spin_unlock (& pag -> pag_buf_lock );
1088+ spin_unlock (& bch -> bc_lock );
10641089 } else {
10651090 /*
10661091 * most of the time buffers will already be removed from the
@@ -1069,16 +1094,17 @@ xfs_buf_rele_cached(
10691094 * was on was the disposal list
10701095 */
10711096 if (!(bp -> b_state & XFS_BSTATE_DISPOSE )) {
1072- list_lru_del_obj (& bp -> b_target -> bt_lru , & bp -> b_lru );
1097+ list_lru_del_obj (& btp -> bt_lru , & bp -> b_lru );
10731098 } else {
10741099 ASSERT (list_empty (& bp -> b_lru ));
10751100 }
10761101
10771102 ASSERT (!(bp -> b_flags & _XBF_DELWRI_Q ));
1078- rhashtable_remove_fast (& pag -> pag_buf_hash , & bp -> b_rhash_head ,
1079- xfs_buf_hash_params );
1080- spin_unlock (& pag -> pag_buf_lock );
1081- xfs_perag_put (pag );
1103+ rhashtable_remove_fast (& bch -> bc_hash , & bp -> b_rhash_head ,
1104+ xfs_buf_hash_params );
1105+ spin_unlock (& bch -> bc_lock );
1106+ if (pag )
1107+ xfs_perag_put (pag );
10821108 freebuf = true;
10831109 }
10841110
0 commit comments