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

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Fri Sep 26 04:20:29 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 | 81 +++++++++++++++++++++++++++++++++++++------------------------
 1 file changed, 49 insertions(+), 32 deletions(-)

diff --git a/sheep/vdi.c b/sheep/vdi.c
index 2166b74..5874c29 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -650,21 +650,21 @@ 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;
 
 	for (int i = 0; i < entry->nr_participants; i++) {
 		if (node_id_cmp(&entry->participants[i], &sys->this_node.nid))
@@ -672,13 +672,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)
@@ -689,18 +692,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))
@@ -708,23 +710,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)
@@ -735,15 +744,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))
@@ -754,22 +762,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,
@@ -777,14 +791,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);
@@ -817,11 +832,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.8.3.2




More information about the sheepdog mailing list