2024-04-15 21:54:17 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/*
|
|
|
|
* Copyright (c) 2020-2024 Oracle. All Rights Reserved.
|
|
|
|
* Author: Darrick J. Wong <djwong@kernel.org>
|
|
|
|
*/
|
|
|
|
#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 */
|
|
|
|
};
|
|
|
|
|
2024-04-15 21:54:20 +00:00
|
|
|
/* 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)
|
|
|
|
|
2024-04-15 21:54:17 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2024-04-15 21:54:44 +00:00
|
|
|
int xfs_exchmaps_estimate_overhead(struct xfs_exchmaps_req *req);
|
2024-04-15 21:54:17 +00:00
|
|
|
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__ */
|