xfs_ag.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2018 Red Hat, Inc.
  4. * All rights reserved.
  5. */
  6. #ifndef __LIBXFS_AG_H
  7. #define __LIBXFS_AG_H 1
  8. struct xfs_mount;
  9. struct xfs_trans;
  10. struct xfs_perag;
  11. /*
  12. * Per-ag infrastructure
  13. */
  14. /* per-AG block reservation data structures*/
  15. struct xfs_ag_resv {
  16. /* number of blocks originally reserved here */
  17. xfs_extlen_t ar_orig_reserved;
  18. /* number of blocks reserved here */
  19. xfs_extlen_t ar_reserved;
  20. /* number of blocks originally asked for */
  21. xfs_extlen_t ar_asked;
  22. };
  23. /*
  24. * Per-ag incore structure, copies of information in agf and agi, to improve the
  25. * performance of allocation group selection.
  26. */
  27. struct xfs_perag {
  28. struct xfs_mount *pag_mount; /* owner filesystem */
  29. xfs_agnumber_t pag_agno; /* AG this structure belongs to */
  30. atomic_t pag_ref; /* passive reference count */
  31. atomic_t pag_active_ref; /* active reference count */
  32. wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */
  33. unsigned long pag_opstate;
  34. uint8_t pagf_bno_level; /* # of levels in bno btree */
  35. uint8_t pagf_cnt_level; /* # of levels in cnt btree */
  36. uint8_t pagf_rmap_level;/* # of levels in rmap btree */
  37. uint32_t pagf_flcount; /* count of blocks in freelist */
  38. xfs_extlen_t pagf_freeblks; /* total free blocks */
  39. xfs_extlen_t pagf_longest; /* longest free space */
  40. uint32_t pagf_btreeblks; /* # of blocks held in AGF btrees */
  41. xfs_agino_t pagi_freecount; /* number of free inodes */
  42. xfs_agino_t pagi_count; /* number of allocated inodes */
  43. /*
  44. * Inode allocation search lookup optimisation.
  45. * If the pagino matches, the search for new inodes
  46. * doesn't need to search the near ones again straight away
  47. */
  48. xfs_agino_t pagl_pagino;
  49. xfs_agino_t pagl_leftrec;
  50. xfs_agino_t pagl_rightrec;
  51. int pagb_count; /* pagb slots in use */
  52. uint8_t pagf_refcount_level; /* recount btree height */
  53. /* Blocks reserved for all kinds of metadata. */
  54. struct xfs_ag_resv pag_meta_resv;
  55. /* Blocks reserved for the reverse mapping btree. */
  56. struct xfs_ag_resv pag_rmapbt_resv;
  57. /* Precalculated geometry info */
  58. xfs_agblock_t block_count;
  59. xfs_agblock_t min_block;
  60. xfs_agino_t agino_min;
  61. xfs_agino_t agino_max;
  62. #ifdef __KERNEL__
  63. /* -- kernel only structures below this line -- */
  64. /*
  65. * Bitsets of per-ag metadata that have been checked and/or are sick.
  66. * Callers should hold pag_state_lock before accessing this field.
  67. */
  68. uint16_t pag_checked;
  69. uint16_t pag_sick;
  70. #ifdef CONFIG_XFS_ONLINE_REPAIR
  71. /*
  72. * Alternate btree heights so that online repair won't trip the write
  73. * verifiers while rebuilding the AG btrees.
  74. */
  75. uint8_t pagf_repair_bno_level;
  76. uint8_t pagf_repair_cnt_level;
  77. uint8_t pagf_repair_refcount_level;
  78. uint8_t pagf_repair_rmap_level;
  79. #endif
  80. spinlock_t pag_state_lock;
  81. spinlock_t pagb_lock; /* lock for pagb_tree */
  82. struct rb_root pagb_tree; /* ordered tree of busy extents */
  83. unsigned int pagb_gen; /* generation count for pagb_tree */
  84. wait_queue_head_t pagb_wait; /* woken when pagb_gen changes */
  85. atomic_t pagf_fstrms; /* # of filestreams active in this AG */
  86. spinlock_t pag_ici_lock; /* incore inode cache lock */
  87. struct radix_tree_root pag_ici_root; /* incore inode cache root */
  88. int pag_ici_reclaimable; /* reclaimable inodes */
  89. unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */
  90. struct xfs_buf_cache pag_bcache;
  91. /* background prealloc block trimming */
  92. struct delayed_work pag_blockgc_work;
  93. /*
  94. * We use xfs_drain to track the number of deferred log intent items
  95. * that have been queued (but not yet processed) so that waiters (e.g.
  96. * scrub) will not lock resources when other threads are in the middle
  97. * of processing a chain of intent items only to find momentary
  98. * inconsistencies.
  99. */
  100. struct xfs_defer_drain pag_intents_drain;
  101. /* Hook to feed rmapbt updates to an active online repair. */
  102. struct xfs_hooks pag_rmap_update_hooks;
  103. #endif /* __KERNEL__ */
  104. };
  105. /*
  106. * Per-AG operational state. These are atomic flag bits.
  107. */
  108. #define XFS_AGSTATE_AGF_INIT 0
  109. #define XFS_AGSTATE_AGI_INIT 1
  110. #define XFS_AGSTATE_PREFERS_METADATA 2
  111. #define XFS_AGSTATE_ALLOWS_INODES 3
  112. #define XFS_AGSTATE_AGFL_NEEDS_RESET 4
  113. #define __XFS_AG_OPSTATE(name, NAME) \
  114. static inline bool xfs_perag_ ## name (struct xfs_perag *pag) \
  115. { \
  116. return test_bit(XFS_AGSTATE_ ## NAME, &pag->pag_opstate); \
  117. }
  118. __XFS_AG_OPSTATE(initialised_agf, AGF_INIT)
  119. __XFS_AG_OPSTATE(initialised_agi, AGI_INIT)
  120. __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
  121. __XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
  122. __XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
  123. int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount,
  124. xfs_agnumber_t agcount, xfs_rfsblock_t dcount,
  125. xfs_agnumber_t *maxagi);
  126. void xfs_free_perag_range(struct xfs_mount *mp, xfs_agnumber_t first_agno,
  127. xfs_agnumber_t end_agno);
  128. int xfs_initialize_perag_data(struct xfs_mount *mp, xfs_agnumber_t agno);
  129. int xfs_update_last_ag_size(struct xfs_mount *mp, xfs_agnumber_t prev_agcount);
  130. /* Passive AG references */
  131. struct xfs_perag *xfs_perag_get(struct xfs_mount *mp, xfs_agnumber_t agno);
  132. struct xfs_perag *xfs_perag_hold(struct xfs_perag *pag);
  133. void xfs_perag_put(struct xfs_perag *pag);
  134. /* Active AG references */
  135. struct xfs_perag *xfs_perag_grab(struct xfs_mount *, xfs_agnumber_t);
  136. void xfs_perag_rele(struct xfs_perag *pag);
  137. /*
  138. * Per-ag geometry infomation and validation
  139. */
  140. xfs_agblock_t xfs_ag_block_count(struct xfs_mount *mp, xfs_agnumber_t agno);
  141. void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno,
  142. xfs_agino_t *first, xfs_agino_t *last);
  143. static inline bool
  144. xfs_verify_agbno(struct xfs_perag *pag, xfs_agblock_t agbno)
  145. {
  146. if (agbno >= pag->block_count)
  147. return false;
  148. if (agbno <= pag->min_block)
  149. return false;
  150. return true;
  151. }
  152. static inline bool
  153. xfs_verify_agbext(
  154. struct xfs_perag *pag,
  155. xfs_agblock_t agbno,
  156. xfs_agblock_t len)
  157. {
  158. if (agbno + len <= agbno)
  159. return false;
  160. if (!xfs_verify_agbno(pag, agbno))
  161. return false;
  162. return xfs_verify_agbno(pag, agbno + len - 1);
  163. }
  164. /*
  165. * Verify that an AG inode number pointer neither points outside the AG
  166. * nor points at static metadata.
  167. */
  168. static inline bool
  169. xfs_verify_agino(struct xfs_perag *pag, xfs_agino_t agino)
  170. {
  171. if (agino < pag->agino_min)
  172. return false;
  173. if (agino > pag->agino_max)
  174. return false;
  175. return true;
  176. }
  177. /*
  178. * Verify that an AG inode number pointer neither points outside the AG
  179. * nor points at static metadata, or is NULLAGINO.
  180. */
  181. static inline bool
  182. xfs_verify_agino_or_null(struct xfs_perag *pag, xfs_agino_t agino)
  183. {
  184. if (agino == NULLAGINO)
  185. return true;
  186. return xfs_verify_agino(pag, agino);
  187. }
  188. static inline bool
  189. xfs_ag_contains_log(struct xfs_mount *mp, xfs_agnumber_t agno)
  190. {
  191. return mp->m_sb.sb_logstart > 0 &&
  192. agno == XFS_FSB_TO_AGNO(mp, mp->m_sb.sb_logstart);
  193. }
  194. /*
  195. * Perag iteration APIs
  196. */
  197. static inline struct xfs_perag *
  198. xfs_perag_next(
  199. struct xfs_perag *pag,
  200. xfs_agnumber_t *agno,
  201. xfs_agnumber_t end_agno)
  202. {
  203. struct xfs_mount *mp = pag->pag_mount;
  204. *agno = pag->pag_agno + 1;
  205. xfs_perag_rele(pag);
  206. while (*agno <= end_agno) {
  207. pag = xfs_perag_grab(mp, *agno);
  208. if (pag)
  209. return pag;
  210. (*agno)++;
  211. }
  212. return NULL;
  213. }
  214. #define for_each_perag_range(mp, agno, end_agno, pag) \
  215. for ((pag) = xfs_perag_grab((mp), (agno)); \
  216. (pag) != NULL; \
  217. (pag) = xfs_perag_next((pag), &(agno), (end_agno)))
  218. #define for_each_perag_from(mp, agno, pag) \
  219. for_each_perag_range((mp), (agno), (mp)->m_sb.sb_agcount - 1, (pag))
  220. #define for_each_perag(mp, agno, pag) \
  221. (agno) = 0; \
  222. for_each_perag_from((mp), (agno), (pag))
  223. static inline struct xfs_perag *
  224. xfs_perag_next_wrap(
  225. struct xfs_perag *pag,
  226. xfs_agnumber_t *agno,
  227. xfs_agnumber_t stop_agno,
  228. xfs_agnumber_t restart_agno,
  229. xfs_agnumber_t wrap_agno)
  230. {
  231. struct xfs_mount *mp = pag->pag_mount;
  232. *agno = pag->pag_agno + 1;
  233. xfs_perag_rele(pag);
  234. while (*agno != stop_agno) {
  235. if (*agno >= wrap_agno) {
  236. if (restart_agno >= stop_agno)
  237. break;
  238. *agno = restart_agno;
  239. }
  240. pag = xfs_perag_grab(mp, *agno);
  241. if (pag)
  242. return pag;
  243. (*agno)++;
  244. }
  245. return NULL;
  246. }
  247. /*
  248. * Iterate all AGs from start_agno through wrap_agno, then restart_agno through
  249. * (start_agno - 1).
  250. */
  251. #define for_each_perag_wrap_range(mp, start_agno, restart_agno, wrap_agno, agno, pag) \
  252. for ((agno) = (start_agno), (pag) = xfs_perag_grab((mp), (agno)); \
  253. (pag) != NULL; \
  254. (pag) = xfs_perag_next_wrap((pag), &(agno), (start_agno), \
  255. (restart_agno), (wrap_agno)))
  256. /*
  257. * Iterate all AGs from start_agno through wrap_agno, then 0 through
  258. * (start_agno - 1).
  259. */
  260. #define for_each_perag_wrap_at(mp, start_agno, wrap_agno, agno, pag) \
  261. for_each_perag_wrap_range((mp), (start_agno), 0, (wrap_agno), (agno), (pag))
  262. /*
  263. * Iterate all AGs from start_agno through to the end of the filesystem, then 0
  264. * through (start_agno - 1).
  265. */
  266. #define for_each_perag_wrap(mp, start_agno, agno, pag) \
  267. for_each_perag_wrap_at((mp), (start_agno), (mp)->m_sb.sb_agcount, \
  268. (agno), (pag))
  269. struct aghdr_init_data {
  270. /* per ag data */
  271. xfs_agblock_t agno; /* ag to init */
  272. xfs_extlen_t agsize; /* new AG size */
  273. struct list_head buffer_list; /* buffer writeback list */
  274. xfs_rfsblock_t nfree; /* cumulative new free space */
  275. /* per header data */
  276. xfs_daddr_t daddr; /* header location */
  277. size_t numblks; /* size of header */
  278. const struct xfs_btree_ops *bc_ops; /* btree ops */
  279. };
  280. int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id);
  281. int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp,
  282. xfs_extlen_t delta);
  283. int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp,
  284. xfs_extlen_t len);
  285. int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
  286. #endif /* __LIBXFS_AG_H */