xref: /linux/fs/xfs/libxfs/xfs_exchmaps.h (revision 629fdaf5)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (c) 2020-2024 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <djwong@kernel.org>
5  */
6 #ifndef __XFS_EXCHMAPS_H__
7 #define __XFS_EXCHMAPS_H__
8 
9 /* In-core deferred operation info about a file mapping exchange request. */
10 struct xfs_exchmaps_intent {
11 	/* List of other incore deferred work. */
12 	struct list_head	xmi_list;
13 
14 	/* Inodes participating in the operation. */
15 	struct xfs_inode	*xmi_ip1;
16 	struct xfs_inode	*xmi_ip2;
17 
18 	/* File offset range information. */
19 	xfs_fileoff_t		xmi_startoff1;
20 	xfs_fileoff_t		xmi_startoff2;
21 	xfs_filblks_t		xmi_blockcount;
22 
23 	/* Set these file sizes after the operation, unless negative. */
24 	xfs_fsize_t		xmi_isize1;
25 	xfs_fsize_t		xmi_isize2;
26 
27 	uint64_t		xmi_flags;	/* XFS_EXCHMAPS_* flags */
28 };
29 
30 /* Try to convert inode2 from block to short format at the end, if possible. */
31 #define __XFS_EXCHMAPS_INO2_SHORTFORM	(1ULL << 63)
32 
33 #define XFS_EXCHMAPS_INTERNAL_FLAGS	(__XFS_EXCHMAPS_INO2_SHORTFORM)
34 
35 /* flags that can be passed to xfs_exchmaps_{estimate,mappings} */
36 #define XFS_EXCHMAPS_PARAMS		(XFS_EXCHMAPS_ATTR_FORK | \
37 					 XFS_EXCHMAPS_SET_SIZES | \
38 					 XFS_EXCHMAPS_INO1_WRITTEN)
39 
40 static inline int
xfs_exchmaps_whichfork(const struct xfs_exchmaps_intent * xmi)41 xfs_exchmaps_whichfork(const struct xfs_exchmaps_intent *xmi)
42 {
43 	if (xmi->xmi_flags & XFS_EXCHMAPS_ATTR_FORK)
44 		return XFS_ATTR_FORK;
45 	return XFS_DATA_FORK;
46 }
47 
48 /* Parameters for a mapping exchange request. */
49 struct xfs_exchmaps_req {
50 	/* Inodes participating in the operation. */
51 	struct xfs_inode	*ip1;
52 	struct xfs_inode	*ip2;
53 
54 	/* File offset range information. */
55 	xfs_fileoff_t		startoff1;
56 	xfs_fileoff_t		startoff2;
57 	xfs_filblks_t		blockcount;
58 
59 	/* XFS_EXCHMAPS_* operation flags */
60 	uint64_t		flags;
61 
62 	/*
63 	 * Fields below this line are filled out by xfs_exchmaps_estimate;
64 	 * callers should initialize this part of the struct to zero.
65 	 */
66 
67 	/*
68 	 * Data device blocks to be moved out of ip1, and free space needed to
69 	 * handle the bmbt changes.
70 	 */
71 	xfs_filblks_t		ip1_bcount;
72 
73 	/*
74 	 * Data device blocks to be moved out of ip2, and free space needed to
75 	 * handle the bmbt changes.
76 	 */
77 	xfs_filblks_t		ip2_bcount;
78 
79 	/* rt blocks to be moved out of ip1. */
80 	xfs_filblks_t		ip1_rtbcount;
81 
82 	/* rt blocks to be moved out of ip2. */
83 	xfs_filblks_t		ip2_rtbcount;
84 
85 	/* Free space needed to handle the bmbt changes */
86 	unsigned long long	resblks;
87 
88 	/* Number of exchanges needed to complete the operation */
89 	unsigned long long	nr_exchanges;
90 };
91 
92 static inline int
xfs_exchmaps_reqfork(const struct xfs_exchmaps_req * req)93 xfs_exchmaps_reqfork(const struct xfs_exchmaps_req *req)
94 {
95 	if (req->flags & XFS_EXCHMAPS_ATTR_FORK)
96 		return XFS_ATTR_FORK;
97 	return XFS_DATA_FORK;
98 }
99 
100 int xfs_exchmaps_estimate_overhead(struct xfs_exchmaps_req *req);
101 int xfs_exchmaps_estimate(struct xfs_exchmaps_req *req);
102 
103 extern struct kmem_cache	*xfs_exchmaps_intent_cache;
104 
105 int __init xfs_exchmaps_intent_init_cache(void);
106 void xfs_exchmaps_intent_destroy_cache(void);
107 
108 struct xfs_exchmaps_intent *xfs_exchmaps_init_intent(
109 		const struct xfs_exchmaps_req *req);
110 void xfs_exchmaps_ensure_reflink(struct xfs_trans *tp,
111 		const struct xfs_exchmaps_intent *xmi);
112 void xfs_exchmaps_upgrade_extent_counts(struct xfs_trans *tp,
113 		const struct xfs_exchmaps_intent *xmi);
114 
115 int xfs_exchmaps_finish_one(struct xfs_trans *tp,
116 		struct xfs_exchmaps_intent *xmi);
117 
118 int xfs_exchmaps_check_forks(struct xfs_mount *mp,
119 		const struct xfs_exchmaps_req *req);
120 
121 void xfs_exchange_mappings(struct xfs_trans *tp,
122 		const struct xfs_exchmaps_req *req);
123 
124 #endif /* __XFS_EXCHMAPS_H__ */
125