|
@@ -272,6 +272,13 @@ void __destroy_inode(struct inode *inode)
|
|
|
}
|
|
|
EXPORT_SYMBOL(__destroy_inode);
|
|
|
|
|
|
+static void i_callback(struct rcu_head *head)
|
|
|
+{
|
|
|
+ struct inode *inode = container_of(head, struct inode, i_rcu);
|
|
|
+ INIT_LIST_HEAD(&inode->i_dentry);
|
|
|
+ kmem_cache_free(inode_cachep, inode);
|
|
|
+}
|
|
|
+
|
|
|
static void destroy_inode(struct inode *inode)
|
|
|
{
|
|
|
BUG_ON(!list_empty(&inode->i_lru));
|
|
@@ -279,7 +286,7 @@ static void destroy_inode(struct inode *inode)
|
|
|
if (inode->i_sb->s_op->destroy_inode)
|
|
|
inode->i_sb->s_op->destroy_inode(inode);
|
|
|
else
|
|
|
- kmem_cache_free(inode_cachep, (inode));
|
|
|
+ call_rcu(&inode->i_rcu, i_callback);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -432,6 +439,7 @@ void end_writeback(struct inode *inode)
|
|
|
BUG_ON(!(inode->i_state & I_FREEING));
|
|
|
BUG_ON(inode->i_state & I_CLEAR);
|
|
|
inode_sync_wait(inode);
|
|
|
+ /* don't need i_lock here, no concurrent mods to i_state */
|
|
|
inode->i_state = I_FREEING | I_CLEAR;
|
|
|
}
|
|
|
EXPORT_SYMBOL(end_writeback);
|