![Gao Xiang](/assets/img/avatar_default.png)
In the course of some operations, we look up the perag from the mount multiple times to get or change perag information. These are often very short pieces of code, so while the lookup cost is generally low, the cost of the lookup is far higher than the cost of the operation we are doing on the perag. Since we changed buffers to hold references to the perag they are cached in, many modification contexts already hold active references to the perag that are held across these operations. This is especially true for any operation that is serialised by an allocation group header buffer. In these cases, we can just use the buffer's reference to the perag to avoid needing to do lookups to access the perag. This means that many operations don't need to do perag lookups at all to access the perag because they've already looked up objects that own persistent references and hence can use that reference instead. Cc: Dave Chinner <dchinner@redhat.com> Cc: "Darrick J. Wong" <darrick.wong@oracle.com> Signed-off-by: Gao Xiang <hsiangkao@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
41 lines
1.2 KiB
C
41 lines
1.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
/*
|
|
* Copyright (C) 2016 Oracle. All Rights Reserved.
|
|
* Author: Darrick J. Wong <darrick.wong@oracle.com>
|
|
*/
|
|
#ifndef __XFS_AG_RESV_H__
|
|
#define __XFS_AG_RESV_H__
|
|
|
|
int xfs_ag_resv_free(struct xfs_perag *pag);
|
|
int xfs_ag_resv_init(struct xfs_perag *pag, struct xfs_trans *tp);
|
|
|
|
bool xfs_ag_resv_critical(struct xfs_perag *pag, enum xfs_ag_resv_type type);
|
|
xfs_extlen_t xfs_ag_resv_needed(struct xfs_perag *pag,
|
|
enum xfs_ag_resv_type type);
|
|
|
|
void xfs_ag_resv_alloc_extent(struct xfs_perag *pag, enum xfs_ag_resv_type type,
|
|
struct xfs_alloc_arg *args);
|
|
void xfs_ag_resv_free_extent(struct xfs_perag *pag, enum xfs_ag_resv_type type,
|
|
struct xfs_trans *tp, xfs_extlen_t len);
|
|
|
|
/*
|
|
* RMAPBT reservation accounting wrappers. Since rmapbt blocks are sourced from
|
|
* the AGFL, they are allocated one at a time and the reservation updates don't
|
|
* require a transaction.
|
|
*/
|
|
static inline void
|
|
xfs_ag_resv_rmapbt_alloc(
|
|
struct xfs_mount *mp,
|
|
xfs_agnumber_t agno)
|
|
{
|
|
struct xfs_alloc_arg args = { NULL };
|
|
struct xfs_perag *pag;
|
|
|
|
args.len = 1;
|
|
pag = xfs_perag_get(mp, agno);
|
|
xfs_ag_resv_alloc_extent(pag, XFS_AG_RESV_RMAPBT, &args);
|
|
xfs_perag_put(pag);
|
|
}
|
|
|
|
#endif /* __XFS_AG_RESV_H__ */
|