All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoph Hellwig <hch@infradead.org>
To: xfs@oss.sgi.com
Subject: [PATCH 7/7] xfs: merge xfs_ialloc_ag_select into xfs_dialloc
Date: Wed, 04 Jul 2012 10:54:51 -0400	[thread overview]
Message-ID: <20120704145616.894941902@bombadil.infradead.org> (raw)
In-Reply-To: 20120704145444.863203951@bombadil.infradead.org

[-- Attachment #1: xfs-dialloc-factor-ag_selection-2 --]
[-- Type: text/plain, Size: 6489 bytes --]

Both function contain the same basic loop over all AGs.  Merge the two
by creating three passes in the loop instead of duplicating the code.

Signed-off-by: Christoph Hellwig <hch@lst.de>

---
 fs/xfs/xfs_ialloc.c |  179 +++++++++++++++-------------------------------------
 1 file changed, 55 insertions(+), 124 deletions(-)

Index: xfs/fs/xfs/xfs_ialloc.c
===================================================================
--- xfs.orig/fs/xfs/xfs_ialloc.c	2012-07-02 12:25:24.365774992 +0200
+++ xfs/fs/xfs/xfs_ialloc.c	2012-07-02 12:26:14.325774734 +0200
@@ -439,114 +439,6 @@ xfs_ialloc_next_ag(
 }
 
 /*
- * Select an allocation group to look for a free inode in, based on the parent
- * inode and then mode.  Return the allocation group buffer.
- */
-STATIC xfs_agnumber_t
-xfs_ialloc_ag_select(
-	xfs_trans_t	*tp,		/* transaction pointer */
-	xfs_ino_t	parent,		/* parent directory inode number */
-	umode_t		mode,		/* bits set to indicate file type */
-	int		okalloc)	/* ok to allocate more space */
-{
-	xfs_agnumber_t	agcount;	/* number of ag's in the filesystem */
-	xfs_agnumber_t	agno;		/* current ag number */
-	int		flags;		/* alloc buffer locking flags */
-	xfs_extlen_t	ineed;		/* blocks needed for inode allocation */
-	xfs_extlen_t	longest = 0;	/* longest extent available */
-	xfs_mount_t	*mp;		/* mount point structure */
-	int		needspace;	/* file mode implies space allocated */
-	xfs_perag_t	*pag;		/* per allocation group data */
-	xfs_agnumber_t	pagno;		/* parent (starting) ag number */
-	int		error;
-
-	/*
-	 * Files of these types need at least one block if length > 0
-	 * (and they won't fit in the inode, but that's hard to figure out).
-	 */
-	needspace = S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode);
-	mp = tp->t_mountp;
-	agcount = mp->m_maxagi;
-	if (S_ISDIR(mode))
-		pagno = xfs_ialloc_next_ag(mp);
-	else {
-		pagno = XFS_INO_TO_AGNO(mp, parent);
-		if (pagno >= agcount)
-			pagno = 0;
-	}
-
-	ASSERT(pagno < agcount);
-
-	/*
-	 * Loop through allocation groups, looking for one with a little
-	 * free space in it.  Note we don't look for free inodes, exactly.
-	 * Instead, we include whether there is a need to allocate inodes
-	 * to mean that blocks must be allocated for them,
-	 * if none are currently free.
-	 */
-	agno = pagno;
-	flags = XFS_ALLOC_FLAG_TRYLOCK;
-	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 nextag;
-		}
-
-		if (pag->pagi_freecount) {
-			xfs_perag_put(pag);
-			return agno;
-		}
-
-		if (!okalloc)
-			goto nextag;
-
-		if (!pag->pagf_init) {
-			error = xfs_alloc_pagf_init(mp, tp, agno, flags);
-			if (error)
-				goto nextag;
-		}
-
-		/*
-		 * Is there enough free space for the file plus a block of
-		 * inodes? (if we need to allocate some)?
-		 */
-		ineed = XFS_IALLOC_BLOCKS(mp);
-		longest = pag->pagf_longest;
-		if (!longest)
-			longest = pag->pagf_flcount > 0;
-
-		if (pag->pagf_freeblks >= needspace + ineed &&
-		    longest >= ineed) {
-			xfs_perag_put(pag);
-			return agno;
-		}
-nextag:
-		xfs_perag_put(pag);
-		/*
-		 * No point in iterating over the rest, if we're shutting
-		 * down.
-		 */
-		if (XFS_FORCED_SHUTDOWN(mp))
-			return NULLAGNUMBER;
-		agno++;
-		if (agno >= agcount)
-			agno = 0;
-		if (agno == pagno) {
-			if (flags == 0)
-				return NULLAGNUMBER;
-			flags = 0;
-		}
-	}
-}
-
-/*
  * Try to retrieve the next record to the left/right from the current one.
  */
 STATIC int
