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