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