提交 55d6af64 编写于 作者: C Christoph Hellwig 提交者: Ben Myers

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: NChristoph Hellwig <hch@lst.de>
Reviewed-by: NDave Chinner <dchinner@redhat.com>
Reviewed-by: NMark Tinguely <tinguely@sgi.com>
Signed-off-by: NBen Myers <bpm@sgi.com>
上级 4bb61069
...@@ -442,14 +442,13 @@ xfs_ialloc_next_ag( ...@@ -442,14 +442,13 @@ xfs_ialloc_next_ag(
* Select an allocation group to look for a free inode in, based on the parent * Select an allocation group to look for a free inode in, based on the parent
* inode and then mode. Return the allocation group buffer. * inode and then mode. Return the allocation group buffer.
*/ */
STATIC xfs_buf_t * /* allocation group buffer */ STATIC xfs_agnumber_t
xfs_ialloc_ag_select( xfs_ialloc_ag_select(
xfs_trans_t *tp, /* transaction pointer */ xfs_trans_t *tp, /* transaction pointer */
xfs_ino_t parent, /* parent directory inode number */ xfs_ino_t parent, /* parent directory inode number */
umode_t mode, /* bits set to indicate file type */ umode_t mode, /* bits set to indicate file type */
int okalloc) /* ok to allocate more space */ int okalloc) /* ok to allocate more space */
{ {
xfs_buf_t *agbp; /* allocation group header buffer */
xfs_agnumber_t agcount; /* number of ag's in the filesystem */ xfs_agnumber_t agcount; /* number of ag's in the filesystem */
xfs_agnumber_t agno; /* current ag number */ xfs_agnumber_t agno; /* current ag number */
int flags; /* alloc buffer locking flags */ int flags; /* alloc buffer locking flags */
...@@ -459,6 +458,7 @@ xfs_ialloc_ag_select( ...@@ -459,6 +458,7 @@ xfs_ialloc_ag_select(
int needspace; /* file mode implies space allocated */ int needspace; /* file mode implies space allocated */
xfs_perag_t *pag; /* per allocation group data */ xfs_perag_t *pag; /* per allocation group data */
xfs_agnumber_t pagno; /* parent (starting) ag number */ xfs_agnumber_t pagno; /* parent (starting) ag number */
int error;
/* /*
* Files of these types need at least one block if length > 0 * Files of these types need at least one block if length > 0
...@@ -474,7 +474,9 @@ xfs_ialloc_ag_select( ...@@ -474,7 +474,9 @@ xfs_ialloc_ag_select(
if (pagno >= agcount) if (pagno >= agcount)
pagno = 0; pagno = 0;
} }
ASSERT(pagno < agcount); ASSERT(pagno < agcount);
/* /*
* Loop through allocation groups, looking for one with a little * Loop through allocation groups, looking for one with a little
* free space in it. Note we don't look for free inodes, exactly. * free space in it. Note we don't look for free inodes, exactly.
...@@ -486,51 +488,45 @@ xfs_ialloc_ag_select( ...@@ -486,51 +488,45 @@ xfs_ialloc_ag_select(
flags = XFS_ALLOC_FLAG_TRYLOCK; flags = XFS_ALLOC_FLAG_TRYLOCK;
for (;;) { for (;;) {
pag = xfs_perag_get(mp, agno); pag = xfs_perag_get(mp, agno);
if (!pag->pagi_inodeok) {
xfs_ialloc_next_ag(mp);
goto nextag;
}
if (!pag->pagi_init) { if (!pag->pagi_init) {
if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { error = xfs_ialloc_pagi_init(mp, tp, agno);
agbp = NULL; if (error)
goto nextag; goto nextag;
} }
} else
agbp = NULL;
if (!pag->pagi_inodeok) { if (pag->pagi_freecount) {
xfs_ialloc_next_ag(mp); xfs_perag_put(pag);
goto unlock_nextag; return agno;
} }
/* if (!okalloc)
* Is there enough free space for the file plus a block goto nextag;
* of inodes (if we need to allocate some)?
*/ if (!pag->pagf_init) {
ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp); error = xfs_alloc_pagf_init(mp, tp, agno, flags);
if (ineed && !pag->pagf_init) { if (error)
if (agbp == NULL &&
xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
agbp = NULL;
goto nextag; goto nextag;
}
(void)xfs_alloc_pagf_init(mp, tp, agno, flags);
} }
if (!ineed || pag->pagf_init) {
if (ineed && !(longest = pag->pagf_longest)) /*
longest = pag->pagf_flcount > 0; * Is there enough free space for the file plus a block of
if (!ineed || * inodes? (if we need to allocate some)?
(pag->pagf_freeblks >= needspace + ineed && */
longest >= ineed && ineed = XFS_IALLOC_BLOCKS(mp);
okalloc)) { longest = pag->pagf_longest;
if (agbp == NULL && if (!longest)
xfs_ialloc_read_agi(mp, tp, agno, &agbp)) { longest = pag->pagf_flcount > 0;
agbp = NULL;
goto nextag; if (pag->pagf_freeblks >= needspace + ineed &&
} longest >= ineed) {
xfs_perag_put(pag); xfs_perag_put(pag);
return agbp; return agno;
}
} }
unlock_nextag:
if (agbp)
xfs_trans_brelse(tp, agbp);
nextag: nextag:
xfs_perag_put(pag); xfs_perag_put(pag);
/* /*
...@@ -538,13 +534,13 @@ xfs_ialloc_ag_select( ...@@ -538,13 +534,13 @@ xfs_ialloc_ag_select(
* down. * down.
*/ */
if (XFS_FORCED_SHUTDOWN(mp)) if (XFS_FORCED_SHUTDOWN(mp))
return NULL; return NULLAGNUMBER;
agno++; agno++;
if (agno >= agcount) if (agno >= agcount)
agno = 0; agno = 0;
if (agno == pagno) { if (agno == pagno) {
if (flags == 0) if (flags == 0)
return NULL; return NULLAGNUMBER;
flags = 0; flags = 0;
} }
} }
...@@ -901,13 +897,13 @@ xfs_dialloc( ...@@ -901,13 +897,13 @@ xfs_dialloc(
struct xfs_buf **IO_agbp, struct xfs_buf **IO_agbp,
xfs_ino_t *inop) xfs_ino_t *inop)
{ {
struct xfs_mount *mp = tp->t_mountp;
struct xfs_buf *agbp; struct xfs_buf *agbp;
xfs_agnumber_t agno; xfs_agnumber_t agno;
struct xfs_agi *agi; struct xfs_agi *agi;
int error; int error;
int ialloced; int ialloced;
int noroom = 0; int noroom = 0;
struct xfs_mount *mp;
xfs_agnumber_t tagno; xfs_agnumber_t tagno;
struct xfs_perag *pag; struct xfs_perag *pag;
...@@ -925,20 +921,17 @@ xfs_dialloc( ...@@ -925,20 +921,17 @@ xfs_dialloc(
* We do not have an agbp, so select an initial allocation * We do not have an agbp, so select an initial allocation
* group for inode allocation. * group for inode allocation.
*/ */
agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc); agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
if (agno == NULLAGNUMBER) {
/*
* Couldn't find an allocation group satisfying the
* criteria, give up.
*/
if (!agbp) {
*inop = NULLFSINO; *inop = NULLFSINO;
return 0; return 0;
} }
error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
if (error)
return XFS_ERROR(error);
agi = XFS_BUF_TO_AGI(agbp); agi = XFS_BUF_TO_AGI(agbp);
mp = tp->t_mountp;
agno = be32_to_cpu(agi->agi_seqno);
tagno = agno; tagno = agno;
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册