: Cluster-aware log module - enabling cluster-aware mirrors
PATCH 1/1 : Cluster-aware log module - enabling cluster-aware mirrors
brassow
The logging API needs an extra function to make cluster mirroring possible. This new function allows us to check whether a mirror region is being recovered on another machine in the cluster. This helps us prevent simultaneous recovery I/O and process I/O to the same locations on disk.
Cluster-aware log modules will implement this function. Single machine log modules will not. So, there is no performance penalty for single machine mirrors.
Signed-off-by Jonathan Brassow <[email protected]>
drivers/md/dm-raid1.c +23 -1
@@ -1157,6 +1157,9 @@ static void do_writes(struct mirror_setint state;struct bio *bio;struct bio_list sync, nosync, recover, *this_list =NULL ; +struct bio_list requeue; +struct dm_dirty_log *log = ms->rh.log; +region_t region;if (!writes->head)return ;
@@ -1167,9 +1170,18 @@ static void do_writes(struct mirror_setbio_list_init (&sync);bio_list_init (&nosync);bio_list_init (&recover); +bio_list_init (&requeue);while ((bio =bio_list_pop (writes))) { - state =rh_state (&ms->rh,bio_to_region (&ms->rh, bio),1 ); + region =bio_to_region (&ms->rh, bio); + +if (log->type->is_remote_recovering && + log->type->is_remote_recovering (log, region)) { +bio_list_add (&requeue, bio); +continue ; + } + + state =rh_state (&ms->rh, region,1 );switch (state) {case RH_CLEAN :case RH_DIRTY :
@@ -1189,6 +1201,16 @@ static void do_writes(struct mirror_set }/* +* Add bios that are delayed due to remote recovery +* back on to the write queue +*/ +if (unlikely (requeue.head)) { +spin_lock_irq (&ms->lock); +bio_list_merge (&ms->writes, &requeue); +spin_unlock_irq (&ms->lock); + } + +/* * Increment the pending counts for any regions that will * be written to (writes to recover regions are going to * be delayed).
include/linux/dm-dirty-log.h +10 -0
@@ -113,6 +113,16 @@ struct dm_dirty_log_type {*/ int (*status)(struct dm_dirty_log *log,status_type_t status_type,char *result,unsigned maxlen); + +/* +* is_remote_recovering is necessary for cluster mirroring. It provides +* a way to detect recovery on another node, so we aren't writing +* concurrently. This function is likely to block (when a cluster log +* is used). +* +* Returns: 0, 1 +*/ +int (*is_remote_recovering)(struct dm_dirty_log *log,region_t region); };int dm_dirty_log_type_register (struct dm_dirty_log_type *type);