[dm-devel] [Patch 1 of 2]: Cluster-aware log module - enabling cluster-aware mirrors
Jonathan Brassow
jbrassow at redhat.com
Fri Jul 25 16:09:28 UTC 2008
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 <jbrassow at redhat.com>
Index: linux-2.6.26-rc8/drivers/md/dm-raid1.c
===================================================================
--- linux-2.6.26-rc8.orig/drivers/md/dm-raid1.c
+++ linux-2.6.26-rc8/drivers/md/dm-raid1.c
@@ -1157,6 +1157,9 @@ static void do_writes(struct mirror_set
int 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_set
bio_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).
Index: linux-2.6.26-rc8/include/linux/dm-dirty-log.h
===================================================================
--- linux-2.6.26-rc8.orig/include/linux/dm-dirty-log.h
+++ linux-2.6.26-rc8/include/linux/dm-dirty-log.h
@@ -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);
More information about the dm-devel
mailing list