* [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 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.