commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

hurd/nfs ChangeLog cache.c mount.c nfs.c ops.c ...


From: Marcus Brinkmann
Subject: hurd/nfs ChangeLog cache.c mount.c nfs.c ops.c ...
Date: Sun, 29 Sep 2002 11:11:59 -0400

CVSROOT:        /cvsroot/hurd
Module name:    hurd
Changes by:     Marcus Brinkmann <address@hidden>       02/09/29 11:11:59

Modified files:
        nfs            : ChangeLog cache.c mount.c nfs.c ops.c rpc.c 

Log message:
        2002-09-29  Marcus Brinkmann  <address@hidden>
        
        * mount.c (mount_root): Add parenthesis for post-decrement (even
        though it is only used as an lvalue here).  Increment P after
        using it in the macro, not within.
        * rpc.c (initialize_rpc, conduct_rpc): Likewise.
        * ops.c (process_returned_stat, process_wcc_stat,
        netfs_validate_stat, netfs_attempt_chown, netfs_attempt_chmod,
        netfs_attempt_utimes, netfs_attempt_set_size,
        netfs_attempt_statfs, netfs_attempt_read, netfs_attempt_write,
        verify_nonexistent, netfs_attempt_lookup, netfs_attempt_mkdir,
        netfs_attempt_rmdir, netfs_attempt_link,
        netfs_attempt_create_file, netfs_attempt_unlink,
        netfs_attempt_rename, netfs_attempt_readlink, netfs_report_access,
        netfs_check_open_permissions): Likewise.
        (fetch_directory): Likewise.  Also use memcpy instead bcopy.
        * cache.c (recache_handle): Likewise.
        * nfs.c (xdr_encode_data, xdr_encode_sattr_mode,
        xdr_encode_sattr_ids, xdr_encode_sattr_size,
        xdr_encode_sattr_times, xdr_encode_create_state,
        xdr_encode_sattr_stat, xdr_decode_64bit, xdr_decode_fattr):
        Likewise.
        (xdr_decode_string): Likewise.  Also use memcpy instead bcopy.
        (xdr_decode_fhandle): Likewise.  Also use memcpy instead bcopy.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd/nfs/ChangeLog.diff?tr1=1.47&tr2=1.48&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd/nfs/cache.c.diff?tr1=1.15&tr2=1.16&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd/nfs/mount.c.diff?tr1=1.26&tr2=1.27&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd/nfs/nfs.c.diff?tr1=1.26&tr2=1.27&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd/nfs/ops.c.diff?tr1=1.43&tr2=1.44&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/hurd/hurd/nfs/rpc.c.diff?tr1=1.11&tr2=1.12&r1=text&r2=text

Patches:
Index: hurd/nfs/ChangeLog
diff -c hurd/nfs/ChangeLog:1.47 hurd/nfs/ChangeLog:1.48
*** hurd/nfs/ChangeLog:1.47     Mon May 13 18:33:36 2002
--- hurd/nfs/ChangeLog  Sun Sep 29 11:11:59 2002
***************
*** 1,3 ****
--- 1,28 ----
+ 2002-09-29  Marcus Brinkmann  <address@hidden>
+ 
+       * mount.c (mount_root): Add parenthesis for post-decrement (even
+       though it is only used as an lvalue here).  Increment P after
+       using it in the macro, not within.
+       * rpc.c (initialize_rpc, conduct_rpc): Likewise.
+       * ops.c (process_returned_stat, process_wcc_stat,
+       netfs_validate_stat, netfs_attempt_chown, netfs_attempt_chmod,
+       netfs_attempt_utimes, netfs_attempt_set_size,
+       netfs_attempt_statfs, netfs_attempt_read, netfs_attempt_write,
+       verify_nonexistent, netfs_attempt_lookup, netfs_attempt_mkdir,
+       netfs_attempt_rmdir, netfs_attempt_link,
+       netfs_attempt_create_file, netfs_attempt_unlink,
+       netfs_attempt_rename, netfs_attempt_readlink, netfs_report_access,
+       netfs_check_open_permissions): Likewise.
+       (fetch_directory): Likewise.  Also use memcpy instead bcopy.
+       * cache.c (recache_handle): Likewise.
+       * nfs.c (xdr_encode_data, xdr_encode_sattr_mode,
+       xdr_encode_sattr_ids, xdr_encode_sattr_size,
+       xdr_encode_sattr_times, xdr_encode_create_state,
+       xdr_encode_sattr_stat, xdr_decode_64bit, xdr_decode_fattr):
+       Likewise.
+       (xdr_decode_string): Likewise.  Also use memcpy instead bcopy.
+       (xdr_decode_fhandle): Likewise.  Also use memcpy instead bcopy.
+ 
  2002-05-13  Roland McGrath  <address@hidden>
  
        * ops.c (register_fresh_stat): Set NP->nn_translated appropriately.
Index: hurd/nfs/cache.c
diff -c hurd/nfs/cache.c:1.15 hurd/nfs/cache.c:1.16
*** hurd/nfs/cache.c:1.15       Mon Jan 29 19:38:45 2001
--- hurd/nfs/cache.c    Sun Sep 29 11:11:59 2002
***************
*** 1,5 ****
! /* Node cache management for NFS client implementation
!    Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
     Written by Michael I. Bushnell, p/BSG.
  
     This file is part of the GNU Hurd.
--- 1,5 ----
! /* cache.c - Node cache management for NFS client implementation.
!    Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
     Written by Michael I. Bushnell, p/BSG.
  
     This file is part of the GNU Hurd.
***************
*** 23,36 ****
  #include <string.h>
  #include <netinet/in.h>
  
! /* Hash table containing all the nodes currently active.
!    XXX Was 512, however, a prime is much nice for the hash
!    function. 509 is nice as not only is it prime, it keeps
!    the array within a page or two */
  #define CACHESIZE 509
  static struct node *nodehash [CACHESIZE];
  
