A dead-lock happens in the following situation: 1. There are two nodes ('A' and 'B') in Sheepdog. 2. A CoW request (oid = 200, cow_oid = 100) is sent to the node 'A'. 3. The object '100' is stored in the node 'A', and the object '200' will be stored in the node 'B' 4. To serialize accesses, the object '100' becomes a busy object in the node 'A'. 5. The node 'A' forwards the CoW request to the node 'B'. 6. The node 'B' reads the object '100' from the node 'A', but the object is busy (dead-lock). In fact, the source object of CoW must be read-only, so we don't need to serialize the accesses to it. This patch removes the object from the busy object list. Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> --- sheep/group.c | 8 +++----- sheep/sdnet.c | 12 ++---------- sheep/sheep_priv.h | 2 +- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/sheep/group.c b/sheep/group.c index 7051698..d2c68bf 100644 --- a/sheep/group.c +++ b/sheep/group.c @@ -1248,7 +1248,7 @@ int is_access_to_busy_objects(uint64_t oid) eprintf("bug\n"); continue; } - if (oid == req->local_oid[0] || oid == req->local_oid[1]) + if (oid == req->local_oid) return 1; } return 0; @@ -1262,12 +1262,10 @@ static int __is_access_to_busy_objects(struct request *req) return 0; } - if (is_access_to_busy_objects(req->local_oid[0]) || - is_access_to_busy_objects(req->local_oid[1])) + if (is_access_to_busy_objects(req->local_oid)) return 1; - if (is_recoverying_oid(req->local_oid[0]) || - is_recoverying_oid(req->local_oid[1])) + if (is_recoverying_oid(req->local_oid)) return 1; return 0; diff --git a/sheep/sdnet.c b/sheep/sdnet.c index c7be51c..b69f539 100644 --- a/sheep/sdnet.c +++ b/sheep/sdnet.c @@ -72,11 +72,7 @@ static void setup_access_to_local_objects(struct request *req) int copies; if (hdr->flags & SD_FLAG_CMD_DIRECT) { - req->local_oid[0] = hdr->oid; - - if (hdr->flags & SD_FLAG_CMD_COW) - req->local_oid[1] = hdr->cow_oid; - + req->local_oid = hdr->oid; return; } @@ -85,11 +81,7 @@ static void setup_access_to_local_objects(struct request *req) copies = sys->nr_sobjs; if (is_access_local(req->entry, req->nr_nodes, hdr->oid, copies)) - req->local_oid[0] = hdr->oid; - - if ((hdr->flags & SD_FLAG_CMD_COW) && - is_access_local(req->entry, req->nr_nodes, hdr->cow_oid, copies)) - req->local_oid[1] = hdr->cow_oid; + req->local_oid = hdr->oid; } static void __done(struct work *work, int idx) diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index 7f24dc9..2687df3 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -81,7 +81,7 @@ struct request { struct list_head r_wlist; struct list_head pending_list; - uint64_t local_oid[2]; + uint64_t local_oid; struct sheepdog_node_list_entry entry[SD_MAX_NODES]; int nr_nodes; -- 1.5.6.5 |