diff options
Diffstat (limited to 'drivers/md/md-cluster.c')
| -rw-r--r-- | drivers/md/md-cluster.c | 65 | 
1 files changed, 43 insertions, 22 deletions
diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 021cbf9ef1bf..94329e03001e 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -304,15 +304,6 @@ static void recover_bitmaps(struct md_thread *thread)  	while (cinfo->recovery_map) {  		slot = fls64((u64)cinfo->recovery_map) - 1; -		/* Clear suspend_area associated with the bitmap */ -		spin_lock_irq(&cinfo->suspend_lock); -		list_for_each_entry_safe(s, tmp, &cinfo->suspend_list, list) -			if (slot == s->slot) { -				list_del(&s->list); -				kfree(s); -			} -		spin_unlock_irq(&cinfo->suspend_lock); -  		snprintf(str, 64, "bitmap%04d", slot);  		bm_lockres = lockres_init(mddev, str, NULL, 1);  		if (!bm_lockres) { @@ -326,19 +317,35 @@ static void recover_bitmaps(struct md_thread *thread)  					str, ret);  			goto clear_bit;  		} -		ret = bitmap_copy_from_slot(mddev, slot, &lo, &hi, true); +		ret = md_bitmap_copy_from_slot(mddev, slot, &lo, &hi, true);  		if (ret) {  			pr_err("md-cluster: Could not copy data from bitmap %d\n", slot);  			goto clear_bit;  		} + +		/* Clear suspend_area associated with the bitmap */ +		spin_lock_irq(&cinfo->suspend_lock); +		list_for_each_entry_safe(s, tmp, &cinfo->suspend_list, list) +			if (slot == s->slot) { +				list_del(&s->list); +				kfree(s); +			} +		spin_unlock_irq(&cinfo->suspend_lock); +  		if (hi > 0) {  			if (lo < mddev->recovery_cp)  				mddev->recovery_cp = lo;  			/* wake up thread to continue resync in case resync  			 * is not finished */  			if (mddev->recovery_cp != MaxSector) { -			    set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); -			    md_wakeup_thread(mddev->thread); +				/* +				 * clear the REMOTE flag since we will launch +				 * resync thread in current node. +				 */ +				clear_bit(MD_RESYNCING_REMOTE, +					  &mddev->recovery); +				set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); +				md_wakeup_thread(mddev->thread);  			}  		}  clear_bit: @@ -457,6 +464,11 @@ static void process_suspend_info(struct mddev *mddev,  	struct suspend_info *s;  	if (!hi) { +		/* +		 * clear the REMOTE flag since resync or recovery is finished +		 * in remote node. +		 */ +		clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery);  		remove_suspend_info(mddev, slot);  		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);  		md_wakeup_thread(mddev->thread); @@ -480,9 +492,7 @@ static void process_suspend_info(struct mddev *mddev,  	 * resync thread is running in another node,  	 * so we don't need to do the resync again  	 * with the same section */ -	bitmap_sync_with_cluster(mddev, cinfo->sync_low, -					cinfo->sync_hi, -					lo, hi); +	md_bitmap_sync_with_cluster(mddev, cinfo->sync_low, cinfo->sync_hi, lo, hi);  	cinfo->sync_low = lo;  	cinfo->sync_hi = hi; @@ -585,6 +595,7 @@ static int process_recvd_msg(struct mddev *mddev, struct cluster_msg *msg)  		revalidate_disk(mddev->gendisk);  		break;  	case RESYNCING: +		set_bit(MD_RESYNCING_REMOTE, &mddev->recovery);  		process_suspend_info(mddev, le32_to_cpu(msg->slot),  				     le64_to_cpu(msg->low),  				     le64_to_cpu(msg->high)); @@ -829,7 +840,7 @@ static int gather_all_resync_info(struct mddev *mddev, int total_slots)  		}  		/* Read the disk bitmap sb and check if it needs recovery */ -		ret = bitmap_copy_from_slot(mddev, i, &lo, &hi, false); +		ret = md_bitmap_copy_from_slot(mddev, i, &lo, &hi, false);  		if (ret) {  			pr_warn("md-cluster: Could not gather bitmaps from slot %d", i);  			lockres_free(bm_lockres); @@ -1127,13 +1138,13 @@ static int cluster_check_sync_size(struct mddev *mddev)  		bm_lockres = lockres_init(mddev, str, NULL, 1);  		if (!bm_lockres) {  			pr_err("md-cluster: Cannot initialize %s\n", str); -			bitmap_free(bitmap); +			md_bitmap_free(bitmap);  			return -1;  		}  		bm_lockres->flags |= DLM_LKF_NOQUEUE;  		rv = dlm_lock_sync(bm_lockres, DLM_LOCK_PW);  		if (!rv) -			bitmap_update_sb(bitmap); +			md_bitmap_update_sb(bitmap);  		lockres_free(bm_lockres);  		sb = kmap_atomic(bitmap->storage.sb_page); @@ -1141,11 +1152,11 @@ static int cluster_check_sync_size(struct mddev *mddev)  			sync_size = sb->sync_size;  		else if (sync_size != sb->sync_size) {  			kunmap_atomic(sb); -			bitmap_free(bitmap); +			md_bitmap_free(bitmap);  			return -1;  		}  		kunmap_atomic(sb); -		bitmap_free(bitmap); +		md_bitmap_free(bitmap);  	}  	return (my_sync_size == sync_size) ? 0 : -1; @@ -1265,8 +1276,18 @@ static int resync_info_update(struct mddev *mddev, sector_t lo, sector_t hi)  static int resync_finish(struct mddev *mddev)  {  	struct md_cluster_info *cinfo = mddev->cluster_info; + +	clear_bit(MD_RESYNCING_REMOTE, &mddev->recovery);  	dlm_unlock_sync(cinfo->resync_lockres); -	return resync_info_update(mddev, 0, 0); + +	/* +	 * If resync thread is interrupted so we can't say resync is finished, +	 * another node will launch resync thread to continue. +	 */ +	if (test_bit(MD_CLOSING, &mddev->flags)) +		return 0; +	else +		return resync_info_update(mddev, 0, 0);  }  static int area_resyncing(struct mddev *mddev, int direction, @@ -1442,7 +1463,7 @@ static int gather_bitmaps(struct md_rdev *rdev)  	for (sn = 0; sn < mddev->bitmap_info.nodes; sn++) {  		if (sn == (cinfo->slot_number - 1))  			continue; -		err = bitmap_copy_from_slot(mddev, sn, &lo, &hi, false); +		err = md_bitmap_copy_from_slot(mddev, sn, &lo, &hi, false);  		if (err) {  			pr_warn("md-cluster: Could not gather bitmaps from slot %d", sn);  			goto out;  |