dm-log.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (C) 2003 Sistina Software
  3. *
  4. * This file is released under the LGPL.
  5. */
  6. #ifndef DM_DIRTY_LOG
  7. #define DM_DIRTY_LOG
  8. #include "dm.h"
  9. typedef sector_t region_t;
  10. struct dirty_log_type;
  11. struct dirty_log {
  12. struct dirty_log_type *type;
  13. void *context;
  14. };
  15. struct dirty_log_type {
  16. struct list_head list;
  17. const char *name;
  18. struct module *module;
  19. unsigned int use_count;
  20. int (*ctr)(struct dirty_log *log, struct dm_target *ti,
  21. unsigned int argc, char **argv);
  22. void (*dtr)(struct dirty_log *log);
  23. /*
  24. * There are times when we don't want the log to touch
  25. * the disk.
  26. */
  27. int (*suspend)(struct dirty_log *log);
  28. int (*resume)(struct dirty_log *log);
  29. /*
  30. * Retrieves the smallest size of region that the log can
  31. * deal with.
  32. */
  33. uint32_t (*get_region_size)(struct dirty_log *log);
  34. /*
  35. * A predicate to say whether a region is clean or not.
  36. * May block.
  37. */
  38. int (*is_clean)(struct dirty_log *log, region_t region);
  39. /*
  40. * Returns: 0, 1, -EWOULDBLOCK, < 0
  41. *
  42. * A predicate function to check the area given by
  43. * [sector, sector + len) is in sync.
  44. *
  45. * If -EWOULDBLOCK is returned the state of the region is
  46. * unknown, typically this will result in a read being
  47. * passed to a daemon to deal with, since a daemon is
  48. * allowed to block.
  49. */
  50. int (*in_sync)(struct dirty_log *log, region_t region, int can_block);
  51. /*
  52. * Flush the current log state (eg, to disk). This
  53. * function may block.
  54. */
  55. int (*flush)(struct dirty_log *log);
  56. /*
  57. * Mark an area as clean or dirty. These functions may
  58. * block, though for performance reasons blocking should
  59. * be extremely rare (eg, allocating another chunk of
  60. * memory for some reason).
  61. */
  62. void (*mark_region)(struct dirty_log *log, region_t region);
  63. void (*clear_region)(struct dirty_log *log, region_t region);
  64. /*
  65. * Returns: <0 (error), 0 (no region), 1 (region)
  66. *
  67. * The mirrord will need perform recovery on regions of
  68. * the mirror that are in the NOSYNC state. This
  69. * function asks the log to tell the caller about the
  70. * next region that this machine should recover.
  71. *
  72. * Do not confuse this function with 'in_sync()', one
  73. * tells you if an area is synchronised, the other
  74. * assigns recovery work.
  75. */
  76. int (*get_resync_work)(struct dirty_log *log, region_t *region);
  77. /*
  78. * This notifies the log that the resync of an area has
  79. * been completed. The log should then mark this region
  80. * as CLEAN.
  81. */
  82. void (*complete_resync_work)(struct dirty_log *log,
  83. region_t region, int success);
  84. /*
  85. * Returns the number of regions that are in sync.
  86. */
  87. region_t (*get_sync_count)(struct dirty_log *log);
  88. /*
  89. * Support function for mirror status requests.
  90. */
  91. int (*status)(struct dirty_log *log, status_type_t status_type,
  92. char *result, unsigned int maxlen);
  93. };
  94. int dm_register_dirty_log_type(struct dirty_log_type *type);
  95. int dm_unregister_dirty_log_type(struct dirty_log_type *type);
  96. /*
  97. * Make sure you use these two functions, rather than calling
  98. * type->constructor/destructor() directly.
  99. */
  100. struct dirty_log *dm_create_dirty_log(const char *type_name, struct dm_target *ti,
  101. unsigned int argc, char **argv);
  102. void dm_destroy_dirty_log(struct dirty_log *log);
  103. /*
  104. * init/exit functions.
  105. */
  106. int dm_dirty_log_init(void);
  107. void dm_dirty_log_exit(void);
  108. #endif