xref: /linux/fs/xfs/libxfs/xfs_exchmaps.h (revision 3eb3c33c1d87029a3832e205eebd59cfb56ba3a4)
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
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
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