generic_forget_inode() normally writes back dirty inodes before
they are reclaimed. however, it only does this for hashed inodes.
Hence if we are going to use unhashed inodes we need to implement
our own writeback of these inodes.
Hook ->drop_inode to replace generic_drop_inode() and allow us
to implement the needed inode writeback.
Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
---
fs/xfs/linux-2.6/xfs_super.c | 31 +++++++++++++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index a432f1d..b718146 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -944,6 +944,36 @@ xfs_fs_write_inode(
return -error;
}
+/*
+ * Because we are not using hashed inodes, we have to write
+ * the inode back here before calling into the generic code.
+ *
+ * XXX: need to sort something out with the inode lock.
+ *
+ * <sigh> generic_forget_inode() is not exported.
+ */
+STATIC void
+xfs_fs_drop_inode(
+ struct inode *inode)
+{
+ extern spinlock_t inode_lock;
+
+ /* this is munged from generic_forget_inode */
+ if (inode->i_nlink) {
+ /*
+ * remove the inode from the dirty list first so writeback
+ * can't race with us as we drop the inode lock here.
+ */
+ list_del_init(&inode->i_list);
+ inode->i_state |= I_WILL_FREE;
+ spin_unlock(&inode_lock);
+ write_inode_now(inode, 1);
+ spin_lock(&inode_lock);
+ inode->i_state &= ~I_WILL_FREE;
+ }
+ generic_drop_inode(inode);
+}
+
STATIC void
xfs_fs_clear_inode(
struct inode *inode)
@@ -1718,6 +1748,7 @@ static struct super_operations xfs_super_operations = {
.destroy_inode = xfs_fs_destroy_inode,
.dirty_inode = xfs_fs_dirty_inode,
.write_inode = xfs_fs_write_inode,
+ .drop_inode = xfs_fs_drop_inode,
.clear_inode = xfs_fs_clear_inode,
.put_super = xfs_fs_put_super,
.write_super = xfs_fs_write_super,
--
1.5.6
|