[sheepdog] [PATCH v2 3/5] sheep: correct locking of vdi status in inode coherence protocol

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Thu Sep 25 16:11:03 CEST 2014


Currnet critical sections of vdi status in inode coherence protocl (in
functions validate_myself(), invalidate_other_nodes(),
inode_coherence_update()) are illegally short. This patch let the
the functions lock the vdi_state_lock correctly.

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 sheep/vdi.c | 83 +++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/sheep/vdi.c b/sheep/vdi.c
index 78c4134..051d606 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -650,24 +650,24 @@ void play_logged_vdi_ops(void)
 worker_fn bool is_refresh_required(uint32_t vid)
 {
 	struct vdi_state_entry *entry;
+	bool ret = false;
 
 	sd_read_lock(&vdi_state_lock);
 	entry = vdi_state_search(&vdi_state_root, vid);
-	sd_rw_unlock(&vdi_state_lock);
 
 	if (!entry) {
 		sd_alert("VID: %"PRIx32" doesn't exist", vid);
-		return false;
+		goto out;
 	}
 
 	if (entry->snapshot)
-		return false;
+		goto out;
 
 	if (entry->lock_state != LOCK_STATE_SHARED)
-		return false;
+		goto out;
 
 	if (!is_modified(entry))
-		return false;
+		goto out;
 
 	for (int i = 0; i < entry->nr_participants; i++) {
 		if (node_id_cmp(&entry->participants[i], &sys->this_node.nid))
@@ -675,13 +675,16 @@ worker_fn bool is_refresh_required(uint32_t vid)
 
 		if (entry->participants_state[i] ==
 		    SHARED_LOCK_STATE_INVALIDATED)
-			return true;
-		else
-			return false;
+			ret = true;
+		goto out;
 	}
 
 	sd_alert("this node isn't locking VID: %"PRIx32, vid);
-	return false;
+
+out:
+	sd_rw_unlock(&vdi_state_lock);
+
+	return ret;
 }
 
 worker_fn void validate_myself(uint32_t vid)
@@ -692,18 +695,17 @@ worker_fn void validate_myself(uint32_t vid)
 
 	sd_read_lock(&vdi_state_lock);
 	entry = vdi_state_search(&vdi_state_root, vid);
-	sd_rw_unlock(&vdi_state_lock);
 
 	if (!entry) {
 		sd_alert("VID: %"PRIx32" doesn't exist", vid);
-		return;
+		goto out;
 	}
 
 	if (entry->snapshot)
-		return;
+		goto out;
 
 	if (entry->lock_state != LOCK_STATE_SHARED)
-		return;
+		goto out;
 
 	for (int i = 0; i < entry->nr_participants; i++) {
 		if (node_id_cmp(&entry->participants[i], &sys->this_node.nid))
@@ -711,23 +713,30 @@ worker_fn void validate_myself(uint32_t vid)
 
 		if (entry->participants_state[i] !=
 		    SHARED_LOCK_STATE_INVALIDATED)
-			return;
+			goto out;
+
 		goto validate;
 	}
 
 	sd_alert("this node isn't locking VID: %"PRIx32, vid);
-	return;
+	goto out;
 
 validate:
+	sd_rw_unlock(&vdi_state_lock);
+
 	sd_init_req(&hdr, SD_OP_INODE_COHERENCE);
 	hdr.inode_coherence.vid = vid;
 	hdr.inode_coherence.validate = 1;
 	ret = sheep_exec_req(&sys->this_node.nid, &hdr, NULL);
-	if (ret == SD_RES_SUCCESS)
-		return;
+	if (ret != SD_RES_SUCCESS) {
+		sd_err("failed to validate VID: %"PRIx32" by %s",
+		       vid, node_id_to_str(&sys->this_node.nid));
+	}
+
+	return;
 
-	sd_err("failed to validate VID: %"PRIx32" by %s",
-	       vid, node_id_to_str(&sys->this_node.nid));
+out:
+	sd_rw_unlock(&vdi_state_lock);
 }
 
 worker_fn void invalidate_other_nodes(uint32_t vid)
@@ -738,15 +747,14 @@ worker_fn void invalidate_other_nodes(uint32_t vid)
 
 	sd_read_lock(&vdi_state_lock);
 	entry = vdi_state_search(&vdi_state_root, vid);
-	sd_rw_unlock(&vdi_state_lock);
 
 	if (!entry) {
 		sd_alert("VID: %"PRIx32" doesn't exist", vid);
-		return;
+		goto out;
 	}
 
 	if (entry->lock_state != LOCK_STATE_SHARED)
-		return;
+		goto out;
 
 	for (int i = 0; i < entry->nr_participants; i++) {
 		if (node_id_cmp(&entry->participants[i], &sys->this_node.nid))
@@ -757,22 +765,28 @@ worker_fn void invalidate_other_nodes(uint32_t vid)
 			goto invalidate;
 
 		/* already owned by myself */
-		return;
+		goto out;
 	}
 
 	sd_alert("this node isn't locking VID: %"PRIx32, vid);
-	return;
+	goto out;
 
 invalidate:
+	sd_rw_unlock(&vdi_state_lock);
+
 	sd_init_req(&hdr, SD_OP_INODE_COHERENCE);
 	hdr.inode_coherence.vid = vid;
 	hdr.inode_coherence.validate = 0;
 	ret = sheep_exec_req(&sys->this_node.nid, &hdr, NULL);
-	if (ret == SD_RES_SUCCESS)
-		return;
+	if (ret != SD_RES_SUCCESS) {
+		sd_err("failed to validate VID: %"PRIx32" by %s",
+		       vid, node_id_to_str(&sys->this_node.nid));
+	}
+
+	return;
 
-	sd_err("failed to validate VID: %"PRIx32" by %s",
-	       vid, node_id_to_str(&sys->this_node.nid));
+out:
+	sd_rw_unlock(&vdi_state_lock);
 }
 
 main_fn int inode_coherence_update(uint32_t vid, bool validate,
@@ -780,14 +794,15 @@ main_fn int inode_coherence_update(uint32_t vid, bool validate,
 {
 	struct vdi_state_entry *entry;
 	bool invalidated = false;
+	int ret = SD_RES_SUCCESS;
 
-	sd_read_lock(&vdi_state_lock);
+	sd_write_lock(&vdi_state_lock);
 	entry = vdi_state_search(&vdi_state_root, vid);
-	sd_rw_unlock(&vdi_state_lock);
 
 	if (!entry) {
 		sd_alert("VID: %"PRIx32" doesn't exist", vid);
-		return SD_RES_NO_VDI;
+		ret = SD_RES_NO_VDI;
+		goto out;
 	}
 
 	assert(entry->lock_state == LOCK_STATE_SHARED);
@@ -820,11 +835,13 @@ main_fn int inode_coherence_update(uint32_t vid, bool validate,
 		if (!invalidated) {
 			sd_err("%s isn't participating in VID: %"PRIx32,
 			       node_id_to_str(sender), vid);
-			return SD_RES_NO_VDI;
+			ret = SD_RES_NO_VDI;
 		}
 	}
 
-	return SD_RES_SUCCESS;
+out:
+	sd_rw_unlock(&vdi_state_lock);
+	return ret;
 }
 
 main_fn void remove_node_from_participants(const struct node_id *left)
-- 
1.9.1




More information about the sheepdog mailing list