提交 22fe4042 编写于 作者: J Jan Kara 提交者: Al Viro

vfs: split generic_forget_inode() so that hugetlbfs does not have to copy it

Hugetlbfs needs to do special things instead of truncate_inode_pages().
 Currently, it copied generic_forget_inode() except for
truncate_inode_pages() call which is asking for trouble (the code there
isn't trivial).  So create a separate function generic_detach_inode()
which does all the list magic done in generic_forget_inode() and call
it from hugetlbfs_forget_inode().
Signed-off-by: NJan Kara <jack@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 af0d9ae8
...@@ -380,36 +380,11 @@ static void hugetlbfs_delete_inode(struct inode *inode) ...@@ -380,36 +380,11 @@ static void hugetlbfs_delete_inode(struct inode *inode)
static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock) static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
{ {
struct super_block *sb = inode->i_sb; if (generic_detach_inode(inode)) {
truncate_hugepages(inode, 0);
if (!hlist_unhashed(&inode->i_hash)) { clear_inode(inode);
if (!(inode->i_state & (I_DIRTY|I_SYNC))) destroy_inode(inode);
list_move(&inode->i_list, &inode_unused);
inodes_stat.nr_unused++;
if (!sb || (sb->s_flags & MS_ACTIVE)) {
spin_unlock(&inode_lock);
return;
}
inode->i_state |= I_WILL_FREE;
spin_unlock(&inode_lock);
/*
* write_inode_now is a noop as we set BDI_CAP_NO_WRITEBACK
* in our backing_dev_info.
*/
write_inode_now(inode, 1);
spin_lock(&inode_lock);
inode->i_state &= ~I_WILL_FREE;
inodes_stat.nr_unused--;
hlist_del_init(&inode->i_hash);
} }
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);
truncate_hugepages(inode, 0);
clear_inode(inode);
destroy_inode(inode);
} }
static void hugetlbfs_drop_inode(struct inode *inode) static void hugetlbfs_drop_inode(struct inode *inode)
......
...@@ -1241,7 +1241,16 @@ void generic_delete_inode(struct inode *inode) ...@@ -1241,7 +1241,16 @@ void generic_delete_inode(struct inode *inode)
} }
EXPORT_SYMBOL(generic_delete_inode); EXPORT_SYMBOL(generic_delete_inode);
static void generic_forget_inode(struct inode *inode) /**
* generic_detach_inode - remove inode from inode lists
* @inode: inode to remove
*
* Remove inode from inode lists, write it if it's dirty. This is just an
* internal VFS helper exported for hugetlbfs. Do not use!
*
* Returns 1 if inode should be completely destroyed.
*/
int generic_detach_inode(struct inode *inode)
{ {
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
...@@ -1251,7 +1260,7 @@ static void generic_forget_inode(struct inode *inode) ...@@ -1251,7 +1260,7 @@ static void generic_forget_inode(struct inode *inode)
inodes_stat.nr_unused++; inodes_stat.nr_unused++;
if (sb->s_flags & MS_ACTIVE) { if (sb->s_flags & MS_ACTIVE) {
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
return; return 0;
} }
WARN_ON(inode->i_state & I_NEW); WARN_ON(inode->i_state & I_NEW);
inode->i_state |= I_WILL_FREE; inode->i_state |= I_WILL_FREE;
...@@ -1269,6 +1278,14 @@ static void generic_forget_inode(struct inode *inode) ...@@ -1269,6 +1278,14 @@ static void generic_forget_inode(struct inode *inode)
inode->i_state |= I_FREEING; inode->i_state |= I_FREEING;
inodes_stat.nr_inodes--; inodes_stat.nr_inodes--;
spin_unlock(&inode_lock); spin_unlock(&inode_lock);
return 1;
}
EXPORT_SYMBOL_GPL(generic_detach_inode);
static void generic_forget_inode(struct inode *inode)
{
if (!generic_detach_inode(inode))
return;
if (inode->i_data.nrpages) if (inode->i_data.nrpages)
truncate_inode_pages(&inode->i_data, 0); truncate_inode_pages(&inode->i_data, 0);
clear_inode(inode); clear_inode(inode);
......
...@@ -2156,6 +2156,7 @@ extern ino_t iunique(struct super_block *, ino_t); ...@@ -2156,6 +2156,7 @@ extern ino_t iunique(struct super_block *, ino_t);
extern int inode_needs_sync(struct inode *inode); extern int inode_needs_sync(struct inode *inode);
extern void generic_delete_inode(struct inode *inode); extern void generic_delete_inode(struct inode *inode);
extern void generic_drop_inode(struct inode *inode); extern void generic_drop_inode(struct inode *inode);
extern int generic_detach_inode(struct inode *inode);
extern struct inode *ilookup5_nowait(struct super_block *sb, extern struct inode *ilookup5_nowait(struct super_block *sb,
unsigned long hashval, int (*test)(struct inode *, void *), unsigned long hashval, int (*test)(struct inode *, void *),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册