diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_exchmaps.h')
| -rw-r--r-- | fs/xfs/libxfs/xfs_exchmaps.h | 124 | 
1 files changed, 124 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_exchmaps.h b/fs/xfs/libxfs/xfs_exchmaps.h new file mode 100644 index 000000000000..fa822dff202a --- /dev/null +++ b/fs/xfs/libxfs/xfs_exchmaps.h @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2020-2024 Oracle.  All Rights Reserved. + * Author: Darrick J. Wong <[email protected]> + */ +#ifndef __XFS_EXCHMAPS_H__ +#define __XFS_EXCHMAPS_H__ + +/* In-core deferred operation info about a file mapping exchange request. */ +struct xfs_exchmaps_intent { +	/* List of other incore deferred work. */ +	struct list_head	xmi_list; + +	/* Inodes participating in the operation. */ +	struct xfs_inode	*xmi_ip1; +	struct xfs_inode	*xmi_ip2; + +	/* File offset range information. */ +	xfs_fileoff_t		xmi_startoff1; +	xfs_fileoff_t		xmi_startoff2; +	xfs_filblks_t		xmi_blockcount; + +	/* Set these file sizes after the operation, unless negative. */ +	xfs_fsize_t		xmi_isize1; +	xfs_fsize_t		xmi_isize2; + +	uint64_t		xmi_flags;	/* XFS_EXCHMAPS_* flags */ +}; + +/* Try to convert inode2 from block to short format at the end, if possible. */ +#define __XFS_EXCHMAPS_INO2_SHORTFORM	(1ULL << 63) + +#define XFS_EXCHMAPS_INTERNAL_FLAGS	(__XFS_EXCHMAPS_INO2_SHORTFORM) + +/* flags that can be passed to xfs_exchmaps_{estimate,mappings} */ +#define XFS_EXCHMAPS_PARAMS		(XFS_EXCHMAPS_ATTR_FORK | \ +					 XFS_EXCHMAPS_SET_SIZES | \ +					 XFS_EXCHMAPS_INO1_WRITTEN) + +static inline int +xfs_exchmaps_whichfork(const struct xfs_exchmaps_intent *xmi) +{ +	if (xmi->xmi_flags & XFS_EXCHMAPS_ATTR_FORK) +		return XFS_ATTR_FORK; +	return XFS_DATA_FORK; +} + +/* Parameters for a mapping exchange request. */ +struct xfs_exchmaps_req { +	/* Inodes participating in the operation. */ +	struct xfs_inode	*ip1; +	struct xfs_inode	*ip2; + +	/* File offset range information. */ +	xfs_fileoff_t		startoff1; +	xfs_fileoff_t		startoff2; +	xfs_filblks_t		blockcount; + +	/* XFS_EXCHMAPS_* operation flags */ +	uint64_t		flags; + +	/* +	 * Fields below this line are filled out by xfs_exchmaps_estimate; +	 * callers should initialize this part of the struct to zero. +	 */ + +	/* +	 * Data device blocks to be moved out of ip1, and free space needed to +	 * handle the bmbt changes. +	 */ +	xfs_filblks_t		ip1_bcount; + +	/* +	 * Data device blocks to be moved out of ip2, and free space needed to +	 * handle the bmbt changes. +	 */ +	xfs_filblks_t		ip2_bcount; + +	/* rt blocks to be moved out of ip1. */ +	xfs_filblks_t		ip1_rtbcount; + +	/* rt blocks to be moved out of ip2. */ +	xfs_filblks_t		ip2_rtbcount; + +	/* Free space needed to handle the bmbt changes */ +	unsigned long long	resblks; + +	/* Number of exchanges needed to complete the operation */ +	unsigned long long	nr_exchanges; +}; + +static inline int +xfs_exchmaps_reqfork(const struct xfs_exchmaps_req *req) +{ +	if (req->flags & XFS_EXCHMAPS_ATTR_FORK) +		return XFS_ATTR_FORK; +	return XFS_DATA_FORK; +} + +int xfs_exchmaps_estimate_overhead(struct xfs_exchmaps_req *req); +int xfs_exchmaps_estimate(struct xfs_exchmaps_req *req); + +extern struct kmem_cache	*xfs_exchmaps_intent_cache; + +int __init xfs_exchmaps_intent_init_cache(void); +void xfs_exchmaps_intent_destroy_cache(void); + +struct xfs_exchmaps_intent *xfs_exchmaps_init_intent( +		const struct xfs_exchmaps_req *req); +void xfs_exchmaps_ensure_reflink(struct xfs_trans *tp, +		const struct xfs_exchmaps_intent *xmi); +void xfs_exchmaps_upgrade_extent_counts(struct xfs_trans *tp, +		const struct xfs_exchmaps_intent *xmi); + +int xfs_exchmaps_finish_one(struct xfs_trans *tp, +		struct xfs_exchmaps_intent *xmi); + +int xfs_exchmaps_check_forks(struct xfs_mount *mp, +		const struct xfs_exchmaps_req *req); + +void xfs_exchange_mappings(struct xfs_trans *tp, +		const struct xfs_exchmaps_req *req); + +#endif /* __XFS_EXCHMAPS_H__ */  |