diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index 2470a8c35393..0c3a4c90b07d 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -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;