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: Dave Chinner <david@fromorbit.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
This commit is contained in:
Родитель
94b97e39b0
Коммит
2cb1599f9b
34
fs/inode.c
34
fs/inode.c
|
@ -108,19 +108,20 @@ static void wake_up_inode(struct inode *inode)
|
|||
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 struct inode_operations empty_iops;
|
||||
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;
|
||||
|
||||
inode->i_sb = sb;
|
||||
|
@ -183,9 +184,24 @@ static struct inode *alloc_inode(struct super_block *sb)
|
|||
}
|
||||
inode->i_private = NULL;
|
||||
inode->i_mapping = mapping;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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 struct inode * inode_init_always(struct super_block *, struct inode *);
|
||||
extern void inode_init_once(struct inode *);
|
||||
extern void iput(struct inode *);
|
||||
extern struct inode * igrab(struct inode *);
|
||||
|
|
Загрузка…
Ссылка в новой задаче