diff options
| author | Dai Ngo <dai.ngo@oracle.com> | 2026-05-19 17:32:59 -0700 |
|---|---|---|
| committer | Carlos Maiolino <cem@kernel.org> | 2026-05-26 12:10:47 +0200 |
| commit | 92ad95ab8dc748b917a37f216e0b76cbc31b70d0 (patch) | |
| tree | ec93bc2e7ec9ee9b1775d7921984144357eeaff1 /fs | |
| parent | ed47e798adcc2d761b40ac5182a62bb09f689411 (diff) | |
| download | linux-next-history-92ad95ab8dc748b917a37f216e0b76cbc31b70d0.tar.gz | |
xfs: fix overlapping extents returned for pNFS LAYOUTGET
xfs_fs_map_blocks() currently passes XFS_BMAPI_ENTIRE to xfs_bmapi_read(),
which causes the bmap code to expand the mapping to cover the entire
extent rather than the requested range.
A single LAYOUTGET request from the client can cause the server to
issue multiple calls to xfs_fs_map_blocks() for different offsets
within the same extent. Because the use of XFS_BMAPI_ENTIRE flag,
these calls can produce overlapping mappings.
As a result, the LAYOUTGET reply sent to the NFS client may contain
overlapping extents. This creates ambiguity in extent selection for a
given file range, which can lead to incorrect device selection,
inconsistent handling of datastate, and ultimately data corruption or
protocol violations on the client side.
Problem discovered with xfstest generic/075 test using NFSv4.2 mount
with SCSI layout.
Fix this by replacing the XFS_BMAPI_ENTIRE flag with '0' so that
xfs_bmapi_read() returns only the mapping for the requested range.
Fixes: cc6c40e09d7b1 ("NFSD/blocklayout: Support multiple extents per LAYOUTGET").
Signed-off-by: Dai Ngo <dai.ngo@oracle.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/xfs/xfs_pnfs.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c index b792e066b403d..d92993367ab64 100644 --- a/fs/xfs/xfs_pnfs.c +++ b/fs/xfs/xfs_pnfs.c @@ -118,7 +118,6 @@ xfs_fs_map_blocks( struct xfs_bmbt_irec imap; xfs_fileoff_t offset_fsb, end_fsb; loff_t limit; - int bmapi_flags = XFS_BMAPI_ENTIRE; int nimaps = 1; uint lock_flags; int error = 0; @@ -172,8 +171,9 @@ xfs_fs_map_blocks( offset_fsb = XFS_B_TO_FSBT(mp, offset); lock_flags = xfs_ilock_data_map_shared(ip); + /* request mappings for the specified range only */ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, - &imap, &nimaps, bmapi_flags); + &imap, &nimaps, 0); if (error) { xfs_iunlock(ip, lock_flags); goto out_unlock; |
