My latest xget patch has some bugs.  This patch is reversion 704 with my
patch from [EMAIL PROTECTED]:45 and a minor fix which appears to be stable.

Signed-off-by: Hugh Greenberg <[EMAIL PROTECTED]>
Index: xget.c
===================================================================
--- xget.c	(revision 705)
+++ xget.c	(working copy)
@@ -47,6 +47,7 @@
 
 Spfileops redir_ops = {
 	.read = redir_read,
+	.closefid = redir_closefid,
 };
 
 Spfileops avail_ops = {
@@ -79,7 +80,7 @@
 int xget_ecode;
 int numconnects = 0;
 int numtransfers = 0;
-int maxlevels = 4;
+int maxlevels = 5;
 int maxconnections = 10;
 int maxretries = 15; /* give at least 15 attempts by default */
 int retrytime = 10; /* wait default of 20 seconds before trying again */
@@ -266,6 +267,9 @@
 	ticksig = 1;
 	if (servicetime && time(NULL) > servicetime) {
 		for(f = files; f != NULL; f = f->next) {
+			if (f->redirfid)
+				spc_close(f->redirfid);
+			
 			if (f->availfid)
 				spc_close(f->availfid);
 		}
@@ -1193,6 +1197,7 @@
 
 	file->fs = NULL;
 	file->datafid = NULL;
+	file->redirfid = NULL;
 	file->datafd = NULL;
 	file->availfid = NULL;
 	/* check if we should go somewhere else for the file */
@@ -1206,7 +1211,6 @@
 		goto error;
 
 	buf[n] = '\0';
-	spc_close(redirfid);
 	redirto = sp_malloc(strlen(buf) + 1);
 	strcpy(redirto, buf);
 	if (!strcmp(buf, "me")) {
@@ -1238,6 +1242,7 @@
 
 	file->fs = redirfs;
 	file->datafid = datafid;
+	file->redirfid = redirfid;
 	file->crc = crc;
 	file->datafd = spcfd_add(file->datafid, netreadcb, file, 0);
 	file->availfid = availfid;
@@ -1791,6 +1796,8 @@
 			spc_close(f->datafid);
 		if (f->availfid)
 			spc_close(f->availfid);
+		if (f->redirfid)
+			spc_close(f->redirfid);
 
 		if (f->fs && f->fs != masterfs)
 			spc_umount(f->fs);
@@ -1809,76 +1816,15 @@
 static void
 connopen(Spconn *conn)
 {
-	Client *c;
-	int n;
-
 	numconnects++;
 	debug(Dbgsrvfn, "Client %s connects %d\n", conn->address, numconnects);
-	n = strlen(conn->address) + 1;
-	c = sp_malloc(sizeof(Client) + n + sizeof(int) * (maxlevels - 1));
-	if (!c)
-		return;
-
-
-	c->caddress = (char *) c + sizeof(Client);
-	if (!c->caddress) {
-		free(c);
-		return;
-	}
-
-	memcpy(c->caddress, conn->address, n);
-	c->clevels = (int *) ((char *) c->caddress + n);
-	if (!c->clevels) {
-		free(c);
-		return;
-	}
-
-	memset(c->clevels, 0, sizeof(int) * (maxlevels - 1));
-	c->workersused = NULL;
-	c->prev = NULL;
-	c->next = clients;
-	if (clients)
-		clients->prev = c;
-
-	clients = c;
 }
 
 static void
 connclose(Spconn *conn)
 {
-	Client *c;
-	Usedworker *uw, *uw2;
-	
 	numconnects--;
-	debug(Dbgsrvfn, "Client %s disconnects %d\n", conn->address, numconnects);	
-
-	for (c = clients; c != NULL; c = c->next) {
-		if (!strcmp(c->caddress, conn->address))
-			break;
-	}
-
-	if (!c)
-		return;
-
-	for (uw = c->workersused; uw != NULL; ) {
-		if (uw->worker && uw->worker->server &&
-		    uw->worker->server->conns > 0)
-			uw->worker->server->conns--;
-		
-		uw2 = uw->next;
-		free(uw);
-		uw = uw2;
-	}
-
-	if (c->next)
-		c->next->prev = c->prev;
-	if (c->prev)
-		c->prev->next = c->next;
-	if (c == clients)
-		clients = c->next;
-
-	debug(Dbgsrvfn, "Removing client with address: %s\n", c->caddress);
-	free(c);
+	debug(Dbgsrvfn, "Client %s disconnects %d\n", conn->address, numconnects);
 }
 
 static int
@@ -1909,9 +1855,35 @@
 		}
 	}
 
-	if (!c) 
-		return -1;
+	if (!c) {
+		c = sp_malloc(sizeof(Client));
+		if (!c)
+			return -1;
+		
+		c->caddress = sp_malloc(strlen(fid->fid->conn->address) + 1);
+		if (!c->caddress) {
+			free(c);
+			return -1;
+		}
 
+		strcpy(c->caddress, fid->fid->conn->address);
+		c->clevels = sp_malloc(sizeof(int) * (maxlevels - 1));
+		if (!c->clevels) {
+			free(c->caddress);
+			free(c);
+			return -1;
+		}
+
+		memset(c->clevels, 0, sizeof(int) * (maxlevels - 1));
+		c->workersused = NULL;
+		c->prev = NULL;
+		c->next = clients;
+		if (clients)
+			clients->prev = c;
+		clients = c;
+		fid->aux = c;
+	}
+	
 	q = 1;
 	j = 0;
 	if (!f->nextworker) {
@@ -1925,7 +1897,7 @@
 				continue;
 			}
 
-			if (!t && w->server->conns < maxconnections) 
+			if (!t && w->slevel - 1 < m && w->server->conns < maxconnections) 
 					t = w;
 			else {
 				if (t) {
@@ -1993,6 +1965,40 @@
 	return count;
 }
 
+static void
+redir_closefid(Spfilefid *fid)
+{
+	Client *c;
+	Usedworker *uw, *uw2;
+		
+	c = fid->aux;
+
+	if (!c)
+		return;
+
+	for (uw = c->workersused; uw != NULL; ) {
+		if (uw->worker && uw->worker->server &&
+		    uw->worker->server->conns > 0)
+			uw->worker->server->conns--;
+		
+		uw2 = uw->next;
+		free(uw);
+		uw = uw2;
+	}
+
+	if (c->next)
+		c->next->prev = c->prev;
+	if (c->prev)
+		c->prev->next = c->next;
+	if (c == clients)
+		clients = c->next;
+
+	debug(Dbgsrvfn, "Removing client with address: %s\n", c->caddress);
+	free(c->caddress);
+	free(c->clevels);
+	free(c);
+}
+
 static int
 data_read(Spfilefid *fid, u64 offset, u32 count, u8 *buf, Spreq *r)
 {
Index: xget.h
===================================================================
--- xget.h	(revision 705)
+++ xget.h	(working copy)
@@ -38,6 +38,7 @@
 	Spcfsys*fs;
 	Spcfid*	datafid;	/* used while reading the file */
 	Spcfid*	availfid;
+	Spcfid* redirfid;
 	Spcfd*	datafd;
 
 	int	numworkers;
@@ -95,6 +96,7 @@
 static void	fsinit(void);
 static int	data_read(Spfilefid *fid, u64 offset, u32 count, u8 *data, Spreq *req);
 static int	redir_read(Spfilefid *fid, u64 offset, u32 count, u8 *data, Spreq *req);
+static void	redir_closefid(Spfilefid *fid);
 static int 	avail_write(Spfilefid *fid, u64 offset, u32 count, u8 *data, Spreq *req);
 static int	avail_wstat(Spfile* file, Spstat* stat);
 static void	avail_closefid(Spfilefid *fid);

Reply via email to