diff options
author | Arjan van de Ven <arjan@linux.intel.com> | 2009-01-06 07:20:54 -0800 |
---|---|---|
committer | Arjan van de Ven <arjan@linux.intel.com> | 2009-01-07 08:47:24 -0800 |
commit | efaee192063a54749c56b7383803e16fe553630e (patch) | |
tree | b18e3072904e53701bdd7889bb32babf8cc7bf7c /fs/inode.c | |
parent | f29d3b23238e1955a8094e038c72546e99308e61 (diff) | |
download | lwn-efaee192063a54749c56b7383803e16fe553630e.tar.gz lwn-efaee192063a54749c56b7383803e16fe553630e.zip |
async: make the final inode deletion an asynchronous event
this makes "rm -rf" on a (names cached) kernel tree go from
11.6 to 8.6 seconds on an ext3 filesystem
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/fs/inode.c b/fs/inode.c index 7a6e8c2ff7b1..0013ac1af8e7 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -22,6 +22,7 @@ #include <linux/bootmem.h> #include <linux/inotify.h> #include <linux/mount.h> +#include <linux/async.h> /* * This is needed for the following functions: @@ -1138,16 +1139,11 @@ EXPORT_SYMBOL(remove_inode_hash); * I_FREEING is set so that no-one will take a new reference to the inode while * it is being deleted. */ -void generic_delete_inode(struct inode *inode) +static void generic_delete_inode_async(void *data, async_cookie_t cookie) { + struct inode *inode = data; const struct super_operations *op = inode->i_sb->s_op; - list_del_init(&inode->i_list); - list_del_init(&inode->i_sb_list); - inode->i_state |= I_FREEING; - inodes_stat.nr_inodes--; - spin_unlock(&inode_lock); - security_inode_delete(inode); if (op->delete_inode) { @@ -1171,6 +1167,16 @@ void generic_delete_inode(struct inode *inode) destroy_inode(inode); } +void generic_delete_inode(struct inode *inode) +{ + list_del_init(&inode->i_list); + list_del_init(&inode->i_sb_list); + inode->i_state |= I_FREEING; + inodes_stat.nr_inodes--; + spin_unlock(&inode_lock); + async_schedule_special(generic_delete_inode_async, inode, &inode->i_sb->s_async_list); +} + EXPORT_SYMBOL(generic_delete_inode); static void generic_forget_inode(struct inode *inode) |