1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2016 Oracle. All Rights Reserved. 4 * Author: Darrick J. Wong <darrick.wong@oracle.com> 5 */ 6 #ifndef __XFS_RMAP_H__ 7 #define __XFS_RMAP_H__ 8 9 struct xfs_perag; 10 struct xfs_rtgroup; 11 12 static inline void 13 xfs_rmap_ino_bmbt_owner( 14 struct xfs_owner_info *oi, 15 xfs_ino_t ino, 16 int whichfork) 17 { 18 oi->oi_owner = ino; 19 oi->oi_offset = 0; 20 oi->oi_flags = XFS_OWNER_INFO_BMBT_BLOCK; 21 if (whichfork == XFS_ATTR_FORK) 22 oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; 23 } 24 #define xfs_rmap_inode_bmbt_owner(oi, ip, whichfork) \ 25 xfs_rmap_ino_bmbt_owner(oi, I_INO(ip), whichfork) 26 27 static inline void 28 xfs_rmap_ino_owner( 29 struct xfs_owner_info *oi, 30 xfs_ino_t ino, 31 int whichfork, 32 xfs_fileoff_t offset) 33 { 34 oi->oi_owner = ino; 35 oi->oi_offset = offset; 36 oi->oi_flags = 0; 37 if (whichfork == XFS_ATTR_FORK) 38 oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; 39 } 40 #define xfs_rmap_inode_owner(oi, ip, whichfork, offset) \ 41 xfs_rmap_ino_owner(oi, I_INO(ip), whichfork, offset) 42 43 static inline bool 44 xfs_rmap_should_skip_owner_update( 45 const struct xfs_owner_info *oi) 46 { 47 return oi->oi_owner == XFS_RMAP_OWN_NULL; 48 } 49 50 /* Reverse mapping functions. */ 51 52 struct xfs_buf; 53 54 static inline __u64 55 xfs_rmap_irec_offset_pack( 56 const struct xfs_rmap_irec *irec) 57 { 58 __u64 x; 59 60 x = XFS_RMAP_OFF(irec->rm_offset); 61 if (irec->rm_flags & XFS_RMAP_ATTR_FORK) 62 x |= XFS_RMAP_OFF_ATTR_FORK; 63 if (irec->rm_flags & XFS_RMAP_BMBT_BLOCK) 64 x |= XFS_RMAP_OFF_BMBT_BLOCK; 65 if (irec->rm_flags & XFS_RMAP_UNWRITTEN) 66 x |= XFS_RMAP_OFF_UNWRITTEN; 67 return x; 68 } 69 70 static inline xfs_failaddr_t 71 xfs_rmap_irec_offset_unpack( 72 __u64 offset, 73 struct xfs_rmap_irec *irec) 74 { 75 if (offset & ~(XFS_RMAP_OFF_MASK | XFS_RMAP_OFF_FLAGS)) 76 return __this_address; 77 78 irec->rm_offset = XFS_RMAP_OFF(offset); 79 irec->rm_flags = 0; 80 if (offset & XFS_RMAP_OFF_ATTR_FORK) 81 irec->rm_flags |= XFS_RMAP_ATTR_FORK; 82 if (offset & XFS_RMAP_OFF_BMBT_BLOCK) 83 irec->rm_flags |= XFS_RMAP_BMBT_BLOCK; 84 if (offset & XFS_RMAP_OFF_UNWRITTEN) 85 irec->rm_flags |= XFS_RMAP_UNWRITTEN; 86 return NULL; 87 } 88 89 static inline void 90 xfs_owner_info_unpack( 91 const struct xfs_owner_info *oinfo, 92 uint64_t *owner, 93 uint64_t *offset, 94 unsigned int *flags) 95 { 96 unsigned int r = 0; 97 98 *owner = oinfo->oi_owner; 99 *offset = oinfo->oi_offset; 100 if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK) 101 r |= XFS_RMAP_ATTR_FORK; 102 if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK) 103 r |= XFS_RMAP_BMBT_BLOCK; 104 *flags = r; 105 } 106 107 static inline void 108 xfs_owner_info_pack( 109 struct xfs_owner_info *oinfo, 110 uint64_t owner, 111 uint64_t offset, 112 unsigned int flags) 113 { 114 oinfo->oi_owner = owner; 115 oinfo->oi_offset = XFS_RMAP_OFF(offset); 116 oinfo->oi_flags = 0; 117 if (flags & XFS_RMAP_ATTR_FORK) 118 oinfo->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; 119 if (flags & XFS_RMAP_BMBT_BLOCK) 120 oinfo->oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK; 121 } 122 123 int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, 124 struct xfs_perag *pag, xfs_agblock_t bno, xfs_extlen_t len, 125 const struct xfs_owner_info *oinfo); 126 int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, 127 struct xfs_perag *pag, xfs_agblock_t bno, xfs_extlen_t len, 128 const struct xfs_owner_info *oinfo); 129 130 int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, 131 uint64_t owner, uint64_t offset, unsigned int flags, 132 struct xfs_rmap_irec *irec, int *stat); 133 int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, 134 xfs_extlen_t len, uint64_t owner, uint64_t offset, 135 unsigned int flags, int *stat); 136 int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_agblock_t agbno, 137 xfs_extlen_t len, uint64_t owner, uint64_t offset, 138 unsigned int flags); 139 int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, 140 int *stat); 141 142 typedef int (*xfs_rmap_query_range_fn)( 143 struct xfs_btree_cur *cur, 144 const struct xfs_rmap_irec *rec, 145 void *priv); 146 147 int xfs_rmap_query_range(struct xfs_btree_cur *cur, 148 const struct xfs_rmap_irec *low_rec, 149 const struct xfs_rmap_irec *high_rec, 150 xfs_rmap_query_range_fn fn, void *priv); 151 int xfs_rmap_query_all(struct xfs_btree_cur *cur, xfs_rmap_query_range_fn fn, 152 void *priv); 153 154 enum xfs_rmap_intent_type { 155 XFS_RMAP_MAP, 156 XFS_RMAP_MAP_SHARED, 157 XFS_RMAP_UNMAP, 158 XFS_RMAP_UNMAP_SHARED, 159 XFS_RMAP_CONVERT, 160 XFS_RMAP_CONVERT_SHARED, 161 XFS_RMAP_ALLOC, 162 XFS_RMAP_FREE, 163 }; 164 165 #define XFS_RMAP_INTENT_STRINGS \ 166 { XFS_RMAP_MAP, "map" }, \ 167 { XFS_RMAP_MAP_SHARED, "map_shared" }, \ 168 { XFS_RMAP_UNMAP, "unmap" }, \ 169 { XFS_RMAP_UNMAP_SHARED, "unmap_shared" }, \ 170 { XFS_RMAP_CONVERT, "cvt" }, \ 171 { XFS_RMAP_CONVERT_SHARED, "cvt_shared" }, \ 172 { XFS_RMAP_ALLOC, "alloc" }, \ 173 { XFS_RMAP_FREE, "free" } 174 175 struct xfs_rmap_intent { 176 struct list_head ri_list; 177 enum xfs_rmap_intent_type ri_type; 178 int ri_whichfork; 179 uint64_t ri_owner; 180 struct xfs_bmbt_irec ri_bmap; 181 struct xfs_group *ri_group; 182 bool ri_realtime; 183 }; 184 185 /* functions for updating the rmapbt based on bmbt map/unmap operations */ 186 void xfs_rmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip, 187 int whichfork, struct xfs_bmbt_irec *imap); 188 void xfs_rmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip, 189 int whichfork, struct xfs_bmbt_irec *imap); 190 void xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_trans *tp, 191 struct xfs_inode *ip, int whichfork, 192 struct xfs_bmbt_irec *imap); 193 void xfs_rmap_alloc_extent(struct xfs_trans *tp, bool isrt, xfs_fsblock_t fsbno, 194 xfs_extlen_t len, uint64_t owner); 195 void xfs_rmap_free_extent(struct xfs_trans *tp, bool isrt, xfs_fsblock_t fsbno, 196 xfs_extlen_t len, uint64_t owner); 197 198 int xfs_rmap_finish_one(struct xfs_trans *tp, struct xfs_rmap_intent *ri, 199 struct xfs_btree_cur **pcur); 200 int __xfs_rmap_finish_intent(struct xfs_btree_cur *rcur, 201 enum xfs_rmap_intent_type op, xfs_agblock_t bno, 202 xfs_extlen_t len, const struct xfs_owner_info *oinfo, 203 bool unwritten); 204 205 int xfs_rmap_lookup_le_range(struct xfs_btree_cur *cur, xfs_agblock_t bno, 206 uint64_t owner, uint64_t offset, unsigned int flags, 207 struct xfs_rmap_irec *irec, int *stat); 208 int xfs_rmap_compare(const struct xfs_rmap_irec *a, 209 const struct xfs_rmap_irec *b); 210 union xfs_btree_rec; 211 xfs_failaddr_t xfs_rmap_btrec_to_irec(const union xfs_btree_rec *rec, 212 struct xfs_rmap_irec *irec); 213 xfs_failaddr_t xfs_rmap_check_irec(struct xfs_perag *pag, 214 const struct xfs_rmap_irec *irec); 215 xfs_failaddr_t xfs_rtrmap_check_irec(struct xfs_rtgroup *rtg, 216 const struct xfs_rmap_irec *irec); 217 218 int xfs_rmap_has_records(struct xfs_btree_cur *cur, xfs_agblock_t bno, 219 xfs_extlen_t len, enum xbtree_recpacking *outcome); 220 221 struct xfs_rmap_matches { 222 /* Number of owner matches. */ 223 unsigned long long matches; 224 225 /* Number of non-owner matches. */ 226 unsigned long long non_owner_matches; 227 228 /* Number of non-owner matches that conflict with the owner matches. */ 229 unsigned long long bad_non_owner_matches; 230 }; 231 232 int xfs_rmap_count_owners(struct xfs_btree_cur *cur, xfs_agblock_t bno, 233 xfs_extlen_t len, const struct xfs_owner_info *oinfo, 234 struct xfs_rmap_matches *rmatch); 235 int xfs_rmap_has_other_keys(struct xfs_btree_cur *cur, xfs_agblock_t bno, 236 xfs_extlen_t len, const struct xfs_owner_info *oinfo, 237 bool *has_other); 238 int xfs_rmap_map_raw(struct xfs_btree_cur *cur, struct xfs_rmap_irec *rmap); 239 240 extern const struct xfs_owner_info XFS_RMAP_OINFO_SKIP_UPDATE; 241 extern const struct xfs_owner_info XFS_RMAP_OINFO_ANY_OWNER; 242 extern const struct xfs_owner_info XFS_RMAP_OINFO_FS; 243 extern const struct xfs_owner_info XFS_RMAP_OINFO_LOG; 244 extern const struct xfs_owner_info XFS_RMAP_OINFO_AG; 245 extern const struct xfs_owner_info XFS_RMAP_OINFO_INOBT; 246 extern const struct xfs_owner_info XFS_RMAP_OINFO_INODES; 247 extern const struct xfs_owner_info XFS_RMAP_OINFO_REFC; 248 extern const struct xfs_owner_info XFS_RMAP_OINFO_COW; 249 250 extern struct kmem_cache *xfs_rmap_intent_cache; 251 252 int __init xfs_rmap_intent_init_cache(void); 253 void xfs_rmap_intent_destroy_cache(void); 254 255 /* 256 * Parameters for tracking reverse mapping changes. The hook function arg 257 * parameter is enum xfs_rmap_intent_type, and the rest is below. 258 */ 259 struct xfs_rmap_update_params { 260 xfs_agblock_t startblock; 261 xfs_extlen_t blockcount; 262 struct xfs_owner_info oinfo; 263 bool unwritten; 264 }; 265 266 #ifdef CONFIG_XFS_LIVE_HOOKS 267 268 struct xfs_rmap_hook { 269 struct xfs_hook rmap_hook; 270 }; 271 272 void xfs_rmap_hook_disable(void); 273 void xfs_rmap_hook_enable(void); 274 275 int xfs_rmap_hook_add(struct xfs_group *xg, struct xfs_rmap_hook *hook); 276 void xfs_rmap_hook_del(struct xfs_group *xg, struct xfs_rmap_hook *hook); 277 void xfs_rmap_hook_setup(struct xfs_rmap_hook *hook, notifier_fn_t mod_fn); 278 #endif 279 280 #endif /* __XFS_RMAP_H__ */ 281