1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (c) 2018 Red Hat, Inc. 4 */ 5 #ifndef __LIBXFS_GROUP_H 6 #define __LIBXFS_GROUP_H 1 7 8 struct xfs_group { 9 struct xfs_mount *xg_mount; 10 uint32_t xg_gno; 11 enum xfs_group_type xg_type; 12 atomic_t xg_ref; /* passive reference count */ 13 atomic_t xg_active_ref; /* active reference count */ 14 15 #ifdef __KERNEL__ 16 /* -- kernel only structures below this line -- */ 17 18 /* 19 * Track freed but not yet committed extents. 20 */ 21 struct xfs_extent_busy_tree *xg_busy_extents; 22 23 /* 24 * Bitsets of per-ag metadata that have been checked and/or are sick. 25 * Callers should hold xg_state_lock before accessing this field. 26 */ 27 uint16_t xg_checked; 28 uint16_t xg_sick; 29 spinlock_t xg_state_lock; 30 31 /* 32 * We use xfs_drain to track the number of deferred log intent items 33 * that have been queued (but not yet processed) so that waiters (e.g. 34 * scrub) will not lock resources when other threads are in the middle 35 * of processing a chain of intent items only to find momentary 36 * inconsistencies. 37 */ 38 struct xfs_defer_drain xg_intents_drain; 39 40 /* 41 * Hook to feed rmapbt updates to an active online repair. 42 */ 43 struct xfs_hooks xg_rmap_update_hooks; 44 #endif /* __KERNEL__ */ 45 }; 46 47 struct xfs_group *xfs_group_get(struct xfs_mount *mp, uint32_t index, 48 enum xfs_group_type type); 49 struct xfs_group *xfs_group_get_by_fsb(struct xfs_mount *mp, 50 xfs_fsblock_t fsbno, enum xfs_group_type type); 51 struct xfs_group *xfs_group_hold(struct xfs_group *xg); 52 void xfs_group_put(struct xfs_group *xg); 53 54 struct xfs_group *xfs_group_grab(struct xfs_mount *mp, uint32_t index, 55 enum xfs_group_type type); 56 struct xfs_group *xfs_group_next_range(struct xfs_mount *mp, 57 struct xfs_group *xg, uint32_t start_index, uint32_t end_index, 58 enum xfs_group_type type); 59 struct xfs_group *xfs_group_grab_next_mark(struct xfs_mount *mp, 60 struct xfs_group *xg, xa_mark_t mark, enum xfs_group_type type); 61 void xfs_group_rele(struct xfs_group *xg); 62 63 void xfs_group_free(struct xfs_mount *mp, uint32_t index, 64 enum xfs_group_type type, void (*uninit)(struct xfs_group *xg)); 65 int xfs_group_insert(struct xfs_mount *mp, struct xfs_group *xg, 66 uint32_t index, enum xfs_group_type); 67 68 #define xfs_group_set_mark(_xg, _mark) \ 69 xa_set_mark(&(_xg)->xg_mount->m_groups[(_xg)->xg_type].xa, \ 70 (_xg)->xg_gno, (_mark)) 71 #define xfs_group_clear_mark(_xg, _mark) \ 72 xa_clear_mark(&(_xg)->xg_mount->m_groups[(_xg)->xg_type].xa, \ 73 (_xg)->xg_gno, (_mark)) 74 #define xfs_group_marked(_mp, _type, _mark) \ 75 xa_marked(&(_mp)->m_groups[(_type)].xa, (_mark)) 76 77 static inline xfs_agblock_t 78 xfs_group_max_blocks( 79 struct xfs_group *xg) 80 { 81 return xg->xg_mount->m_groups[xg->xg_type].blocks; 82 } 83 84 static inline xfs_fsblock_t 85 xfs_group_start_fsb( 86 struct xfs_group *xg) 87 { 88 return ((xfs_fsblock_t)xg->xg_gno) << 89 xg->xg_mount->m_groups[xg->xg_type].blklog; 90 } 91 92 static inline xfs_fsblock_t 93 xfs_gbno_to_fsb( 94 struct xfs_group *xg, 95 xfs_agblock_t gbno) 96 { 97 return xfs_group_start_fsb(xg) | gbno; 98 } 99 100 static inline xfs_daddr_t 101 xfs_gbno_to_daddr( 102 struct xfs_group *xg, 103 xfs_agblock_t gbno) 104 { 105 struct xfs_mount *mp = xg->xg_mount; 106 uint32_t blocks = mp->m_groups[xg->xg_type].blocks; 107 108 return XFS_FSB_TO_BB(mp, (xfs_fsblock_t)xg->xg_gno * blocks + gbno); 109 } 110 111 static inline uint32_t 112 xfs_fsb_to_gno( 113 struct xfs_mount *mp, 114 xfs_fsblock_t fsbno, 115 enum xfs_group_type type) 116 { 117 if (!mp->m_groups[type].blklog) 118 return 0; 119 return fsbno >> mp->m_groups[type].blklog; 120 } 121 122 static inline xfs_agblock_t 123 xfs_fsb_to_gbno( 124 struct xfs_mount *mp, 125 xfs_fsblock_t fsbno, 126 enum xfs_group_type type) 127 { 128 return fsbno & mp->m_groups[type].blkmask; 129 } 130 131 #endif /* __LIBXFS_GROUP_H */ 132