Skip to content

Commit

Permalink
[XFS] Combine the XFS and Linux inodes
Browse files Browse the repository at this point in the history
To avoid issues with different lifecycles of XFS and Linux inodes, embedd
the linux inode inside the XFS inode. This means that the linux inode has
the same lifecycle as the XFS inode, even when it has been released by the
OS. XFS inodes don't live much longer than this (a short stint in reclaim
at most), so there isn't significant memory usage penalties here.

Version 3 o kill xfs_icount()

Version 2 o remove unused commented out code from xfs_iget(). o kill
useless cast in VFS_I()

SGI-PV: 988141

SGI-Modid: xfs-linux-melb:xfs-kern:32323a

Signed-off-by: David Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
  • Loading branch information
David Chinner authored and Lachlan McIlroy committed Oct 30, 2008
1 parent 8290c35 commit bf90424
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 203 deletions.
17 changes: 13 additions & 4 deletions fs/xfs/linux-2.6/xfs_iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ xfs_synchronize_atime(
{
struct inode *inode = VFS_I(ip);

if (inode) {
if (!(inode->i_state & I_CLEAR)) {
ip->i_d.di_atime.t_sec = (__int32_t)inode->i_atime.tv_sec;
ip->i_d.di_atime.t_nsec = (__int32_t)inode->i_atime.tv_nsec;
}
}

/*
* If the linux inode exists, mark it dirty.
* If the linux inode is valid, mark it dirty.
* Used when commiting a dirty inode into a transaction so that
* the inode will get written back by the linux code
*/
Expand All @@ -81,7 +81,7 @@ xfs_mark_inode_dirty_sync(
{
struct inode *inode = VFS_I(ip);

if (inode)
if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR)))
mark_inode_dirty_sync(inode);
}

Expand Down Expand Up @@ -766,12 +766,21 @@ xfs_diflags_to_iflags(
* When reading existing inodes from disk this is called directly
* from xfs_iget, when creating a new inode it is called from
* xfs_ialloc after setting up the inode.
*
* We are always called with an uninitialised linux inode here.
* We need to initialise the necessary fields and take a reference
* on it.
*/
void
xfs_setup_inode(
struct xfs_inode *ip)
{
struct inode *inode = ip->i_vnode;
struct inode *inode = &ip->i_vnode;

inode->i_ino = ip->i_ino;
inode->i_state = I_NEW|I_LOCK;
inode_add_to_lists(ip->i_mount->m_super, inode);
ASSERT(atomic_read(&inode->i_count) == 1);

inode->i_mode = ip->i_d.di_mode;
inode->i_nlink = ip->i_d.di_nlink;
Expand Down
47 changes: 18 additions & 29 deletions fs/xfs/linux-2.6/xfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@

static struct quotactl_ops xfs_quotactl_operations;
static struct super_operations xfs_super_operations;
static kmem_zone_t *xfs_vnode_zone;
static kmem_zone_t *xfs_ioend_zone;
mempool_t *xfs_ioend_pool;

Expand Down Expand Up @@ -867,29 +866,24 @@ xfsaild_stop(
}



/* Catch misguided souls that try to use this interface on XFS */
STATIC struct inode *
xfs_fs_alloc_inode(
struct super_block *sb)
{
return kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
BUG();
}

/*
* we need to provide an empty inode free function to prevent
* the generic code from trying to free our combined inode.
*/
STATIC void
xfs_fs_destroy_inode(
struct inode *inode)
{
kmem_zone_free(xfs_vnode_zone, inode);
}

STATIC void
xfs_fs_inode_init_once(
void *vnode)
struct inode *inode)
{
inode_init_once((struct inode *)vnode);
}


/*
* Slab object creation initialisation for the XFS inode.
* This covers only the idempotent fields in the XFS inode;
Expand All @@ -898,13 +892,18 @@ xfs_fs_inode_init_once(
* fields in the xfs inode that left in the initialise state
* when freeing the inode.
*/
void
xfs_inode_init_once(
STATIC void
xfs_fs_inode_init_once(
void *inode)
{
struct xfs_inode *ip = inode;

memset(ip, 0, sizeof(struct xfs_inode));

/* vfs inode */
inode_init_once(VFS_I(ip));

/* xfs inode */
atomic_set(&ip->i_iocount, 0);
atomic_set(&ip->i_pincount, 0);
spin_lock_init(&ip->i_flags_lock);
Expand Down Expand Up @@ -975,8 +974,6 @@ xfs_fs_clear_inode(
if (xfs_reclaim(ip))
panic("%s: cannot reclaim 0x%p\n", __func__, inode);
}

ASSERT(XFS_I(inode) == NULL);
}

STATIC void
Expand Down Expand Up @@ -1829,16 +1826,10 @@ xfs_free_trace_bufs(void)
STATIC int __init
xfs_init_zones(void)
{
xfs_vnode_zone = kmem_zone_init_flags(sizeof(struct inode), "xfs_vnode",
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
KM_ZONE_SPREAD,
xfs_fs_inode_init_once);
if (!xfs_vnode_zone)
goto out;

xfs_ioend_zone = kmem_zone_init(sizeof(xfs_ioend_t), "xfs_ioend");
if (!xfs_ioend_zone)
goto out_destroy_vnode_zone;
goto out;

xfs_ioend_pool = mempool_create_slab_pool(4 * MAX_BUF_PER_PAGE,
xfs_ioend_zone);
Expand All @@ -1854,6 +1845,7 @@ xfs_init_zones(void)
"xfs_bmap_free_item");
if (!xfs_bmap_free_item_zone)
goto out_destroy_log_ticket_zone;

xfs_btree_cur_zone = kmem_zone_init(sizeof(xfs_btree_cur_t),
"xfs_btree_cur");
if (!xfs_btree_cur_zone)
Expand Down Expand Up @@ -1901,8 +1893,8 @@ xfs_init_zones(void)

xfs_inode_zone =
kmem_zone_init_flags(sizeof(xfs_inode_t), "xfs_inode",
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM |
KM_ZONE_SPREAD, xfs_inode_init_once);
KM_ZONE_HWALIGN | KM_ZONE_RECLAIM | KM_ZONE_SPREAD,
xfs_fs_inode_init_once);
if (!xfs_inode_zone)
goto out_destroy_efi_zone;

Expand Down Expand Up @@ -1950,8 +1942,6 @@ xfs_init_zones(void)
mempool_destroy(xfs_ioend_pool);
out_destroy_ioend_zone:
kmem_zone_destroy(xfs_ioend_zone);
out_destroy_vnode_zone:
kmem_zone_destroy(xfs_vnode_zone);
out:
return -ENOMEM;
}
Expand All @@ -1976,7 +1966,6 @@ xfs_destroy_zones(void)
kmem_zone_destroy(xfs_log_ticket_zone);
mempool_destroy(xfs_ioend_pool);
kmem_zone_destroy(xfs_ioend_zone);
kmem_zone_destroy(xfs_vnode_zone);

}

Expand Down
15 changes: 1 addition & 14 deletions fs/xfs/linux-2.6/xfs_vnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,25 +84,12 @@ vn_ioerror(

#ifdef XFS_INODE_TRACE

/*
* Reference count of Linux inode if present, -1 if the xfs_inode
* has no associated Linux inode.
*/
static inline int xfs_icount(struct xfs_inode *ip)
{
struct inode *inode = VFS_I(ip);

if (inode)
return atomic_read(&inode->i_count);
return -1;
}

#define KTRACE_ENTER(ip, vk, s, line, ra) \
ktrace_enter( (ip)->i_trace, \
/* 0 */ (void *)(__psint_t)(vk), \
/* 1 */ (void *)(s), \
/* 2 */ (void *)(__psint_t) line, \
/* 3 */ (void *)(__psint_t)xfs_icount(ip), \
/* 3 */ (void *)(__psint_t)atomic_read(&VFS_I(ip)->i_count), \
/* 4 */ (void *)(ra), \
/* 5 */ NULL, \
/* 6 */ (void *)(__psint_t)current_cpu(), \
Expand Down
Loading

0 comments on commit bf90424

Please sign in to comment.