提交 4b5bd5bf 编写于 作者: D Darrick J. Wong

xfs: fix toctou race when locking an inode to access the data map

We use di_format and if_flags to decide whether we're grabbing the ilock
in btree mode (btree extents not loaded) or shared mode (anything else),
but the state of those fields can be changed by other threads that are
also trying to load the btree extents -- IFEXTENTS gets set before the
_bmap_read_extents call and cleared if it fails.

We don't actually need to have IFEXTENTS set until after the bmbt
records are successfully loaded and validated, which will fix the race
between multiple threads trying to read the same directory.  The next
patch strengthens directory bmbt validation by refusing to open the
directory if reading the bmbt to start directory readahead fails.
Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: NChristoph Hellwig <hch@lst.de>
上级 1dbba086
...@@ -497,15 +497,14 @@ xfs_iread_extents( ...@@ -497,15 +497,14 @@ xfs_iread_extents(
* We know that the size is valid (it's checked in iformat_btree) * We know that the size is valid (it's checked in iformat_btree)
*/ */
ifp->if_bytes = ifp->if_real_bytes = 0; ifp->if_bytes = ifp->if_real_bytes = 0;
ifp->if_flags |= XFS_IFEXTENTS;
xfs_iext_add(ifp, 0, nextents); xfs_iext_add(ifp, 0, nextents);
error = xfs_bmap_read_extents(tp, ip, whichfork); error = xfs_bmap_read_extents(tp, ip, whichfork);
if (error) { if (error) {
xfs_iext_destroy(ifp); xfs_iext_destroy(ifp);
ifp->if_flags &= ~XFS_IFEXTENTS;
return error; return error;
} }
xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip));
ifp->if_flags |= XFS_IFEXTENTS;
return 0; return 0;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册