@@ -901,10 +793,10 @@ xfs_dialloc(
 	struct xfs_buf		*agbp;
 	xfs_agnumber_t		agno;
 	int			error;
-	int			ialloced;
 	int			noroom = 0;
 	xfs_agnumber_t		start_agno;
 	struct xfs_perag	*pag;
+	int			pass;
 
 	if (*IO_agbp) {
 		/*
@@ -917,16 +809,6 @@ xfs_dialloc(
 	}
 
 	/*
-	 * We do not have an agbp, so select an initial allocation
-	 * group for inode allocation.
-	 */
-	start_agno = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
-	if (start_agno == NULLAGNUMBER) {
-		*inop = NULLFSINO;
-		return 0;
-	}
-
-	/*
 	 * If we have already hit the ceiling of inode blocks then clear
 	 * okalloc so we scan all available agi structures for a free
 	 * inode.
@@ -938,12 +820,31 @@ xfs_dialloc(
 	}
 
 	/*
-	 * Loop until we find an allocation group that either has free inodes
-	 * or in which we can allocate some inodes.  Iterate through the
-	 * allocation groups upward, wrapping at the end.
+	 * For directories start with a new allocation groups, for other file
+	 * types aim to find an inode close to the parent.
 	 */
+	if (S_ISDIR(mode)) {
+		start_agno = xfs_ialloc_next_ag(mp);
+		ASSERT(start_agno < mp->m_maxagi);
+	} else {
+		start_agno = XFS_INO_TO_AGNO(mp, parent);
+		if (start_agno >= mp->m_maxagi)
+			start_agno = 0;
+	}
+
+	/*
+	 * Loop through allocation groups, looking for one with a little
+	 * free space in it.  Note we don't look for free inodes, exactly.
+	 * Instead, we include whether there is a need to allocate inodes
+	 * to mean that blocks must be allocated for them, if none are
+	 * currently free.
+	 */
+	*inop = NULLFSINO;
 	agno = start_agno;
+	pass = 0;
 	for (;;) {
+		int			ialloced;
+
 		pag = xfs_perag_get(mp, agno);
 		if (!pag->pagi_inodeok) {
 			xfs_ialloc_next_ag(mp);
@@ -980,6 +881,33 @@ xfs_dialloc(
 			goto nextag;
 		}
 
+		if (!pag->pagf_init) {
+			int flags = pass ? 0 : XFS_ALLOC_FLAG_TRYLOCK;
+
+			error = xfs_alloc_pagf_init(mp, tp, agno, flags);
+			if (error)
+				goto out_error;
+		}
+
+		if (pass < 2) {
+			/*
+			 * Is there enough free space for the file plus a block
+			 * of inodes?
+			 */
+			xfs_extlen_t	longest = pag->pagf_longest;
+			int		needspace =
+				S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode);
+
+			if (!longest)
+				longest = pag->pagf_flcount > 0;
+
+			if (pag->pagf_freeblks <
+			    XFS_IALLOC_BLOCKS(mp) + needspace)
+				goto nextag;
+			if (longest < XFS_IALLOC_BLOCKS(mp))
+				goto nextag;
+		}
+
 		error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced);
 		if (error) {
 			xfs_trans_brelse(tp, agbp);
@@ -1012,8 +940,11 @@ nextag:
 		if (++agno == mp->m_sb.sb_agcount)
 			agno = 0;
 		if (agno == start_agno) {
-			*inop = NULLFSINO;
-			return noroom ? ENOSPC : 0;
+			if (pass == 2) {
+				*inop = NULLFSINO;
+				return noroom ? ENOSPC : 0;
+			}
+			pass++;
 		}
 	}
 

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  parent reply	other threads:[~2012-07-04 14:56 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-04 14:54 [PATCH 0/7] inode allocator refactoring V2 Christoph Hellwig
2012-07-04 14:54 ` [PATCH 1/7] xfs: remove xfs_ialloc_find_free Christoph Hellwig
2012-07-04 14:54 ` [PATCH 2/7] xfs: split xfs_dialloc Christoph Hellwig
2012-07-29 20:55   ` Ben Myers
2012-07-04 14:54 ` [PATCH 3/7] xfs: remove the alloc_done argument to xfs_dialloc Christoph Hellwig
2012-07-26 17:48   ` Mark Tinguely
2012-07-04 14:54 ` [PATCH 4/7] xfs: add a short cut to xfs_dialloc for the non-NULL agbp case Christoph Hellwig
2012-07-26 17:50   ` Mark Tinguely
2012-07-04 14:54 ` [PATCH 5/7] xfs: refactor xfs_ialloc_ag_select Christoph Hellwig
2012-07-26 17:53   ` Mark Tinguely
2012-07-04 14:54 ` [PATCH 6/7] xfs: do not read the AGI buffer in xfs_dialloc until nessecary Christoph Hellwig
2012-07-26 17:53   ` Mark Tinguely
2012-07-04 14:54 ` Christoph Hellwig [this message]
2012-07-26 17:47   ` [PATCH 7/7] xfs: merge xfs_ialloc_ag_select into xfs_dialloc Mark Tinguely
2012-07-30 17:21     ` Mark Tinguely
  -- strict thread matches above, loose matches on Subject: below --
2012-06-05 14:46 [PATCH 0/7] inode allocator refactoring Christoph Hellwig
2012-06-05 14:46 ` [PATCH 7/7] xfs: merge xfs_ialloc_ag_select into xfs_dialloc Christoph Hellwig
2012-06-18  3:10   ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120704145616.894941902@bombadil.infradead.org \
    --to=hch@infradead.org \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.