aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
authorDai Ngo <dai.ngo@oracle.com>2026-05-19 17:32:59 -0700
committerCarlos Maiolino <cem@kernel.org>2026-05-26 12:10:47 +0200
commit92ad95ab8dc748b917a37f216e0b76cbc31b70d0 (patch)
treeec93bc2e7ec9ee9b1775d7921984144357eeaff1 /fs
parented47e798adcc2d761b40ac5182a62bb09f689411 (diff)
downloadlinux-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.c4
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;