patch-1.3.32 linux/fs/nfs/sock.c

Next file: linux/include/asm-alpha/apecs.h
Previous file: linux/fs/nfs/rpcsock.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.31/linux/fs/nfs/sock.c linux/fs/nfs/sock.c
@@ -31,6 +31,7 @@
 #include <linux/in.h>
 #include <linux/net.h>
 #include <linux/mm.h>
+#include <linux/rpcsock.h>
 
 /* JEJB/JSP 2/7/94
  * this must match the value of NFS_SLACK_SPACE in linux/fs/nfs/proc.c 
@@ -49,197 +50,64 @@
  * to the server socket.
  */
 
-static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end, int size)
+int
+nfs_rpc_call(struct nfs_server *server, int *start, int *end, int size)
 {
-	struct file *file;
-	struct inode *inode;
-	struct socket *sock;
-	unsigned short fs;
-	int result;
-	int xid;
-	int len;
-	select_table wait_table;
-	struct select_table_entry entry;
-	int (*select) (struct inode *, struct file *, int, select_table *);
-	int init_timeout, max_timeout;
-	int timeout;
-	int retrans;
-	int major_timeout_seen;
-	char *server_name;
-	int n;
-	int addrlen;
-	unsigned long old_mask;
-	/* JEJB/JSP 2/7/94
-	 * This is for a 4 byte recv of the xid only */
-	int recv_xid;
-
-	xid = start[0];
-	len = ((char *) end) - ((char *) start);
-	file = server->file;
-	inode = file->f_inode;
-	select = file->f_op->select;
-	sock = &inode->u.socket_i;
-	if (!sock) {
-		printk("nfs_rpc_call: socki_lookup failed\n");
-		return -EBADF;
-	}
-	init_timeout = server->timeo;
-	max_timeout = NFS_MAX_RPC_TIMEOUT*HZ/10;
-	retrans = server->retrans;
-	major_timeout_seen = 0;
-	server_name = server->hostname;
-	old_mask = current->blocked;
+	struct rpc_timeout	timeout;
+	unsigned long		maxtimeo;
+	unsigned long		oldmask;
+	int			major_timeout_seen, result;
+
+	timeout.init_timeout = server->timeo;
+	timeout.max_timeout = maxtimeo = NFS_MAX_RPC_TIMEOUT*HZ/10;
+	timeout.retries = server->retrans;
+	timeout.exponential = 1;
+
+	oldmask = current->blocked;
 	current->blocked |= ~(_S(SIGKILL)
-#if 0
-		| _S(SIGSTOP)
-#endif
 		| ((server->flags & NFS_MOUNT_INTR)
 		? ((current->sig->action[SIGINT - 1].sa_handler == SIG_DFL
 			? _S(SIGINT) : 0)
 		| (current->sig->action[SIGQUIT - 1].sa_handler == SIG_DFL
 			? _S(SIGQUIT) : 0))
 		: 0));
-	fs = get_fs();
-	set_fs(get_ds());
-	for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
-	  /* JSP 1995-07-01  Use sendto() not send() to cope with multi-homed hosts
-	     as we have set the socket to have INADDR_ANY as it's desination */
-		result = sock->ops->sendto(sock, (void *) start, len, 0, 0,
-					   &(server->toaddr), sizeof((server->toaddr))) ;
-		if (result < 0) {
-			printk("nfs_rpc_call: send error = %d\n", result);
-			break;
-		}
-	re_select:
-		wait_table.nr = 0;
-		wait_table.entry = &entry;
-		current->state = TASK_INTERRUPTIBLE;
-		if (!select(inode, file, SEL_IN, &wait_table)
-		    && !select(inode, file, SEL_IN, NULL)) {
-			if (timeout > max_timeout) {
-			  /* JEJB/JSP 2/7/94
-			   * This is useful to see if the system is
-			   * hanging */
-			  printk("NFS max timeout reached on %s\n",
-				 server_name);
-			  timeout = max_timeout;
-			}
-			current->timeout = jiffies + timeout;
-			schedule();
-			remove_wait_queue(entry.wait_address, &entry.wait);
-			current->state = TASK_RUNNING;
-			if (current->signal & ~current->blocked) {
-				current->timeout = 0;
-				result = -ERESTARTSYS;
+	major_timeout_seen = 0;
+
+	do {
+		result = rpc_call(server->rsock, 
+				&server->toaddr, sizeof(server->toaddr),
+				start, ((char *) end) - ((char *) start),
+				start, size + 1024,
+				&timeout, 1);
+		if (current->signal & ~current->blocked)
+			result = -ERESTARTSYS;
+		if (result == -ETIMEDOUT) {
+			if (server->flags & NFS_MOUNT_SOFT) {
+				printk("NFS server %s not responding, "
+					"still trying.\n", server->hostname);
+				result = -EIO;
 				break;
 			}
-			if (!current->timeout) {
-				if (n < retrans)
-					continue;
-				if (server->flags & NFS_MOUNT_SOFT) {
-					printk("NFS server %s not responding, "
-						"timed out\n", server_name);
-					result = -EIO;
-					break;
-				}
-				n = 0;
-				timeout = init_timeout;
-				init_timeout <<= 1;
-				if (!major_timeout_seen) {
-				  printk("NFS server %s not responding, "
-					 "still trying\n", server_name);
-				}
+			if (!major_timeout_seen) {
+				printk("NFS server %s not responding, "
+					"timed out.\n", server->hostname);
 				major_timeout_seen = 1;
-				continue;
-			}
-			else
-				current->timeout = 0;
-		}
-		else if (wait_table.nr)
-			remove_wait_queue(entry.wait_address, &entry.wait);
-		current->state = TASK_RUNNING;
-		addrlen = 0;
-		/* JEJB/JSP 2/7/94
-		 * Get the xid from the next packet using a peek, so keep it
-		 * on the recv queue.  If it is wrong, it will be some reply
-		 * we don't now need, so discard it */
-		result = sock->ops->recvfrom(sock, (void *)&recv_xid,
-					     sizeof(recv_xid), 1, MSG_PEEK,
-					     NULL, &addrlen);
-		if (result < 0) {
-			if (result == -EAGAIN) {
-#if 0
-				printk("nfs_rpc_call: bad select ready\n");
-#endif
-				goto re_select;
-			}
-			if (result == -ECONNREFUSED) {
-#if 0
-				printk("nfs_rpc_call: server playing coy\n");
-#endif
-				goto re_select;
-			}
-			if (result != -ERESTARTSYS) {
-				printk("nfs_rpc_call: recv error = %d\n",
-					-result);
 			}
-			break;
+			if ((timeout.init_timeout <<= 1) >= maxtimeo)
+				timeout.init_timeout = maxtimeo;
+		} else if (result < 0) {
+			printk("NFS: notice message: result = %d.\n", result);
 		}
-		if (recv_xid == xid) {
-			if (major_timeout_seen)
-				printk("NFS server %s OK\n", server_name);
-			break;
-		}
-		/* JEJB/JSP 2/7/94
-		 * we have xid mismatch, so discard the packet and start
-		 * again.  What a hack! but I can't call recvfrom with
-		 * a null buffer yet. */
-		(void)sock->ops->recvfrom(sock, (void *)&recv_xid,
-					  sizeof(recv_xid), 1, 0, NULL,
-					  &addrlen);
-#if 0
-		printk("nfs_rpc_call: XID mismatch\n");
-#endif
-		goto re_select;
-	}
-	/* JEJB/JSP 2/7/94
-	 *
-	 * we have the correct xid, so read into the correct place and
-	 * return it
-	 *
-	 */
-	result=sock->ops->recvfrom(sock, (void *)start, 
-				  size + 1024, 1, 0, NULL,
-			/* Here is NFS_SLACK_SPACE..., hack */
-				  &addrlen);
-	if (result < 0) {
-		printk("NFS: notice message: result=%d\n", result);
-	} else if (result < addrlen) {
-		printk("NFS: just caught a too small read memory size..., email to NET channel\n");
-		printk("NFS: result=%d,addrlen=%d\n", result, addrlen);
+	} while (result == -ETIMEDOUT && !(server->flags & NFS_MOUNT_SOFT));
+
+	if (result >= 0 && major_timeout_seen)
+		printk("NFS server %s OK.\n", server->hostname);
+	/* 20 is the minimum RPC reply header size */
+	if (result >= 0 && result < 20) {
+		printk("NFS: too small read memory size (%d bytes)\n", result);
 		result = -EIO;
 	}
-	current->blocked = old_mask;
-	set_fs(fs);
-	return result;
-}
 
-/*
- * For now we lock out other simultaneous nfs calls for the same filesystem
- * because we are single-threaded and don't want to get mismatched
- * RPC replies.
- */
-
-int nfs_rpc_call(struct nfs_server *server, int *start, int *end, int size)
-{
-	int result;
-
-	while (server->lock)
-		sleep_on(&server->wait);
-	server->lock = 1;
-	result = do_nfs_rpc_call(server, start, end, size);
-	server->lock = 0;
-	wake_up(&server->wait);
+	current->blocked = oldmask;
 	return result;
 }
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this