From: Dave Chinner Date: Wed, 15 Mar 2023 14:47:39 +0000 (+0100) Subject: xfs: use iomap_valid method to detect stale cached iomaps X-Git-Tag: v6.2.0~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;ds=sidebyside;h=1dcdf5051790867e4631dfaa5fc02e1d9e957fee;p=thirdparty%2Fxfsprogs-dev.git xfs: use iomap_valid method to detect stale cached iomaps Source kernel commit: 304a68b9c63bbfc1f6e159d68e8892fc54a06067 Now that iomap supports a mechanism to validate cached iomaps for buffered write operations, hook it up to the XFS buffered write ops so that we can avoid data corruptions that result from stale cached iomaps. See: https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/ or the ->iomap_valid() introduction commit for exact details of the corruption vector. The validity cookie we store in the iomap is based on the type of iomap we return. It is expected that the iomap->flags we set in xfs_bmbt_to_iomap() is not perturbed by the iomap core and are returned to us in the iomap passed via the .iomap_valid() callback. This ensures that the validity cookie is always checking the correct inode fork sequence numbers to detect potential changes that affect the extent cached by the iomap. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Carlos Maiolino --- diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index ad4b94758..456c82d70 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -68,7 +68,7 @@ extern struct kmem_cache *xfs_trans_cache; /* fake up iomap, (not) used in xfs_bmap.[ch] */ #define IOMAP_F_SHARED 0x04 -#define xfs_bmbt_to_iomap(a, b, c, d, e) ((void) 0) +#define xfs_bmbt_to_iomap(a, b, c, d, e, f) ((void) 0) /* CRC stuff, buffer API dependent on it */ #define crc32c(c,p,l) crc32c_le((c),(unsigned char const *)(p),(l)) diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 6d6f9e7dd..3b1739bdb 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -4544,7 +4544,8 @@ xfs_bmapi_convert_delalloc( * the extent. Just return the real extent at this offset. */ if (!isnullstartblock(bma.got.br_startblock)) { - xfs_bmbt_to_iomap(ip, iomap, &bma.got, 0, flags); + xfs_bmbt_to_iomap(ip, iomap, &bma.got, 0, flags, + xfs_iomap_inode_sequence(ip, flags)); *seq = READ_ONCE(ifp->if_seq); goto out_trans_cancel; } @@ -4592,7 +4593,8 @@ xfs_bmapi_convert_delalloc( XFS_STATS_INC(mp, xs_xstrat_quick); ASSERT(!isnullstartblock(bma.got.br_startblock)); - xfs_bmbt_to_iomap(ip, iomap, &bma.got, 0, flags); + xfs_bmbt_to_iomap(ip, iomap, &bma.got, 0, flags, + xfs_iomap_inode_sequence(ip, flags)); *seq = READ_ONCE(ifp->if_seq); if (whichfork == XFS_COW_FORK)