#ifndef BITMAP_H
#define BITMAP_H 1
#define BITMAP_MAGIC 0x6d746962
#define BITMAP_MAJOR_LO 3
#define BITMAP_MAJOR_HOSTENDIAN 3
#define BITMAP_MAJOR_HI 4
#define BITMAP_MAJOR_CLUSTERED 5
#define BITMAP_MAJOR_LOCKLESS 6
enum bitmap_state {
BITMAP_STALE = 1,
BITMAP_WRITE_ERROR = 2,
BITMAP_FIRST_USE = 3,
BITMAP_CLEAN = 4,
BITMAP_DAEMON_BUSY = 5,
BITMAP_HOSTENDIAN =15,
};
typedef struct bitmap_super_s {
__le32 magic;
__le32 version;
__u8 uuid[16];
__le64 events;
__le64 events_cleared;
__le64 sync_size;
__le32 state;
__le32 chunksize;
__le32 daemon_sleep;
__le32 write_behind;
__le32 sectors_reserved;
__le32 nodes;
__u8 cluster_name[64];
__u8 pad[256 - 136];
} bitmap_super_t;
struct md_bitmap_stats {
u64 events_cleared;
int behind_writes;
bool behind_wait;
unsigned long missing_pages;
unsigned long file_pages;
unsigned long sync_size;
unsigned long pages;
struct file *file;
};
typedef void (md_bitmap_fn)(struct mddev *mddev, sector_t offset,
unsigned long sectors);
struct bitmap_operations {
struct md_submodule_head head;
bool (*enabled)(void *data, bool flush);
int (*create)(struct mddev *mddev);
int (*resize)(struct mddev *mddev, sector_t blocks, int chunksize);
int (*load)(struct mddev *mddev);
void (*destroy)(struct mddev *mddev);
void (*flush)(struct mddev *mddev);
void (*write_all)(struct mddev *mddev);
void (*dirty_bits)(struct mddev *mddev, unsigned long s,
unsigned long e);
void (*unplug)(struct mddev *mddev, bool sync);
void (*daemon_work)(struct mddev *mddev);
void (*start_behind_write)(struct mddev *mddev);
void (*end_behind_write)(struct mddev *mddev);
void (*wait_behind_writes)(struct mddev *mddev);
md_bitmap_fn *start_write;
md_bitmap_fn *end_write;
md_bitmap_fn *start_discard;
md_bitmap_fn *end_discard;
sector_t (*skip_sync_blocks)(struct mddev *mddev, sector_t offset);
bool (*blocks_synced)(struct mddev *mddev, sector_t offset);
bool (*start_sync)(struct mddev *mddev, sector_t offset,
sector_t *blocks, bool degraded);
void (*end_sync)(struct mddev *mddev, sector_t offset, sector_t *blocks);
void (*cond_end_sync)(struct mddev *mddev, sector_t sector, bool force);
void (*close_sync)(struct mddev *mddev);
void (*update_sb)(void *data);
int (*get_stats)(void *data, struct md_bitmap_stats *stats);
void (*sync_with_cluster)(struct mddev *mddev,
sector_t old_lo, sector_t old_hi,
sector_t new_lo, sector_t new_hi);
void *(*get_from_slot)(struct mddev *mddev, int slot);
int (*copy_from_slot)(struct mddev *mddev, int slot, sector_t *lo,
sector_t *hi, bool clear_bits);
void (*set_pages)(void *data, unsigned long pages);
void (*free)(void *data);
struct attribute_group *group;
};
static inline bool md_bitmap_registered(struct mddev *mddev)
{
return mddev->bitmap_ops != NULL;
}
static inline bool md_bitmap_enabled(struct mddev *mddev, bool flush)
{
if (!md_bitmap_registered(mddev))
return false;
if (!mddev->bitmap)
return false;
return mddev->bitmap_ops->enabled(mddev->bitmap, flush);
}
static inline bool md_bitmap_start_sync(struct mddev *mddev, sector_t offset,
sector_t *blocks, bool degraded)
{
if (!md_bitmap_enabled(mddev, false)) {
*blocks = 1024;
return true;
}
return mddev->bitmap_ops->start_sync(mddev, offset, blocks, degraded);
}
static inline void md_bitmap_end_sync(struct mddev *mddev, sector_t offset,
sector_t *blocks)
{
if (!md_bitmap_enabled(mddev, false)) {
*blocks = 1024;
return;
}
mddev->bitmap_ops->end_sync(mddev, offset, blocks);
}
#ifdef CONFIG_MD_BITMAP
int md_bitmap_init(void);
void md_bitmap_exit(void);
#else
static inline int md_bitmap_init(void)
{
return 0;
}
static inline void md_bitmap_exit(void)
{
}
#endif
#ifdef CONFIG_MD_LLBITMAP
int md_llbitmap_init(void);
void md_llbitmap_exit(void);
#else
static inline int md_llbitmap_init(void)
{
return 0;
}
static inline void md_llbitmap_exit(void)
{
}
#endif
#endif