Commit 2cb1599f authored by David Chinner's avatar David Chinner Committed by Lachlan McIlroy

Inode: Allow external initialisers

To allow XFS to combine the XFS and linux inodes into a single
structure, we need to drive inode lookup from the XFS inode cache,
not the generic inode cache. This means that we need initialise a
struct inode from a context outside alloc_inode() as it is no longer
used by XFS.

Factor and export the struct inode initialisation code from
alloc_inode() to inode_init_always() as a counterpart to
inode_init_once().  i.e. we have to call this init function for each
inode instantiation (always), as opposed inode_init_once() which is
only called on slab object instantiation (once).
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent 94b97e39
...@@ -108,19 +108,20 @@ static void wake_up_inode(struct inode *inode) ...@@ -108,19 +108,20 @@ static void wake_up_inode(struct inode *inode)
wake_up_bit(&inode->i_state, __I_LOCK); wake_up_bit(&inode->i_state, __I_LOCK);
} }
static struct inode *alloc_inode(struct super_block *sb) /**
* inode_init_always - perform inode structure intialisation
* @sb - superblock inode belongs to.
* @inode - inode to initialise
*
* These are initializations that need to be done on every inode
* allocation as the fields are not initialised by slab allocation.
*/
struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
{ {
static const struct address_space_operations empty_aops; static const struct address_space_operations empty_aops;
static struct inode_operations empty_iops; static struct inode_operations empty_iops;
static const struct file_operations empty_fops; static const struct file_operations empty_fops;
struct inode *inode;
if (sb->s_op->alloc_inode)
inode = sb->s_op->alloc_inode(sb);
else
inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL);
if (inode) {
struct address_space * const mapping = &inode->i_data; struct address_space * const mapping = &inode->i_data;
inode->i_sb = sb; inode->i_sb = sb;
...@@ -183,9 +184,24 @@ static struct inode *alloc_inode(struct super_block *sb) ...@@ -183,9 +184,24 @@ static struct inode *alloc_inode(struct super_block *sb)
} }
inode->i_private = NULL; inode->i_private = NULL;
inode->i_mapping = mapping; inode->i_mapping = mapping;
}
return inode; return inode;
} }
EXPORT_SYMBOL(inode_init_always);
static struct inode *alloc_inode(struct super_block *sb)
{
struct inode *inode;
if (sb->s_op->alloc_inode)
inode = sb->s_op->alloc_inode(sb);
else
inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL);
if (inode)
return inode_init_always(sb, inode);
return NULL;
}
void destroy_inode(struct inode *inode) void destroy_inode(struct inode *inode)
{ {
......
...@@ -1881,6 +1881,7 @@ extern loff_t default_llseek(struct file *file, loff_t offset, int origin); ...@@ -1881,6 +1881,7 @@ extern loff_t default_llseek(struct file *file, loff_t offset, int origin);
extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin); extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin);
extern struct inode * inode_init_always(struct super_block *, struct inode *);
extern void inode_init_once(struct inode *); extern void inode_init_once(struct inode *);
extern void iput(struct inode *); extern void iput(struct inode *);
extern struct inode * igrab(struct inode *); extern struct inode * igrab(struct inode *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment