diff options
author | Brian Behlendorf <[email protected]> | 2011-02-11 13:46:10 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-02-11 13:47:51 -0800 |
commit | 2c395def2763ccc7a549d297f7f11bd304caaeae (patch) | |
tree | 8fb1ad970c68fcb7fdb9daed4be78ee32bbb8cd6 /module | |
parent | f9637c6c8b9c452c440a366aa937b363f027d95e (diff) |
Linux 2.6.36 compat, sops->evict_inode()
The new prefered inteface for evicting an inode from the inode cache
is the ->evict_inode() callback. It replaces both the ->delete_inode()
and ->clear_inode() callbacks which were previously used for this.
Diffstat (limited to 'module')
-rw-r--r-- | module/zfs/zfs_vnops.c | 2 | ||||
-rw-r--r-- | module/zfs/zpl_super.c | 54 |
2 files changed, 45 insertions, 11 deletions
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 30b30891b..363307932 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -3632,8 +3632,6 @@ zfs_inactive(struct inode *ip) zfs_sb_t *zsb = ITOZSB(ip); int error; - truncate_inode_pages(&ip->i_data, 0); - #ifdef HAVE_SNAPSHOT /* Early return for snapshot inode? */ #endif /* HAVE_SNAPSHOT */ diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c index bbb7beaf3..0417ce2ff 100644 --- a/module/zfs/zpl_super.c +++ b/module/zfs/zpl_super.c @@ -47,23 +47,55 @@ zpl_inode_destroy(struct inode *ip) zfs_inode_destroy(ip); } +/* + * When ->drop_inode() is called its return value indicates if the + * inode should be evicted from the inode cache. If the inode is + * unhashed and has no links the default policy is to evict it + * immediately. + * + * Prior to 2.6.36 this eviction was accomplished by the vfs calling + * ->delete_inode(). It was ->delete_inode()'s responsibility to + * truncate the inode pages and call clear_inode(). The call to + * clear_inode() synchronously invalidates all the buffers and + * calls ->clear_inode(). It was ->clear_inode()'s responsibility + * to cleanup and filesystem specific data before freeing the inode. + * + * This elaborate mechanism was replaced by ->evict_inode() which + * does the job of both ->delete_inode() and ->clear_inode(). It + * will be called exactly once, and when it returns the inode must + * be in a state where it can simply be freed. The ->evict_inode() + * callback must minimally truncate the inode pages, and call + * end_writeback() to complete all outstanding writeback for the + * inode. After this is complete evict inode can cleanup any + * remaining filesystem specific data. + */ +#ifdef HAVE_EVICT_INODE static void -zpl_inode_delete(struct inode *ip) +zpl_evict_inode(struct inode *ip) { - loff_t oldsize = i_size_read(ip); - - i_size_write(ip, 0); - truncate_pagecache(ip, oldsize, 0); - clear_inode(ip); + truncate_inode_pages(&ip->i_data, 0); + end_writeback(ip); + zfs_inactive(ip); } +#else + static void -zpl_evict_inode(struct inode *ip) +zpl_clear_inode(struct inode *ip) { zfs_inactive(ip); } static void +zpl_inode_delete(struct inode *ip) +{ + truncate_inode_pages(&ip->i_data, 0); + clear_inode(ip); +} + +#endif /* HAVE_EVICT_INODE */ + +static void zpl_put_super(struct super_block *sb) { int error; @@ -136,11 +168,15 @@ zpl_kill_sb(struct super_block *sb) const struct super_operations zpl_super_operations = { .alloc_inode = zpl_inode_alloc, .destroy_inode = zpl_inode_destroy, - .delete_inode = zpl_inode_delete, .dirty_inode = NULL, .write_inode = NULL, .drop_inode = NULL, - .clear_inode = zpl_evict_inode, +#ifdef HAVE_EVICT_INODE + .evict_inode = zpl_evict_inode, +#else + .clear_inode = zpl_clear_inode, + .delete_inode = zpl_inode_delete, +#endif /* HAVE_EVICT_INODE */ .put_super = zpl_put_super, .write_super = NULL, .sync_fs = NULL, |