summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--Makefile2
-rw-r--r--TODO15
-rw-r--r--libdiskfs/ChangeLog6
-rw-r--r--libdiskfs/node-create.c12
-rw-r--r--nfsd/ChangeLog73
-rw-r--r--nfsd/cache.c93
-rw-r--r--nfsd/fsys.c42
-rw-r--r--nfsd/loop.c293
-rw-r--r--nfsd/main.c37
-rw-r--r--nfsd/nfsd.h10
-rw-r--r--nfsd/ops.c164
-rw-r--r--nfsd/proctables.c57
-rw-r--r--nfsd/xdr.c21
-rw-r--r--release/=announce-0.057
-rw-r--r--release/checklist5
-rw-r--r--ufs/ChangeLog13
-rw-r--r--ufs/inode.c122
18 files changed, 650 insertions, 376 deletions
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 <thomas@gnu.ai.mit.edu>
+
+ * Makefile (prog-subdirs): Add `nfsd'.
+
Tue Aug 6 12:20:37 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* 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 <thomas@gnu.ai.mit.edu>
+
+ * 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 <thomas@gnu.ai.mit.edu>
* 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 <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 **);
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 <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;
}
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 <thomas@gnu.ai.mit.edu>
+
+ * 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 <thomas@gnu.ai.mit.edu>
+
+ * inode.c: Include <fcntl.h>.
+ (struct ufs_fhandle): New type.
+ (diskfs_S_fsys_getfile, diskfs_S_file_getfh): New functions.
+
Tue Jul 23 15:58:28 1996 Miles Bader <miles@gnu.ai.mit.edu>
* 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 <unistd.h>
#include <stdio.h>
#include <netinet/in.h>
+#include <fcntl.h>
#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;
+}
+