From: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp> Now we may call for_each_object_in_wd() in kick_recovery() and get a read lock of md_lock in it. To avoid a dead lock, kick_recovery() must be called outside the write lock context. Even if we don't get the lock inside kick_recovery(), it is better to release the write lock asap to avoid blocking long time.
Signed-off-by: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp> --- sheep/md.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sheep/md.c b/sheep/md.c index 1b45a37..cd5b243 100644 --- a/sheep/md.c +++ b/sheep/md.c @@ -407,7 +407,7 @@ static inline void kick_recover(void) static void md_do_recover(struct work *work) { struct md_work *mw = container_of(work, struct md_work, work); - int idx; + int idx, nr = 0; pthread_rwlock_wrlock(&md_lock); idx = path_to_disk_idx(mw->path); @@ -416,10 +416,13 @@ static void md_do_recover(struct work *work) goto out; remove_disk(idx); sys->disk_space = md_init_space(); - if (md_nr_disks > 0) - kick_recover(); + nr = md_nr_disks; out: pthread_rwlock_unlock(&md_lock); + + if (nr > 0) + kick_recover(); + free(mw); } @@ -599,7 +602,7 @@ static inline void md_del_disk(char *path) static int do_plug_unplug(char *disks, bool plug) { char *path; - int old_nr, ret = SD_RES_UNKNOWN; + int old_nr, cur_nr = 0, ret = SD_RES_UNKNOWN; pthread_rwlock_wrlock(&md_lock); old_nr = md_nr_disks; @@ -619,17 +622,20 @@ static int do_plug_unplug(char *disks, bool plug) goto out; sys->disk_space = md_init_space(); + cur_nr = md_nr_disks; + + ret = SD_RES_SUCCESS; +out: + pthread_rwlock_unlock(&md_lock); + /* * We have to kick recover aggressively because there is possibility * that nr of disks are removed during md_init_space() happens to equal * nr of disks we added. */ - if (md_nr_disks > 0) + if (cur_nr > 0) kick_recover(); - ret = SD_RES_SUCCESS; -out: - pthread_rwlock_unlock(&md_lock); return ret; } -- 1.7.9.5 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog