From: Christoph Lameter <clameter@sgi.com>
To: akpm@linux-foundation.org
Cc: linux-mm@kvack.org, Mel Gorman <mel@skynet.ie>, andi@firstfloor.org
Subject: [patch 10/17] inodes: Support generic defragmentation
Date: Fri, 15 Feb 2008 16:45:36 -0800 [thread overview]
Message-ID: <20080216004633.988315225@sgi.com> (raw)
In-Reply-To: 20080216004526.763643520@sgi.com
[-- Attachment #1: 0055-inodes-Support-generic-defragmentation.patch --]
[-- Type: text/plain, Size: 4295 bytes --]
This implements the ability to remove inodes in a particular slab
from inode caches. In order to remove an inode we may have to write out
the pages of an inode, the inode itself and remove the dentries referring
to the node.
Provide generic functionality that can be used by filesystems that have
their own inode caches to also tie into the defragmentation functions
that are made available here.
Reviewed-by: Rik van Riel <riel@redhat.com>
Signed-off-by: Christoph Lameter <clameter@sgi.com>
---
fs/inode.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 6 +++
2 files changed, 102 insertions(+)
Index: linux-2.6/fs/inode.c
===================================================================
--- linux-2.6.orig/fs/inode.c 2008-02-14 15:19:12.457507589 -0800
+++ linux-2.6/fs/inode.c 2008-02-15 15:49:22.309268623 -0800
@@ -1370,6 +1370,101 @@ static int __init set_ihash_entries(char
}
__setup("ihash_entries=", set_ihash_entries);
+void *get_inodes(struct kmem_cache *s, int nr, void **v)
+{
+ int i;
+
+ spin_lock(&inode_lock);
+ for (i = 0; i < nr; i++) {
+ struct inode *inode = v[i];
+
+ if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+ v[i] = NULL;
+ else
+ __iget(inode);
+ }
+ spin_unlock(&inode_lock);
+ return NULL;
+}
+EXPORT_SYMBOL(get_inodes);
+
+/*
+ * Function for filesystems that embedd struct inode into their own
+ * structures. The offset is the offset of the struct inode in the fs inode.
+ */
+void *fs_get_inodes(struct kmem_cache *s, int nr, void **v,
+ unsigned long offset)
+{
+ int i;
+
+ for (i = 0; i < nr; i++)
+ v[i] += offset;
+
+ return get_inodes(s, nr, v);
+}
+EXPORT_SYMBOL(fs_get_inodes);
+
+void kick_inodes(struct kmem_cache *s, int nr, void **v, void *private)
+{
+ struct inode *inode;
+ int i;
+ int abort = 0;
+ LIST_HEAD(freeable);
+ struct super_block *sb;
+
+ for (i = 0; i < nr; i++) {
+ inode = v[i];
+ if (!inode)
+ continue;
+
+ if (inode_has_buffers(inode) || inode->i_data.nrpages) {
+ if (remove_inode_buffers(inode))
+ invalidate_mapping_pages(&inode->i_data,
+ 0, -1);
+ }
+
+ /* Invalidate children and dentry */
+ if (S_ISDIR(inode->i_mode)) {
+ struct dentry *d = d_find_alias(inode);
+
+ if (d) {
+ d_invalidate(d);
+ dput(d);
+ }
+ }
+
+ if (inode->i_state & I_DIRTY)
+ write_inode_now(inode, 1);
+
+ d_prune_aliases(inode);
+ }
+
+ mutex_lock(&iprune_mutex);
+ for (i = 0; i < nr; i++) {
+ inode = v[i];
+ if (!inode)
+ continue;
+
+ sb = inode->i_sb;
+ iput(inode);
+ if (abort || !(sb->s_flags & MS_ACTIVE))
+ continue;
+
+ spin_lock(&inode_lock);
+ abort = !can_unuse(inode);
+
+ if (!abort) {
+ list_move(&inode->i_list, &freeable);
+ inode->i_state |= I_FREEING;
+ inodes_stat.nr_unused--;
+ }
+ spin_unlock(&inode_lock);
+ }
+ dispose_list(&freeable);
+ mutex_unlock(&iprune_mutex);
+}
+EXPORT_SYMBOL(kick_inodes);
+
/*
* Initialize the waitqueues and inode hash table.
*/
@@ -1409,6 +1504,7 @@ void __init inode_init(void)
SLAB_MEM_SPREAD),
init_once);
register_shrinker(&icache_shrinker);
+ kmem_cache_setup_defrag(inode_cachep, get_inodes, kick_inodes);
/* Hash may have been set up in inode_init_early */
if (!hashdist)
Index: linux-2.6/include/linux/fs.h
===================================================================
--- linux-2.6.orig/include/linux/fs.h 2008-02-15 10:48:35.463846699 -0800
+++ linux-2.6/include/linux/fs.h 2008-02-15 15:49:22.309268623 -0800
@@ -1787,6 +1787,12 @@ static inline void insert_inode_hash(str
__insert_inode_hash(inode, inode->i_ino);
}
+/* Helper functions for inode defragmentation support in filesystems */
+extern void kick_inodes(struct kmem_cache *, int, void **, void *);
+extern void *get_inodes(struct kmem_cache *, int nr, void **);
+extern void *fs_get_inodes(struct kmem_cache *, int nr, void **,
+ unsigned long offset);
+
extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list);
extern void file_kill(struct file *f);
--
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2008-02-16 0:45 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-16 0:45 [patch 00/17] Slab Fragmentation Reduction V10 Christoph Lameter
2008-02-16 0:45 ` [patch 01/17] SLUB: Extend slabinfo to support -D and -F options Christoph Lameter
2008-02-16 0:45 ` [patch 02/17] SLUB: Add defrag_ratio field and sysfs support Christoph Lameter
2008-02-16 0:45 ` [patch 03/17] SLUB: Replace ctor field with ops field in /sys/slab/* Christoph Lameter
2008-02-16 0:45 ` [patch 04/17] SLUB: Add get() and kick() methods Christoph Lameter
2008-02-16 0:45 ` [patch 05/17] SLUB: Sort slab cache list and establish maximum objects for defrag slabs Christoph Lameter
2008-02-16 0:45 ` [patch 06/17] SLUB: Slab defrag core Christoph Lameter
2008-02-16 0:45 ` [patch 07/17] SLUB: Add KICKABLE to avoid repeated kick() attempts Christoph Lameter
2008-02-16 0:45 ` [patch 08/17] SLUB: Trigger defragmentation from memory reclaim Christoph Lameter
2008-02-16 0:45 ` [patch 09/17] Buffer heads: Support slab defrag Christoph Lameter
2008-02-16 0:45 ` Christoph Lameter [this message]
2008-02-16 0:45 ` [patch 11/17] FS: ExtX filesystem defrag Christoph Lameter
2008-02-16 0:45 ` [patch 12/17] FS: XFS slab defragmentation Christoph Lameter
2008-02-16 0:45 ` [patch 13/17] FS: Proc filesystem support for slab defrag Christoph Lameter
2008-02-16 0:45 ` [patch 14/17] FS: Slab defrag: Reiserfs support Christoph Lameter
2008-02-16 0:45 ` [patch 15/17] FS: Socket inode defragmentation Christoph Lameter
2008-02-16 0:45 ` [patch 16/17] dentries: Add constructor Christoph Lameter
2008-02-16 0:45 ` [patch 17/17] dentries: dentry defragmentation Christoph Lameter
2008-02-23 8:07 ` [patch 00/17] Slab Fragmentation Reduction V10 Andrew Morton
2008-02-23 14:20 ` Andi Kleen
2008-02-27 19:22 ` Christoph Lameter
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=20080216004633.988315225@sgi.com \
--to=clameter@sgi.com \
--cc=akpm@linux-foundation.org \
--cc=andi@firstfloor.org \
--cc=linux-mm@kvack.org \
--cc=mel@skynet.ie \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).