xfs
[Top] [All Lists]

[PATCH] make inode reclaim synchronise with xfs_iflush_done()

To: xfs-dev <xfs-dev@xxxxxxx>, xfs-oss <xfs@xxxxxxxxxxx>
Subject: [PATCH] make inode reclaim synchronise with xfs_iflush_done()
From: Lachlan McIlroy <lachlan@xxxxxxx>
Date: Wed, 12 Dec 2007 18:02:37 +1100
Reply-to: lachlan@xxxxxxx
Sender: xfs-bounce@xxxxxxxxxxx
User-agent: Thunderbird 2.0.0.9 (X11/20071031)
On a forced shutdown, xfs_finish_reclaim() will skip flushing the inode.
If the inode flush lock is not already held and there is an outstanding
xfs_iflush_done() then we might free the inode prematurely.  By acquiring
and releasing the flush lock we will synchronise with xfs_iflush_done().

Alternatively we could take a hold on the inode when when issuing I/Os
with xfs_iflush_done() and release it in xfs_iflush_done().  Would this
be a better approach?

Lachlan
--- fs/xfs/xfs_vnodeops.c_1.726 2007-12-12 17:14:59.000000000 +1100
+++ fs/xfs/xfs_vnodeops.c       2007-12-12 17:15:42.000000000 +1100
@@ -3762,20 +3762,29 @@ xfs_finish_reclaim(
                                goto reclaim;
                        }
                        xfs_iflock(ip); /* synchronize with xfs_iflush_done */
+                       xfs_ifunlock(ip);
                }
 
                ASSERT(ip->i_update_core == 0);
                ASSERT(ip->i_itemp == NULL ||
                       ip->i_itemp->ili_format.ilf_fields == 0);
                xfs_iunlock(ip, XFS_ILOCK_EXCL);
-       } else if (locked) {
+       } else {
                /*
                 * We are not interested in doing an iflush if we're
                 * in the process of shutting down the filesystem forcibly.
                 * So, just reclaim the inode.
-                */
-               xfs_ifunlock(ip);
-               xfs_iunlock(ip, XFS_ILOCK_EXCL);
+                * 
+                * If the flush lock is not already held then temporarily
+                * acquire it to synchronize with xfs_iflush_done.
+                */
+               if (locked) {
+                       xfs_ifunlock(ip);
+                       xfs_iunlock(ip, XFS_ILOCK_EXCL);
+               } else {
+                       xfs_iflock(ip);
+                       xfs_ifunlock(ip);
+               }
        }
 
  reclaim:
<Prev in Thread] Current Thread [Next in Thread>