Commit 22fe4042 authored by Jan Kara's avatar Jan Kara Committed by Al Viro
Browse files

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: default avatarJan Kara <jack@suse.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent af0d9ae8
Loading
Loading
Loading
Loading
+4 −29
Original line number Diff line number Diff line
@@ -380,37 +380,12 @@ static void hugetlbfs_delete_inode(struct inode *inode)

static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
{
	struct super_block *sb = inode->i_sb;

	if (!hlist_unhashed(&inode->i_hash)) {
		if (!(inode->i_state & (I_DIRTY|I_SYNC)))
			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);
	if (generic_detach_inode(inode)) {
		truncate_hugepages(inode, 0);
		clear_inode(inode);
		destroy_inode(inode);
	}
}

static void hugetlbfs_drop_inode(struct inode *inode)
{
+19 −2
Original line number Diff line number Diff line
@@ -1241,7 +1241,16 @@ void generic_delete_inode(struct inode *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;

@@ -1251,7 +1260,7 @@ static void generic_forget_inode(struct inode *inode)
		inodes_stat.nr_unused++;
		if (sb->s_flags & MS_ACTIVE) {
			spin_unlock(&inode_lock);
			return;
			return 0;
		}
		WARN_ON(inode->i_state & I_NEW);
		inode->i_state |= I_WILL_FREE;
@@ -1269,6 +1278,14 @@ static void generic_forget_inode(struct inode *inode)
	inode->i_state |= I_FREEING;
	inodes_stat.nr_inodes--;
	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)
		truncate_inode_pages(&inode->i_data, 0);
	clear_inode(inode);
+1 −0
Original line number Diff line number Diff line
@@ -2156,6 +2156,7 @@ extern ino_t iunique(struct super_block *, ino_t);
extern int inode_needs_sync(struct inode *inode);
extern void generic_delete_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,
		unsigned long hashval, int (*test)(struct inode *, void *),