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