304a68b9c6
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 <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
59 lines
1.7 KiB
C
59 lines
1.7 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2003-2005 Silicon Graphics, Inc.
|
|
* All Rights Reserved.
|
|
*/
|
|
#ifndef __XFS_IOMAP_H__
|
|
#define __XFS_IOMAP_H__
|
|
|
|
#include <linux/iomap.h>
|
|
|
|
struct xfs_inode;
|
|
struct xfs_bmbt_irec;
|
|
|
|
int xfs_iomap_write_direct(struct xfs_inode *ip, xfs_fileoff_t offset_fsb,
|
|
xfs_fileoff_t count_fsb, unsigned int flags,
|
|
struct xfs_bmbt_irec *imap, u64 *sequence);
|
|
int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
|
|
xfs_fileoff_t xfs_iomap_eof_align_last_fsb(struct xfs_inode *ip,
|
|
xfs_fileoff_t end_fsb);
|
|
|
|
u64 xfs_iomap_inode_sequence(struct xfs_inode *ip, u16 iomap_flags);
|
|
int xfs_bmbt_to_iomap(struct xfs_inode *ip, struct iomap *iomap,
|
|
struct xfs_bmbt_irec *imap, unsigned int mapping_flags,
|
|
u16 iomap_flags, u64 sequence_cookie);
|
|
|
|
int xfs_zero_range(struct xfs_inode *ip, loff_t pos, loff_t len,
|
|
bool *did_zero);
|
|
int xfs_truncate_page(struct xfs_inode *ip, loff_t pos, bool *did_zero);
|
|
|
|
static inline xfs_filblks_t
|
|
xfs_aligned_fsb_count(
|
|
xfs_fileoff_t offset_fsb,
|
|
xfs_filblks_t count_fsb,
|
|
xfs_extlen_t extsz)
|
|
{
|
|
if (extsz) {
|
|
xfs_extlen_t align;
|
|
|
|
div_u64_rem(offset_fsb, extsz, &align);
|
|
if (align)
|
|
count_fsb += align;
|
|
div_u64_rem(count_fsb, extsz, &align);
|
|
if (align)
|
|
count_fsb += extsz - align;
|
|
}
|
|
|
|
return count_fsb;
|
|
}
|
|
|
|
extern const struct iomap_ops xfs_buffered_write_iomap_ops;
|
|
extern const struct iomap_ops xfs_page_mkwrite_iomap_ops;
|
|
extern const struct iomap_ops xfs_direct_write_iomap_ops;
|
|
extern const struct iomap_ops xfs_read_iomap_ops;
|
|
extern const struct iomap_ops xfs_seek_iomap_ops;
|
|
extern const struct iomap_ops xfs_xattr_iomap_ops;
|
|
extern const struct iomap_ops xfs_dax_write_iomap_ops;
|
|
|
|
#endif /* __XFS_IOMAP_H__*/
|