Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 319861
b: refs/heads/master
c: be60fe5
h: refs/heads/master
i:
  319859: eafc897
v: v3
  • Loading branch information
Christoph Hellwig authored and Ben Myers committed Jul 29, 2012
1 parent 62ff2b5 commit 36ded2c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 59 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 55d6af64cb8bf8c7e9a84b254d2c3479be8c067c
refs/heads/master: be60fe54b216a62403b816d3930a66ad7c51cbc6
127 changes: 69 additions & 58 deletions trunk/fs/xfs/xfs_ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,11 +900,10 @@ xfs_dialloc(
struct xfs_mount *mp = tp->t_mountp;
struct xfs_buf *agbp;
xfs_agnumber_t agno;
struct xfs_agi *agi;
int error;
int ialloced;
int noroom = 0;
xfs_agnumber_t tagno;
xfs_agnumber_t start_agno;
struct xfs_perag *pag;

if (*IO_agbp) {
Expand All @@ -921,25 +920,17 @@ xfs_dialloc(
* We do not have an agbp, so select an initial allocation
* group for inode allocation.
*/
agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
if (agno == NULLAGNUMBER) {
start_agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
if (start_agno == NULLAGNUMBER) {
*inop = NULLFSINO;
return 0;
}

error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
if (error)
return XFS_ERROR(error);
agi = XFS_BUF_TO_AGI(agbp);

tagno = agno;

/*
* If we have already hit the ceiling of inode blocks then clear
* okalloc so we scan all available agi structures for a free
* inode.
*/

if (mp->m_maxicount &&
mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) {
noroom = 1;
Expand All @@ -951,67 +942,87 @@ xfs_dialloc(
* or in which we can allocate some inodes. Iterate through the
* allocation groups upward, wrapping at the end.
*/
while (!agi->agi_freecount) {
/*
* Don't do anything if we're not supposed to allocate
* any blocks, just go on to the next ag.
*/
if (okalloc) {
/*
* Try to allocate some new inodes in the allocation
* group.
*/
if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) {
xfs_trans_brelse(tp, agbp);
if (error == ENOSPC) {
*inop = NULLFSINO;
return 0;
} else
return error;
}
if (ialloced) {
/*
* We successfully allocated some inodes, return
* the current context to the caller so that it
* can commit the current transaction and call
* us again where we left off.
*/
ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
*IO_agbp = agbp;
*inop = NULLFSINO;
return 0;
}
agno = start_agno;
for (;;) {
pag = xfs_perag_get(mp, agno);
if (!pag->pagi_inodeok) {
xfs_ialloc_next_ag(mp);
goto nextag;
}

if (!pag->pagi_init) {
error = xfs_ialloc_pagi_init(mp, tp, agno);
if (error)
goto out_error;
}

/*
* If it failed, give up on this ag.
* Do a first racy fast path check if this AG is usable.
*/
xfs_trans_brelse(tp, agbp);
if (!pag->pagi_freecount && !okalloc)
goto nextag;

error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
if (error)
goto out_error;

/*
* Go on to the next ag: get its ag header.
* Once the AGI has been read in we have to recheck
* pagi_freecount with the AGI buffer lock held.
*/
nextag:
if (++tagno == mp->m_sb.sb_agcount)
tagno = 0;
if (tagno == agno) {
if (pag->pagi_freecount) {
xfs_perag_put(pag);
goto out_alloc;
}

if (!okalloc) {
xfs_trans_brelse(tp, agbp);
goto nextag;
}

error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced);
if (error) {
xfs_trans_brelse(tp, agbp);

if (error != ENOSPC)
goto out_error;

xfs_perag_put(pag);
*inop = NULLFSINO;
return noroom ? ENOSPC : 0;
return 0;
}
pag = xfs_perag_get(mp, tagno);
if (pag->pagi_inodeok == 0) {

if (ialloced) {
/*
* We successfully allocated some inodes, return
* the current context to the caller so that it
* can commit the current transaction and call
* us again where we left off.
*/
ASSERT(pag->pagi_freecount > 0);
xfs_perag_put(pag);
goto nextag;

*IO_agbp = agbp;
*inop = NULLFSINO;
return 0;
}
error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);

nextag:
xfs_perag_put(pag);
if (error)
goto nextag;
agi = XFS_BUF_TO_AGI(agbp);
ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
if (++agno == mp->m_sb.sb_agcount)
agno = 0;
if (agno == start_agno) {
*inop = NULLFSINO;
return noroom ? ENOSPC : 0;
}
}

out_alloc:
*IO_agbp = NULL;
return xfs_dialloc_ag(tp, agbp, parent, inop);
out_error:
xfs_perag_put(pag);
return XFS_ERROR(error);
}

/*
Expand Down

0 comments on commit 36ded2c

Please sign in to comment.