This patch is against revision 705. There was a bug causing excessive
retries. I originally thought it was a problem with revision 705, but
it wasn't. This patch fixes that bug and fixes a few things with the
worker scheduling logic.
Index: xget.c
===================================================================
--- xget.c (revision 705)
+++ xget.c (working copy)
@@ -1002,13 +1002,15 @@
static void
respondreqs(File *f)
{
- int fd;
+ int fd, n;
Req *req, *nreq;
Spfcall *rc;
u8 *buf;
u64 count;
req = f->reqs;
+ fd = -1;
+ buf = NULL;
while (req != NULL) {
count = f->datalen - req->offset;
if (count < 0)
@@ -1017,32 +1019,27 @@
if (count > req->count)
count = req->count;
- if (f->datalen == f->datasize || (count>4096 && req->offset + count <= f->datalen) ) {
+ if (f->datalen == f->datasize || (count>4096 && req->offset + count < f->datalen)) {
/* if we haven't got the whole file and can send back
only small chunk, don't respond, wait for more */
buf = sp_malloc(count);
- if ((fd = open(f->lname, O_RDONLY)) == -1) {
- xget_uerror(errno);
- free(buf);
- continue;
- }
+ if (!buf)
+ goto error;
+
+ if ((fd = open(f->lname, O_RDONLY)) == -1)
+ goto error;
- if ((lseek(fd, req->offset, SEEK_SET)) == (off_t)-1) {
- xget_uerror(errno);
- free(buf);
- close(fd);
- continue;
- }
+ if ((lseek(fd, req->offset, SEEK_SET)) == (off_t)-1)
+ goto error;
- if ((read(fd, buf, count)) < count) {
- xget_uerror(errno);
- free(buf);
- close(fd);
- continue;
- }
+ if ((n = read(fd, buf, count)) < 0)
+ goto error;
close(fd);
+ if (n < count)
+ count = n;
+
rc = sp_create_rread(count, buf);
free(buf);
sp_respond(req->req, rc);
@@ -1059,6 +1056,15 @@
} else
req = req->next;
}
+
+ return;
+
+error:
+ xget_uerror(errno);
+ if (buf)
+ free(buf);
+ if (fd > 0)
+ close(fd);
}
static void
@@ -1636,7 +1642,6 @@
}
signal(SIGHUP, reload);
-
if (netaddress) {
if (netmount(netaddress, user, port) < 0) {
fprintf(stderr, "Could not connect to server\n");
@@ -1814,6 +1819,9 @@
numconnects++;
debug(Dbgsrvfn, "Client %s connects %d\n", conn->address, numconnects);
+ if (netaddress)
+ return;
+
n = strlen(conn->address) + 1;
c = sp_malloc(sizeof(Client) + n + sizeof(int) * (maxlevels - 1));
if (!c)
@@ -1851,6 +1859,8 @@
numconnects--;
debug(Dbgsrvfn, "Client %s disconnects %d\n", conn->address, numconnects);
+ if (netaddress)
+ return;
for (c = clients; c != NULL; c = c->next) {
if (!strcmp(c->caddress, conn->address))
@@ -1884,7 +1894,7 @@
static int
redir_read(Spfilefid *fid, u64 offset, u32 count, u8 *data, Spreq *req)
{
- int n, m, i, j, q;
+ int n, dl, conns, level;
char buf[128];
File *f;
Worker *w, *p, *t;
@@ -1897,49 +1907,56 @@
return 0;
memset(buf, 0, sizeof(buf));
- m = 0;
- for (c = clients; c != NULL; c = c->next) {
+ dl = 0; //The desired level in the tree
+
+ //Find this client and determine the desired level
+ for (c = clients; c != NULL; c = c->next) {
if (!strcmp(c->caddress, fid->fid->conn->address)) {
- for (i = 1; i < maxlevels - 1; i++) {
- if (c->clevels[m] > c->clevels[i])
- m = i;
+ for (n = 1; n < maxlevels - 1; n++) {
+ if (c->clevels[dl] > c->clevels[n])
+ dl = n;
}
break;
}
}
+ dl++;
if (!c)
return -1;
- q = 1;
- j = 0;
- if (!f->nextworker) {
+ level = 1;
+ conns = 0;
+ if (!f->nextworker)
snprintf(buf, sizeof(buf), "me");
- c->clevels[0]++;
- } else {
+ else {
p = f->nextworker;
t = NULL;
for (w = f->nextworker; w != NULL; ) {
if (w->slevel >= maxlevels) {
continue;
}
+
+ /*Try to find a worker with the desired level and the least number
+ of connections. If the desired level cannot be found, just find
+ a worker with the least number of connections. */
- if (!t && w->server->conns < maxconnections)
+ if (!t) {
+ if (w->server->conns < maxconnections &&
+ dl == w->slevel)
t = w;
+
+ else if (w->server->conns < maxconnections)
+ t = w;
+ }
else {
- if (t) {
- if (t->server->conns > w->server->conns &&
- m == w->slevel - 1)
- t = w;
- } else {
- if (w->server->conns < maxconnections &&
- m == w->slevel - 1)
- t = w;
- }
+ if (t->server->conns > w->server->conns &&
+ dl == w->slevel)
+ t = w;
- if (t && t->server->conns == 0)
- break;
+ else if (t->slevel != dl && t->server->conns >
+ w->server->conns)
+ t = w;
}
if (!w->next && p == f->firstworker)
@@ -1950,10 +1967,8 @@
break;
else
w = w->next;
-
- continue;
}
-
+
if (t) {
snprintf(buf, sizeof(buf), "%s", t->server->saddress);
if (t == f->lastworker)
@@ -1962,8 +1977,8 @@
f->nextworker = t->next;
c->clevels[t->slevel - 1]++;
- j = t->server->conns + 1;
- q = t->slevel;
+ conns = t->server->conns + 1;
+ level = t->slevel;
uw = sp_malloc(sizeof(Usedworker));
if (!uw)
return -1;
@@ -1976,10 +1991,8 @@
c->workersused = uw;
}
- else {
+ else
snprintf(buf, sizeof(buf), "me");
- c->clevels[0]++;
- }
}
n = strlen(buf);
@@ -1988,7 +2001,7 @@
memcpy(data, buf, count);
debug(Dbgsrvfn, "Client %s redirected to %s with conns: %d and level: %d"
- " for file: %s\n", fid->fid->conn->address, buf, j, q, f->nname);
+ " for file: %s\n", fid->fid->conn->address, buf, conns, level, f->nname);
return count;
}