! /* Compute and return a hash key for NFS file handle DATA of LEN bytes. */
  static inline int
  hash (int *data, size_t len)
  {
--- 23,37 ----
  #include <string.h>
  #include <netinet/in.h>
  
! /* Hash table containing all the nodes currently active.  XXX Was 512,
!    however, a prime is much nicer for the hash function.  509 is nice
!    as not only is it prime, it also keeps the array within a page or
!    two.  */
  #define CACHESIZE 509
  static struct node *nodehash [CACHESIZE];
  
! /* Compute and return a hash key for NFS file handle DATA of LEN
!    bytes.  */
  static inline int
  hash (int *data, size_t len)
  {
***************
*** 96,110 ****
    *npp = np;
  }
  
! /* Package holding args to forked_node_delete. */
  struct fnd
  {
    struct node *dir;
    char *name;
  };
  
! /* Worker function to delete nodes that don't have any more local references
!    or links.  */
  any_t
  forked_node_delete (any_t arg)
  {
--- 97,111 ----
    *npp = np;
  }
  
! /* Package holding args to forked_node_delete.  */
  struct fnd
  {
    struct node *dir;
    char *name;
  };
  
! /* Worker function to delete nodes that don't have any more local
!    references or links.  */
  any_t
  forked_node_delete (any_t arg)
  {
***************
*** 121,127 ****
  /* Called by libnetfs when node NP has no more references.  (See
     <hurd/libnetfs.h> for details.  Just clear its local state and
     remove it from the hash table.  Called and expected to leave with
!    NETFS_NODE_REFCNT_LOCK held. */
  void
  netfs_node_norefs (struct node *np)
  {
--- 122,128 ----
  /* Called by libnetfs when node NP has no more references.  (See
     <hurd/libnetfs.h> for details.  Just clear its local state and
     remove it from the hash table.  Called and expected to leave with
!    NETFS_NODE_REFCNT_LOCK held.  */
  void
  netfs_node_norefs (struct node *np)
  {
***************
*** 141,148 ****
        np->nn->dead_name = 0;
        netfs_nput (np);
  
!       /* Do this in a separate thread so that we don't wait for it;
!        it acquires a lock on the dir, which we are not allowed to do. */
        cthread_detach (cthread_fork (forked_node_delete, (any_t) args));
  
        /* Caller expects us to leave this locked... */
--- 142,150 ----
        np->nn->dead_name = 0;
        netfs_nput (np);
  
!       /* Do this in a separate thread so that we don't wait for it; it
!        acquires a lock on the dir, which we are not allowed to
!        do.  */
        cthread_detach (cthread_fork (forked_node_delete, (any_t) args));
  
        /* Caller expects us to leave this locked... */
***************
*** 162,168 ****
  
  /* Change the file handle used for node NP to be the handle at P.
     Make sure the hash table stays up to date.  Return the address
!    after the handle.  The lock on the node should be held. */
  int *
  recache_handle (int *p, struct node *np)
  {
--- 164,170 ----
  
  /* Change the file handle used for node NP to be the handle at P.
     Make sure the hash table stays up to date.  Return the address
!    after the handle.  The lock on the node should be held.  */
  int *
  recache_handle (int *p, struct node *np)
  {
***************
*** 172,178 ****
    if (protocol_version == 2)
      len = NFS2_FHSIZE;
    else
!     len = ntohl (*p++);
    
    /* Unlink it */
    spin_lock (&netfs_node_refcnt_lock);
--- 174,183 ----
    if (protocol_version == 2)
      len = NFS2_FHSIZE;
    else
!     {
!       len = ntohl (*p);
!       p++;
!     }
    
    /* Unlink it */
    spin_lock (&netfs_node_refcnt_lock);
Index: hurd/nfs/mount.c
diff -c hurd/nfs/mount.c:1.26 hurd/nfs/mount.c:1.27
*** hurd/nfs/mount.c:1.26       Fri May  3 18:52:35 2002
--- hurd/nfs/mount.c    Sun Sep 29 11:11:59 2002
***************
*** 116,122 ****
         argument is either "tcp" or "udp"  Thus, is this backwards
         (as service_name suggests)?  If so, should it read:
               s = getservbyname (pmap_service_name, "udp");
!          or is there something I am missing here? */
        s = getservbyname ("sunrpc", pmap_service_name);
        if (s)
        pmapport = s->s_port;
--- 116,122 ----
         argument is either "tcp" or "udp"  Thus, is this backwards
         (as service_name suggests)?  If so, should it read:
               s = getservbyname (pmap_service_name, "udp");
!          or is there something I am missing here?  */
        s = getservbyname ("sunrpc", pmap_service_name);
        if (s)
        pmapport = s->s_port;
***************
*** 158,171 ****
          return 0;
        }
  
!       *p++ = htonl (MOUNTPROG);
!       *p++ = htonl (MOUNTVERS);
!       *p++ = htonl (IPPROTO_UDP);
!       *p++ = htonl (0);
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         port = ntohl (*p++);
          addr.sin_port = htons (port);
        }
        else if (mount_port)
--- 158,172 ----
          return 0;
        }
  
!       *(p++) = htonl (MOUNTPROG);
!       *(p++) = htonl (MOUNTVERS);
!       *(p++) = htonl (IPPROTO_UDP);
!       *(p++) = htonl (0);
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         port = ntohl (*p);
!         p++;
          addr.sin_port = htons (port);
        }
        else if (mount_port)
***************
*** 204,210 ****
    /* XXX Protocol spec says this should be a "unix error code"; we'll
       pretend that an NFS error code is what's meant; the numbers match
       anyhow.  */
!   err = nfs_error_trans (htonl (*p++));
    if (err)
      {
        error (0, err, name);
--- 205,212 ----
    /* XXX Protocol spec says this should be a "unix error code"; we'll
       pretend that an NFS error code is what's meant; the numbers match
       anyhow.  */
!   err = nfs_error_trans (htonl (*p));
!   p++;
    if (err)
      {
        error (0, err, name);
***************
*** 235,247 ****
          error (0, errno, "rpc");
          goto error_with_rpcbuf;
        }
!       *p++ = htonl (NFS_PROGRAM);
!       *p++ = htonl (NFS_VERSION);
!       *p++ = htonl (IPPROTO_UDP);
!       *p++ = htonl (0);
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
!       port = ntohl (*p++);
        else if (nfs_port)
        port = nfs_port;
        else
--- 237,252 ----
          error (0, errno, "rpc");
          goto error_with_rpcbuf;
        }
!       *(p++) = htonl (NFS_PROGRAM);
!       *(p++) = htonl (NFS_VERSION);
!       *(p++) = htonl (IPPROTO_UDP);
!       *(p++) = htonl (0);
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
!       {
!         port = ntohl (*p);
!         p++;
!       }
        else if (nfs_port)
        port = nfs_port;
        else
Index: hurd/nfs/nfs.c
diff -c hurd/nfs/nfs.c:1.26 hurd/nfs/nfs.c:1.27
*** hurd/nfs/nfs.c:1.26 Mon Jan 29 19:38:45 2001
--- hurd/nfs/nfs.c      Sun Sep 29 11:11:59 2002
***************
*** 1,5 ****
! /* XDR frobbing and lower level routines for NFS client
!    Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
     Written by Michael I. Bushnell, p/BSG.
  
     This file is part of the GNU Hurd.
--- 1,5 ----
! /* nfs.c - XDR frobbing and lower level routines for NFS client.
!    Copyright (C) 1995, 1996, 1997, 1999, 2002 Free Software Foundation, Inc.
     Written by Michael I. Bushnell, p/BSG.
  
     This file is part of the GNU Hurd.
***************
*** 24,30 ****
  #include <netinet/in.h>
  #include <stdio.h>
  
! /* Convert an NFS mode (TYPE and MODE) to a Hurd mode and return it. */
  mode_t
  nfs_mode_to_hurd_mode (int type, int mode)
  {
--- 24,31 ----
  #include <netinet/in.h>
  #include <stdio.h>
  
! /* Convert an NFS mode (TYPE and MODE) to a Hurd mode and return
!    it.  */
  mode_t
  nfs_mode_to_hurd_mode (int type, int mode)
  {
***************
*** 88,94 ****
    return hurdmode;
  }
  
! /* Convert a Hurd mode to an NFS mode */
  int
  hurd_mode_to_nfs_mode (mode_t mode)
  {
--- 89,95 ----
    return hurdmode;
  }
  
! /* Convert a Hurd mode to an NFS mode.  */
  int
  hurd_mode_to_nfs_mode (mode_t mode)
  {
***************
*** 97,103 ****
    return mode & 07777;
  }
  
! /* Convert a Hurd mode to an NFS type */
  int
  hurd_mode_to_nfs_type (mode_t mode)
  {
--- 98,104 ----
    return mode & 07777;
  }
  
! /* Convert a Hurd mode to an NFS type.  */
  int
  hurd_mode_to_nfs_type (mode_t mode)
  {
***************
*** 131,297 ****
  
  /* Each of the functions on this page copies its second arg to *P,
     converting it to XDR representation along the way.  They then
!    return the address after the copied value. */
  
! /* Encode an NFS file handle. */
  int *
  xdr_encode_fhandle (int *p, struct fhandle *fhandle)
  {
    if (protocol_version == 2)
      {
!       bcopy (fhandle->data, p, NFS2_FHSIZE);
        return p + INTSIZE (NFS2_FHSIZE);
      }
    else
      return xdr_encode_data (p, fhandle->data, fhandle->size);
  }
  
! /* Encode uninterpreted bytes. */
  int *
  xdr_encode_data (int *p, char *data, size_t len)
  {
    int nints = INTSIZE (len);
  
    p[nints] = 0;
!   *p++ = htonl (len);
    memcpy (p, data, len);
    return p + nints;
  }
  
! /* Encode a 64 bit integer */
  int *
  xdr_encode_64bit (int *p, long long n)
  {
!   *p++ = htonl (n & 0xffffffff00000000LL >> 32);
!   *p++ = htonl (n & 0xffffffff);
    return p;
  }
  
! /* Encode a C string. */
  int *
  xdr_encode_string (int *p, char *string)
  {
    return xdr_encode_data (p, string, strlen (string));
  }
  
! /* Encode a MODE into an otherwise empty sattr. */
  int *
  xdr_encode_sattr_mode (int *p, mode_t mode)
  {
    if (protocol_version == 2)
      {
!       *p++ = htonl (hurd_mode_to_nfs_mode (mode));
!       *p++ = -1;                      /* uid */
!       *p++ = -1;                      /* gid */
!       *p++ = -1;                      /* size */
!       *p++ = -1;                      /* atime secs */
!       *p++ = -1;                      /* atime usecs */
!       *p++ = -1;                      /* mtime secs */
!       *p++ = -1;                      /* mtime usecs */
      }
    else
      {
!       *p++ = htonl (1);               /* set mode */
!       *p++ = htonl (hurd_mode_to_nfs_mode (mode));
!       *p++ = 0;                       /* no uid */
!       *p++ = 0;                       /* no gid */
!       *p++ = 0;                       /* no size */
!       *p++ = DONT_CHANGE;     /* no atime */
!       *p++ = DONT_CHANGE;     /* no mtime */
      }
    return p;
  }
  
! /* Encode UID and GID into an otherwise empty sattr. */
  int *
  xdr_encode_sattr_ids (int *p, u_int uid, u_int gid)
  {
    if (protocol_version == 2)
      {
!       *p++ = -1;                      /* mode */
!       *p++ = htonl (uid);
!       *p++ = htonl (gid);
!       *p++ = -1;                      /* size */
!       *p++ = -1;                      /* atime secs */
!       *p++ = -1;                      /* atime usecs */
!       *p++ = -1;                      /* mtime secs */
!       *p++ = -1;                      /* mtime usecs */
      }
    else
      {
!       *p++ = 0;                       /* no mode */
!       *p++ = htonl (1);               /* set uid */
!       *p++ = htonl (uid);
!       *p++ = htonl (1);               /* set gid */
!       *p++ = htonl (gid);
!       *p++ = 0;                       /* no size */
!       *p++ = DONT_CHANGE;     /* no atime */
!       *p++ = DONT_CHANGE;     /* no mtime */
      }
    return p;
  }
  
! /* Encode a file size into an otherwise empty sattr. */
  int *
  xdr_encode_sattr_size (int *p, off_t size)
  {
    if (protocol_version == 2)
      {
!       *p++ = -1;                      /* mode */
!       *p++ = -1;                      /* uid */
!       *p++ = -1;                      /* gid */
!       *p++ = htonl (size);
!       *p++ = -1;                      /* atime secs */
!       *p++ = -1;                      /* atime usecs */
!       *p++ = -1;                      /* mtime secs */
!       *p++ = -1;                      /* mtime secs */
      }
    else
      {
!       *p++ = 0;                       /* no mode */
!       *p++ = 0;                       /* no uid */
!       *p++ = 0;                       /* no gid */
!       *p++ = htonl (1);               /* size */
        p = xdr_encode_64bit (p, size);
!       *p++ = DONT_CHANGE;     /* no atime */
!       *p++ = DONT_CHANGE;     /* no mtime */
      }
    return p;
  }
  
! /* Encode ATIME and MTIME into an otherwise empty sattr. */
  int *
  xdr_encode_sattr_times (int *p, struct timespec *atime, struct timespec 
*mtime)
  {
    if (protocol_version == 2)
      {
!       *p++ = -1;                      /* mode */
!       *p++ = -1;                      /* uid */
!       *p++ = -1;                      /* gid */
!       *p++ = -1;                      /* size */
!       *p++ = htonl (atime->tv_sec);
!       *p++ = htonl (atime->tv_nsec / 1000);
!       *p++ = htonl (mtime->tv_sec);
!       *p++ = htonl (mtime->tv_nsec / 1000);
      }
    else
      {
!       *p++ = 0;                       /* no mode */
!       *p++ = 0;                       /* no uid */
!       *p++ = 0;                       /* no gid */
!       *p++ = 0;                       /* no size */
!       *p++ = htonl (SET_TO_CLIENT_TIME); /* atime */
!       *p++ = htonl (atime->tv_sec);
!       *p++ = htonl (atime->tv_nsec);
!       *p++ = htonl (SET_TO_CLIENT_TIME); /* mtime */
!       *p++ = htonl (mtime->tv_sec);
!       *p++ = htonl (mtime->tv_nsec);
      }
    return p;
  }
  
! /* Encode MODE, a size of zero, and the specified owner into an otherwise
!    empty sattr.  */
  int *
  xdr_encode_create_state (int *p,
                         mode_t mode,
--- 132,298 ----
  
  /* Each of the functions on this page copies its second arg to *P,
     converting it to XDR representation along the way.  They then
!    return the address after the copied value.  */
  
! /* Encode an NFS file handle.  */
  int *
  xdr_encode_fhandle (int *p, struct fhandle *fhandle)
  {
    if (protocol_version == 2)
      {
!       memcpy (p, fhandle->data, NFS2_FHSIZE);
        return p + INTSIZE (NFS2_FHSIZE);
      }
    else
      return xdr_encode_data (p, fhandle->data, fhandle->size);
  }
  
! /* Encode uninterpreted bytes.  */
  int *
  xdr_encode_data (int *p, char *data, size_t len)
  {
    int nints = INTSIZE (len);
  
    p[nints] = 0;
!   *(p++) = htonl (len);
    memcpy (p, data, len);
    return p + nints;
  }
  
! /* Encode a 64 bit integer.  */
  int *
  xdr_encode_64bit (int *p, long long n)
  {
!   *(p++) = htonl (n & 0xffffffff00000000LL >> 32);
!   *(p++) = htonl (n & 0xffffffff);
    return p;
  }
  
! /* Encode a C string.  */
  int *
  xdr_encode_string (int *p, char *string)
  {
    return xdr_encode_data (p, string, strlen (string));
  }
  
! /* Encode a MODE into an otherwise empty sattr.  */
  int *
  xdr_encode_sattr_mode (int *p, mode_t mode)
  {
    if (protocol_version == 2)
      {
!       *(p++) = htonl (hurd_mode_to_nfs_mode (mode));
!       *(p++) = -1;                    /* uid */
!       *(p++) = -1;                    /* gid */
!       *(p++) = -1;                    /* size */
!       *(p++) = -1;                    /* atime secs */
!       *(p++) = -1;                    /* atime usecs */
!       *(p++) = -1;                    /* mtime secs */
!       *(p++) = -1;                    /* mtime usecs */
      }
    else
      {
!       *(p++) = htonl (1);             /* set mode */
!       *(p++) = htonl (hurd_mode_to_nfs_mode (mode));
!       *(p++) = 0;                     /* no uid */
!       *(p++) = 0;                     /* no gid */
!       *(p++) = 0;                     /* no size */
!       *(p++) = DONT_CHANGE;   /* no atime */
!       *(p++) = DONT_CHANGE;   /* no mtime */
      }
    return p;
  }
  
! /* Encode UID and GID into an otherwise empty sattr.  */
  int *
  xdr_encode_sattr_ids (int *p, u_int uid, u_int gid)
  {
    if (protocol_version == 2)
      {
!       *(p++) = -1;                    /* mode */
!       *(p++) = htonl (uid);
!       *(p++) = htonl (gid);
!       *(p++) = -1;                    /* size */
!       *(p++) = -1;                    /* atime secs */
!       *(p++) = -1;                    /* atime usecs */
!       *(p++) = -1;                    /* mtime secs */
!       *(p++) = -1;                    /* mtime usecs */
      }
    else
      {
!       *(p++) = 0;                     /* no mode */
!       *(p++) = htonl (1);             /* set uid */
!       *(p++) = htonl (uid);
!       *(p++) = htonl (1);             /* set gid */
!       *(p++) = htonl (gid);
!       *(p++) = 0;                     /* no size */
!       *(p++) = DONT_CHANGE;   /* no atime */
!       *(p++) = DONT_CHANGE;   /* no mtime */
      }
    return p;
  }
  
! /* Encode a file size into an otherwise empty sattr.  */
  int *
  xdr_encode_sattr_size (int *p, off_t size)
  {
    if (protocol_version == 2)
      {
!       *(p++) = -1;                    /* mode */
!       *(p++) = -1;                    /* uid */
!       *(p++) = -1;                    /* gid */
!       *(p++) = htonl (size);
!       *(p++) = -1;                    /* atime secs */
!       *(p++) = -1;                    /* atime usecs */
!       *(p++) = -1;                    /* mtime secs */
!       *(p++) = -1;                    /* mtime secs */
      }
    else
      {
!       *(p++) = 0;                     /* no mode */
!       *(p++) = 0;                     /* no uid */
!       *(p++) = 0;                     /* no gid */
!       *(p++) = htonl (1);             /* size */
        p = xdr_encode_64bit (p, size);
!       *(p++) = DONT_CHANGE;   /* no atime */
!       *(p++) = DONT_CHANGE;   /* no mtime */
      }
    return p;
  }
  
! /* Encode ATIME and MTIME into an otherwise empty sattr.  */
  int *
  xdr_encode_sattr_times (int *p, struct timespec *atime, struct timespec 
*mtime)
  {
    if (protocol_version == 2)
      {
!       *(p++) = -1;                    /* mode */
!       *(p++) = -1;                    /* uid */
!       *(p++) = -1;                    /* gid */
!       *(p++) = -1;                    /* size */
!       *(p++) = htonl (atime->tv_sec);
!       *(p++) = htonl (atime->tv_nsec / 1000);
!       *(p++) = htonl (mtime->tv_sec);
!       *(p++) = htonl (mtime->tv_nsec / 1000);
      }
    else
      {
!       *(p++) = 0;                     /* no mode */
!       *(p++) = 0;                     /* no uid */
!       *(p++) = 0;                     /* no gid */
!       *(p++) = 0;                     /* no size */
!       *(p++) = htonl (SET_TO_CLIENT_TIME); /* atime */
!       *(p++) = htonl (atime->tv_sec);
!       *(p++) = htonl (atime->tv_nsec);
!       *(p++) = htonl (SET_TO_CLIENT_TIME); /* mtime */
!       *(p++) = htonl (mtime->tv_sec);
!       *(p++) = htonl (mtime->tv_nsec);
      }
    return p;
  }
  
! /* Encode MODE, a size of zero, and the specified owner into an
!    otherwise empty sattr.  */
  int *
  xdr_encode_create_state (int *p,
                         mode_t mode,
***************
*** 299,372 ****
  {
    if (protocol_version == 2)
      {
!       *p++ = htonl (hurd_mode_to_nfs_mode (mode));
!       *p++ = htonl (owner);   /* uid */
!       *p++ = -1;              /* gid */
!       *p++ = 0;                       /* size */
!       *p++ = -1;              /* atime sec */
!       *p++ = -1;              /* atime usec */
!       *p++ = -1;              /* mtime sec */
!       *p++ = -1;              /* mtime usec */
      }
    else
      {
!       *p++ = htonl (1);               /* mode */
!       *p++ = htonl (hurd_mode_to_nfs_mode (mode));
!       *p++ = htonl (1);               /* set uid */
!       *p++ = htonl (owner);
!       *p++ = 0;                       /* no gid */
!       *p++ = htonl (1);               /* set size */
        p = xdr_encode_64bit (p, 0);
!       *p++ = htonl (SET_TO_SERVER_TIME); /* atime */
!       *p++ = htonl (SET_TO_SERVER_TIME); /* mtime */
      }
    return p;
  }
  
! /* Encode ST into an sattr. */
  int *
  xdr_encode_sattr_stat (int *p,
                       struct stat *st)
  {
    if (protocol_version == 2)
      {
!       *p++ = htonl (hurd_mode_to_nfs_mode (st->st_mode));
!       *p++ = htonl (st->st_uid);
!       *p++ = htonl (st->st_gid);
!       *p++ = htonl (st->st_size);
!       *p++ = htonl (st->st_atime);
!       *p++ = htonl (st->st_atime_usec);
!       *p++ = htonl (st->st_mtime);
!       *p++ = htonl (st->st_mtime_usec);
      }
    else
      {
!       *p++ = htonl (1);               /* set mode */
!       *p++ = htonl (hurd_mode_to_nfs_mode (st->st_mode));
!       *p++ = htonl (1);               /* set uid */
!       *p++ = htonl (st->st_uid);
!       *p++ = htonl (1);               /* set gid */
!       *p++ = htonl (st->st_gid);
!       *p++ = htonl (1);               /* set size */
        p = xdr_encode_64bit (p, st->st_size);
!       *p++ = htonl (SET_TO_CLIENT_TIME); /* set atime */
!       *p++ = htonl (st->st_atime);
!       *p++ = htonl (st->st_atime_usec * 1000);
!       *p++ = htonl (SET_TO_CLIENT_TIME); /* set mtime */
!       *p++ = htonl (st->st_mtime);
!       *p++ = htonl (st->st_mtime_usec * 1000);
      }
    return p;
  }
  
  
! /* Decode *P into a long long; return the address of the following data. */
  int *
  xdr_decode_64bit (int *p, long long *n)
  {
    long long high, low;
!   high = ntohl (*p++);
!   low = ntohl (*p++);
    *n = ((high & 0xffffffff) << 32) | (low & 0xffffffff);
    return p;
  }
--- 300,376 ----
  {
    if (protocol_version == 2)
      {
!       *(p++) = htonl (hurd_mode_to_nfs_mode (mode));
!       *(p++) = htonl (owner); /* uid */
!       *(p++) = -1;            /* gid */
!       *(p++) = 0;                     /* size */
!       *(p++) = -1;            /* atime sec */
!       *(p++) = -1;            /* atime usec */
!       *(p++) = -1;            /* mtime sec */
!       *(p++) = -1;            /* mtime usec */
      }
    else
      {
!       *(p++) = htonl (1);             /* mode */
!       *(p++) = htonl (hurd_mode_to_nfs_mode (mode));
!       *(p++) = htonl (1);             /* set uid */
!       *(p++) = htonl (owner);
!       *(p++) = 0;                     /* no gid */
!       *(p++) = htonl (1);             /* set size */
        p = xdr_encode_64bit (p, 0);
!       *(p++) = htonl (SET_TO_SERVER_TIME); /* atime */
!       *(p++) = htonl (SET_TO_SERVER_TIME); /* mtime */
      }
    return p;
  }
  
! /* Encode ST into an sattr.  */
  int *
  xdr_encode_sattr_stat (int *p,
                       struct stat *st)
  {
    if (protocol_version == 2)
      {
!       *(p++) = htonl (hurd_mode_to_nfs_mode (st->st_mode));
!       *(p++) = htonl (st->st_uid);
!       *(p++) = htonl (st->st_gid);
!       *(p++) = htonl (st->st_size);
!       *(p++) = htonl (st->st_atime);
!       *(p++) = htonl (st->st_atime_usec);
!       *(p++) = htonl (st->st_mtime);
!       *(p++) = htonl (st->st_mtime_usec);
      }
    else
      {
!       *(p++) = htonl (1);             /* set mode */
!       *(p++) = htonl (hurd_mode_to_nfs_mode (st->st_mode));
!       *(p++) = htonl (1);             /* set uid */
!       *(p++) = htonl (st->st_uid);
!       *(p++) = htonl (1);             /* set gid */
!       *(p++) = htonl (st->st_gid);
!       *(p++) = htonl (1);             /* set size */
        p = xdr_encode_64bit (p, st->st_size);
!       *(p++) = htonl (SET_TO_CLIENT_TIME); /* set atime */
!       *(p++) = htonl (st->st_atime);
!       *(p++) = htonl (st->st_atime_usec * 1000);
!       *(p++) = htonl (SET_TO_CLIENT_TIME); /* set mtime */
!       *(p++) = htonl (st->st_mtime);
!       *(p++) = htonl (st->st_mtime_usec * 1000);
      }
    return p;
  }
  
  
! /* Decode *P into a long long; return the address of the following
!    data.  */
  int *
  xdr_decode_64bit (int *p, long long *n)
  {
    long long high, low;
!   high = ntohl (*p);
!   p++;
!   low = ntohl (*p);
!   p++;
    *n = ((high & 0xffffffff) << 32) | (low & 0xffffffff);
    return p;
  }
***************
*** 378,408 ****
  {
    size_t len;
  
!   len = protocol_version == 2 ? NFS2_FHSIZE : ntohl (*p++);
!   /* Enter into cache */
    lookup_fhandle (p, len, npp);
    return p + len / sizeof (int);
  }
  
  /* Decode *P into a stat structure; return the address of the
!    following data. */
  int *
  xdr_decode_fattr (int *p, struct stat *st)
  {
    int type, mode;
  
!   type = ntohl (*p++);
!   mode = ntohl (*p++);
    st->st_mode = nfs_mode_to_hurd_mode (type, mode);
!   st->st_nlink = ntohl (*p++);
!   st->st_uid = ntohl (*p++);
!   st->st_gid = ntohl (*p++);
    if (protocol_version == 2)
      {
!       st->st_size = ntohl (*p++);
!       st->st_blksize = ntohl (*p++);
!       st->st_rdev = ntohl (*p++);
!       st->st_blocks = ntohl (*p++);
      }
    else
      {
--- 382,427 ----
  {
    size_t len;
  
!   if (protocol_version == 2)
!     len = NFS2_FHSIZE;
!   else
!     {
!       len = ntohl (*p);
!       p++;
!     }
!   /* Enter into cache.  */
    lookup_fhandle (p, len, npp);
    return p + len / sizeof (int);
  }
  
  /* Decode *P into a stat structure; return the address of the
!    following data.  */
  int *
  xdr_decode_fattr (int *p, struct stat *st)
  {
    int type, mode;
  
!   type = ntohl (*p);
!   p++;
!   mode = ntohl (*p);
!   p++;
    st->st_mode = nfs_mode_to_hurd_mode (type, mode);
!   st->st_nlink = ntohl (*p);
!   p++;
!   st->st_uid = ntohl (*p);
!   p++;
!   st->st_gid = ntohl (*p);
!   p++;
    if (protocol_version == 2)
      {
!       st->st_size = ntohl (*p);
!       p++;
!       st->st_blksize = ntohl (*p);
!       p++;
!       st->st_rdev = ntohl (*p);
!       p++;
!       st->st_blocks = ntohl (*p);
!       p++;
      }
    else
      {
***************
*** 413,430 ****
        p = xdr_decode_64bit (p, &size);
        st->st_blocks = size / 512;
        st->st_blksize = read_size < write_size ? read_size : write_size;
!       major = ntohl (*p++);
!       minor = ntohl (*p++);
        st->st_rdev = makedev (major, minor);
      }
!   st->st_fsid = ntohl (*p++);
!   st->st_ino = ntohl (*p++);
!   st->st_atime = ntohl (*p++);
!   st->st_atime_usec = ntohl (*p++);
!   st->st_mtime = ntohl (*p++);
!   st->st_mtime_usec = ntohl (*p++);
!   st->st_ctime = ntohl (*p++);
!   st->st_ctime_usec = ntohl (*p++);
  
    if (protocol_version == 3)
      {
--- 432,459 ----
        p = xdr_decode_64bit (p, &size);
        st->st_blocks = size / 512;
        st->st_blksize = read_size < write_size ? read_size : write_size;
!       major = ntohl (*p);
!       p++;
!       minor = ntohl (*p);
!       p++;
        st->st_rdev = makedev (major, minor);
      }
!   st->st_fsid = ntohl (*p);
!   p++;
!   st->st_ino = ntohl (*p);
!   p++;
!   st->st_atime = ntohl (*p);
!   p++;
!   st->st_atime_usec = ntohl (*p);
!   p++;
!   st->st_mtime = ntohl (*p);
!   p++;
!   st->st_mtime_usec = ntohl (*p);
!   p++;
!   st->st_ctime = ntohl (*p);
!   p++;
!   st->st_ctime_usec = ntohl (*p);
!   p++;
  
    if (protocol_version == 3)
      {
***************
*** 438,451 ****
  }
  
  /* Decode *P into a string, stored at BUF; return the address
!    of the following data. */
  int *
  xdr_decode_string (int *p, char *buf)
  {
    int len;
  
!   len = ntohl (*p++);
!   bcopy (p, buf, len);
    buf[len] = '\0';
    return p + INTSIZE (len);
  }
--- 467,481 ----
  }
  
  /* Decode *P into a string, stored at BUF; return the address
!    of the following data.  */
  int *
  xdr_decode_string (int *p, char *buf)
  {
    int len;
  
!   len = ntohl (*p);
!   p++;
!   memcpy (buf, p, len);
    buf[len] = '\0';
    return p + INTSIZE (len);
  }
***************
*** 458,464 ****
     means superuser), NP (identifying the node we are operating on), and
     SECOND_GID (specifying another GID the server might be interested
     in).  Allocate at least LEN bytes of space for bulk data in
!    addition to the normal amount for an RPC. */
  int *
  nfs_initialize_rpc (int rpc_proc, struct iouser *cred,
                    size_t len, void **bufp, struct node *np,
--- 488,494 ----
     means superuser), NP (identifying the node we are operating on), and
     SECOND_GID (specifying another GID the server might be interested
     in).  Allocate at least LEN bytes of space for bulk data in
!    addition to the normal amount for an RPC.  */
  int *
  nfs_initialize_rpc (int rpc_proc, struct iouser *cred,
                    size_t len, void **bufp, struct node *np,
***************
*** 469,475 ****
    error_t err;
  
    /* Use heuristics to figure out what ids to present to the server.
!      Don't lie, but adjust ids as necessary to secure the desired result. */
  
    if (cred == (struct iouser *) -1)
      {
--- 499,506 ----
    error_t err;
  
    /* Use heuristics to figure out what ids to present to the server.
!      Don't lie, but adjust ids as necessary to secure the desired
!      result.  */
  
    if (cred == (struct iouser *) -1)
      {
***************
*** 548,554 ****
                         uid, gid, second_gid);
  }
  
! /* ERROR is an NFS error code; return the correspending Hurd error. */
  error_t
  nfs_error_trans (int error)
  {
--- 579,586 ----
                         uid, gid, second_gid);
  }
  
! /* ERROR is an NFS error code; return the correspending Hurd
!    error.  */
  error_t
  nfs_error_trans (int error)
  {
***************
*** 639,645 ****
          case NFSERR_BAD_COOKIE:
          case NFSERR_TOOSMALL:
          case NFSERR_JUKEBOX:  /* ??? */
!           /* These indicate bugs in the client, so EGRATUITOUS is right. */
            return EGRATUITOUS;
          }
      }
--- 671,677 ----
          case NFSERR_BAD_COOKIE:
          case NFSERR_TOOSMALL:
          case NFSERR_JUKEBOX:  /* ??? */
!           /* These indicate bugs in the client, so EGRATUITOUS is right.  */
            return EGRATUITOUS;
          }
      }
Index: hurd/nfs/ops.c
diff -c hurd/nfs/ops.c:1.43 hurd/nfs/ops.c:1.44
*** hurd/nfs/ops.c:1.43 Mon May 13 18:23:48 2002
--- hurd/nfs/ops.c      Sun Sep 29 11:11:59 2002
***************
*** 1,4 ****
! /* Libnetfs callbacks for node operations in NFS client
     Copyright (C) 1994,95,96,97,99,2002 Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or
--- 1,4 ----
! /* ops.c - Libnetfs callbacks for node operations in NFS client.
     Copyright (C) 1994,95,96,97,99,2002 Free Software Foundation, Inc.
  
     This program is free software; you can redistribute it and/or
***************
*** 91,97 ****
      {
        int attrs_exist;
  
!       attrs_exist = ntohl (*p++);
        if (attrs_exist)
        p = register_fresh_stat (np, p);
        else if (mod)
--- 91,98 ----
      {
        int attrs_exist;
  
!       attrs_exist = ntohl (*p);
!       p++;
        if (attrs_exist)
        p = register_fresh_stat (np, p);
        else if (mod)
***************
*** 106,112 ****
     version 2, this is just register_fresh_stat.  In version 3, it does
     the wcc_data interpretation too.  If this follows an operation that
     we expect has modified the attributes, MOD should be set.
!    (This unpacks the wcc_data XDR type.) */
  int *
  process_wcc_stat (struct node *np, int *p, int mod)
  {
--- 107,113 ----
     version 2, this is just register_fresh_stat.  In version 3, it does
     the wcc_data interpretation too.  If this follows an operation that
     we expect has modified the attributes, MOD should be set.
!    (This unpacks the wcc_data XDR type.)  */
  int *
  process_wcc_stat (struct node *np, int *p, int mod)
  {
***************
*** 117,123 ****
        int attrs_exist;
  
        /* First the pre_op_attr */
!       attrs_exist = ntohl (*p++);
        if (attrs_exist)
        {
          /* Just skip them for now */
--- 118,125 ----
        int attrs_exist;
  
        /* First the pre_op_attr */
!       attrs_exist = ntohl (*p);
!       p++;
        if (attrs_exist)
        {
          /* Just skip them for now */
***************
*** 133,139 ****
  
  
  /* Implement the netfs_validate_stat callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_validate_stat (struct node *np, struct iouser *cred)
  {
--- 135,141 ----
  
  
  /* Implement the netfs_validate_stat callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_validate_stat (struct node *np, struct iouser *cred)
  {
***************
*** 153,159 ****
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     err = nfs_error_trans (ntohl (*p++));
    if (!err)
      register_fresh_stat (np, p);
  
--- 155,164 ----
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
!     }
    if (!err)
      register_fresh_stat (np, p);
  
***************
*** 162,168 ****
  }
  
  /* Implement the netfs_attempt_chown callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_chown (struct iouser *cred, struct node *np,
                     uid_t uid, gid_t gid)
--- 167,173 ----
  }
  
  /* Implement the netfs_attempt_chown callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_chown (struct iouser *cred, struct node *np,
                     uid_t uid, gid_t gid)
***************
*** 179,190 ****
    p = xdr_encode_fhandle (p, &np->nn->handle);
    p = xdr_encode_sattr_ids (p, uid, gid);
    if (protocol_version == 3)
!     *p++ = 0;                 /* guard_check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
--- 184,196 ----
    p = xdr_encode_fhandle (p, &np->nn->handle);
    p = xdr_encode_sattr_ids (p, uid, gid);
    if (protocol_version == 3)
!     *(p++) = 0;                       /* guard_check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
***************
*** 204,210 ****
  }
  
  /* Implement the netfs_attempt_chmod callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_chmod (struct iouser *cred, struct node *np,
                     mode_t mode)
--- 210,216 ----
  }
  
  /* Implement the netfs_attempt_chmod callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_chmod (struct iouser *cred, struct node *np,
                     mode_t mode)
***************
*** 219,225 ****
        if (err)
        return err;
  
!       /* Has the file type changed? (e.g. from symlink to directory) */
        if ((mode & S_IFMT) != (np->nn_stat.st_mode & S_IFMT))
        {
          char *f = 0;
--- 225,232 ----
        if (err)
        return err;
  
!       /* Has the file type changed? (e.g. from symlink to
!        directory).  */
        if ((mode & S_IFMT) != (np->nn_stat.st_mode & S_IFMT))
        {
          char *f = 0;
***************
*** 258,269 ****
    p = xdr_encode_fhandle (p, &np->nn->handle);
    p = xdr_encode_sattr_mode (p, mode);
    if (protocol_version == 3)
!     *p++ = 0;                 /* guard check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
--- 265,277 ----
    p = xdr_encode_fhandle (p, &np->nn->handle);
    p = xdr_encode_sattr_mode (p, mode);
    if (protocol_version == 3)
!     *(p++) = 0;                       /* guard check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
***************
*** 273,279 ****
  }
  
  /* Implement the netfs_attempt_chflags callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_chflags (struct iouser *cred, struct node *np,
                       int flags)
--- 281,287 ----
  }
  
  /* Implement the netfs_attempt_chflags callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_chflags (struct iouser *cred, struct node *np,
                       int flags)
***************
*** 312,323 ****
                              atime ?: &current,
                              mtime ?: &current);
    if (protocol_version == 3)
!     *p++ = 0;                 /* guard check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
--- 320,332 ----
                              atime ?: &current,
                              mtime ?: &current);
    if (protocol_version == 3)
!     *(p++) = 0;                       /* guard check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
***************
*** 327,333 ****
  }
  
  /* Implement the netfs_attempt_set_size callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_set_size (struct iouser *cred, struct node *np,
                        off_t size)
--- 336,342 ----
  }
  
  /* Implement the netfs_attempt_set_size callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_set_size (struct iouser *cred, struct node *np,
                        off_t size)
***************
*** 344,355 ****
    p = xdr_encode_fhandle (p, &np->nn->handle);
    p = xdr_encode_sattr_size (p, size);
    if (protocol_version == 3)
!     *p++ = 0;                 /* guard_check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
--- 353,365 ----
    p = xdr_encode_fhandle (p, &np->nn->handle);
    p = xdr_encode_sattr_size (p, size);
    if (protocol_version == 3)
!     *(p++) = 0;                       /* guard_check == 0 */
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (!err || protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
***************
*** 390,404 ****
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     err = nfs_error_trans (ntohl (*p++));
  
    if (!err)
      {
        p++;                    /* skip IOSIZE field */
!       st->f_bsize = ntohl (*p++);
!       st->f_blocks = ntohl (*p++);
!       st->f_bfree = ntohl (*p++);
!       st->f_bavail = ntohl (*p++);
        st->f_type = FSTYPE_NFS;
        st->f_files = 0;
        st->f_ffree = 0;
--- 400,421 ----
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
!     }
  
    if (!err)
      {
        p++;                    /* skip IOSIZE field */
!       st->f_bsize = ntohl (*p);
!       p++;
!       st->f_blocks = ntohl (*p);
!       p++;
!       st->f_bfree = ntohl (*p);
!       p++;
!       st->f_bavail = ntohl (*p);
!       p++;
        st->f_type = FSTYPE_NFS;
        st->f_files = 0;
        st->f_ffree = 0;
***************
*** 411,417 ****
  }
  
  /* Implement the netfs_attempt_sync callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_sync (struct iouser *cred, struct node *np, int wait)
  {
--- 428,434 ----
  }
  
  /* Implement the netfs_attempt_sync callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_sync (struct iouser *cred, struct node *np, int wait)
  {
***************
*** 428,434 ****
  }
  
  /* Implement the netfs_attempt_read callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_read (struct iouser *cred, struct node *np,
                    off_t offset, size_t *len, void *data)
--- 445,451 ----
  }
  
  /* Implement the netfs_attempt_read callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_read (struct iouser *cred, struct node *np,
                    off_t offset, size_t *len, void *data)
***************
*** 452,466 ****
          return errno;
  
        p = xdr_encode_fhandle (p, &np->nn->handle);
!       *p++ = htonl (offset);
!       *p++ = htonl (thisamt);
        if (protocol_version == 2)
!       *p++ = 0;
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p++));
  
          if (!err || protocol_version == 3)
            p = process_returned_stat (np, p, !err);
--- 469,484 ----
          return errno;
  
        p = xdr_encode_fhandle (p, &np->nn->handle);
!       *(p++) = htonl (offset);
!       *(p++) = htonl (thisamt);
        if (protocol_version == 2)
!       *(p++) = 0;
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p));
!         p++;
  
          if (!err || protocol_version == 3)
            p = process_returned_stat (np, p, !err);
***************
*** 471,482 ****
              return err;
            }
  
!         trans_len = ntohl (*p++);
          if (trans_len > thisamt)
            trans_len = thisamt;        /* ??? */
  
          if (protocol_version == 3)
!           eof = ntohl (*p++);
          else
            eof = (trans_len < thisamt);
  
--- 489,504 ----
              return err;
            }
  
!         trans_len = ntohl (*p);
!         p++;
          if (trans_len > thisamt)
            trans_len = thisamt;        /* ??? */
  
          if (protocol_version == 3)
!           {
!             eof = ntohl (*p);
!             p++;
!           }
          else
            eof = (trans_len < thisamt);
  
***************
*** 498,504 ****
  }
  
  /* Implement the netfs_attempt_write callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_write (struct iouser *cred, struct node *np,
                     off_t offset, size_t *len, void *data)
--- 520,526 ----
  }
  
  /* Implement the netfs_attempt_write callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_write (struct iouser *cred, struct node *np,
                     off_t offset, size_t *len, void *data)
***************
*** 522,546 ****
  
        p = xdr_encode_fhandle (p, &np->nn->handle);
        if (protocol_version == 2)
!       *p++ = 0;
!       *p++ = htonl (offset);
        if (protocol_version == 2)
!       *p++ = 0;
        if (protocol_version == 3)
!       *p++ = htonl (FILE_SYNC);
        p = xdr_encode_data (p, data, thisamt);
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p++));
          if (!err || protocol_version == 3)
            p = process_wcc_stat (np, p, !err);
          if (!err)
            {
              if (protocol_version == 3)
                {
!                 count = ntohl (*p++);
                  p++;          /* ignore COMMITTED */
                  /* ignore verf for now */
                  p += NFS3_WRITEVERFSIZE / sizeof (int);
--- 544,570 ----
  
        p = xdr_encode_fhandle (p, &np->nn->handle);
        if (protocol_version == 2)
!       *(p++) = 0;
!       *(p++) = htonl (offset);
        if (protocol_version == 2)
!       *(p++) = 0;
        if (protocol_version == 3)
!       *(p++) = htonl (FILE_SYNC);
        p = xdr_encode_data (p, data, thisamt);
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p));
!         p++;
          if (!err || protocol_version == 3)
            p = process_wcc_stat (np, p, !err);
          if (!err)
            {
              if (protocol_version == 3)
                {
!                 count = ntohl (*p);
!                 p++;
                  p++;          /* ignore COMMITTED */
                  /* ignore verf for now */
                  p += NFS3_WRITEVERFSIZE / sizeof (int);
***************
*** 596,602 ****
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     err = nfs_error_trans (ntohl (*p++));
  
    free (rpcbuf);
  
--- 620,629 ----
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
!     }
  
    free (rpcbuf);
  
***************
*** 607,613 ****
  }
  
  /* Implement the netfs_attempt_lookup callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_lookup (struct iouser *cred, struct node *np,
                      char *name, struct node **newnp)
--- 634,640 ----
  }
  
  /* Implement the netfs_attempt_lookup callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_lookup (struct iouser *cred, struct node *np,
                      char *name, struct node **newnp)
***************
*** 649,655 ****
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (!err)
        {
          p = xdr_decode_fhandle (p, newnp);
--- 676,683 ----
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (!err)
        {
          p = xdr_decode_fhandle (p, newnp);
***************
*** 680,686 ****
  }
  
  /* Implement the netfs_attempt_mkdir callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_mkdir (struct iouser *cred, struct node *np,
                     char *name, mode_t mode)
--- 708,714 ----
  }
  
  /* Implement the netfs_attempt_mkdir callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_mkdir (struct iouser *cred, struct node *np,
                     char *name, mode_t mode)
***************
*** 713,719 ****
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     err = nfs_error_trans (ntohl (*p++));
  
    if (!err)
      {
--- 741,750 ----
  
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
!     {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
!     }
  
    if (!err)
      {
***************
*** 735,741 ****
  }
  
  /* Implement the netfs_attempt_rmdir callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_rmdir (struct iouser *cred, struct node *np,
                     char *name)
--- 766,772 ----
  }
  
  /* Implement the netfs_attempt_rmdir callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_rmdir (struct iouser *cred, struct node *np,
                     char *name)
***************
*** 759,765 ****
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
--- 790,797 ----
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (protocol_version == 3)
        p = process_wcc_stat (np, p, !err);
      }
***************
*** 769,775 ****
  }
  
  /* Implement the netfs_attempt_link callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_link (struct iouser *cred, struct node *dir,
                    struct node *np, char *name, int excl)
--- 801,807 ----
  }
  
  /* Implement the netfs_attempt_link callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_link (struct iouser *cred, struct node *dir,
                    struct node *np, char *name, int excl)
***************
*** 819,825 ****
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
!       err = nfs_error_trans (ntohl (*p++));
        mutex_unlock (&dir->lock);
  
        free (rpcbuf);
--- 851,860 ----
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
!       {
!         err = nfs_error_trans (ntohl (*p));
!         p++;
!       }
        mutex_unlock (&dir->lock);
  
        free (rpcbuf);
***************
*** 868,874 ****
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p++));
  
          if (protocol_version == 2 && !err)
            {
--- 903,910 ----
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p));
!         p++;
  
          if (protocol_version == 2 && !err)
            {
***************
*** 890,896 ****
  
              err = conduct_rpc (&rpcbuf, &p);
              if (!err)
!               err = nfs_error_trans (ntohl (*p++));
              if (!err)
                {
                  mutex_lock (&np->lock);
--- 926,935 ----
  
              err = conduct_rpc (&rpcbuf, &p);
              if (!err)
!               {
!                 err = nfs_error_trans (ntohl (*p));
!                 p++;
!               }
              if (!err)
                {
                  mutex_lock (&np->lock);
***************
*** 966,972 ****
                                        _lengthy_ (blocking) conduct_rpc? */
          err = conduct_rpc (&rpcbuf, &p);
          if (!err)
!           err = nfs_error_trans (ntohl (*p++));
  
          if (!err)
            {
--- 1005,1014 ----
                                        _lengthy_ (blocking) conduct_rpc? */
          err = conduct_rpc (&rpcbuf, &p);
          if (!err)
!           {
!             err = nfs_error_trans (ntohl (*p));
!             p++;
!           }
  
          if (!err)
            {
***************
*** 999,1010 ****
              free (rpcbuf);
              return err;
            }
!         *p++ = htonl (hurd_mode_to_nfs_type (np->nn_stat.st_mode));
          p = xdr_encode_sattr_stat (p, &np->nn_stat);
          if (np->nn->dtrans == BLKDEV || np->nn->dtrans == CHRDEV)
            {
!             *p++ = htonl (major (np->nn_stat.st_rdev));
!             *p++ = htonl (minor (np->nn_stat.st_rdev));
            }
          mutex_unlock (&np->lock);
  
--- 1041,1052 ----
              free (rpcbuf);
              return err;
            }
!         *(p++) = htonl (hurd_mode_to_nfs_type (np->nn_stat.st_mode));
          p = xdr_encode_sattr_stat (p, &np->nn_stat);
          if (np->nn->dtrans == BLKDEV || np->nn->dtrans == CHRDEV)
            {
!             *(p++) = htonl (major (np->nn_stat.st_rdev));
!             *(p++) = htonl (minor (np->nn_stat.st_rdev));
            }
          mutex_unlock (&np->lock);
  
***************
*** 1012,1018 ****
          err = conduct_rpc (&rpcbuf, &p);
          if (!err)
            {
!             err = nfs_error_trans (ntohl (*p++));
              if (!err)
                {
                  mutex_lock (&np->lock);
--- 1054,1062 ----
          err = conduct_rpc (&rpcbuf, &p);
          if (!err)
            {
!             err = nfs_error_trans (ntohl (*p));
!             p++;
! 
              if (!err)
                {
                  mutex_lock (&np->lock);
***************
*** 1058,1064 ****
  }
  
  /* Implement the netfs_attempt_mkfile callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_mkfile (struct iouser *cred, struct node *dir,
                      mode_t mode, struct node **newnp)
--- 1102,1108 ----
  }
  
  /* Implement the netfs_attempt_mkfile callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_mkfile (struct iouser *cred, struct node *dir,
                      mode_t mode, struct node **newnp)
***************
*** 1101,1107 ****
  }
  
  /* Implement the netfs_attempt_create_file callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_create_file (struct iouser *cred, struct node *np,
                           char *name, mode_t mode, struct node **newnp)
--- 1145,1151 ----
  }
  
  /* Implement the netfs_attempt_create_file callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_create_file (struct iouser *cred, struct node *np,
                           char *name, mode_t mode, struct node **newnp)
***************
*** 1147,1155 ****
        /* We happen to know this is where the XID is. */
        int verf = *(int *)rpcbuf;
  
!       *p++ = ntohl (EXCLUSIVE);
        /* 8 byte verf */
!       *p++ = ntohl (verf);
        p++;
      }
    else
--- 1191,1199 ----
        /* We happen to know this is where the XID is. */
        int verf = *(int *)rpcbuf;
  
!       *(p++) = ntohl (EXCLUSIVE);
        /* 8 byte verf */
!       *(p++) = ntohl (verf);
        p++;
      }
    else
***************
*** 1161,1167 ****
  
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (!err)
        {
          p = xdr_decode_fhandle (p, newnp);
--- 1205,1212 ----
  
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (!err)
        {
          p = xdr_decode_fhandle (p, newnp);
***************
*** 1192,1198 ****
  }
  
  /* Implement the netfs_attempt_unlink callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_unlink (struct iouser *cred, struct node *dir,
                      char *name)
--- 1237,1243 ----
  }
  
  /* Implement the netfs_attempt_unlink callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_unlink (struct iouser *cred, struct node *dir,
                      char *name)
***************
*** 1283,1289 ****
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (protocol_version == 3)
        p = process_wcc_stat (dir, p, !err);
      }
--- 1328,1335 ----
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (protocol_version == 3)
        p = process_wcc_stat (dir, p, !err);
      }
***************
*** 1294,1300 ****
  }
  
  /* Implement the netfs_attempt_rename callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_rename (struct iouser *cred, struct node *fromdir,
                      char *fromname, struct node *todir, char *toname,
--- 1340,1346 ----
  }
  
  /* Implement the netfs_attempt_rename callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_rename (struct iouser *cred, struct node *fromdir,
                      char *fromname, struct node *todir, char *toname,
***************
*** 1360,1366 ****
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (protocol_version == 3)  /* XXX Should we add `&& !err' ? */
        {
          mutex_lock (&fromdir->lock);
--- 1406,1413 ----
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (protocol_version == 3)  /* XXX Should we add `&& !err' ? */
        {
          mutex_lock (&fromdir->lock);
***************
*** 1374,1380 ****
  }
  
  /* Implement the netfs_attempt_readlink callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_readlink (struct iouser *cred, struct node *np,
                        char *buf)
--- 1421,1427 ----
  }
  
  /* Implement the netfs_attempt_readlink callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_readlink (struct iouser *cred, struct node *np,
                        char *buf)
***************
*** 1399,1405 ****
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p++));
        if (protocol_version == 3)
        p = process_returned_stat (np, p, 0);
        if (!err)
--- 1446,1453 ----
    err = conduct_rpc (&rpcbuf, &p);
    if (!err)
      {
!       err = nfs_error_trans (ntohl (*p));
!       p++;
        if (protocol_version == 3)
        p = process_returned_stat (np, p, 0);
        if (!err)
***************
*** 1411,1417 ****
  }
  
  /* Implement the netfs_check_open_permissions callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_check_open_permissions (struct iouser *cred, struct node *np,
                              int flags, int newnode)
--- 1459,1465 ----
  }
  
  /* Implement the netfs_check_open_permissions callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_check_open_permissions (struct iouser *cred, struct node *np,
                              int flags, int newnode)
***************
*** 1429,1435 ****
  }
  
  /* Implement the netfs_report_access callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_report_access (struct iouser *cred,
                     struct node *np,
--- 1477,1483 ----
  }
  
  /* Implement the netfs_report_access callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_report_access (struct iouser *cred,
                     struct node *np,
***************
*** 1477,1494 ****
        return errno;
  
        p = xdr_encode_fhandle (p, &np->nn->handle);
!       *p++ = htonl (ACCESS3_READ | write_check | execute_check);
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p++));
          p = process_returned_stat (np, p, 0);   /* XXX Should this be
                                                     protected by the
                                                     if (!err) ? */
          if (!err)
            {
!             ret = ntohl (*p++);
              *types = ((ret & ACCESS3_READ ? O_READ : 0)
                        | (ret & write_check ? O_WRITE : 0)
                        | (ret & execute_check ? O_EXEC : 0));
--- 1525,1544 ----
        return errno;
  
        p = xdr_encode_fhandle (p, &np->nn->handle);
!       *(p++) = htonl (ACCESS3_READ | write_check | execute_check);
  
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
        {
!         err = nfs_error_trans (ntohl (*p));
!         p++;
          p = process_returned_stat (np, p, 0);   /* XXX Should this be
                                                     protected by the
                                                     if (!err) ? */
          if (!err)
            {
!             ret = ntohl (*p);
!             p++;
              *types = ((ret & ACCESS3_READ ? O_READ : 0)
                        | (ret & write_check ? O_WRITE : 0)
                        | (ret & execute_check ? O_EXEC : 0));
***************
*** 1499,1505 ****
  }
  
  /* These definitions have unfortunate side effects, don't use them,
!    clever though they are. */
  #if 0
  /* Implement the netfs_check_open_permissions callback as described in
     <hurd/netfs.h>. */
--- 1549,1555 ----
  }
  
  /* These definitions have unfortunate side effects, don't use them,
!    clever though they are.  */
  #if 0
  /* Implement the netfs_check_open_permissions callback as described in
     <hurd/netfs.h>. */
***************
*** 1577,1587 ****
             return failure.  Otherwise, succeed. */
          p = nfs_initialize_rpc (NFSPROC_READDIR, cred, 0, &rpcbuf, np, -1);
          p = xdr_encode_fhandle (p, &np->nn->handle);
!         *p++ = 0;
!         *p++ = htonl (50);
          err = conduct_rpc (&rpcbuf, &p);
          if (!err)
!           err = nfs_error_trans (ntohl (*p++));
          free (rpcbuf);
  
          if (err)
--- 1627,1640 ----
             return failure.  Otherwise, succeed. */
          p = nfs_initialize_rpc (NFSPROC_READDIR, cred, 0, &rpcbuf, np, -1);
          p = xdr_encode_fhandle (p, &np->nn->handle);
!         *(p++) = 0;
!         *(p++) = htonl (50);
          err = conduct_rpc (&rpcbuf, &p);
          if (!err)
!           {
!             err = nfs_error_trans (ntohl (*p));
!             p++;
!           }
          free (rpcbuf);
  
          if (err)
***************
*** 1592,1598 ****
  }
  
  /* Implement the netfs_report_access callback as described in
!    <hurd/netfs.h>. */
  void
  netfs_report_access (struct iouser *cred,
                     struct node *np,
--- 1645,1651 ----
  }
  
  /* Implement the netfs_report_access callback as described in
!    <hurd/netfs.h>.  */
  void
  netfs_report_access (struct iouser *cred,
                     struct node *np,
***************
*** 1642,1648 ****
     *BUFP to that buffer.  *BUFP must be freed by the caller when no
     longer needed.  If an error occurs, don't touch *BUFP and return
     the error code.  Set BUFSIZEP to the amount of data used inside
!    *BUFP and TOTALENTRIES to the total number of entries copied. */
  static error_t
  fetch_directory (struct iouser *cred, struct node *dir,
                 void **bufp, size_t *bufsizep, int *totalentries)
--- 1695,1701 ----
     *BUFP to that buffer.  *BUFP must be freed by the caller when no
     longer needed.  If an error occurs, don't touch *BUFP and return
     the error code.  Set BUFSIZEP to the amount of data used inside
!    *BUFP and TOTALENTRIES to the total number of entries copied.  */
  static error_t
  fetch_directory (struct iouser *cred, struct node *dir,
                 void **bufp, size_t *bufsizep, int *totalentries)
***************
*** 1681,1698 ****
        }
  
        p = xdr_encode_fhandle (p, &dir->nn->handle);
!       *p++ = cookie;
!       *p++ = ntohl (read_size);
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
!       err = nfs_error_trans (ntohl (*p++));
        if (err)
        {
          free (buf);
          return err;
        }
  
!       isnext = ntohl (*p++);
  
        /* Now copy them one at a time. */
        while (isnext)
--- 1734,1755 ----
        }
  
        p = xdr_encode_fhandle (p, &dir->nn->handle);
!       *(p++) = cookie;
!       *(p++) = ntohl (read_size);
        err = conduct_rpc (&rpcbuf, &p);
        if (!err)
!       {
!         err = nfs_error_trans (ntohl (*p));
!         p++;
!       }
        if (err)
        {
          free (buf);
          return err;
        }
  
!       isnext = ntohl (*p);
!       p++;
  
        /* Now copy them one at a time. */
        while (isnext)
***************
*** 1701,1708 ****
          int namlen;
          int reclen;
  
!         fileno = ntohl (*p++);
!         namlen = ntohl (*p++);
  
          /* There's a hidden +1 here for the null byte and -1 because d_name
             has a size of one already in the sizeof.  */
--- 1758,1767 ----
          int namlen;
          int reclen;
  
!         fileno = ntohl (*p);
!         p++;
!         namlen = ntohl (*p);
!         p++;
  
          /* There's a hidden +1 here for the null byte and -1 because d_name
             has a size of one already in the sizeof.  */
***************
*** 1727,1733 ****
          entry->d_reclen = reclen;
          entry->d_type = DT_UNKNOWN;
          entry->d_namlen = namlen;
!         bcopy (p, entry->d_name, namlen);
          entry->d_name[namlen] = '\0';
  
          p += INTSIZE (namlen);
--- 1786,1792 ----
          entry->d_reclen = reclen;
          entry->d_type = DT_UNKNOWN;
          entry->d_namlen = namlen;
!         memcpy (entry->d_name, p, namlen);
          entry->d_name[namlen] = '\0';
  
          p += INTSIZE (namlen);
***************
*** 1735,1745 ****
  
          ++*totalentries;
  
!         cookie = *p++;
!         isnext = ntohl (*p++);
        }
  
!       eof = ntohl (*p++);
        free (rpcbuf);
      }
  
--- 1794,1806 ----
  
          ++*totalentries;
  
!         cookie = *(p++);
!         isnext = ntohl (*p);
!         p++;
        }
  
!       eof = ntohl (*p);
!       p++;
        free (rpcbuf);
      }
  
***************
*** 1751,1757 ****
  
  
  /* Implement the netfs_get_directs callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_get_dirents (struct iouser *cred, struct node *np,
                   int entry, int nentries, char **data,
--- 1812,1818 ----
  
  
  /* Implement the netfs_get_directs callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_get_dirents (struct iouser *cred, struct node *np,
                   int entry, int nentries, char **data,
***************
*** 1821,1827 ****
  
  
  /* Implement the netfs_set_translator callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_set_translator (struct iouser *cred,
                      struct node *np,
--- 1882,1888 ----
  
  
  /* Implement the netfs_set_translator callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_set_translator (struct iouser *cred,
                      struct node *np,
***************
*** 1832,1838 ****
  }
  
  /* Implement the netfs_attempt_mksymlink callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_mksymlink (struct iouser *cred,
                         struct node *np,
--- 1893,1899 ----
  }
  
  /* Implement the netfs_attempt_mksymlink callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_mksymlink (struct iouser *cred,
                         struct node *np,
***************
*** 1852,1858 ****
  }
  
  /* Implement the netfs_attempt_mkdev callback as described in
!    <hurd/netfs.h>. */
  error_t
  netfs_attempt_mkdev (struct iouser *cred,
                     struct node *np,
--- 1913,1919 ----
  }
  
  /* Implement the netfs_attempt_mkdev callback as described in
!    <hurd/netfs.h>.  */
  error_t
  netfs_attempt_mkdev (struct iouser *cred,
                     struct node *np,
Index: hurd/nfs/rpc.c
diff -c hurd/nfs/rpc.c:1.11 hurd/nfs/rpc.c:1.12
*** hurd/nfs/rpc.c:1.11 Tue Mar 26 14:07:55 2002
--- hurd/nfs/rpc.c      Sun Sep 29 11:11:59 2002
***************
*** 1,4 ****
! /* SunRPC management for NFS client
     Copyright (C) 1994, 1995, 1996, 1997, 2002 Free Software Foundation
  
     This program is free software; you can redistribute it and/or
--- 1,4 ----
! /* rpc.c - SunRPC management for NFS client.
     Copyright (C) 1994, 1995, 1996, 1997, 2002 Free Software Foundation
  
     This program is free software; you can redistribute it and/or
***************
*** 17,26 ****
  
  #include "nfs.h"
  
! /* Needed in order to get the RPC header files to include correctly */
  #undef TRUE
  #undef FALSE
! #define malloc spoiufasdf     /* Avoid bogus definition in rpc/types.h */
  
  #include <rpc/types.h>
  #include <rpc/xdr.h>
--- 17,26 ----
  
  #include "nfs.h"
  
! /* Needed in order to get the RPC header files to include correctly.  */
  #undef TRUE
  #undef FALSE
! #define malloc spoiufasdf     /* Avoid bogus definition in rpc/types.h.  */
  
  #include <rpc/types.h>
  #include <rpc/xdr.h>
***************
*** 28,34 ****
  #include <rpc/rpc_msg.h>
  #include <rpc/auth_unix.h>
  
! #undef malloc                 /* Get rid of the sun block */
  
  #include <netinet/in.h>
  #include <assert.h>
--- 28,34 ----
  #include <rpc/rpc_msg.h>
  #include <rpc/auth_unix.h>
  
! #undef malloc                 /* Get rid of the sun block.  */
  
  #include <netinet/in.h>
  #include <assert.h>
***************
*** 37,62 ****
  #include <unistd.h>
  #include <stdio.h>
  
! /* One of these exists for each pending RPC. */
  struct rpc_list
  {
    struct rpc_list *next, **prevp;
    void *reply;
  };
  
! /* A list of all pending RPCs. */
  static struct rpc_list *outstanding_rpcs;
  
  /* Wake up this condition when an outstanding RPC has received a reply
!    or we should check for timeouts. */
  static struct condition rpc_wakeup = CONDITION_INITIALIZER;
  
! /* Lock the global data and the REPLY fields of outstanding RPC's. */
  static struct mutex outstanding_lock = MUTEX_INITIALIZER;
  
  
  
! /* Generate and return a new transaction ID. */
  static inline int
  generate_xid ()
  {
--- 37,62 ----
  #include <unistd.h>
  #include <stdio.h>
  
! /* One of these exists for each pending RPC.  */
  struct rpc_list
  {
    struct rpc_list *next, **prevp;
    void *reply;
  };
  
! /* A list of all pending RPCs.  */
  static struct rpc_list *outstanding_rpcs;
  
  /* Wake up this condition when an outstanding RPC has received a reply
!    or we should check for timeouts.  */
  static struct condition rpc_wakeup = CONDITION_INITIALIZER;
  
! /* Lock the global data and the REPLY fields of outstanding RPC's.  */
  static struct mutex outstanding_lock = MUTEX_INITIALIZER;
  
  
  
! /* Generate and return a new transaction ID.  */
  static inline int
  generate_xid ()
  {
***************
*** 76,82 ****
     may be -1 to indicate that it does not apply, however, exactly zero
     or two of UID and GID must be -1.  The returned address is a pointer
     to the start of the payload.  If NULL is returned, an error occured
!    and the code is set in errno. */
  int *
  initialize_rpc (int program, int version, int rpc_proc, 
                size_t len, void **bufp, 
--- 76,82 ----
     may be -1 to indicate that it does not apply, however, exactly zero
     or two of UID and GID must be -1.  The returned address is a pointer
     to the start of the payload.  If NULL is returned, an error occured
!    and the code is set in errno.  */
  int *
  initialize_rpc (int program, int version, int rpc_proc, 
                size_t len, void **bufp, 
***************
*** 100,151 ****
    p = buf + sizeof (struct rpc_list);
  
    /* RPC header */
!   *p++ = htonl (generate_xid ());
!   *p++ = htonl (CALL);
!   *p++ = htonl (RPC_MSG_VERSION);
!   *p++ = htonl (program);
!   *p++ = htonl (version);
!   *p++ = htonl (rpc_proc);
    
    assert ((uid == -1) == (gid == -1));
  
    if (uid == -1)
      {
        /* No authentication */
!       *p++ = htonl (AUTH_NONE);
!       *p++ = 0;
      }
    else
      {
        /* Unixy authentication */
!       *p++ = htonl (AUTH_UNIX);
        /* The length of the message.  We do not yet know what this
           is, so, just remember where we should put it when we know */
        lenaddr = p++;
!       *p++ = htonl (mapped_time->seconds);
        p = xdr_encode_string (p, hostname);
!       *p++ = htonl (uid);
!       *p++ = htonl (gid);
        if (second_gid == -1)
!       *p++ = 0;
        else
        {
!         *p++ = htonl (1);
!         *p++ = htonl (second_gid);
        }
        *lenaddr = htonl ((p - (lenaddr + 1)) * sizeof (int));
      }
          
    /* VERF field */
!   *p++ = htonl (AUTH_NONE);
!   *p++ = 0;
    
    *bufp = buf;
    return p;
  }
  
  /* Remove HDR from the list of pending RPC's.  The rpc_list's lock
!    (OUTSTANDING_LOCK) must be held */
  static inline void
  unlink_rpc (struct rpc_list *hdr)
  {
--- 100,151 ----
    p = buf + sizeof (struct rpc_list);
  
    /* RPC header */
!   *(p++) = htonl (generate_xid ());
!   *(p++) = htonl (CALL);
!   *(p++) = htonl (RPC_MSG_VERSION);
!   *(p++) = htonl (program);
!   *(p++) = htonl (version);
!   *(p++) = htonl (rpc_proc);
    
    assert ((uid == -1) == (gid == -1));
  
    if (uid == -1)
      {
        /* No authentication */
!       *(p++) = htonl (AUTH_NONE);
!       *(p++) = 0;
      }
    else
      {
        /* Unixy authentication */
!       *(p++) = htonl (AUTH_UNIX);
        /* The length of the message.  We do not yet know what this
           is, so, just remember where we should put it when we know */
        lenaddr = p++;
!       *(p++) = htonl (mapped_time->seconds);
        p = xdr_encode_string (p, hostname);
!       *(p++) = htonl (uid);
!       *(p++) = htonl (gid);
        if (second_gid == -1)
!       *(p++) = 0;
        else
        {
!         *(p++) = htonl (1);
!         *(p++) = htonl (second_gid);
        }
        *lenaddr = htonl ((p - (lenaddr + 1)) * sizeof (int));
      }
          
    /* VERF field */
!   *(p++) = htonl (AUTH_NONE);
!   *(p++) = 0;
    
    *bufp = buf;
    return p;
  }
  
  /* Remove HDR from the list of pending RPC's.  The rpc_list's lock
!    (OUTSTANDING_LOCK) must be held.  */
  static inline void
  unlink_rpc (struct rpc_list *hdr)
  {
***************
*** 155,161 ****
  }
  
  /* Insert HDR at the head of the LIST.  The rpc_list's lock
!    (OUTSTANDING_LOCK) must be held */
  static inline void
  link_rpc (struct rpc_list **list, struct rpc_list *hdr)
  {
--- 155,161 ----
  }
  
  /* Insert HDR at the head of the LIST.  The rpc_list's lock
!    (OUTSTANDING_LOCK) must be held.  */
  static inline void
  link_rpc (struct rpc_list **list, struct rpc_list *hdr)
  {
***************
*** 171,177 ****
     the filledin args.  Set *PP to the address of the reply contents
     themselves.  The user will be expected to free *RPCBUF (which will
     have changed) when done with the reply contents.  The old value of
!    *RPCBUF will be freed by this routine. */
  error_t
  conduct_rpc (void **rpcbuf, int **pp)
  {
--- 171,177 ----
     the filledin args.  Set *PP to the address of the reply contents
     themselves.  The user will be expected to free *RPCBUF (which will
     have changed) when done with the reply contents.  The old value of
!    *RPCBUF will be freed by this routine.  */
  error_t
  conduct_rpc (void **rpcbuf, int **pp)
  {
***************
*** 194,200 ****
  
    do
      {
!       /* If we've sent enough, give up */
        if (mounted_soft && ntransmit == soft_retries)
        {
          unlink_rpc (hdr);
--- 194,200 ----
  
    do
      {
!       /* If we've sent enough, give up.  */
        if (mounted_soft && ntransmit == soft_retries)
        {
          unlink_rpc (hdr);
***************
*** 202,208 ****
          return ETIMEDOUT;
        }
  
!       /* Issue the RPC */
        lasttrans = mapped_time->seconds;
        ntransmit++;
        nc = (void *) *pp - *rpcbuf - sizeof (struct rpc_list);
--- 202,208 ----
          return ETIMEDOUT;
        }
  
!       /* Issue the RPC.  */
        lasttrans = mapped_time->seconds;
        ntransmit++;
        nc = (void *) *pp - *rpcbuf - sizeof (struct rpc_list);
***************
*** 216,222 ****
        else 
        assert (cc == nc);
        
!       /* Wait for reply */
        cancel = 0;
        while (!hdr->reply
             && (mapped_time->seconds - lasttrans < timeout)
--- 216,222 ----
        else 
        assert (cc == nc);
        
!       /* Wait for reply.  */
        cancel = 0;
        while (!hdr->reply
             && (mapped_time->seconds - lasttrans < timeout)
***************
*** 232,238 ****
  
        /* hdr->reply will have been filled in by rpc_receive_thread,
           if it has been filled in, then the rpc has been fulfilled,
!          otherwise, retransmit and continue to wait */
        if (!hdr->reply)
        {
          timeout *= 2;
--- 232,238 ----
  
        /* hdr->reply will have been filled in by rpc_receive_thread,
           if it has been filled in, then the rpc has been fulfilled,
!          otherwise, retransmit and continue to wait.  */
        if (!hdr->reply)
        {
          timeout *= 2;
***************
*** 244,277 ****
  
    mutex_unlock (&outstanding_lock);
  
!   /* Switch to the reply buffer. */
    *rpcbuf = hdr->reply;
    free (hdr);
  
    /* Process the reply, dissecting errors.  When we're done and if
!      there is no error, set *PP to the rpc return contents */ 
    p = (int *) *rpcbuf;
    
    /* If the transmition id does not match that in the message,
!      something strange happened in rpc_receive_thread */
    assert (*p == xid);
    p++;
    
!   switch (ntohl (*p++))
      {
      default:
        err = EBADRPC;
        break;
        
      case REPLY:
!       switch (ntohl (*p++))
        {
        default:
          err = EBADRPC;
          break;
          
        case MSG_DENIED:
!         switch (ntohl (*p++))
            {
            default:
              err = EBADRPC;
--- 244,279 ----
  
    mutex_unlock (&outstanding_lock);
  
!   /* Switch to the reply buffer.  */
    *rpcbuf = hdr->reply;
    free (hdr);
  
    /* Process the reply, dissecting errors.  When we're done and if
!      there is no error, set *PP to the rpc return contents.  */ 
    p = (int *) *rpcbuf;
    
    /* If the transmition id does not match that in the message,
!      something strange happened in rpc_receive_thread.  */
    assert (*p == xid);
    p++;
    
!   switch (ntohl (*p))
      {
      default:
        err = EBADRPC;
        break;
        
      case REPLY:
!       p++;
!       switch (ntohl (*p))
        {
        default:
          err = EBADRPC;
          break;
          
        case MSG_DENIED:
!         p++;
!         switch (ntohl (*p))
            {
            default:
              err = EBADRPC;
***************
*** 282,288 ****
              break;
                      
            case AUTH_ERROR:
!             switch (ntohl (*p++))
                {
                case AUTH_BADCRED:
                case AUTH_REJECTEDCRED:
--- 284,291 ----
              break;
                      
            case AUTH_ERROR:
!             p++;
!             switch (ntohl (*p))
                {
                case AUTH_BADCRED:
                case AUTH_REJECTEDCRED:
***************
*** 304,316 ****
          break;
          
        case MSG_ACCEPTED:
  
!         /* Process VERF field. */
!         p++;                  /* skip verf type */
!         n = ntohl (*p++);     /* size of verf */
!         p += INTSIZE (n);     /* skip verf itself */
  
!         switch (ntohl (*p++))
            {
            default:
            case GARBAGE_ARGS:
--- 307,321 ----
          break;
          
        case MSG_ACCEPTED:
+         p++;
  
!         /* Process VERF field.  */
!         p++;                  /* Skip verf type.  */
!         n = ntohl (*p);       /* Size of verf.  */
!         p++;
!         p += INTSIZE (n);     /* Skip verf itself.  */
  
!         switch (ntohl (*p))
            {
            default:
            case GARBAGE_ARGS:
***************
*** 330,335 ****
--- 335,341 ----
              break;
  
            case SUCCESS:
+             p++;
              *pp = p;
              err = 0;
              break;
***************
*** 342,348 ****
  }
  
  /* Dedicated thread to signal those waiting on rpc_wakeup
!    once a second. */
  void
  timeout_service_thread ()
  {
--- 348,354 ----
  }
  
  /* Dedicated thread to signal those waiting on rpc_wakeup
!    once a second.  */
  void
  timeout_service_thread ()
  {
***************
*** 356,368 ****
  }
  
  /* Dedicate thread to receive RPC replies, register them on the queue
!    of pending wakeups, and deal appropriately. */
  void
  rpc_receive_thread ()
  {
    void *buf;
  
!   /* Allocate a receive buffer */
    buf = malloc (1024 + read_size);
    assert (buf);
  
--- 362,374 ----
  }
  
  /* Dedicate thread to receive RPC replies, register them on the queue
!    of pending wakeups, and deal appropriately.  */
  void
  rpc_receive_thread ()
  {
    void *buf;
  
!   /* Allocate a receive buffer.  */
    buf = malloc (1024 + read_size);
    assert (buf);
  
***************
*** 381,387 ****
  
            mutex_lock (&outstanding_lock);
  
!           /* Find the rpc that we just fulfilled */
            for (r = outstanding_rpcs; r; r = r->next)
            {
              if (* (int *) &r[1] == xid)
--- 387,393 ----
  
            mutex_lock (&outstanding_lock);
  
!           /* Find the rpc that we just fulfilled.  */
            for (r = outstanding_rpcs; r; r = r->next)
            {
              if (* (int *) &r[1] == xid)
***************
*** 399,406 ****
          mutex_unlock (&outstanding_lock);
  
          /* If r is not null then we had a message from a pending
!            (i.e. known) rpc.  Thus, it was fulfilled and if we
!            want to get another request, a new buffer is needed */
          if (r)
            {
                buf = malloc (1024 + read_size);
--- 405,412 ----
          mutex_unlock (&outstanding_lock);
  
          /* If r is not null then we had a message from a pending
!            (i.e. known) rpc.  Thus, it was fulfilled and if we want
!            to get another request, a new buffer is needed.  */
          if (r)
            {
                buf = malloc (1024 + read_size);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]