Commit 4b6a4688 authored by Dave Chinner's avatar Dave Chinner Committed by Alex Elder
Browse files

xfs: fix stale inode flush avoidance



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: default avatarDave Chinner <david@fromorbit.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAlex Elder <aelder@sgi.com>
parent 126976c7
......@@ -2842,13 +2842,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;
}
......@@ -2871,6 +2867,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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment