Loading fs/inode.c +13 −7 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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) { Loading @@ -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) Loading fs/super.c +10 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include <linux/kobject.h> #include <linux/mutex.h> #include <linux/file.h> #include <linux/async.h> #include <asm/uaccess.h> #include "internal.h" Loading Loading @@ -71,6 +72,7 @@ static struct super_block *alloc_super(struct file_system_type *type) INIT_HLIST_HEAD(&s->s_anon); INIT_LIST_HEAD(&s->s_inodes); INIT_LIST_HEAD(&s->s_dentry_lru); INIT_LIST_HEAD(&s->s_async_list); init_rwsem(&s->s_umount); mutex_init(&s->s_lock); lockdep_set_class(&s->s_umount, &type->s_umount_key); Loading Loading @@ -289,11 +291,18 @@ void generic_shutdown_super(struct super_block *sb) { const struct super_operations *sop = sb->s_op; if (sb->s_root) { shrink_dcache_for_umount(sb); fsync_super(sb); lock_super(sb); sb->s_flags &= ~MS_ACTIVE; /* * wait for asynchronous fs operations to finish before going further */ async_synchronize_full_special(&sb->s_async_list); /* bad name - it should be evict_inodes() */ invalidate_inodes(sb); lock_kernel(); Loading Loading @@ -449,6 +458,7 @@ void sync_filesystems(int wait) if (sb->s_flags & MS_RDONLY) continue; sb->s_need_sync_fs = 1; async_synchronize_full_special(&sb->s_async_list); } restart: Loading include/linux/fs.h +5 −0 Original line number Diff line number Diff line Loading @@ -1184,6 +1184,11 @@ struct super_block { * generic_show_options() */ char *s_options; /* * storage for asynchronous operations */ struct list_head s_async_list; }; extern struct timespec current_fs_time(struct super_block *sb); Loading Loading
fs/inode.c +13 −7 Original line number Diff line number Diff line Loading @@ -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: Loading Loading @@ -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) { Loading @@ -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) Loading
fs/super.c +10 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ #include <linux/kobject.h> #include <linux/mutex.h> #include <linux/file.h> #include <linux/async.h> #include <asm/uaccess.h> #include "internal.h" Loading Loading @@ -71,6 +72,7 @@ static struct super_block *alloc_super(struct file_system_type *type) INIT_HLIST_HEAD(&s->s_anon); INIT_LIST_HEAD(&s->s_inodes); INIT_LIST_HEAD(&s->s_dentry_lru); INIT_LIST_HEAD(&s->s_async_list); init_rwsem(&s->s_umount); mutex_init(&s->s_lock); lockdep_set_class(&s->s_umount, &type->s_umount_key); Loading Loading @@ -289,11 +291,18 @@ void generic_shutdown_super(struct super_block *sb) { const struct super_operations *sop = sb->s_op; if (sb->s_root) { shrink_dcache_for_umount(sb); fsync_super(sb); lock_super(sb); sb->s_flags &= ~MS_ACTIVE; /* * wait for asynchronous fs operations to finish before going further */ async_synchronize_full_special(&sb->s_async_list); /* bad name - it should be evict_inodes() */ invalidate_inodes(sb); lock_kernel(); Loading Loading @@ -449,6 +458,7 @@ void sync_filesystems(int wait) if (sb->s_flags & MS_RDONLY) continue; sb->s_need_sync_fs = 1; async_synchronize_full_special(&sb->s_async_list); } restart: Loading
include/linux/fs.h +5 −0 Original line number Diff line number Diff line Loading @@ -1184,6 +1184,11 @@ struct super_block { * generic_show_options() */ char *s_options; /* * storage for asynchronous operations */ struct list_head s_async_list; }; extern struct timespec current_fs_time(struct super_block *sb); Loading