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