summaryrefslogtreecommitdiff
path: root/nfsd/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'nfsd/loop.c')
-rw-r--r--nfsd/loop.c293
1 files changed, 137 insertions, 156 deletions
diff --git a/nfsd/loop.c b/nfsd/loop.c
index 3520e1da..c7053234 100644
--- a/nfsd/loop.c
+++ b/nfsd/loop.c
@@ -36,7 +36,7 @@
#undef malloc
void
-server_loop ()
+server_loop (int fd)
{
char buf[MAXIOSIZE];
int xid;
@@ -53,181 +53,162 @@ server_loop ()
struct cache_handle *c, fakec;
error_t err;
size_t addrlen;
- fd_set readfds;
- int maxfd;
- int i;
int *errloc;
-
+ int cc;
+
bzero (&fakec, sizeof (struct cache_handle));
- if (main_udp_socket > pmap_udp_socket)
- maxfd = main_udp_socket;
- else
- maxfd = pmap_udp_socket;
-
for (;;)
{
- FD_ZERO (&readfds);
- FD_SET (main_udp_socket, &readfds);
- FD_SET (pmap_udp_socket, &readfds);
- select (maxfd, &readfds, 0, 0, 0);
-
- for (i = main_udp_socket;
- i != -1;
- i = (i == main_udp_socket ? pmap_udp_socket : -1))
- {
- if (!FD_ISSET (i, &readfds))
- continue;
-
- p = (int *) buf;
- proc = 0;
- addrlen = sizeof (struct sockaddr_in);
- recvfrom (i, buf, MAXIOSIZE, 0, &sender, &addrlen);
- xid = *p++;
-
- /* Ignore things that aren't proper RPCs. */
- if (ntohl (*p++) != CALL)
- continue;
-
- cr = check_cached_replies (xid, &sender);
- if (cr->data)
- /* This transacation has already completed */
- goto repost_reply;
+ p = (int *) buf;
+ proc = 0;
+ addrlen = sizeof (struct sockaddr_in);
+ cc = recvfrom (fd, buf, MAXIOSIZE, 0, &sender, &addrlen);
+ if (cc == -1)
+ continue; /* ignore errors */
+ xid = *p++;
- r = (int *) rbuf = malloc (MAXIOSIZE);
-
- if (ntohl (*p++) != RPC_MSG_VERSION)
- {
- /* Reject RPC */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_DENIED);
- *r++ = htonl (RPC_MISMATCH);
- *r++ = htonl (RPC_MSG_VERSION);
- *r++ = htonl (RPC_MSG_VERSION);
- goto send_reply;
- }
+ /* Ignore things that aren't proper RPCs. */
+ if (ntohl (*p++) != CALL)
+ continue;
- program = ntohl (*p++);
- switch (program)
- {
- case MOUNTPROG:
- version = MOUNTVERS;
- table = &mounttable;
- break;
-
- case NFS_PROGRAM:
- version = NFS_VERSION;
- table = &nfstable;
- break;
+ cr = check_cached_replies (xid, &sender);
+ if (cr->data)
+ /* This transacation has already completed */
+ goto repost_reply;
+
+ r = (int *) rbuf = malloc (MAXIOSIZE);
+
+ if (ntohl (*p++) != RPC_MSG_VERSION)
+ {
+ /* Reject RPC */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_DENIED);
+ *r++ = htonl (RPC_MISMATCH);
+ *r++ = htonl (RPC_MSG_VERSION);
+ *r++ = htonl (RPC_MSG_VERSION);
+ goto send_reply;
+ }
+
+ program = ntohl (*p++);
+ switch (program)
+ {
+ case MOUNTPROG:
+ version = MOUNTVERS;
+ table = &mounttable;
+ break;
- case PMAPPROG:
- version = PMAPVERS;
- table = &pmaptable;
- break;
+ case NFS_PROGRAM:
+ version = NFS_VERSION;
+ table = &nfstable;
+ break;
- default:
- /* Program unavailable */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_ACCEPTED);
- *r++ = htonl (AUTH_NULL);
- *r++ = htonl (0);
- *r++ = htonl (PROG_UNAVAIL);
- goto send_reply;
- }
+ case PMAPPROG:
+ version = PMAPVERS;
+ table = &pmaptable;
+ break;
- if (ntohl (*p++) != version)
- {
- /* Program mismatch */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_ACCEPTED);
- *r++ = htonl (AUTH_NULL);
- *r++ = htonl (0);
- *r++ = htonl (PROG_MISMATCH);
- *r++ = htonl (version);
- *r++ = htonl (version);
- goto send_reply;
- }
+ default:
+ /* Program unavailable */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_ACCEPTED);
+ *r++ = htonl (AUTH_NULL);
+ *r++ = htonl (0);
+ *r++ = htonl (PROG_UNAVAIL);
+ goto send_reply;
+ }
- procedure = htonl (*p++);
- if (procedure < table->min
- || procedure > table->max
- || table->procs[procedure - table->min].func == 0)
- {
- /* Procedure unavailable */
- *r++ = xid;
- *r++ = htonl (REPLY);
- *r++ = htonl (MSG_ACCEPTED);
- *r++ = htonl (AUTH_NULL);
- *r++ = htonl (0);
- *r++ = htonl (PROC_UNAVAIL);
- *r++ = htonl (table->min);
- *r++ = htonl (table->max);
- goto send_reply;
- }
- proc = &table->procs[procedure - table->min];
-
- p = process_cred (p, &cred); /* auth */
- p = skip_cred (p); /* verf */
+ if (ntohl (*p++) != version)
+ {
+ /* Program mismatch */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_ACCEPTED);
+ *r++ = htonl (AUTH_NULL);
+ *r++ = htonl (0);
+ *r++ = htonl (PROG_MISMATCH);
+ *r++ = htonl (version);
+ *r++ = htonl (version);
+ goto send_reply;
+ }
- if (proc->need_handle)
- p = lookup_cache_handle (p, &c, cred);
- else
- {
- fakec.ids = cred;
- c = &fakec;
- }
-
- if (proc->alloc_reply)
- {
- size_t amt;
- amt = (*proc->alloc_reply) (p) + 256;
- if (amt > MAXIOSIZE)
- {
- free (rbuf);
- r = (int *) rbuf = malloc (amt);
- }
- }
-
- /* Fill in beginning of reply */
+ procedure = htonl (*p++);
+ if (procedure < table->min
+ || procedure > table->max
+ || table->procs[procedure - table->min].func == 0)
+ {
+ /* Procedure unavailable */
*r++ = xid;
*r++ = htonl (REPLY);
*r++ = htonl (MSG_ACCEPTED);
*r++ = htonl (AUTH_NULL);
*r++ = htonl (0);
- *r++ = htonl (SUCCESS);
- if (proc->process_error)
- {
- /* Assume success for now and patch it later if necessary */
- errloc = r;
- *r++ = htonl (0);
- }
-
- if (c)
- err = (*proc->func) (c, p, &r);
- else
- err = ESTALE;
+ *r++ = htonl (PROC_UNAVAIL);
+ *r++ = htonl (table->min);
+ *r++ = htonl (table->max);
+ goto send_reply;
+ }
+ proc = &table->procs[procedure - table->min];
+
+ p = process_cred (p, &cred);
+
+ if (proc->need_handle)
+ p = lookup_cache_handle (p, &c, cred);
+ else
+ {
+ fakec.ids = cred;
+ c = &fakec;
+ }
- if (proc->process_error && err)
+ if (proc->alloc_reply)
+ {
+ size_t amt;
+ amt = (*proc->alloc_reply) (p, version) + 256;
+ if (amt > MAXIOSIZE)
{
- r = errloc;
- *r++ = htonl (nfs_error_trans (err));
+ free (rbuf);
+ r = (int *) rbuf = malloc (amt);
}
-
- cred_rele (cred);
- if (c != &fakec)
- cache_handle_rele (c);
-
- send_reply:
- cr->data = rbuf;
- cr->len = (char *)r - rbuf;
-
- repost_reply:
- sendto (i, cr->data, cr->len, 0,
- (struct sockaddr *)&sender, addrlen);
- release_cached_reply (cr);
}
+
+ /* Fill in beginning of reply */
+ *r++ = xid;
+ *r++ = htonl (REPLY);
+ *r++ = htonl (MSG_ACCEPTED);
+ *r++ = htonl (AUTH_NULL);
+ *r++ = htonl (0);
+ *r++ = htonl (SUCCESS);
+ if (proc->process_error)
+ {
+ /* Assume success for now and patch it later if necessary */
+ errloc = r;
+ *r++ = htonl (0);
+ }
+
+ if (c)
+ err = (*proc->func) (c, p, &r, version);
+ else
+ err = ESTALE;
+
+ if (proc->process_error && err)
+ {
+ r = errloc;
+ *r++ = htonl (nfs_error_trans (err));
+ }
+
+ cred_rele (cred);
+ if (c && c != &fakec)
+ cache_handle_rele (c);
+
+ send_reply:
+ cr->data = rbuf;
+ cr->len = (char *)r - rbuf;
+
+ repost_reply:
+ sendto (fd, cr->data, cr->len, 0,
+ (struct sockaddr *)&sender, addrlen);
+ release_cached_reply (cr);
}
}