summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2011-02-11 13:46:10 -0800
committerBrian Behlendorf <[email protected]>2011-02-11 13:47:51 -0800
commit2c395def2763ccc7a549d297f7f11bd304caaeae (patch)
tree8fb1ad970c68fcb7fdb9daed4be78ee32bbb8cd6 /module
parentf9637c6c8b9c452c440a366aa937b363f027d95e (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.c2
-rw-r--r--module/zfs/zpl_super.c54
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,