Author: rmacklem
Date: Thu May  5 00:11:09 2011
New Revision: 221467
URL: http://svn.freebsd.org/changeset/base/221467

Log:
  Fix the new NFS client so that it handles the 64bit fields
  that are now in "struct statfs" for NFSv3 and NFSv4. Since
  the ffiles value is uint64_t on the wire, I clip the value
  to INT64_MAX to avoid setting f_ffree negative.
  
  Tested by:    kib
  MFC after:    2 weeks

Modified:
  head/sys/fs/nfsclient/nfs_clport.c

Modified: head/sys/fs/nfsclient/nfs_clport.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clport.c  Wed May  4 23:41:11 2011        
(r221466)
+++ head/sys/fs/nfsclient/nfs_clport.c  Thu May  5 00:11:09 2011        
(r221467)
@@ -838,21 +838,33 @@ void
 nfscl_loadsbinfo(struct nfsmount *nmp, struct nfsstatfs *sfp, void *statfs)
 {
        struct statfs *sbp = (struct statfs *)statfs;
-       nfsquad_t tquad;
 
        if (nmp->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4)) {
                sbp->f_bsize = NFS_FABLKSIZE;
-               tquad.qval = sfp->sf_tbytes;
-               sbp->f_blocks = (long)(tquad.qval / ((u_quad_t)NFS_FABLKSIZE));
-               tquad.qval = sfp->sf_fbytes;
-               sbp->f_bfree = (long)(tquad.qval / ((u_quad_t)NFS_FABLKSIZE));
-               tquad.qval = sfp->sf_abytes;
-               sbp->f_bavail = (long)(tquad.qval / ((u_quad_t)NFS_FABLKSIZE));
-               tquad.qval = sfp->sf_tfiles;
-               sbp->f_files = (tquad.lval[0] & 0x7fffffff);
-               tquad.qval = sfp->sf_ffiles;
-               sbp->f_ffree = (tquad.lval[0] & 0x7fffffff);
+               sbp->f_blocks = sfp->sf_tbytes / NFS_FABLKSIZE;
+               sbp->f_bfree = sfp->sf_fbytes / NFS_FABLKSIZE;
+               /*
+                * Although sf_abytes is uint64_t and f_bavail is int64_t,
+                * the value after dividing by NFS_FABLKSIZE is small
+                * enough that it will fit in 63bits, so it is ok to
+                * assign it to f_bavail without fear that it will become
+                * negative.
+                */
+               sbp->f_bavail = sfp->sf_abytes / NFS_FABLKSIZE;
+               sbp->f_files = sfp->sf_tfiles;
+               /* Since f_ffree is int64_t, clip it to 63bits. */
+               if (sfp->sf_ffiles > INT64_MAX)
+                       sbp->f_ffree = INT64_MAX;
+               else
+                       sbp->f_ffree = sfp->sf_ffiles;
        } else if ((nmp->nm_flag & NFSMNT_NFSV4) == 0) {
+               /*
+                * The type casts to (int32_t) ensure that this code is
+                * compatible with the old NFS client, in that it will
+                * propagate bit31 to the high order bits. This may or may
+                * not be correct for NFSv2, but since it is a legacy
+                * environment, I'd rather retain backwards compatibility.
+                */
                sbp->f_bsize = (int32_t)sfp->sf_bsize;
                sbp->f_blocks = (int32_t)sfp->sf_blocks;
                sbp->f_bfree = (int32_t)sfp->sf_bfree;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to