Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> --- sheep/sdnet.c | 21 +++++++++++++++++++-- sheep/sheep_priv.h | 1 + sheep/store.c | 10 +++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/sheep/sdnet.c b/sheep/sdnet.c index 5c97374..66ce6b3 100644 --- a/sheep/sdnet.c +++ b/sheep/sdnet.c @@ -791,10 +791,27 @@ int remove_object(struct sheepdog_vnode_list_entry *e, return 0; } +static __thread int cached_fds[SD_MAX_NODES]; +static __thread uint32_t cached_epoch = 0; + +void del_sheep_fd(int fd) +{ + int i; + + for (i = 0; i < SD_MAX_NODES; i++) { + if (cached_fds[i] == fd) { + if (fd >= 0) + close(fd); + + cached_fds[i] = -1; + + return; + } + } +} + int get_sheep_fd(uint8_t *addr, uint16_t port, int node_idx, uint32_t epoch) { - static __thread int cached_fds[SD_MAX_NODES]; - static __thread uint32_t cached_epoch = 0; int i, fd, ret; char name[INET6_ADDRSTRLEN]; diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index 556d719..a448157 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -268,6 +268,7 @@ int remove_object(struct sheepdog_vnode_list_entry *e, int vnodes, int zones, uint32_t node_version, uint64_t oid, int nr); +void del_sheep_fd(int fd); int get_sheep_fd(uint8_t *addr, uint16_t port, int node_idx, uint32_t epoch); /* Operations */ diff --git a/sheep/store.c b/sheep/store.c index c0d7b62..70f9011 100644 --- a/sheep/store.c +++ b/sheep/store.c @@ -260,9 +260,10 @@ static int forward_read_obj_req(struct request *req) ret = exec_req(fd, (struct sd_req *)&hdr, req->data, &wlen, &rlen); - if (ret) /* network errors */ + if (ret) { /* network errors */ + del_sheep_fd(fd); ret = SD_RES_NETWORK_ERROR; - else { + } else { memcpy(&req->rp, rsp, sizeof(*rsp)); ret = rsp->result; } @@ -272,7 +273,7 @@ out: static int forward_write_obj_req(struct request *req) { - int i, n, nr, fd, ret; + int i, n, nr, fd, ret, pollret; unsigned wlen; char name[128]; struct sd_obj_req hdr = *(struct sd_obj_req *)&req->rq; @@ -323,6 +324,7 @@ static int forward_write_obj_req(struct request *req) ret = send_req(fd, (struct sd_req *)&hdr, req->data, &wlen); if (ret) { /* network errors */ + del_sheep_fd(fd); ret = SD_RES_NETWORK_ERROR; dprintf("fail %"PRIu32"\n", ret); goto out; @@ -362,6 +364,7 @@ again: break; if (pfds[i].revents & POLLERR || pfds[i].revents & POLLHUP || pfds[i].revents & POLLNVAL) { + del_sheep_fd(pfds[i].fd); ret = SD_RES_NETWORK_ERROR; break; } @@ -371,6 +374,7 @@ again: if (do_read(pfds[i].fd, rsp, sizeof(*rsp))) { eprintf("failed to read a response: %m\n"); + del_sheep_fd(pfds[i].fd); ret = SD_RES_NETWORK_ERROR; break; } -- 1.7.2.5 |