public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3 of 4] Convert xfs_icluster lists to use list.h
@ 2007-08-09 11:42 David Chinner
  0 siblings, 0 replies; only message in thread
From: David Chinner @ 2007-08-09 11:42 UTC (permalink / raw)
  To: xfs-dev; +Cc: xfs-oss

Convert the xfs_icluster inode list to use hlist constructs.
Use a hlist as we only need a single list head pointer and that
keeps the memory usage of these structures down.

Signed-off-by: Dave Chinner <dgc@sgi.com>
---
 fs/xfs/xfs_iget.c  |   61 +++++++++++++----------------------------------------
 fs/xfs/xfs_inode.c |    6 ++++-
 fs/xfs/xfs_inode.h |    5 +---
 fs/xfs/xfsidbg.c   |    4 +--
 4 files changed, 24 insertions(+), 52 deletions(-)

Index: 2.6.x-xfs-new/fs/xfs/xfs_inode.h
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_inode.h	2007-08-09 13:03:53.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_inode.h	2007-08-09 18:14:29.650646277 +1000
@@ -178,7 +178,7 @@ extern void xfs_iocore_inode_reinit(stru
  * the same time.
  */
 typedef struct xfs_icluster {
-	struct xfs_inode	*icl_ip;
+	struct hlist_head	icl_inodes;	/* list of inodes on cluster */
 	xfs_daddr_t		icl_blkno;	/* starting block number of
 						 * the cluster */
 	struct xfs_buf		*icl_buf;	/* the inode buffer */
@@ -296,8 +296,7 @@ typedef struct xfs_inode {
 
 	xfs_icdinode_t		i_d;		/* most of ondisk inode */
 	xfs_icluster_t		*i_cluster;	/* cluster list header */
-	struct xfs_inode	*i_cnext;	/* cluster link forward */
-	struct xfs_inode	*i_cprev;	/* cluster link backward */
+	struct hlist_node	i_cnode;	/* cluster link node */
 
 	xfs_fsize_t		i_size;		/* in-memory size */
 	/* Trace buffers per inode. */
Index: 2.6.x-xfs-new/fs/xfs/xfs_iget.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_iget.c	2007-08-09 13:03:53.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_iget.c	2007-08-09 18:15:16.832572205 +1000
@@ -290,31 +290,21 @@ finish_inode:
 	ip->i_udquot = ip->i_gdquot = NULL;
 	xfs_iflags_set(ip, XFS_INEW);
 
-	ASSERT(ip->i_cluster == NULL && ip->i_cprev == NULL &&
-	       ip->i_cnext == NULL);
+	ASSERT(ip->i_cluster == NULL);
 
-	if (icl) {
-		/* insert this inode into the doubly-linked list
-		 * where icl points. lock the icl to protect against
-		 * others traversing the icl list */
-		spin_lock(&icl->icl_lock);
-		ASSERT(icl->icl_ip != NULL);
-		iq = icl->icl_ip;
-		ip->i_cprev = iq->i_cprev;
-		iq->i_cprev->i_cnext = ip;
-		iq->i_cprev = ip;
-		ip->i_cnext = iq;
-		icl->icl_ip = ip;
-		ip->i_cluster = icl;
-		spin_unlock(&icl->icl_lock);
-	} else {
-		ip->i_cnext = ip;
-		ip->i_cprev = ip;
-		ip->i_cluster = new_icl;
-		new_icl->icl_ip = ip;
+	if (!icl) {
 		spin_lock_init(&new_icl->icl_lock);
+		INIT_HLIST_HEAD(&new_icl->icl_inodes);
+		icl = new_icl;
 		new_icl = NULL;
+	} else {
+		ASSERT(!hlist_empty(&icl->icl_inodes));
 	}
+	spin_lock(&icl->icl_lock);
+	hlist_add_head(&ip->i_cnode, &icl->icl_inodes);
+	ip->i_cluster = icl;
+	spin_unlock(&icl->icl_lock);
+
 	write_unlock(&pag->pag_ici_lock);
 	radix_tree_preload_end();
 	if (new_icl)
@@ -579,33 +569,12 @@ xfs_iextract(
 	 */
 	mp = ip->i_mount;
 	spin_lock(&ip->i_cluster->icl_lock);
-	if (unlikely(ip->i_cnext == ip)) {
-		/*
-		 * Last inode in cluster object.
-		 *
-		 * We've been removed from the inode radix tree, and
-		 * we are the last inode to reference the cluster.
-		 * We can simply drop our loks and free it at this point
-		 * because nothing can find us or the cluster.
-		 */
-		ASSERT(ip->i_cnext == ip && ip->i_cprev == ip);
-		ASSERT(ip->i_cluster != NULL);
+	hlist_del(&ip->i_cnode);
+	spin_unlock(&ip->i_cluster->icl_lock);
 
-		spin_unlock(&ip->i_cluster->icl_lock);
+	/* was last inode in cluster? */
+	if (hlist_empty(&ip->i_cluster->icl_inodes))
 		kmem_zone_free(xfs_icluster_zone, ip->i_cluster);
-	} else {
-		/* delete one inode from a non-empty list */
-		iq = ip->i_cnext;
-		iq->i_cprev = ip->i_cprev;
-		ip->i_cprev->i_cnext = iq;
-		if (ip->i_cluster->icl_ip == ip) {
-			ip->i_cluster->icl_ip = iq;
-		}
-		spin_unlock(&ip->i_cluster->icl_lock);
-		ip->i_cluster = __return_address;
-		ip->i_cprev = __return_address;
-		ip->i_cnext = __return_address;
-	}
 
 	/*
 	 * Remove from mount's inode list.
Index: 2.6.x-xfs-new/fs/xfs/xfs_inode.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_inode.c	2007-08-09 13:03:53.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_inode.c	2007-08-09 18:11:14.059874991 +1000
@@ -3050,6 +3050,7 @@ xfs_iflush(
 	xfs_inode_t		*iq;
 	int			clcount;	/* count of inodes clustered */
 	int			bufwasdelwri;
+	struct hlist_node	*entry;
 	enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) };
 
 	XFS_STATS_INC(xs_iflush_count);
@@ -3168,7 +3169,10 @@ xfs_iflush(
 	ip->i_cluster->icl_buf = bp;
 
 	clcount = 0;
-	for (iq = ip->i_cnext; iq != ip; iq = iq->i_cnext) {
+	hlist_for_each_entry(iq, entry, &ip->i_cluster->icl_inodes, i_cnode) {
+		if (iq == ip)
+			continue;
+
 		/*
 		 * Do an un-protected check to see if the inode is dirty and
 		 * is a candidate for flushing.  These checks will be repeated
Index: 2.6.x-xfs-new/fs/xfs/xfsidbg.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfsidbg.c	2007-08-09 13:03:53.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfsidbg.c	2007-08-09 18:16:46.581017645 +1000
@@ -6755,8 +6755,8 @@ xfsidbg_xnode(xfs_inode_t *ip)
 	kdb_printf("\n");
 	kdb_printf("icluster 0x%p cnext 0x%p cprev 0x%p\n",
 		ip->i_cluster,
-		ip->i_cnext,
-		ip->i_cprev);
+		ip->i_cnode.next,
+		ip->i_cnode.pprev);
 	xfs_xnode_fork("data", &ip->i_df);
 	xfs_xnode_fork("attr", ip->i_afp);
 	kdb_printf("\n");

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-08-09 11:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-09 11:42 [PATCH 3 of 4] Convert xfs_icluster lists to use list.h David Chinner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox