physical-zone.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright 2023 Red Hat
  4. */
  5. #ifndef VDO_PHYSICAL_ZONE_H
  6. #define VDO_PHYSICAL_ZONE_H
  7. #include <linux/atomic.h>
  8. #include "types.h"
  9. /*
  10. * The type of a PBN lock.
  11. */
  12. enum pbn_lock_type {
  13. VIO_READ_LOCK,
  14. VIO_WRITE_LOCK,
  15. VIO_BLOCK_MAP_WRITE_LOCK,
  16. };
  17. struct pbn_lock_implementation;
  18. /*
  19. * A PBN lock.
  20. */
  21. struct pbn_lock {
  22. /* The implementation of the lock */
  23. const struct pbn_lock_implementation *implementation;
  24. /* The number of VIOs holding or sharing this lock */
  25. data_vio_count_t holder_count;
  26. /*
  27. * The number of compressed block writers holding a share of this lock while they are
  28. * acquiring a reference to the PBN.
  29. */
  30. u8 fragment_locks;
  31. /* Whether the locked PBN has been provisionally referenced on behalf of the lock holder. */
  32. bool has_provisional_reference;
  33. /*
  34. * For read locks, the number of references that were known to be available on the locked
  35. * block at the time the lock was acquired.
  36. */
  37. u8 increment_limit;
  38. /*
  39. * For read locks, the number of data_vios that have tried to claim one of the available
  40. * increments during the lifetime of the lock. Each claim will first increment this
  41. * counter, so it can exceed the increment limit.
  42. */
  43. atomic_t increments_claimed;
  44. };
  45. struct physical_zone {
  46. /* Which physical zone this is */
  47. zone_count_t zone_number;
  48. /* The thread ID for this zone */
  49. thread_id_t thread_id;
  50. /* In progress operations keyed by PBN */
  51. struct int_map *pbn_operations;
  52. /* Pool of unused pbn_lock instances */
  53. struct pbn_lock_pool *lock_pool;
  54. /* The block allocator for this zone */
  55. struct block_allocator *allocator;
  56. /* The next zone from which to attempt an allocation */
  57. struct physical_zone *next;
  58. };
  59. struct physical_zones {
  60. /* The number of zones */
  61. zone_count_t zone_count;
  62. /* The physical zones themselves */
  63. struct physical_zone zones[];
  64. };
  65. bool __must_check vdo_is_pbn_read_lock(const struct pbn_lock *lock);
  66. void vdo_downgrade_pbn_write_lock(struct pbn_lock *lock, bool compressed_write);
  67. bool __must_check vdo_claim_pbn_lock_increment(struct pbn_lock *lock);
  68. /**
  69. * vdo_pbn_lock_has_provisional_reference() - Check whether a PBN lock has a provisional reference.
  70. * @lock: The PBN lock.
  71. */
  72. static inline bool vdo_pbn_lock_has_provisional_reference(struct pbn_lock *lock)
  73. {
  74. return ((lock != NULL) && lock->has_provisional_reference);
  75. }
  76. void vdo_assign_pbn_lock_provisional_reference(struct pbn_lock *lock);
  77. void vdo_unassign_pbn_lock_provisional_reference(struct pbn_lock *lock);
  78. int __must_check vdo_make_physical_zones(struct vdo *vdo,
  79. struct physical_zones **zones_ptr);
  80. void vdo_free_physical_zones(struct physical_zones *zones);
  81. struct pbn_lock * __must_check vdo_get_physical_zone_pbn_lock(struct physical_zone *zone,
  82. physical_block_number_t pbn);
  83. int __must_check vdo_attempt_physical_zone_pbn_lock(struct physical_zone *zone,
  84. physical_block_number_t pbn,
  85. enum pbn_lock_type type,
  86. struct pbn_lock **lock_ptr);
  87. bool __must_check vdo_allocate_block_in_zone(struct data_vio *data_vio);
  88. void vdo_release_physical_zone_pbn_lock(struct physical_zone *zone,
  89. physical_block_number_t locked_pbn,
  90. struct pbn_lock *lock);
  91. void vdo_dump_physical_zone(const struct physical_zone *zone);
  92. #endif /* VDO_PHYSICAL_ZONE_H */