diff options
author | Thomas Bushnell <thomas@gnu.org> | 1996-08-07 19:03:53 +0000 |
---|---|---|
committer | Thomas Bushnell <thomas@gnu.org> | 1996-08-07 19:03:53 +0000 |
commit | 19d0f00234b0884a31c8bd4b806c6d512baae9be (patch) | |
tree | b1fbd27e19126286009ba2486e1fc49886b8d8d7 /nfsd | |
parent | feecb48f23f7e3cff12f14a579a56b8b8143b275 (diff) |
*** empty log message ***
Diffstat (limited to 'nfsd')
-rw-r--r-- | nfsd/ChangeLog | 73 | ||||
-rw-r--r-- | nfsd/cache.c | 93 | ||||
-rw-r--r-- | nfsd/fsys.c | 42 | ||||
-rw-r--r-- | nfsd/loop.c | 293 | ||||
-rw-r--r-- | nfsd/main.c | 37 | ||||
-rw-r--r-- | nfsd/nfsd.h | 10 | ||||
-rw-r--r-- | nfsd/ops.c | 164 | ||||
-rw-r--r-- | nfsd/proctables.c | 57 | ||||
-rw-r--r-- | nfsd/xdr.c | 21 |
9 files changed, 456 insertions, 334 deletions
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 <thomas@gnu.ai.mit.edu> + + * 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 <hurd.h>. + (main): Initialize AUTHSERVER. + * cache.c: Include <hurd/io.h> and <hurd/auth.h>. + (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 <thomas@gnu.ai.mit.edu> + + * 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 <hurd/fsys.h> #include <assert.h> #include <string.h> +#include <hurd/io.h> +#include <hurd/auth.h> #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 <unistd.h> #include <rpc/pmap_prot.h> #include <maptime.h> +#include <hurd.h> 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 **); @@ -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 */ -}; @@ -23,22 +23,11 @@ #include <string.h> #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; } |