lkml.org 
[lkml]   [2010]   [Apr]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[021/197] xfs: fix stale inode flush avoidance
2.6.32-stable review patch.  If anyone has any objections, please let us know.

------------------

From: Dave Chinner <david@fromorbit.com>

commit 4b6a46882cca8349e8942e2650c33b11bc571c92 upstream

When reclaiming stale inodes, we need to guarantee that inodes are
unpinned before returning with a "clean" status. If we don't we can
reclaim inodes that are pinned, leading to use after free in the
transaction subsystem as transactions complete.

Signed-off-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
fs/xfs/xfs_inode.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)

--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2878,13 +2878,9 @@ xfs_iflush(

/*
* If the inode isn't dirty, then just release the inode flush lock and
- * do nothing. Treat stale inodes the same; we cannot rely on the
- * backing buffer remaining stale in cache for the remaining life of
- * the stale inode and so xfs_itobp() below may give us a buffer that
- * no longer contains inodes below. Doing this stale check here also
- * avoids forcing the log on pinned, stale inodes.
+ * do nothing.
*/
- if (xfs_inode_clean(ip) || xfs_iflags_test(ip, XFS_ISTALE)) {
+ if (xfs_inode_clean(ip)) {
xfs_ifunlock(ip);
return 0;
}
@@ -2908,6 +2904,19 @@ xfs_iflush(
xfs_iunpin_wait(ip);

/*
+ * For stale inodes we cannot rely on the backing buffer remaining
+ * stale in cache for the remaining life of the stale inode and so
+ * xfs_itobp() below may give us a buffer that no longer contains
+ * inodes below. We have to check this after ensuring the inode is
+ * unpinned so that it is safe to reclaim the stale inode after the
+ * flush call.
+ */
+ if (xfs_iflags_test(ip, XFS_ISTALE)) {
+ xfs_ifunlock(ip);
+ return 0;
+ }
+
+ /*
* This may have been unpinned because the filesystem is shutting
* down forcibly. If that's the case we must not write this inode
* to disk, because the log record didn't make it to disk!



\
 
 \ /
  Last update: 2010-04-22 22:47    [W:0.809 / U:0.360 seconds]
©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site