From 19d0f00234b0884a31c8bd4b806c6d512baae9be Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Wed, 7 Aug 1996 19:03:53 +0000 Subject: *** empty log message *** --- ChangeLog | 4 + Makefile | 2 +- TODO | 15 ++- libdiskfs/ChangeLog | 6 + libdiskfs/node-create.c | 12 +- nfsd/ChangeLog | 73 ++++++++++++ nfsd/cache.c | 93 ++++++++++----- nfsd/fsys.c | 42 +++++-- nfsd/loop.c | 293 ++++++++++++++++++++++-------------------------- nfsd/main.c | 37 ++++-- nfsd/nfsd.h | 10 +- nfsd/ops.c | 164 +++++++++++++++++---------- nfsd/proctables.c | 57 ---------- nfsd/xdr.c | 21 ++-- release/=announce-0.0 | 57 +++++----- release/checklist | 5 +- ufs/ChangeLog | 13 +++ ufs/inode.c | 122 ++++++++++++++++++++ 18 files changed, 650 insertions(+), 376 deletions(-) create mode 100644 nfsd/ChangeLog delete mode 100644 nfsd/proctables.c diff --git a/ChangeLog b/ChangeLog index 2e349f19..e4d8dfe4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Wed Aug 7 14:57:55 1996 Thomas Bushnell, n/BSG + + * Makefile (prog-subdirs): Add `nfsd'. + Tue Aug 6 12:20:37 1996 Thomas Bushnell, n/BSG * Released source version 0.0. diff --git a/Makefile b/Makefile index 3c953b7f..e35b9e50 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \ prog-subdirs = auth boot exec fstests init \ proc term ufs utils sutils trans ufs-fsck \ devio ufs-utils ext2fs benchmarks pflocal defpager \ - login nfs pfinet daemons + login nfs pfinet daemons nfsd other-subdirs = hurd doc config release include subdirs = $(lib-subdirs) $(prog-subdirs) $(other-subdirs) subdirs-nodist = diff --git a/TODO b/TODO index 3d146107..288bccbf 100644 --- a/TODO +++ b/TODO @@ -139,11 +139,16 @@ See `tasks', the exported task list. *** Allow multiple pfinets to arp on the same ethernet interface for different IP addresses. *** Register a shutdown notification to close TCP channels. +*** select for read on a UDP socket seems never to return. ** nfs *** Implement async I/O *** Finish work to turn on paging. *** Finish excl arg work in link and rename. +*** Implement TCP nfs. +*** Implement V3 nfs. +*** Implement nqnfs. +*** Add Hurd-specific calls. ** devio: *** Make a server (/servers/devio?) to share multiple devio nodes? @@ -172,6 +177,7 @@ See `tasks', the exported task list. *** Try to write directories with 512-byte record boundaries. *** Maybe file_pager_write_page should be able to accurately reproduce holes... *** Add byte-swapping. +*** Implement file_getfh and fsys_getfile. ** crash *** Write core files. @@ -211,14 +217,15 @@ See `tasks', the exported task list. internal thread list. *** read core files -** nfsd -- fix remaining bugs -*** Add necessary support to filesystems +** nfsd +*** Implement TCP nfs. +*** Implement V3 nfs. +*** Implement nqnfs. +*** Add Hurd-specific calls. ** fsck.ufs -- zero-length directories and attachment into lost+found still don't work. - - * Mach: ** Have some analogue of /dev/klog that syslogd can get kernel messages from (maybe there is already?); the boot file system, and other people deeming diff --git a/libdiskfs/ChangeLog b/libdiskfs/ChangeLog index 6d0fa719..531ad50b 100644 --- a/libdiskfs/ChangeLog +++ b/libdiskfs/ChangeLog @@ -1,3 +1,9 @@ +Wed Aug 7 13:53:56 1996 Thomas Bushnell, n/BSG + + * node-create.c (diskfs_create_node): New files always copy GID + from their parent; that's NetBSD's behavior, and it's good enough + for me. + Thu Aug 1 17:24:08 1996 Thomas Bushnell, n/BSG * file-get-transcntl.c (diskfs_S_file_get_translator_cntl): Don't diff --git a/libdiskfs/node-create.c b/libdiskfs/node-create.c index 3f8dc4c1..11f5b0fe 100644 --- a/libdiskfs/node-create.c +++ b/libdiskfs/node-create.c @@ -64,15 +64,9 @@ diskfs_create_node (struct node *dir, goto change_err; np->dn_stat.st_uid = newuid; - if (diskfs_groupmember (dir->dn_stat.st_gid, cred)) - newgid = dir->dn_stat.st_gid; - else if (cred->ngids) - newgid = cred->gids[0]; - else - { - newgid = dir->dn_stat.st_gid; - mode &= ~S_ISGID; - } + newgid = dir->dn_stat.st_gid; + if (!diskfs_groupmember (newgid, cred)) + mode &= ~S_ISGID; err = diskfs_validate_group_change (np, newgid); if (err) goto change_err; diff --git a/nfsd/ChangeLog b/nfsd/ChangeLog new file mode 100644 index 00000000..977a77de --- /dev/null +++ b/nfsd/ChangeLog @@ -0,0 +1,73 @@ +Wed Aug 7 11:39:31 1996 Thomas Bushnell, n/BSG + + * ops.c (op_null, op_getattr, op_setattr, op_lookup, op_readlink, + count_read_buffersize, op_read, op_write, op_create, op_remove, + op_rename, op_link, op_symlink, op_mkdir, op_rmdir, + count_readdir_buffersize, op_statfs, op_mnt, op_getport): Add new + parm `version'. + * loop.c (server_loop): Supply VERSION to PROC->alloc_reply and + PROC->func. + * nfsd.h (struct procedure): Add new parm to `func' and + `alloc_reply' members to specify protocol version. + + * ops.c (mounttable): Use op_null for MOUNTPROC_UMNT and + MOUNTPROC_UMNTALL. + + * ops.c (op_create): Ignore most of setattr structure given. + (op_mkdir): Likewise. + (complete_setattr): Clean up and be less active when possible. + + * ops.c (op_readdir): Correctly end list of directory entries. + + * nfsd.h (authserver): New variable. +n * main.c: Include . + (main): Initialize AUTHSERVER. + * cache.c: Include and . + (create_cached_handle): Reauthenticate port before calling + file_getfh. + + * fsys.c (init_filesystems): When setting NFSYS, it needs to be at + least as big as INDEX + 1, and install the control port into the + correct slot. + (init_filesystems): When allocating or reallocating FSYSTABLE, + make sure the new entries are zeroed. + (enter_filesystem): Likewise. + +Tue Aug 6 13:18:40 1996 Thomas Bushnell, n/BSG + + * cache.c (create_cached_handle): Always call fsys_getfile when + creating a new cached handle instead of relying upon the passed in + port. + + * xdr.c (hurd_mode_to_nfs_mode): Specify octal number in octal + notation. + (encode_fattr): Bother filling in all the fields. + + * loop.c (server_loop): Don't attempt to call cache_handle_rele if + C is null. + + * cache.c (fh_hash): Mod-ulize HASH before returning it. + + * cache.c (process_cred): Arrange to skip VERF field for + non-AUTH_UNIX creds too. + + * loop.c (server_loop): Don't call skip_cred for the VERF here; + process_cred does it for us. + * xdr.c (skip_cred): Delete function. + * nfsd.h (skip_cred): Delete decl. + + * cache.c (process_cred): After processing gid list, set P after + it. Start gid processing loop at 0. + + * main.c (main): Detach one thread for pmap_udp_socket, + and NTHREADS threads for main_udp_socket. + * loop.c (server_loop): New parm `fd'; don't do select. + Ignore errors that we get from recvfrom instead of processing the + last message again. + + * nfsd.h (server_loop): New parm. + + * main.c (main): Stringify LOCALSTATEDIR; but for now just pound + in /var. Call asprintf correctly. + + diff --git a/nfsd/cache.c b/nfsd/cache.c index 745a7c8e..8b1ee134 100644 --- a/nfsd/cache.c +++ b/nfsd/cache.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "nfsd.h" @@ -136,35 +138,40 @@ process_cred (int *p, struct idspec **credp) { int size = ntohl (*p++); *credp = idspec_lookup (0, 0, 0, 0); - return p + INTSIZE (size); + p += INTSIZE (size); + } + else + { + p++; /* skip size */ + p++; /* skip seconds */ + len = ntohl (*p++); + p += INTSIZE (len); /* skip hostname */ + + uid = p++; /* remember loc of uid */ + *uid = ntohl (*uid); + + firstgid = *p++; /* remember first gid */ + gids = p; /* here's where the array will start */ + ngids = ntohl (*p++); + + /* Now swap the first gid to be the first element of the array */ + *gids = firstgid; + ngids++; /* and count it */ + + /* And byteswap the gids */ + for (i = 0; i < ngids; i++) + gids[i] = ntohl (gids[i]); + + p += ngids - 1; + + *credp = idspec_lookup (1, ngids, uid, gids); } - - p++; /* skip size */ - p++; /* skip seconds */ - len = ntohl (*p++); - p += INTSIZE (len); /* skip hostname */ - - uid = p++; /* remember loc of uid */ - *uid = ntohl (*uid); - - firstgid = *p++; /* remember first gid */ - gids = p; /* here's where the array will start */ - ngids = ntohl (*p++); - - /* Now swap the first gid to be the first element of the array */ - *gids = firstgid; - ngids++; /* and count it */ - - /* And byteswap the gids */ - for (i = 1; i < ngids; i++) - gids[i] = ntohl (gids[i]); /* Next is the verf field; skip it entirely */ p++; /* skip id */ len = htonl (*p++); p += INTSIZE (len); - *credp = idspec_lookup (1, ngids, uid, gids); return p; } @@ -239,7 +246,7 @@ fh_hash (char *fhandle, struct idspec *i) for (n = 0; n < NFS_FHSIZE; n++) hash += fhandle[n]; hash += (int) i >> 6; - return hash; + return hash % FHHASH_TABLE_SIZE; } int * @@ -342,7 +349,7 @@ scan_fhs () } struct cache_handle * -create_cached_handle (int fs, struct cache_handle *credc, file_t newport) +create_cached_handle (int fs, struct cache_handle *credc, file_t userport) { char fhandle[NFS_FHSIZE]; error_t err; @@ -350,20 +357,35 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t newport) int hash; char *bp = fhandle + sizeof (int); size_t handlelen = NFS_FHSIZE - sizeof (int); + mach_port_t newport, ref; + /* Authenticate USERPORT so that we can call file_getfh on it. */ + ref = mach_reply_port (); + if (io_reauthenticate (userport, ref, MACH_MSG_TYPE_MAKE_SEND) + || auth_user_authenticate (authserver, ref, MACH_MSG_TYPE_MAKE_SEND, + &newport)) + { + /* Reauthentication has failed, but maybe the filesystem will let + us call file_getfh anyway. */ + newport = userport; + } + else + mach_port_deallocate (mach_task_self (), userport); + mach_port_destroy (mach_task_self (), ref); + + /* Fetch the file handle */ *(int *)fhandle = fs; err = file_getfh (newport, &bp, &handlelen); + mach_port_deallocate (mach_task_self (), newport); if (err || handlelen != NFS_FHSIZE - sizeof (int)) - { - mach_port_deallocate (mach_task_self (), newport); - return 0; - } + return 0; if (bp != fhandle + sizeof (int)) { bcopy (bp, fhandle + sizeof (int), NFS_FHSIZE - sizeof (int)); vm_deallocate (mach_task_self (), (vm_address_t) bp, handlelen); } + /* Cache it */ hash = fh_hash (fhandle, credc->ids); mutex_lock (&fhhashlock); for (c = fhhashtable[hash]; c; c = c->next) @@ -374,9 +396,22 @@ create_cached_handle (int fs, struct cache_handle *credc, file_t newport) nfreefh--; c->references++; mutex_unlock (&fhhashlock); - mach_port_deallocate (mach_task_self (), newport); return c; } + + /* Always call fsys_getfile so that we don't depend on the + particular open modes of the port passed in. */ + + err = fsys_getfile (lookup_filesystem (fs), + credc->ids->uids, credc->ids->nuids, + credc->ids->gids, credc->ids->ngids, + fhandle + sizeof (int), NFS_FHSIZE - sizeof (int), + &newport); + if (err) + { + mutex_unlock (&fhhashlock); + return 0; + } /* Create it anew */ c = malloc (sizeof (struct cache_handle)); diff --git a/nfsd/fsys.c b/nfsd/fsys.c index d3c50220..97137455 100644 --- a/nfsd/fsys.c +++ b/nfsd/fsys.c @@ -49,10 +49,16 @@ init_filesystems (void) int line; file_t root; static FILE *index_file; + int i; fsystable = (struct fsys_spec *) malloc ((fsystablesize = 10) * sizeof (struct fsys_spec)); - + for (i = 0; i < fsystablesize; i++) + { + fsystable[i].fsys = MACH_PORT_NULL; + fsystable[i].name = 0; + } + if (!index_file_name) return; @@ -91,14 +97,22 @@ init_filesystems (void) } if (index >= fsystablesize) - fsystable = (struct fsys_spec *) realloc (fsystable, - (fsystablesize = index * 2) - * sizeof (struct fsys_spec)); - if (index > nfsys) - nfsys = index; + { + fsystable = (struct fsys_spec *) + realloc (fsystable, index * 2 * sizeof (struct fsys_spec)); + for (i = fsystablesize; i < index * 2; i++) + { + fsystable[i].fsys = MACH_PORT_NULL; + fsystable[i].name = 0; + } + fsystablesize = index * 2; + } + + if (index + 1 > nfsys) + nfsys = index + 1; fsystable[index].name = name; - file_getcontrol (root, &fsystable[nfsys].fsys); + file_getcontrol (root, &fsystable[index].fsys); mach_port_deallocate (mach_task_self (), root); } } @@ -176,9 +190,17 @@ enter_filesystem (char *name, file_t root) return i; if (nfsys == fsystablesize) - fsystable = (struct fsys_spec *) realloc (fsystable, - (fsystablesize *= 2) - * sizeof (struct fsys_spec)); + { + fsystable = (struct fsys_spec *) realloc (fsystable, + (fsystablesize * 2) + * sizeof (struct fsys_spec)); + for (i = fsystablesize; i < fsystablesize * 2; i++) + { + fsystable[i].fsys = MACH_PORT_NULL; + fsystable[i].name = 0; + } + fsystablesize *= 2; + } fsystable[nfsys].name = malloc (strlen (name) + 1); strcpy (fsystable[nfsys].name, name); 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); } } diff --git a/nfsd/main.c b/nfsd/main.c index 69099361..4dcd816f 100644 --- a/nfsd/main.c +++ b/nfsd/main.c @@ -23,16 +23,24 @@ #include #include #include +#include int main_udp_socket, pmap_udp_socket; struct sockaddr_in main_address, pmap_address; char *index_file_name; +#ifdef makefiles_not_broken +#define STATEDIR # LOCALSTATEDIR +#else +#define STATEDIR "/var" +#endif + int main (int argc, char **argv) { int nthreads; - + int fail; + if (argc > 2) { fprintf (stderr, "%s [num-threads]\n", argv[0]); @@ -45,8 +53,9 @@ main (int argc, char **argv) if (!nthreads) nthreads = 4; - index_file_name = asprintf ("%s/state/misc/nfsd.index", LOCALSTATEDIR); + asprintf (&index_file_name, "%s/state/misc/nfsd.index", STATEDIR); + authserver = getauth (); maptime_map (0, 0, &mapped_time); main_address.sin_family = AF_INET; @@ -58,15 +67,29 @@ main (int argc, char **argv) main_udp_socket = socket (PF_INET, SOCK_DGRAM, 0); pmap_udp_socket = socket (PF_INET, SOCK_DGRAM, 0); - bind (main_udp_socket, (struct sockaddr *)&main_address, - sizeof (struct sockaddr_in)); - bind (pmap_udp_socket, (struct sockaddr *)&pmap_address, - sizeof (struct sockaddr_in)); + fail = bind (main_udp_socket, (struct sockaddr *)&main_address, + sizeof (struct sockaddr_in)); + if (fail) + { + perror ("Binding NFS socket"); + exit (1); + } + fail = bind (pmap_udp_socket, (struct sockaddr *)&pmap_address, + sizeof (struct sockaddr_in)); + if (fail) + { + perror ("Binding PMAP socket"); + exit (1); + } init_filesystems (); + cthread_detach (cthread_fork ((cthread_fn_t) server_loop, + pmap_udp_socket)); + while (nthreads--) - cthread_detach (cthread_fork ((cthread_fn_t) server_loop, 0)); + cthread_detach (cthread_fork ((cthread_fn_t) server_loop, + main_udp_socket)); for (;;) { diff --git a/nfsd/nfsd.h b/nfsd/nfsd.h index 7b6f530d..0ea93703 100644 --- a/nfsd/nfsd.h +++ b/nfsd/nfsd.h @@ -67,8 +67,8 @@ struct cached_reply struct procedure { - error_t (*func) (struct cache_handle *, int *, int **); - size_t (*alloc_reply) (int *); + error_t (*func) (struct cache_handle *, int *, int **, int); + size_t (*alloc_reply) (int *, int); int need_handle; int process_error; }; @@ -92,6 +92,9 @@ extern struct sockaddr_in main_address, pmap_address; /* Name of the file on disk containing the filesystem index table */ extern char *index_file_name; +/* Our auth server */ +auth_t authserver; + /* cache.c */ int *process_cred (int *, struct idspec **); @@ -107,13 +110,12 @@ void release_cached_reply (struct cached_reply *cr); void scan_replies (void); /* loop.c */ -void server_loop (void); +void server_loop (int); /* ops.c */ extern struct proctable nfstable, mounttable, pmaptable; /* xdr.c */ -int *skip_cred (int *); int nfs_error_trans (error_t); int *encode_fattr (int *, struct stat *); int *decode_name (int *, char **); diff --git a/nfsd/ops.c b/nfsd/ops.c index 93c8373c..cbcfb409 100644 --- a/nfsd/ops.c +++ b/nfsd/ops.c @@ -32,7 +32,8 @@ static error_t op_null (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { return 0; } @@ -40,7 +41,8 @@ op_null (struct cache_handle *c, static error_t op_getattr (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { struct stat st; error_t err; @@ -67,17 +69,14 @@ complete_setattr (mach_port_t port, uid = ntohl (*p++); gid = ntohl (*p++); - if ((uid != -1 && uid != st.st_uid) - || (gid != -1 && gid != st.st_gid)) - { - if (uid == -1) - uid = st.st_uid; - if (gid == -1) - gid = st.st_gid; - err = file_chown (port, uid, gid); - if (err) - return err; - } + if (uid == -1) + uid = st.st_uid; + if (gid == -1) + gid = st.st_gid; + if (uid != st.st_uid || gid != st.st_gid) + err = file_chown (port, uid, gid); + if (err) + return err; size = ntohl (*p++); if (size != -1 && size != st.st_size) @@ -89,33 +88,35 @@ complete_setattr (mach_port_t port, atime.microseconds = ntohl (*p++); mtime.seconds = ntohl (*p++); mtime.microseconds = ntohl (*p++); + if (atime.seconds != -1 && atime.microseconds == -1) atime.microseconds = 0; if (mtime.seconds != -1 && mtime.microseconds == -1) mtime.microseconds = 0; - if (atime.seconds != -1 || mtime.seconds != -1 - || atime.microseconds != -1 || mtime.microseconds != -1) - { - if (atime.seconds == -1) - atime.seconds = st.st_atime; - if (atime.microseconds == -1) - atime.microseconds = st.st_atime_usec; - if (mtime.seconds == -1) - mtime.seconds = st.st_mtime; - if (mtime.microseconds == -1) - mtime.microseconds = st.st_mtime_usec; - err = file_utimes (port, atime, mtime); - if (err) - return err; - } - - return 0; + + if (atime.seconds == -1) + atime.seconds = st.st_atime; + if (atime.microseconds == -1) + atime.microseconds = st.st_atime_usec; + if (mtime.seconds == -1) + mtime.seconds = st.st_mtime; + if (mtime.microseconds == -1) + mtime.microseconds = st.st_mtime_usec; + + if (atime.seconds != st.st_atime + || atime.microseconds != st.st_atime_usec + || mtime.seconds != st.st_mtime + || mtime.microseconds != st.st_mtime_usec) + err = file_utimes (port, atime, mtime); + + return err; } static error_t op_setattr (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { error_t err = 0; mode_t mode; @@ -132,7 +133,8 @@ op_setattr (struct cache_handle *c, static error_t op_lookup (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { error_t err; char *name; @@ -171,7 +173,8 @@ op_lookup (struct cache_handle *c, static error_t op_readlink (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { char buf[2048], *transp = buf; mach_msg_type_number_t len = sizeof (buf); @@ -193,7 +196,7 @@ op_readlink (struct cache_handle *c, } static size_t -count_read_buffersize (int *p) +count_read_buffersize (int *p, int version) { return ntohl (*++p); /* skip OFFSET, return COUNT */ } @@ -201,7 +204,8 @@ count_read_buffersize (int *p) static error_t op_read (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { off_t offset; size_t count; @@ -229,7 +233,8 @@ op_read (struct cache_handle *c, static error_t op_write (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { off_t offset; size_t count; @@ -268,7 +273,8 @@ op_write (struct cache_handle *c, static error_t op_create (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { error_t err; char *name; @@ -278,6 +284,8 @@ op_create (struct cache_handle *c, struct cache_handle *newc; struct stat st; mode_t mode; + int statchanged = 0; + off_t size; p = decode_name (p, &name); mode = ntohl (*p++); @@ -292,12 +300,33 @@ op_create (struct cache_handle *c, if (err) return err; - err = complete_setattr (newport, p); if (!err) err = io_stat (newport, &st); + if (err) + goto errout; + + /* NetBSD ignores most of the setattr fields given; that's good enough + for me too. */ + + p++, p++; /* skip uid and gid */ + + size = ntohl (*p++); + if (size != -1 && size != st.st_size) + { + err = file_set_size (newport, size); + statchanged = 1; + } + if (err) + goto errout; + + /* ignore times */ + + if (statchanged) + err = io_stat (newport, &st); if (err) { + errout: dir_unlink (c->port, name); free (name); return err; @@ -316,7 +345,8 @@ op_create (struct cache_handle *c, static error_t op_remove (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { error_t err; char *name; @@ -332,7 +362,8 @@ op_remove (struct cache_handle *c, static error_t op_rename (struct cache_handle *fromc, int *p, - int **reply) + int **reply, + int version) { struct cache_handle *toc; char *fromname, *toname; @@ -354,7 +385,8 @@ op_rename (struct cache_handle *fromc, static error_t op_link (struct cache_handle *filec, int *p, - int **reply) + int **reply, + int version) { struct cache_handle *dirc; char *name; @@ -375,7 +407,8 @@ op_link (struct cache_handle *filec, static error_t op_symlink (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { char *name, *target; error_t err; @@ -416,7 +449,8 @@ op_symlink (struct cache_handle *c, static error_t op_mkdir (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { char *name; mode_t mode; @@ -448,7 +482,8 @@ op_mkdir (struct cache_handle *c, if (err) return err; - err = complete_setattr (newport, p); + /* Ignore the rest of the sattr structure */ + if (!err) err = io_stat (newport, &st); if (err) @@ -465,7 +500,8 @@ op_mkdir (struct cache_handle *c, static error_t op_rmdir (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { char *name; error_t err; @@ -480,7 +516,8 @@ op_rmdir (struct cache_handle *c, static error_t op_readdir (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { int cookie; unsigned count; @@ -491,6 +528,7 @@ op_readdir (struct cache_handle *c, int nentries; int i; int *replystart; + int *r; cookie = ntohl (*p++); count = ntohl (*p++); @@ -501,10 +539,12 @@ op_readdir (struct cache_handle *c, if (err) return err; + r = *reply; + if (nentries == 0) { - *(*reply)++ = htonl (0); /* no entry */ - *(*reply)++ = htonl (1); /* EOF */ + *r++ = htonl (0); /* no entry */ + *r++ = htonl (1); /* EOF */ } else { @@ -514,19 +554,22 @@ op_readdir (struct cache_handle *c, && (char *)reply < (char *)replystart + count); i++, dp = (struct dirent *) ((char *)dp + dp->d_reclen)) { - *(*reply)++ = htonl (1); /* entry present */ - *(*reply)++ = htonl (dp->d_ino); - *reply = encode_string (*reply, dp->d_name); - *(*reply)++ = htonl (i + cookie + 1); /* next entry */ + *r++ = htonl (1); /* entry present */ + *r++ = htonl (dp->d_ino); + r = encode_string (r, dp->d_name); + *r++ = htonl (i + cookie + 1); /* next entry */ } - *(*reply)++ = htonl (0); /* not EOF */ + *r++ = htonl (0); /* no more entries */ + *r++ = htonl (0); /* not EOF */ } + *reply = r; + return 0; } static size_t -count_readdir_buffersize (int *p) +count_readdir_buffersize (int *p, int version) { return ntohl (*++p); /* skip COOKIE; return COUNT */ } @@ -534,7 +577,8 @@ count_readdir_buffersize (int *p) static error_t op_statfs (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { struct statfs st; error_t err; @@ -548,7 +592,8 @@ op_statfs (struct cache_handle *c, static error_t op_mnt (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { file_t root; struct cache_handle *newc; @@ -574,7 +619,8 @@ op_mnt (struct cache_handle *c, static error_t op_getport (struct cache_handle *c, int *p, - int **reply) + int **reply, + int version) { int prog, vers, prot; @@ -631,8 +677,8 @@ struct proctable mounttable = { op_null, 0, 0, 0}, { op_mnt, 0, 0, 1}, { 0, 0, 0, 0}, /* MOUNTPROC_DUMP */ - { 0, 0, 0, 0}, /* MOUNTPROC_UMNT */ - { 0, 0, 0, 0}, /* MOUNTPROC_UMNTALL */ + { op_null, 0, 0, 0}, /* MOUNTPROC_UMNT */ + { op_null, 0, 0, 0}, /* MOUNTPROC_UMNTALL */ { 0, 0, 0, 0}, /* MOUNTPROC_EXPORT */ } }; diff --git a/nfsd/proctables.c b/nfsd/proctables.c deleted file mode 100644 index 1bc76a38..00000000 --- a/nfsd/proctables.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 1996 Free Software Foundation, Inc. - Written by Michael I. Bushnell, p/BSG. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ - - -struct proctable nfstable = -{ - NFSPROC_NULL, /* first proc */ - NFSPROC_STATFS, /* last proc */ - { op_null, 0, 0}, - { op_getattr, 0, 1}, - { op_setattr, 0, 1}, - { 0, 0, 0 }, /* deprecated NFSPROC_ROOT */ - { op_lookup, 0, 1}, - { op_readlink, 0, 1}, - { op_read, count_read_buffersize, 1}, - { 0, 0, 0 }, /* nonexistent NFSPROC_WRITECACHE */ - { op_write, 0, 1}, - { op_create, 0, 1}, - { op_remove, 0, 1}, - { op_rename, 0, 1}, - { op_link, 0, 1}, - { op_symlink, 0, 1}, - { op_mkdir, 0, 1}, - { op_rmdir, 0, 1}, - { op_readdir, count_readdir_buffersize, 1}, - { op_statfs, 0, 1}, -}; - - -struct proctable mounttable = -{ - MOUNTPROC_NULL, /* first proc */ - MOUNTPROC_EXPORT, /* last proc */ - { op_null, 0, 0}, - { op_mnt, 0, 0}, - { 0, 0, 0}, /* MOUNTPROC_DUMP */ - { 0, 0, 0}, /* MOUNTPROC_UMNT */ - { 0, 0, 0}, /* MOUNTPROC_UMNTALL */ - { 0, 0, 0}, /* MOUNTPROC_EXPORT */ -}; diff --git a/nfsd/xdr.c b/nfsd/xdr.c index d5bea0bd..5b13b2a5 100644 --- a/nfsd/xdr.c +++ b/nfsd/xdr.c @@ -23,22 +23,11 @@ #include #include "nfsd.h" -/* Return the address of the next thing after the credential at P. */ -int * -skip_cred (int *p) -{ - int size; - - p++; /* TYPE */ - size = ntohl (*p++); - return p + INTSIZE (size); -} - /* Any better ideas? */ static int hurd_mode_to_nfs_mode (mode_t m) { - return m & 0x177777; + return m & 0177777; } static int @@ -85,6 +74,14 @@ encode_fattr (int *p, struct stat *st) *p++ = htonl (st->st_blksize); *p++ = htonl (st->st_rdev); *p++ = htonl (st->st_blocks); + *p++ = htonl (st->st_fsid); + *p++ = htonl (st->st_ino); + *p++ = htonl (st->st_atime); + *p++ = htonl (st->st_atime_usec); + *p++ = htonl (st->st_mtime); + *p++ = htonl (st->st_mtime_usec); + *p++ = htonl (st->st_ctime); + *p++ = htonl (st->st_ctime_usec); return p; } diff --git a/release/=announce-0.0 b/release/=announce-0.0 index 08d610ac..7aa1fa9f 100644 --- a/release/=announce-0.0 +++ b/release/=announce-0.0 @@ -6,17 +6,23 @@ anonymous FTP from prep.ai.mit.edu [18.159.0.42] in the file This file contains complete source code for the following: -Hurd servers: auth, crash, devio, devport, exec, ext2fs, fifo, fwd, -ifsock, init, magic, new-fifo, nfs, null, pfinet, pflocal, proc, -symlink, term, ufs. +Hurd servers: + + auth, crash, devio, devport, exec, ext2fs, fifo, fwd, ifsock, init, + magic, new-fifo, nfs, null, pfinet, pflocal, proc, symlink, term, + ufs. -Hurd libraries: diskfs, fshelp, ihash, iohelp, netfs, pager, pipe, -ports, ps, shouldbeinlibc, store, threads, trivfs. +Hurd libraries: + + diskfs, fshelp, ihash, iohelp, netfs, pager, pipe, ports, ps, + shouldbeinlibc, store, threads, trivfs. -Hurd utilities, etc: boot, shd, ps, settrans, showtrans, sync, su, -mount, fsysopts, storeinfo, login, w, uptime, hurdids, loginpr, sush, -vmstat, portinfo, devprobe, reboot, halt, fsck, fsck.ufs, mkfs.ufs, -clri.ufs, stati.ufs, getty, rc. +Hurd utilities and other programs: + + boot, shd, ps, settrans, showtrans, sync, su, mount, fsysopts, + storeinfo, login, w, uptime, hurdids, loginpr, sush, vmstat, + portinfo, devprobe, reboot, halt, fsck, fsck.ufs, mkfs.ufs, clri.ufs, + stati.ufs, getty, rc. ------ @@ -46,12 +52,12 @@ This release may be fetched by anonymous FTP from prep.ai.mit.edu In that directory, you should find the following files: -README -SOURCES -INSTALL-binary -grub-boot.image (about 1.4 MB, not compressed) -gnu-0.0.tar.gz (about 56.9 MB compressed) -gnu-0.0-stripped.tar.gz (about 26.2 MB compressed) + README + SOURCES + INSTALL-binary + grub-boot.image (about 1.4 MB, not compressed) + gnu-0.0.tar.gz (about 56.9 MB compressed) + gnu-0.0-stripped.tar.gz (about 26.2 MB compressed) SOURCES contains a complete list describing the sources for the binaries found in the image. INSTALL-binary contains complete @@ -78,13 +84,13 @@ in order to complete part of the installation instructions. The following free software packages are found in this release: -autoconf, automake, bash, bc, binutils, bison, cpio, cvs, diffutils, -doschk, e2fsprogs, ed, emacs, fileutils, findutils, flex, from, gawk, -gcal, gcc, gdb, gdbm, gettext, glibc, gmp, gperf, grep, grub, gzip, -hello, hurd, indent, inetutils, less, mach, make, m4, miscfiles, -ncurses, nethack, nvi, patch, ptx, rcs, readline, recode, sed, -serverboot, sharutils, shellutils, tar, termcap, termutils, texinfo, -textutils, time, wdiff. + autoconf, automake, bash, bc, binutils, bison, cpio, cvs, diffutils, + doschk, e2fsprogs, ed, emacs, fileutils, findutils, flex, from, gawk, + gcal, gcc, gdb, gdbm, gettext, glibc, gmp, gperf, grep, grub, gzip, + hello, hurd, indent, inetutils, less, mach, make, m4, miscfiles, + ncurses, nethack, nvi, patch, ptx, rcs, readline, recode, sed, + serverboot, sharutils, shellutils, tar, termcap, termutils, texinfo, + textutils, time, wdiff. ------ @@ -95,11 +101,10 @@ Here are md5sum checksums for the files mentioned in this message: b5f888bab3eb193fe97a00a141324c9d INSTALL-binary 345dcd826747d7b11fc78f4db162d75b README 1a5744bb4ed3448045fa6d24153d65fe SOURCES - - - +f7b1bc428bc4ee29977a5b28f5762092 gnu-0.0-stripped.tar.gz +24554c58e5c89f295176e17d21dbae8e gnu-0.0.tar.gz 8338c619d860b71bc4128c9c0fd39d63 grub-boot.image - +1fd18ccc4c81d051b83d28b13dc07ee2 hurd-0.0.tar.gz ----- diff --git a/release/checklist b/release/checklist index 2f5c7e7c..13c31f65 100644 --- a/release/checklist +++ b/release/checklist @@ -9,13 +9,14 @@ Checklist for Hurd releases. * Make sure there is only a stubby resolv.conf in the distribution. * Make sure /etc/fstab has no active members * Make sure nethack is clean -o Source code for Hurd and libc must be released. +* Source code for Hurd and libc must be released. * Make sure everything listed in SOURCES is on prep. * Remove .stamp files from binary tree. * Chown everything root.wheel, mode 755/644. +* /tmp is 1777. * Chown /games games.games. * Check permissions on set[gu]id files in binary tree. (login, ps, w, vmstat, rsh, rlogin, games/lib/nethack/nethack) * Check each directory for bogus cruft files. * Especially delete .bash_history, .gnunfs*, and .stamp files. -o Verify installation on bare machine. +* Verify installation on bare machine. diff --git a/ufs/ChangeLog b/ufs/ChangeLog index 2ccd6c11..c541523e 100644 --- a/ufs/ChangeLog +++ b/ufs/ChangeLog @@ -1,3 +1,16 @@ +Wed Aug 7 13:00:30 1996 Thomas Bushnell, n/BSG + + * inode.c (struct ufs_fhandle): Layout filehandle more like Unixy + NFSD. + (diskfs_S_file_getfh): Bother to clear unused parts of a + file handle so that they always compare equal. + +Tue Aug 6 12:19:38 1996 Thomas Bushnell, n/BSG + + * inode.c: Include . + (struct ufs_fhandle): New type. + (diskfs_S_fsys_getfile, diskfs_S_file_getfh): New functions. + Tue Jul 23 15:58:28 1996 Miles Bader * inode.c (write_node, read_disknode): `struct timespec' now uses diff --git a/ufs/inode.c b/ufs/inode.c index 640e6b6f..27f7c3bb 100644 --- a/ufs/inode.c +++ b/ufs/inode.c @@ -20,6 +20,7 @@ #include #include #include +#include #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) @@ -723,4 +724,125 @@ diskfs_S_file_get_storage_info (struct protid *cred, return 0; } +/* Must be exactly 28 bytes long */ +struct ufs_fhandle +{ + int filler1; + ino_t inum; + long gen; + int filler2[4]; +}; + +/* Return an NFS file handle */ + +error_t +diskfs_S_file_getfh (struct protid *cred, + char **fh, + u_int *fh_len) +{ + struct node *np; + error_t err; + struct ufs_fhandle *f; + + if (!cred) + return EOPNOTSUPP; + + if (!diskfs_isuid (0, cred)) + return EPERM; + + np = cred->po->np; + + mutex_lock (&np->lock); + + if (*fh_len < sizeof (struct ufs_fhandle)) + vm_allocate (mach_task_self (), (vm_address_t *) fh, + sizeof (struct ufs_fhandle), 1); + *fh_len = sizeof (struct ufs_fhandle); + + f = (struct ufs_fhandle *) *fh; + f->inum = np->dn->number; + f->gen = np->dn_stat.st_gen; + f->filler1 = 0; + f->filler2[0] = f->filler2[1] = f->filler2[2] = f->filler2[3] = 0; + mutex_unlock (&np->lock); + return 0; +} + +/* Lookup an NFS file handle */ +error_t +diskfs_S_fsys_getfile (mach_port_t fsys, + mach_port_t reply, + mach_msg_type_name_t replytype, + uid_t *uids, + u_int nuids, + uid_t *gids, + u_int ngids, + char *handle, + u_int handlelen, + mach_port_t *file, + mach_msg_type_name_t *filetype) +{ + struct port_info *pt = ports_lookup_port (diskfs_port_bucket, fsys, + diskfs_control_class); + struct node *np; + struct ufs_fhandle *f; + error_t err; + int flags; + struct protid fakecred, *newpi; + + if (!pt) + return EOPNOTSUPP; + + if (handlelen != sizeof (struct ufs_fhandle)) + { + ports_port_deref (pt); + return EINVAL; + } + + f = (struct ufs_fhandle *) handle; + + err = diskfs_cached_lookup (f->inum, &np); + if (err) + { + ports_port_deref (pt); + return err; + } + + if (np->dn_stat.st_gen != f->gen) + { + diskfs_nput (np); + ports_port_deref (pt); + return ESTALE; + } + + /* This call should have a flags arg, but until then... */ + fakecred.uids = uids; + fakecred.gids = gids; + fakecred.nuids = nuids; + fakecred.ngids = ngids; + + flags = 0; + if (!diskfs_access (np, S_IREAD, &fakecred)) + flags |= O_READ; + if (!diskfs_access (np, S_IEXEC, &fakecred)) + flags |= O_EXEC; + if (!diskfs_access (np, S_IWRITE, &fakecred) + && !S_ISDIR (np->dn_stat.st_mode) + && !diskfs_check_readonly ()) + flags |= O_WRITE; + + err = diskfs_create_protid (diskfs_make_peropen (np, flags, MACH_PORT_NULL), + uids, nuids, gids, ngids, &newpi); + + diskfs_nput (np); + ports_port_deref (pt); + + if (!err) + { + *file = ports_get_right (newpi); + *filetype = MACH_MSG_TYPE_MAKE_SEND; + } + return err; +} + -- cgit v1.2.3