raid6-serialize-ovelapping-reqs.patch
来自「lustre 1.6.5 source code」· PATCH 代码 · 共 151 行
PATCH
151 行
diff -pur linux-2.6.9.orig/drivers/md/raid6main.c linux-2.6.9/drivers/md/raid6main.c--- linux-2.6.9.orig/drivers/md/raid6main.c 2008-01-10 13:55:37.000000000 +0800+++ linux-2.6.9/drivers/md/raid6main.c 2008-01-10 13:55:56.000000000 +0800@@ -749,6 +749,10 @@ static void compute_parity(struct stripe if ( i != pd_idx && i != qd_idx && sh->dev[i].towrite ) { chosen = sh->dev[i].towrite; sh->dev[i].towrite = NULL;++ if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))+ wake_up(&conf->wait_for_overlap);+ if (sh->dev[i].written) BUG(); sh->dev[i].written = chosen; }@@ -907,7 +911,7 @@ static void compute_block_2(struct strip * toread/towrite point to the first in a chain. * The bi_next chain must be in order. */-static void add_stripe_bio (struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)+static int add_stripe_bio (struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite) { struct bio **bip; raid6_conf_t *conf = sh->raid_conf;@@ -924,10 +928,13 @@ static void add_stripe_bio (struct strip else bip = &sh->dev[dd_idx].toread; while (*bip && (*bip)->bi_sector < bi->bi_sector) {- BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector);+ if((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)+ goto overlap; bip = & (*bip)->bi_next; }-/* FIXME do I need to worry about overlapping bion */+ if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))+ goto overlap;+ if (*bip && bi->bi_next && (*bip) != bi->bi_next) BUG(); if (*bip)@@ -954,6 +961,14 @@ static void add_stripe_bio (struct strip if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS) set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags); }++ return 1;++overlap:+ set_bit(R5_Overlap, &sh->dev[dd_idx].flags);+ spin_unlock_irq(&conf->device_lock);+ spin_unlock(&sh->lock);+ return 0; } /*@@ -1038,6 +1053,9 @@ static void handle_stripe(struct stripe_ spin_lock_irq(&conf->device_lock); rbi = dev->toread; dev->toread = NULL;++ if (test_and_clear_bit(R5_Overlap, &dev->flags))+ wake_up(&conf->wait_for_overlap); spin_unlock_irq(&conf->device_lock); while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) { copy_data(0, rbi, dev->page, dev->sector);@@ -1087,6 +1105,9 @@ static void handle_stripe(struct stripe_ sh->dev[i].towrite = NULL; if (bi) to_write--; + if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))+ wake_up(&conf->wait_for_overlap);+ while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector); clear_bit(BIO_UPTODATE, &bi->bi_flags);@@ -1115,6 +1136,8 @@ static void handle_stripe(struct stripe_ if (!test_bit(R5_Insync, &sh->dev[i].flags)) { bi = sh->dev[i].toread; sh->dev[i].toread = NULL;+ if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))+ wake_up(&conf->wait_for_overlap); if (bi) to_read--; while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){ struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);@@ -1648,6 +1671,8 @@ static int make_request (request_queue_t sh = NULL; /* iterrate through all pages in the stripe */ for (j = 0; j < data_disks && sectors > 0; j++) {+ DEFINE_WAIT(w);+ if (r_sector + STRIPE_SECTORS <= bi->bi_sector || r_sector >= last_sector) { r_sector += sectors_per_chunk;@@ -1656,6 +1681,9 @@ static int make_request (request_queue_t new_sector = raid6_compute_sector(r_sector, raid_disks, data_disks, &dd_idx, &pd_idx, conf);++retry:+ prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); if (sh == NULL) { /* first, try to get stripe w/o blocking * if we can't, then it's time to submit@@ -1668,10 +1696,18 @@ static int make_request (request_queue_t } } if (sh) {- add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));+ if(!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {+ /* Failed to be added due to overlapped. */+ raid6_unplug_device(mddev->queue);+ release_stripe(sh);+ schedule();+ goto retry;+ }+ finish_wait(&conf->wait_for_overlap, &w); } else { /* cannot get stripe for read-ahead, just give-up */ clear_bit(BIO_UPTODATE, &bi->bi_flags);+ finish_wait(&conf->wait_for_overlap, &w); sectors = 0; break; }@@ -1847,6 +1883,7 @@ static int run (mddev_t *mddev) conf->device_lock = SPIN_LOCK_UNLOCKED; init_waitqueue_head(&conf->wait_for_stripe);+ init_waitqueue_head(&conf->wait_for_overlap); INIT_LIST_HEAD(&conf->handle_list); INIT_LIST_HEAD(&conf->delayed_list); INIT_LIST_HEAD(&conf->inactive_list);diff -pur linux-2.6.9.orig/include/linux/raid/raid5.h linux-2.6.9/include/linux/raid/raid5.h--- linux-2.6.9.orig/include/linux/raid/raid5.h 2008-01-10 13:46:05.000000000 +0800+++ linux-2.6.9/include/linux/raid/raid5.h 2008-01-10 13:55:56.000000000 +0800@@ -154,6 +154,8 @@ struct stripe_head { #define R5_Wantwrite 5 #define R5_Syncio 6 /* this io need to be accounted as resync io */ #define R5_Direct 7 /* use page from passed bio to avoid memcpy */+#define R5_Overlap 8 /* There is a pending overlapping request + * on this block */ /* * Write method@@ -221,6 +223,7 @@ struct raid5_private_data { atomic_t active_stripes; struct list_head inactive_list; wait_queue_head_t wait_for_stripe;+ wait_queue_head_t wait_for_overlap; int inactive_blocked; /* release of inactive stripes blocked, * waiting for 25% to be free */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?